Re: [RFC PATCH v2 12/16] bcache: add pendings_cleanup to stop pending bcache device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2019/4/23 3:08 下午, Hannes Reinecke wrote:
> On 4/19/19 6:05 PM, Coly Li wrote:
>> If a bcache device is in dirty state and its cache set is not
>> registered, this bcache deivce will not appear in /dev/bcache<N>,
>> and there is no way to stop it or remove the bcache kernel module.
>>
>> This is an as-designed behavior, but sometimes people has to reboot
>> whole system to release or stop the pending backing device.
>>
>> This sysfs interface may remove such pending bcache devices when
>> write anything into the sysfs file manually.
>>
>> Signed-off-by: Coly Li <colyli@xxxxxxx>
>> ---
>>   drivers/md/bcache/super.c | 55
>> +++++++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 55 insertions(+)
>>
>> diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
>> index 9b41e0b62cc0..e988e46a6479 100644
>> --- a/drivers/md/bcache/super.c
>> +++ b/drivers/md/bcache/super.c
>> @@ -2246,9 +2246,13 @@ static int register_cache(struct cache_sb *sb,
>> struct page *sb_page,
>>     static ssize_t register_bcache(struct kobject *k, struct
>> kobj_attribute *attr,
>>                      const char *buffer, size_t size);
>> +static ssize_t bch_pending_bdevs_cleanup(struct kobject *k,
>> +                     struct kobj_attribute *attr,
>> +                     const char *buffer, size_t size);
>>     kobj_attribute_write(register,        register_bcache);
>>   kobj_attribute_write(register_quiet,    register_bcache);
>> +kobj_attribute_write(pendings_cleanup,    bch_pending_bdevs_cleanup);
>>     static bool bch_is_open_backing(struct block_device *bdev)
>>   {
>> @@ -2373,6 +2377,56 @@ static ssize_t register_bcache(struct kobject
>> *k, struct kobj_attribute *attr,
>>       goto out;
>>   }
>>   +
>> +struct pdev {
>> +    struct list_head list;
>> +    struct cached_dev *dc;
>> +};
>> +
>> +static ssize_t bch_pending_bdevs_cleanup(struct kobject *k,
>> +                     struct kobj_attribute *attr,
>> +                     const char *buffer,
>> +                     size_t size)
>> +{
>> +    LIST_HEAD(pending_devs);
>> +    ssize_t ret = size;
>> +    struct cached_dev *dc, *tdc;
>> +    struct pdev *pdev, *tpdev;
>> +    struct cache_set *c, *tc;
>> +
>> +    mutex_lock(&bch_register_lock);
>> +    list_for_each_entry_safe(dc, tdc, &uncached_devices, list) {
>> +        pdev = kmalloc(sizeof(struct pdev), GFP_KERNEL);
>> +        if (!pdev)
>> +            break;
>> +        pdev->dc = dc;
>> +        list_add(&pdev->list, &pending_devs);
>> +    }
>> +
>> +    list_for_each_entry_safe(pdev, tpdev, &pending_devs, list) {
>> +        list_for_each_entry_safe(c, tc, &bch_cache_sets, list) {
>> +            char *pdev_set_uuid = pdev->dc->sb.set_uuid;
>> +            char *set_uuid = c->sb.uuid;
>> +
>> +            if (!memcmp(pdev_set_uuid, set_uuid, 16)) {
>> +                list_del(&pdev->list);
>> +                kfree(pdev);
>> +                break;
>> +            }
>> +        }
>> +    }
>> +    mutex_unlock(&bch_register_lock);
>> +
>> +    list_for_each_entry_safe(pdev, tpdev, &pending_devs, list) {
>> +        pr_info("delete pdev %p", pdev);
>> +        list_del(&pdev->list);
>> +        bcache_device_stop(&pdev->dc->disk);
>> +        kfree(pdev);
>> +    }
>> +
>> +    return ret;
>> +}
>> +
>>   static int bcache_reboot(struct notifier_block *n, unsigned long
>> code, void *x)
>>   {
>>       if (code == SYS_DOWN ||
>> @@ -2483,6 +2537,7 @@ static int __init bcache_init(void)
>>       static const struct attribute *files[] = {
>>           &ksysfs_register.attr,
>>           &ksysfs_register_quiet.attr,
>> +        &ksysfs_pendings_cleanup.attr,
>>           NULL
>>       };
>>  
> _Actually_ I would like it better if the bcache device would be present
> in sysfs for these cases, too, albeit in a disabled state.
> That would allow us to remove the device like normal and we wouldn't
> need to worry about yet another interface.

Hi Hannes,

I see. The awkward condition is,
- If only show up the bcache device in /sys/block/bcache<?>/ directory
but not show up in /dev/bcache<?> node, it might be more confused for users.
- If show up both bcache devices in /sys/block/bcache<?> and
/dev/bcache<?>, it means such device can be read/written, but it is
staled (there are dirty data on cache device), which may corrupt
existing data.

So I choose to not change current code behavior and just add a sysfs
interface.

-- 

Coly Li



[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux