[go: nahoru, domu]

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