From 537d817f8a232f6b1918981492ad904aa6587d65 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Mon, 20 Aug 2001 16:12:22 +0000 Subject: [PATCH] o dm_activate/dm_close --- driver/device-mapper/device-mapper.h | 23 ++++------ driver/device-mapper/dm-target.c | 11 +++-- driver/device-mapper/dm.c | 66 +++++++++++++++++++++++++--- driver/device-mapper/dm.h | 11 ++++- 4 files changed, 86 insertions(+), 25 deletions(-) diff --git a/driver/device-mapper/device-mapper.h b/driver/device-mapper/device-mapper.h index 88b94a1a0..337156d1c 100644 --- a/driver/device-mapper/device-mapper.h +++ b/driver/device-mapper/device-mapper.h @@ -28,34 +28,29 @@ #ifndef DEVICE_MAPPER_H #define DEVICE_MAPPER_H +#ifdef __KERNEL__ + #include /* FIXME: steal LVM's devices for now */ #define DM_BLK_MAJOR LVM_BLK_MAJOR -#define DM_CTL_MAJOR LVM_CHAR_MAJOR - -#define DM_NAME_LEN 64 +struct mapped_device; typedef unsigned int offset_t; -struct dm_request { - int minor; /* -1 indicates no preference */ - char name[DM_NAME_LEN]; -}; - -#define MAPPED_DEVICE_CREATE _IOWR(DM_CTL_MAJOR, 0, struct dm_request) -#define MAPPED_DEVICE_DESTROY _IOW(DM_CTL_MAJOR, 1, struct dm_request) - -#ifdef __KERNEL__ -typedef int (*dm_ctr_fn)(offset_t b, offset_t e, +typedef int (*dm_ctr_fn)(offset_t b, offset_t e, struct mapped_device *md, const char *context, void **result); typedef void (*dm_dtr_fn)(void *c); typedef int (*dm_map_fn)(struct buffer_head *bh, void *context); int register_map_target(const char *name, dm_ctr_fn ctr, dm_dtr_fn dtr, dm_map_fn map); -#endif +/* contructors should call this to make sure any destination devices + are handled correctly (ie. opened/closed) */ +int dm_add_device(struct mapped_device *md, kdev_t dev); + +#endif #endif /* diff --git a/driver/device-mapper/dm-target.c b/driver/device-mapper/dm-target.c index 6853ba980..58636f9e1 100644 --- a/driver/device-mapper/dm-target.c +++ b/driver/device-mapper/dm-target.c @@ -82,7 +82,8 @@ int register_map_target(const char *name, dm_ctr_fn ctr, * * 'linear' target maps a linear range of a device */ -int _io_err_ctr(offset_t b, offset_t e, const char *context, void **result) +int _io_err_ctr(offset_t b, offset_t e, struct mapped_device *md, + const char *context, void **result) { /* this takes no arguments */ *result = 0; @@ -106,7 +107,8 @@ struct linear_c { int offset; /* FIXME: we need a signed offset type */ }; -int _linear_ctr(offset_t b, offset_t e, const char *context, void **result) +int _linear_ctr(offset_t b, offset_t e, struct mapped_device *md, + const char *context, void **result) { /* context string should be of the form: * @@ -138,7 +140,10 @@ int _linear_ctr(offset_t b, offset_t e, const char *context, void **result) lc->dev = MKDEV(major, minor); lc->offset = start - b; - /* FIXME: we should open the PV */ + if (!dm_add_device(md, lc->dev)) { + kfree(lc); + return 0; + } *result = lc; return 1; diff --git a/driver/device-mapper/dm.c b/driver/device-mapper/dm.c index a4812bbde..bd72fcd28 100644 --- a/driver/device-mapper/dm.c +++ b/driver/device-mapper/dm.c @@ -97,10 +97,8 @@ * implement most LVM features (omitting striped volumes and * snapshots). * - * At the moment this driver has a temporary ioctl interface, but I will - * move this to a read/write interface on either a /proc file or a - * char device. This will allow scripts to simply cat a text mapping - * table in order to set up a volume. + * The driver is controlled through a /proc interface... + * FIXME: finish * * At the moment the table assumes 32 bit keys (sectors), the move to * 64 bits will involve no interface changes, since the tables will be @@ -439,7 +437,7 @@ struct mapped_device *dm_find_minor(int minor) return md; } -static int dm_create(int minor, const char *name) +int dm_create(int minor, const char *name) { struct mapped_device *md; @@ -462,10 +460,11 @@ static int dm_create(int minor, const char *name) up_write(&_dev_lock); } -static int dm_remove(const char *name, int minor) +int dm_remove(const char *name, int minor) { struct mapped_device *md; int minor; + struct dev_list *d, *n; down_write(&_dev_lock); if (!(md = __find_dev(name))) { @@ -474,6 +473,10 @@ static int dm_remove(const char *name, int minor) } dm_clear_table(md); + for (d = md->devices; d; d = n) { + n = d->next; + kfree(d); + } minor = MINOR(md->dev); _free_dev(md); @@ -482,6 +485,57 @@ static int dm_remove(const char *name, int minor) return 0; } +int dm_add_device(struct mapped_device *md, kdev_t dev) +{ + struct dev_list *d = kmalloc(sizeof(*d)); + + if (!d) + return 0; + + d->dev = dev; + d->next = md->devices; + md->devices = d; + return 1; +} + +int dm_activate(struct mapped_device *md) +{ + int ret; + struct dev_list *d, *od; + + if (is_active(md)) + return 1; + + /* open all the devices */ + for (d = md->devices; d; d = d->next) + if ((ret = _open_dev(d->dev))) + goto bad; + + return 0; + + bad: + + od = d; + for (d = md->devices; d != od; d = d->next) + _close_dev(d->dev); + + return ret; +} + +void dm_suspend(struct mapped_device *md) +{ + struct dev_list *d; + if (!is_active(md)) + return; + + /* close all the devices */ + for (d = md->devices; d; d = d->next) + _close_dev(d->dev)); + + set_active(md, 0); +} + + /* * module hooks */ diff --git a/driver/device-mapper/dm.h b/driver/device-mapper/dm.h index 4c46d3c6d..d0de61929 100644 --- a/driver/device-mapper/dm.h +++ b/driver/device-mapper/dm.h @@ -39,6 +39,11 @@ enum { DM_ACTIVE, }; +struct dev_list { + kdev_t dev; + struct dev_list *next; +}; + struct mapped_device { kdev_t dev; char name[DM_NAME_LEN]; @@ -59,6 +64,9 @@ struct mapped_device { /* used by dm-fs.c */ devfs_handle_t devfs_entry; + + /* a list of devices used by this md */ + struct dev_list *devices; }; /* dm-target.c */ @@ -74,13 +82,12 @@ struct target { struct target *dm_get_target(const char *name); int dm_std_targets(void); - /* dm.c */ struct mapped_device *dm_find_name(const char *name); struct mapped_device *dm_find_minor(int minor); -void dm_suspend(struct mapped_device *md); void dm_activate(struct mapped_device *md); +void dm_suspend(struct mapped_device *md); /* dm-table.c */ int dm_start_table(struct mapped_device *md);