summaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2008-07-21 09:05:25 +0200
committerNeilBrown <neilb@suse.de>2008-07-21 09:05:25 +0200
commitf2ea68cf42aafdd93393b6b8b20fc3c2b5f4390c (patch)
tree00b025b91898ff32dba742b5075dd290fec4dc91 /drivers/md
parentmd: linear: Make array_size sector-based and rename it to array_sectors. (diff)
downloadlinux-f2ea68cf42aafdd93393b6b8b20fc3c2b5f4390c.tar.xz
linux-f2ea68cf42aafdd93393b6b8b20fc3c2b5f4390c.zip
md: only count actual openers as access which prevent a 'stop'
Open isn't the only thing that increments ->active. e.g. reading /proc/mdstat will increment it briefly. So to avoid false positives in testing for concurrent access, introduce a new counter that counts just the number of times the md device it open. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/md.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 4bfbc1982cda..450f30b6edf9 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -273,6 +273,7 @@ static mddev_t * mddev_find(dev_t unit)
INIT_LIST_HEAD(&new->all_mddevs);
init_timer(&new->safemode_timer);
atomic_set(&new->active, 1);
+ atomic_set(&new->openers, 0);
spin_lock_init(&new->write_lock);
init_waitqueue_head(&new->sb_wait);
init_waitqueue_head(&new->recovery_wait);
@@ -2695,14 +2696,14 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
break;
case clear:
/* stopping an active array */
- if (atomic_read(&mddev->active) > 1)
+ if (atomic_read(&mddev->openers) > 0)
return -EBUSY;
err = do_md_stop(mddev, 0, 0);
break;
case inactive:
/* stopping an active array */
if (mddev->pers) {
- if (atomic_read(&mddev->active) > 1)
+ if (atomic_read(&mddev->openers) > 0)
return -EBUSY;
err = do_md_stop(mddev, 2, 0);
} else
@@ -3816,7 +3817,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
int err = 0;
struct gendisk *disk = mddev->gendisk;
- if (atomic_read(&mddev->active) > 1 + is_open) {
+ if (atomic_read(&mddev->openers) > is_open) {
printk("md: %s still in use.\n",mdname(mddev));
return -EBUSY;
}
@@ -5014,6 +5015,7 @@ static int md_open(struct inode *inode, struct file *file)
err = 0;
mddev_get(mddev);
+ atomic_inc(&mddev->openers);
mddev_unlock(mddev);
check_disk_change(inode->i_bdev);
@@ -5026,6 +5028,7 @@ static int md_release(struct inode *inode, struct file * file)
mddev_t *mddev = inode->i_bdev->bd_disk->private_data;
BUG_ON(!mddev);
+ atomic_dec(&mddev->openers);
mddev_put(mddev);
return 0;