diff --git a/driver/device-mapper/device-mapper.h b/driver/device-mapper/device-mapper.h index 3160530bb..e932059fe 100644 --- a/driver/device-mapper/device-mapper.h +++ b/driver/device-mapper/device-mapper.h @@ -22,7 +22,6 @@ struct dm_table; struct dm_dev; -struct text_region; typedef unsigned int offset_t; typedef void (*dm_error_fn)(const char *message, void *private); @@ -31,13 +30,12 @@ typedef void (*dm_error_fn)(const char *message, void *private); * constructor, destructor and map fn types */ typedef int (*dm_ctr_fn)(struct dm_table *t, offset_t b, offset_t l, - struct text_region *args, void **context, - dm_error_fn err, void *e_private); + char *args, void **context); typedef void (*dm_dtr_fn)(struct dm_table *t, void *c); typedef int (*dm_map_fn)(struct buffer_head *bh, int rw, void *context); typedef int (*dm_err_fn)(struct buffer_head *bh, int rw, void *context); - +typedef char *(*dm_print_fn)(void *context); /* * Contructors should call this to make sure any @@ -58,25 +56,23 @@ struct target_type { dm_dtr_fn dtr; dm_map_fn map; dm_err_fn err; + dm_print_fn print; }; int dm_register_target(struct target_type *t); int dm_unregister_target(struct target_type *t); -/* - * These may be useful for people writing target - * types. - */ -struct text_region { - const char *b; - const char *e; -}; +static inline char *next_token(char **p) +{ + static const char *delim = " \t"; + char *r; -int dm_get_number(struct text_region *txt, unsigned int *n); -int dm_get_line(struct text_region *txt, struct text_region *line); -int dm_get_word(struct text_region *txt, struct text_region *word); -void dm_txt_copy(char *dest, size_t max, struct text_region *txt); -void dm_eat_space(struct text_region *txt); + do { + r = strsep(p, delim); + } while(r && *r == 0); + + return r; +} #endif /* DEVICE_MAPPER_H */ diff --git a/driver/device-mapper/dm-linear.c b/driver/device-mapper/dm-linear.c index d07650189..322bef1c7 100644 --- a/driver/device-mapper/dm-linear.c +++ b/driver/device-mapper/dm-linear.c @@ -29,44 +29,43 @@ struct linear_c { * */ static int linear_ctr(struct dm_table *t, offset_t b, offset_t l, - struct text_region *args, void **context, - dm_error_fn err, void *e_private) + char *args, void **context) { struct linear_c *lc; unsigned int start; - struct text_region word; - char path[256]; /* FIXME: magic */ int r = -EINVAL; + char *tok; + char *path; + char *p = args; - if (!(lc = kmalloc(sizeof(lc), GFP_KERNEL))) { - err("couldn't allocate memory for linear context", e_private); - return -ENOMEM; - } - - if (!dm_get_word(args, &word)) { - err("couldn't get device path", e_private); + *context = "No device path given"; + path = next_token(&p); + if (!path) goto bad; - } - dm_txt_copy(path, sizeof(path) - 1, &word); - - if (!dm_get_number(args, &start)) { - err("destination start not given", e_private); + *context = "No initial offset given"; + tok = next_token(&p); + if (!tok) goto bad; - } + start = simple_strtoul(tok, NULL, 10); - if ((r = dm_table_get_device(t, path, &lc->dev))) { - err("couldn't lookup device", e_private); - r = -ENXIO; + *context = "Cannot allocate linear context private structure"; + lc = kmalloc(sizeof(lc), GFP_KERNEL); + if (lc == NULL) goto bad; - } + + *context = "Cannot get target device"; + r = dm_table_get_device(t, path, &lc->dev); + if (r) + goto bad_free; lc->delta = (int) start - (int) b; *context = lc; return 0; - bad: +bad_free: kfree(lc); +bad: return r; } @@ -86,12 +85,24 @@ static int linear_map(struct buffer_head *bh, int rw, void *context) return 1; } +/* + * Debugging use only. + */ +static char *linear_print(void *context) +{ + struct linear_c *lc = (struct linear_c *)context; +static char buf[256]; + sprintf(buf, " %lu", lc->delta); + return buf; +} + static struct target_type linear_target = { name: "linear", module: THIS_MODULE, ctr: linear_ctr, dtr: linear_dtr, map: linear_map, + print: linear_print, }; static int __init linear_init(void) @@ -119,7 +130,5 @@ module_exit(linear_exit); MODULE_AUTHOR("Joe Thornber "); MODULE_DESCRIPTION("Device Mapper: Linear mapping"); -#ifdef MODULE_LICENSE MODULE_LICENSE("GPL"); -#endif diff --git a/driver/device-mapper/dm-table.c b/driver/device-mapper/dm-table.c index 4b4d7e2d5..5b601656c 100644 --- a/driver/device-mapper/dm-table.c +++ b/driver/device-mapper/dm-table.c @@ -114,6 +114,7 @@ struct dm_table *dm_table_create(void) memset(t, 0, sizeof(*t)); INIT_LIST_HEAD(&t->devices); + INIT_LIST_HEAD(&t->errors); /* allocate a single nodes worth of targets to begin with */ @@ -140,18 +141,22 @@ void dm_table_destroy(struct dm_table *t) { int i; + dmfs_zap_errors(t); + /* free the indexes (see dm_table_complete) */ if (t->depth >= 2) vfree(t->index[t->depth - 2]); - vfree(t->highs); + /* free the targets */ for (i = 0; i < t->num_targets; i++) { struct target *tgt = &t->targets[i]; - if (tgt->private) + if (tgt->type->dtr) tgt->type->dtr(t, tgt->private); } + vfree(t->highs); + /* free the device list */ if (t->devices.next != &t->devices) { WARN("there are still devices present, someone isn't " @@ -202,7 +207,7 @@ int lookup_device(const char *path, kdev_t *dev) goto bad; } - *dev = inode->i_bdev->bd_dev; + *dev = inode->i_rdev; bad: path_release(&nd); diff --git a/driver/device-mapper/dm-target.c b/driver/device-mapper/dm-target.c index ae5adc7af..662a7c8a8 100644 --- a/driver/device-mapper/dm-target.c +++ b/driver/device-mapper/dm-target.c @@ -145,8 +145,7 @@ int dm_unregister_target(struct target_type *t) * up LV's that have holes in them. */ static int io_err_ctr(struct dm_table *t, offset_t b, offset_t l, - struct text_region *args, void **context, - dm_error_fn err, void *e_private) + char *args, void **context) { *context = 0; return 0; diff --git a/driver/device-mapper/dm.c b/driver/device-mapper/dm.c index 6c2ef5dc1..9d08aed34 100644 --- a/driver/device-mapper/dm.c +++ b/driver/device-mapper/dm.c @@ -75,26 +75,38 @@ static devfs_handle_t _dev_dir; static int request(request_queue_t *q, int rw, struct buffer_head *bh); static int dm_user_bmap(struct inode *inode, struct lv_bmap *lvb); +static DECLARE_FSTYPE(dmfs_fstype, "dmfs", dmfs_read_super, FS_SINGLE); +static struct vfsmount *dmfs_mnt; /* * setup and teardown the driver */ static int dm_init(void) { - int ret; + int ret = -ENOMEM; init_rwsem(&_dev_lock); - if (!_io_hook_cache) - _io_hook_cache = kmem_cache_create("dm io hooks", - sizeof(struct io_hook), - 0, 0, NULL, NULL); + _io_hook_cache = kmem_cache_create("dm io hooks", + sizeof(struct io_hook), + 0, 0, NULL, NULL); if (!_io_hook_cache) - return -ENOMEM; + goto err; - if ((ret = dm_fs_init()) || (ret = dm_target_init())) - return ret; + ret = register_filesystem(&dmfs_fstype); + if (ret < 0) + goto err_kmem_cache_destroy; + + dmfs_mnt = kern_mount(&dmfs_fstype); + if (IS_ERR(dmfs_mnt)) { + ret = PTR_ERR(dmfs_mnt); + goto err_unregister; + } + + ret = dm_target_init(); + if (ret) + goto err_umount; /* set up the arrays */ read_ahead[MAJOR_NR] = DEFAULT_READ_AHEAD; @@ -102,10 +114,9 @@ static int dm_init(void) blksize_size[MAJOR_NR] = _blksize_size; hardsect_size[MAJOR_NR] = _hardsect_size; - if (devfs_register_blkdev(MAJOR_NR, _name, &dm_blk_dops) < 0) { - printk(KERN_ERR "%s -- register_blkdev failed\n", _name); - return -EIO; - } + ret = -EIO; + if (devfs_register_blkdev(MAJOR_NR, _name, &dm_blk_dops) < 0) + goto err_blkdev; blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), request); @@ -114,15 +125,28 @@ static int dm_init(void) printk(KERN_INFO "%s %d.%d.%d initialised\n", _name, _version[0], _version[1], _version[2]); return 0; + +err_blkdev: + printk(KERN_ERR "%s -- register_blkdev failed\n", _name); +err_umount: + /* kern_umount(&dmfs_mnt); */ +err_unregister: + unregister_filesystem(&dmfs_fstype); +err_kmem_cache_destroy: + kmem_cache_destroy(_io_hook_cache); +err: + return ret; } static void dm_exit(void) { + /* kern_umount(&dmfs_mnt); */ + + unregister_filesystem(&dmfs_fstype); + if (kmem_cache_destroy(_io_hook_cache)) WARN("it looks like there are still some io_hooks allocated"); - _io_hook_cache = 0; - dm_fs_exit(); if (devfs_unregister_blkdev(MAJOR_NR, _name) < 0) printk(KERN_ERR "%s -- unregister_blkdev failed\n", _name); @@ -663,6 +687,7 @@ struct mapped_device *dm_find_by_minor(int minor) return md; } +#ifdef CONFIG_DEVFS static int register_device(struct mapped_device *md) { md->devfs_entry = @@ -676,6 +701,12 @@ static int register_device(struct mapped_device *md) return 0; } +#else +static int register_device(struct mapped_device *md) +{ + return 0; +} +#endif static int unregister_device(struct mapped_device *md) { diff --git a/driver/device-mapper/dm.h b/driver/device-mapper/dm.h index 00c43befa..a96f6e788 100644 --- a/driver/device-mapper/dm.h +++ b/driver/device-mapper/dm.h @@ -178,6 +178,8 @@ struct dm_table { /* a list of devices used by this table */ struct list_head devices; + + struct list_head errors; }; /* @@ -202,6 +204,15 @@ struct mapped_device { devfs_handle_t devfs_entry; }; +struct dmfs_i { + struct semaphore sem; + struct dm_table *table; + struct mapped_device *md; + struct dentry *dentry; +}; + +#define DMFS_I(inode) ((struct dmfs_i *)(inode)->u.generic_ip) + extern struct block_device_operations dm_blk_dops; @@ -230,24 +241,13 @@ int dm_table_add_target(struct dm_table *t, offset_t high, struct target_type *type, void *private); int dm_table_complete(struct dm_table *t); -/* dm-parse.c */ -typedef int (*extract_line_fn)(struct text_region *line, - void *private); - -struct dm_table *dm_parse(extract_line_fn line_fn, void *line_private, - dm_error_fn err_fn, void *err_private); - - -static inline int dm_empty_tok(struct text_region *txt) -{ - return txt->b >= txt->e; -} - -/* dm-fs.c */ -int dm_fs_init(void); -void dm_fs_exit(void); - +/* dmfs-error.c */ +void dmfs_add_error(struct dm_table *t, unsigned num, char *str); +void dmfs_zap_errors(struct dm_table *t); +/* dmfs-super.c */ +struct super_block *dmfs_read_super(struct super_block *, void *, int); +struct inode *dmfs_new_inode(struct super_block *sb, int mode); #define WARN(f, x...) printk(KERN_WARNING "device-mapper: " f "\n" , ## x)