1 /* 2 * $Id: block2mtd.c,v 1.30 2005/11/29 14:48:32 gleixner Exp $ 3 * 4 * block2mtd.c - create an mtd from a block device 5 * 6 * Copyright (C) 2001,2002 Simon Evans <spse@secret.org.uk> 7 * Copyright (C) 2004-2006 Joern Engel <joern@wh.fh-wedel.de> 8 * 9 * Licence: GPL 10 */ 11 #include <linux/module.h> 12 #include <linux/fs.h> 13 #include <linux/blkdev.h> 14 #include <linux/bio.h> 15 #include <linux/pagemap.h> 16 #include <linux/list.h> 17 #include <linux/init.h> 18 #include <linux/mtd/mtd.h> 19 #include <linux/buffer_head.h> 20 #include <linux/mutex.h> 21 #include <linux/mount.h> 22 23 #define VERSION "$Revision: 1.30 $" 24 25 26 #define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args) 27 #define INFO(fmt, args...) printk(KERN_INFO "block2mtd: " fmt "\n" , ## args) 28 29 30 /* Info for the block device */ 31 struct block2mtd_dev { 32 struct list_head list; 33 struct block_device *blkdev; 34 struct mtd_info mtd; 35 struct mutex write_mutex; 36 }; 37 38 39 /* Static info about the MTD, used in cleanup_module */ 40 static LIST_HEAD(blkmtd_device_list); 41 42 43 static struct page *page_read(struct address_space *mapping, int index) 44 { 45 return read_mapping_page(mapping, index, NULL); 46 } 47 48 /* erase a specified part of the device */ 49 static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len) 50 { 51 struct address_space *mapping = dev->blkdev->bd_inode->i_mapping; 52 struct page *page; 53 int index = to >> PAGE_SHIFT; // page index 54 int pages = len >> PAGE_SHIFT; 55 u_long *p; 56 u_long *max; 57 58 while (pages) { 59 page = page_read(mapping, index); 60 if (!page) 61 return -ENOMEM; 62 if (IS_ERR(page)) 63 return PTR_ERR(page); 64 65 max = page_address(page) + PAGE_SIZE; 66 for (p=page_address(page); p<max; p++) 67 if (*p != -1UL) { 68 lock_page(page); 69 memset(page_address(page), 0xff, PAGE_SIZE); 70 set_page_dirty(page); 71 unlock_page(page); 72 break; 73 } 74 75 page_cache_release(page); 76 pages--; 77 index++; 78 } 79 return 0; 80 } 81 static int block2mtd_erase(struct mtd_info *mtd, struct erase_info *instr) 82 { 83 struct block2mtd_dev *dev = mtd->priv; 84 size_t from = instr->addr; 85 size_t len = instr->len; 86 int err; 87 88 instr->state = MTD_ERASING; 89 mutex_lock(&dev->write_mutex); 90 err = _block2mtd_erase(dev, from, len); 91 mutex_unlock(&dev->write_mutex); 92 if (err) { 93 ERROR("erase failed err = %d", err); 94 instr->state = MTD_ERASE_FAILED; 95 } else 96 instr->state = MTD_ERASE_DONE; 97 98 instr->state = MTD_ERASE_DONE; 99 mtd_erase_callback(instr); 100 return err; 101 } 102 103 104 static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len, 105 size_t *retlen, u_char *buf) 106 { 107 struct block2mtd_dev *dev = mtd->priv; 108 struct page *page; 109 int index = from >> PAGE_SHIFT; 110 int offset = from & (PAGE_SIZE-1); 111 int cpylen; 112 113 if (from > mtd->size) 114 return -EINVAL; 115 if (from + len > mtd->size) 116 len = mtd->size - from; 117 118 if (retlen) 119 *retlen = 0; 120 121 while (len) { 122 if ((offset + len) > PAGE_SIZE) 123 cpylen = PAGE_SIZE - offset; // multiple pages 124 else 125 cpylen = len; // this page 126 len = len - cpylen; 127 128 page = page_read(dev->blkdev->bd_inode->i_mapping, index); 129 if (!page) 130 return -ENOMEM; 131 if (IS_ERR(page)) 132 return PTR_ERR(page); 133 134 memcpy(buf, page_address(page) + offset, cpylen); 135 page_cache_release(page); 136 137 if (retlen) 138 *retlen += cpylen; 139 buf += cpylen; 140 offset = 0; 141 index++; 142 } 143 return 0; 144 } 145 146 147 /* write data to the underlying device */ 148 static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf, 149 loff_t to, size_t len, size_t *retlen) 150 { 151 struct page *page; 152 struct address_space *mapping = dev->blkdev->bd_inode->i_mapping; 153 int index = to >> PAGE_SHIFT; // page index 154 int offset = to & ~PAGE_MASK; // page offset 155 int cpylen; 156 157 if (retlen) 158 *retlen = 0; 159 while (len) { 160 if ((offset+len) > PAGE_SIZE) 161 cpylen = PAGE_SIZE - offset; // multiple pages 162 else 163 cpylen = len; // this page 164 len = len - cpylen; 165 166 page = page_read(mapping, index); 167 if (!page) 168 return -ENOMEM; 169 if (IS_ERR(page)) 170 return PTR_ERR(page); 171 172 if (memcmp(page_address(page)+offset, buf, cpylen)) { 173 lock_page(page); 174 memcpy(page_address(page) + offset, buf, cpylen); 175 set_page_dirty(page); 176 unlock_page(page); 177 } 178 page_cache_release(page); 179 180 if (retlen) 181 *retlen += cpylen; 182 183 buf += cpylen; 184 offset = 0; 185 index++; 186 } 187 return 0; 188 } 189 190 191 static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len, 192 size_t *retlen, const u_char *buf) 193 { 194 struct block2mtd_dev *dev = mtd->priv; 195 int err; 196 197 if (!len) 198 return 0; 199 if (to >= mtd->size) 200 return -ENOSPC; 201 if (to + len > mtd->size) 202 len = mtd->size - to; 203 204 mutex_lock(&dev->write_mutex); 205 err = _block2mtd_write(dev, buf, to, len, retlen); 206 mutex_unlock(&dev->write_mutex); 207 if (err > 0) 208 err = 0; 209 return err; 210 } 211 212 213 /* sync the device - wait until the write queue is empty */ 214 static void block2mtd_sync(struct mtd_info *mtd) 215 { 216 struct block2mtd_dev *dev = mtd->priv; 217 sync_blockdev(dev->blkdev); 218 return; 219 } 220 221 222 static void block2mtd_free_device(struct block2mtd_dev *dev) 223 { 224 if (!dev) 225 return; 226 227 kfree(dev->mtd.name); 228 229 if (dev->blkdev) { 230 invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, 231 0, -1); 232 close_bdev_excl(dev->blkdev); 233 } 234 235 kfree(dev); 236 } 237 238 239 /* FIXME: ensure that mtd->size % erase_size == 0 */ 240 static struct block2mtd_dev *add_device(char *devname, int erase_size) 241 { 242 struct block_device *bdev; 243 struct block2mtd_dev *dev; 244 char *name; 245 246 if (!devname) 247 return NULL; 248 249 dev = kzalloc(sizeof(struct block2mtd_dev), GFP_KERNEL); 250 if (!dev) 251 return NULL; 252 253 /* Get a handle on the device */ 254 bdev = open_bdev_excl(devname, O_RDWR, NULL); 255 #ifndef MODULE 256 if (IS_ERR(bdev)) { 257 258 /* We might not have rootfs mounted at this point. Try 259 to resolve the device name by other means. */ 260 261 dev_t devt = name_to_dev_t(devname); 262 if (devt) { 263 bdev = open_by_devnum(devt, FMODE_WRITE | FMODE_READ); 264 } 265 } 266 #endif 267 268 if (IS_ERR(bdev)) { 269 ERROR("error: cannot open device %s", devname); 270 goto devinit_err; 271 } 272 dev->blkdev = bdev; 273 274 if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) { 275 ERROR("attempting to use an MTD device as a block device"); 276 goto devinit_err; 277 } 278 279 mutex_init(&dev->write_mutex); 280 281 /* Setup the MTD structure */ 282 /* make the name contain the block device in */ 283 name = kmalloc(sizeof("block2mtd: ") + strlen(devname) + 1, 284 GFP_KERNEL); 285 if (!name) 286 goto devinit_err; 287 288 sprintf(name, "block2mtd: %s", devname); 289 dev->mtd.name = name; 290 291 dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; 292 dev->mtd.erasesize = erase_size; 293 dev->mtd.writesize = 1; 294 dev->mtd.type = MTD_RAM; 295 dev->mtd.flags = MTD_CAP_RAM; 296 dev->mtd.erase = block2mtd_erase; 297 dev->mtd.write = block2mtd_write; 298 dev->mtd.writev = default_mtd_writev; 299 dev->mtd.sync = block2mtd_sync; 300 dev->mtd.read = block2mtd_read; 301 dev->mtd.priv = dev; 302 dev->mtd.owner = THIS_MODULE; 303 304 if (add_mtd_device(&dev->mtd)) { 305 /* Device didnt get added, so free the entry */ 306 goto devinit_err; 307 } 308 list_add(&dev->list, &blkmtd_device_list); 309 INFO("mtd%d: [%s] erase_size = %dKiB [%d]", dev->mtd.index, 310 dev->mtd.name + strlen("block2mtd: "), 311 dev->mtd.erasesize >> 10, dev->mtd.erasesize); 312 return dev; 313 314 devinit_err: 315 block2mtd_free_device(dev); 316 return NULL; 317 } 318 319 320 /* This function works similar to reguler strtoul. In addition, it 321 * allows some suffixes for a more human-readable number format: 322 * ki, Ki, kiB, KiB - multiply result with 1024 323 * Mi, MiB - multiply result with 1024^2 324 * Gi, GiB - multiply result with 1024^3 325 */ 326 static int ustrtoul(const char *cp, char **endp, unsigned int base) 327 { 328 unsigned long result = simple_strtoul(cp, endp, base); 329 switch (**endp) { 330 case 'G' : 331 result *= 1024; 332 case 'M': 333 result *= 1024; 334 case 'K': 335 case 'k': 336 result *= 1024; 337 /* By dwmw2 editorial decree, "ki", "Mi" or "Gi" are to be used. */ 338 if ((*endp)[1] == 'i') { 339 if ((*endp)[2] == 'B') 340 (*endp) += 3; 341 else 342 (*endp) += 2; 343 } 344 } 345 return result; 346 } 347 348 349 static int parse_num(size_t *num, const char *token) 350 { 351 char *endp; 352 size_t n; 353 354 n = (size_t) ustrtoul(token, &endp, 0); 355 if (*endp) 356 return -EINVAL; 357 358 *num = n; 359 return 0; 360 } 361 362 363 static inline void kill_final_newline(char *str) 364 { 365 char *newline = strrchr(str, '\n'); 366 if (newline && !newline[1]) 367 *newline = 0; 368 } 369 370 371 #define parse_err(fmt, args...) do { \ 372 ERROR(fmt, ## args); \ 373 return 0; \ 374 } while (0) 375 376 #ifndef MODULE 377 static int block2mtd_init_called = 0; 378 static char block2mtd_paramline[80 + 12]; /* 80 for device, 12 for erase size */ 379 #endif 380 381 382 static int block2mtd_setup2(const char *val) 383 { 384 char buf[80 + 12]; /* 80 for device, 12 for erase size */ 385 char *str = buf; 386 char *token[2]; 387 char *name; 388 size_t erase_size = PAGE_SIZE; 389 int i, ret; 390 391 if (strnlen(val, sizeof(buf)) >= sizeof(buf)) 392 parse_err("parameter too long"); 393 394 strcpy(str, val); 395 kill_final_newline(str); 396 397 for (i = 0; i < 2; i++) 398 token[i] = strsep(&str, ","); 399 400 if (str) 401 parse_err("too many arguments"); 402 403 if (!token[0]) 404 parse_err("no argument"); 405 406 name = token[0]; 407 if (strlen(name) + 1 > 80) 408 parse_err("device name too long"); 409 410 if (token[1]) { 411 ret = parse_num(&erase_size, token[1]); 412 if (ret) { 413 parse_err("illegal erase size"); 414 } 415 } 416 417 add_device(name, erase_size); 418 419 return 0; 420 } 421 422 423 static int block2mtd_setup(const char *val, struct kernel_param *kp) 424 { 425 #ifdef MODULE 426 return block2mtd_setup2(val); 427 #else 428 /* If more parameters are later passed in via 429 /sys/module/block2mtd/parameters/block2mtd 430 and block2mtd_init() has already been called, 431 we can parse the argument now. */ 432 433 if (block2mtd_init_called) 434 return block2mtd_setup2(val); 435 436 /* During early boot stage, we only save the parameters 437 here. We must parse them later: if the param passed 438 from kernel boot command line, block2mtd_setup() is 439 called so early that it is not possible to resolve 440 the device (even kmalloc() fails). Deter that work to 441 block2mtd_setup2(). */ 442 443 strlcpy(block2mtd_paramline, val, sizeof(block2mtd_paramline)); 444 445 return 0; 446 #endif 447 } 448 449 450 module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200); 451 MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>]\""); 452 453 static int __init block2mtd_init(void) 454 { 455 int ret = 0; 456 INFO("version " VERSION); 457 458 #ifndef MODULE 459 if (strlen(block2mtd_paramline)) 460 ret = block2mtd_setup2(block2mtd_paramline); 461 block2mtd_init_called = 1; 462 #endif 463 464 return ret; 465 } 466 467 468 static void __devexit block2mtd_exit(void) 469 { 470 struct list_head *pos, *next; 471 472 /* Remove the MTD devices */ 473 list_for_each_safe(pos, next, &blkmtd_device_list) { 474 struct block2mtd_dev *dev = list_entry(pos, typeof(*dev), list); 475 block2mtd_sync(&dev->mtd); 476 del_mtd_device(&dev->mtd); 477 INFO("mtd%d: [%s] removed", dev->mtd.index, 478 dev->mtd.name + strlen("block2mtd: ")); 479 list_del(&dev->list); 480 block2mtd_free_device(dev); 481 } 482 } 483 484 485 module_init(block2mtd_init); 486 module_exit(block2mtd_exit); 487 488 MODULE_LICENSE("GPL"); 489 MODULE_AUTHOR("Joern Engel <joern@lazybastard.org>"); 490 MODULE_DESCRIPTION("Emulate an MTD using a block device"); 491