diff options
author | Gabriel de Perthuis <g2p.code@gmail.com> | 2013-05-04 12:19:41 +0200 |
---|---|---|
committer | Kent Overstreet <koverstreet@google.com> | 2013-06-26 17:08:52 -0700 |
commit | a9dd53adbb84c12f769a862ba2c80404873c2c99 (patch) | |
tree | 6f9120b97dd4b89bf606e95a54f63de66f864507 /drivers | |
parent | bbc77aa7fb72e616edcb1b165c293e47c6d4d0cf (diff) | |
download | op-kernel-dev-a9dd53adbb84c12f769a862ba2c80404873c2c99.zip op-kernel-dev-a9dd53adbb84c12f769a862ba2c80404873c2c99.tar.gz |
bcache: Warn when a device is already registered.
Signed-off-by: Gabriel de Perthuis <g2p.code+bcache@gmail.com>
Signed-off-by: Kent Overstreet <koverstreet@google.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/md/bcache/super.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index f88e2b6..3de5626 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -1786,6 +1786,36 @@ static ssize_t register_bcache(struct kobject *, struct kobj_attribute *, kobj_attribute_write(register, register_bcache); kobj_attribute_write(register_quiet, register_bcache); +static bool bch_is_open_backing(struct block_device *bdev) { + struct cache_set *c, *tc; + struct cached_dev *dc, *t; + + list_for_each_entry_safe(c, tc, &bch_cache_sets, list) + list_for_each_entry_safe(dc, t, &c->cached_devs, list) + if (dc->bdev == bdev) + return true; + list_for_each_entry_safe(dc, t, &uncached_devices, list) + if (dc->bdev == bdev) + return true; + return false; +} + +static bool bch_is_open_cache(struct block_device *bdev) { + struct cache_set *c, *tc; + struct cache *ca; + unsigned i; + + list_for_each_entry_safe(c, tc, &bch_cache_sets, list) + for_each_cache(ca, c, i) + if (ca->bdev == bdev) + return true; + return false; +} + +static bool bch_is_open(struct block_device *bdev) { + return bch_is_open_cache(bdev) || bch_is_open_backing(bdev); +} + static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr, const char *buffer, size_t size) { @@ -1810,8 +1840,13 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr, FMODE_READ|FMODE_WRITE|FMODE_EXCL, sb); if (IS_ERR(bdev)) { - if (bdev == ERR_PTR(-EBUSY)) - err = "device busy"; + if (bdev == ERR_PTR(-EBUSY)) { + bdev = lookup_bdev(strim(path)); + if (!IS_ERR(bdev) && bch_is_open(bdev)) + err = "device already registered"; + else + err = "device busy"; + } goto err; } |