From 00bcb4ac7ee7e557a491b614219142cea0ef16f4 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 1 Jun 2010 19:37:23 +1000 Subject: md: reduce dependence on sysfs. We will want md devices to live as dm targets where sysfs is not visible. So allow md to not connect to sysfs. Signed-off-by: NeilBrown --- drivers/md/md.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/md/md.h') diff --git a/drivers/md/md.h b/drivers/md/md.h index 10597bfec000..1e6405918eec 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -382,6 +382,18 @@ struct md_sysfs_entry { }; extern struct attribute_group md_bitmap_group; +static inline struct sysfs_dirent *sysfs_get_dirent_safe(struct sysfs_dirent *sd, char *name) +{ + if (sd) + return sysfs_get_dirent(sd, NULL, name); + return sd; +} +static inline void sysfs_notify_dirent_safe(struct sysfs_dirent *sd) +{ + if (sd) + sysfs_notify_dirent(sd); +} + static inline char * mdname (mddev_t * mddev) { return mddev->gendisk ? mddev->gendisk->disk_name : "mdX"; -- cgit v1.2.3 From e8bb9a839a26f076379e9cb9f46a879d210156f1 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 1 Jun 2010 19:37:26 +1000 Subject: md: split out md_rdev_init This functionality will be needed separately in a subsequent patch, so split it into it's own exported function. Signed-off-by: NeilBrown --- drivers/md/md.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/md/md.h') diff --git a/drivers/md/md.h b/drivers/md/md.h index 1e6405918eec..cc8030543e82 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -487,4 +487,5 @@ extern void md_integrity_add_rdev(mdk_rdev_t *rdev, mddev_t *mddev); extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale); extern void restore_bitmap_write_access(struct file *file); +extern void md_rdev_init(mdk_rdev_t *rdev); #endif /* _MD_MD_H */ -- cgit v1.2.3 From 390ee602a142a93f2c7eb7bffee8e277058b8e0a Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 1 Jun 2010 19:37:27 +1000 Subject: md: export various start/stop interfaces export entry points for starting and stopping md arrays. This will be used by a module to make md/raid5 work under dm. Also stop calling md_stop_writes from md_stop, as that won't work well with dm - it will want to call the two separately. Signed-off-by: NeilBrown --- drivers/md/md.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/md/md.h') diff --git a/drivers/md/md.h b/drivers/md/md.h index cc8030543e82..6e7e3495f6e4 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -487,5 +487,12 @@ extern void md_integrity_add_rdev(mdk_rdev_t *rdev, mddev_t *mddev); extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale); extern void restore_bitmap_write_access(struct file *file); +extern void mddev_init(mddev_t *mddev); +extern int md_run(mddev_t *mddev); +extern void md_stop(mddev_t *mddev); +extern void md_stop_writes(mddev_t *mddev); extern void md_rdev_init(mdk_rdev_t *rdev); + +extern void mddev_suspend(mddev_t *mddev); +extern void mddev_resume(mddev_t *mddev); #endif /* _MD_MD_H */ -- cgit v1.2.3 From 768a418db102bb6aa6064e6090892b5c21ff1f9e Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 26 Jul 2010 11:49:55 +1000 Subject: md: add support for raising dm events. dm uses scheduled work to raise events to user-space. So allow md device to have work_structs and schedule them on an error. Signed-off-by: NeilBrown --- drivers/md/md.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/md/md.h') diff --git a/drivers/md/md.h b/drivers/md/md.h index 6e7e3495f6e4..c88b04745e85 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -318,6 +318,7 @@ struct mddev_s struct bio *barrier; atomic_t flush_pending; struct work_struct barrier_work; + struct work_struct event_work; /* used by dm to report failure event */ }; -- cgit v1.2.3 From 2ac8740151b082f045e58010eb92560c3a23a0e9 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 1 Jun 2010 19:37:29 +1000 Subject: md/raid5: add simple plugging infrastructure. md/raid5 uses the plugging infrastructure provided by the block layer and 'struct request_queue'. However when we plug raid5 under dm there is no request queue so we cannot use that. So create a similar infrastructure that is much lighter weight and use it for raid5. Signed-off-by: NeilBrown --- drivers/md/md.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers/md/md.h') diff --git a/drivers/md/md.h b/drivers/md/md.h index c88b04745e85..5be0d6921b9d 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -29,6 +29,26 @@ typedef struct mddev_s mddev_t; typedef struct mdk_rdev_s mdk_rdev_t; +/* generic plugging support - like that provided with request_queue, + * but does not require a request_queue + */ +struct plug_handle { + void (*unplug_fn)(struct plug_handle *); + struct timer_list unplug_timer; + struct work_struct unplug_work; + unsigned long unplug_flag; +}; +#define PLUGGED_FLAG 1 +void plugger_init(struct plug_handle *plug, + void (*unplug_fn)(struct plug_handle *)); +void plugger_set_plug(struct plug_handle *plug); +int plugger_remove_plug(struct plug_handle *plug); +static inline void plugger_flush(struct plug_handle *plug) +{ + del_timer_sync(&plug->unplug_timer); + cancel_work_sync(&plug->unplug_work); +} + /* * MD's 'extended' device */ -- cgit v1.2.3 From 252ac5221a71be72b7e7c7b7482af91e9c962e8c Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 1 Jun 2010 19:37:29 +1000 Subject: md/plug: optionally use plugger to unplug an array during resync/recovery. If an array doesn't have a 'queue' then md_do_sync cannot unplug it. In that case it will have a 'plugger', so make that available to the mddev, and use it to unplug the array if needed. Signed-off-by: NeilBrown --- drivers/md/md.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/md/md.h') diff --git a/drivers/md/md.h b/drivers/md/md.h index 5be0d6921b9d..57eb864a8249 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -328,6 +328,8 @@ struct mddev_s struct list_head all_mddevs; struct attribute_group *to_remove; + struct plug_handle *plug; /* if used by personality */ + /* Generic barrier handling. * If there is a pending barrier request, all other * writes are blocked while the devices are flushed. -- cgit v1.2.3 From ac2f40be46ce6ab3bec4c8c297d6923f941741ce Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 1 Jun 2010 19:37:31 +1000 Subject: md/bitmap: white space clean up and similar. Fixes some whitespace problems Fixed some checkpatch.pl complaints. Replaced kmalloc ... memset(0), with kzalloc Fixed an unlikely memory leak on an error path. Reformatted a number of 'if/else' sets, sometimes replacing goto with an else clause. Removed some old comments and commented-out code. Signed-off-by: NeilBrown --- drivers/md/md.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/md/md.h') diff --git a/drivers/md/md.h b/drivers/md/md.h index 57eb864a8249..209993207a55 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -319,7 +319,7 @@ struct mddev_s */ struct mutex mutex; unsigned long chunksize; - unsigned long daemon_sleep; /* how many seconds between updates? */ + unsigned long daemon_sleep; /* how many jiffies between updates? */ unsigned long max_write_behind; /* write-behind mode */ int external; } bitmap_info; -- cgit v1.2.3 From b63d7c2e29bf9cc94989806f2df0cfca4976b830 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 1 Jun 2010 19:37:33 +1000 Subject: md/bitmap: clean up plugging calls. 1/ use md_unplug in bitmap.c as we will soon be using bitmaps under arrays with no queue attached. 2/ Don't bother plugging the queue when we set a bit in the bitmap. The reason for this was to encourage as many bits as possible to get set before we unplug and write stuff out. However every personality already plugs the queue after bitmap_startwrite either directly (raid1/raid10) or be setting STRIPE_BIT_DELAY which causes the queue to be plugged later (raid5). Signed-off-by: NeilBrown --- drivers/md/md.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/md/md.h') diff --git a/drivers/md/md.h b/drivers/md/md.h index 209993207a55..0a850780b5d1 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -509,6 +509,7 @@ extern int md_integrity_register(mddev_t *mddev); extern void md_integrity_add_rdev(mdk_rdev_t *rdev, mddev_t *mddev); extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale); extern void restore_bitmap_write_access(struct file *file); +extern void md_unplug(mddev_t *mddev); extern void mddev_init(mddev_t *mddev); extern int md_run(mddev_t *mddev); -- cgit v1.2.3 From e384e58549a2e9a83071ad80280c1a9053cfd84c Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 1 Jun 2010 19:37:34 +1000 Subject: md/bitmap: prepare for storing write-intent-bitmap via dm-dirty-log. This allows md/raid5 to fully work as a dm target. Normally md uses a 'filemap' which contains a list of pages of bits each of which may be written separately. dm-log uses and all-or-nothing approach to writing the log, so when using a dm-log, ->filemap is NULL and the flags normally stored in filemap_attr are stored in ->logattrs instead. Signed-off-by: NeilBrown --- drivers/md/md.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/md/md.h') diff --git a/drivers/md/md.h b/drivers/md/md.h index 0a850780b5d1..cccbadb31bae 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -317,6 +317,11 @@ struct mddev_s * hot-adding a bitmap. It should * eventually be settable by sysfs. */ + /* When md is serving under dm, it might use a + * dirty_log to store the bits. + */ + struct dm_dirty_log *log; + struct mutex mutex; unsigned long chunksize; unsigned long daemon_sleep; /* how many jiffies between updates? */ -- cgit v1.2.3 From bb4f1e9d0e2ef93de8e36ca0f5f26625fcd70b7d Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sun, 8 Aug 2010 21:18:03 +1000 Subject: md: fix another deadlock with removing sysfs attributes. Move the deletion of sysfs attributes from reconfig_mutex to open_mutex didn't really help as a process can try to take open_mutex while holding reconfig_mutex, so the same deadlock can happen, just requiring one more process to be involved in the chain. I looks like I cannot easily use locking to wait for the sysfs deletion to complete, so don't. The only things that we cannot do while the deletions are still pending is other things which can change the sysfs namespace: run, takeover, stop. Each of these can fail with -EBUSY. So set a flag while doing a sysfs deletion, and fail run, takeover, stop if that flag is set. This is suitable for 2.6.35.x Cc: stable@kernel.org Signed-off-by: NeilBrown --- drivers/md/md.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/md/md.h') diff --git a/drivers/md/md.h b/drivers/md/md.h index cccbadb31bae..6f797eceae31 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -145,6 +145,10 @@ struct mddev_s int suspended; atomic_t active_io; int ro; + int sysfs_active; /* set when sysfs deletes + * are happening, so run/ + * takeover/stop are not safe + */ struct gendisk *gendisk; -- cgit v1.2.3