Re: [PATCH] bcache: decouple emitting a cached_dev CHANGE uevent

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

 



Apologies for the duplicate; this time in plaintext.

On Fri, Mar 2, 2018 at 1:55 AM,  <tang.junhui@xxxxxxxxxx> wrote:
> From: Tang Junhui <tang.junhui@xxxxxxxxxx>
>
> Hello Ryan Harper

Hello Tang Junhui,


>
>> From: Ryan Harper <ryan.harper@xxxxxxxxxxxxx>
>>
>> BugLink: http://bugs.launchpad.net/bugs/1729145
>>
>> A bug is preventing /dev/bcache/by-uuid links from being created after reboot.
>> It appears that since the initramfs loads the bcache module which probes and
>> finds all of the cache devices and backing devices
>
> I am just curious, is initramfs or the loaded bcache module probes and finds all
> of the cache devices and backing devices? As far as I known, bcache never
> does this thing, and all the bcache devices were registered by uevent message
> through udev rules.

I believe that udev via the bcache rules triggers the registration of
the device, via writing
to /sys/fs/bcache/register for either a backing device or a cache
device; both include a super block
of information on the device.

The bcache module in super.c associates register_bcache function as a
kobj write handler for
the attribute;  This examines the block device string passed in the
sysfs attr write
and starts the process of determining if the specified device is a
bcache device, if it's of
type backing, or a cache device.  If the device is a backing device
and it's not yet opened, then
the module reads the superblock to find the cache device it's
associated with and then if that
device is present it will complete the registration by creating a new
bcacheN block device.

This happens in the initramfs for kernels which include bcache module.
After the rootfs is
mounted and we've pivoted into system boot, then the udev cold-plug
replay will repeat
the disk add/change events but when the bcache register method runs  a
second time and
finds a backing device, a bcacheN block device already has it open, so
the module exits out
the path of "device already registered" which prevents bcache from
calling register_bdev()
which is the only path where a backing device could call
bch_cached_dev_run() which is
responsible for emitting the KOBJ_CHANGE event which the bcache udev
rules use to
generate the /dev/bcache/{by-uuid, by-label} events.


Ryan Harper

>
>> then once the rootfs is
>> mounted and udev gets to run, the bcache kernel module does not emit the
>> CACHED_UUID value into the environment if the underlying devices are already registered.
>>
>> With this patch, instead of just failing with "device already registered"
>> the kernel emits another uevent with CACHED_UUID which would be processed
>> another time to set up a symlink.
>>
>>
>> - decouple emitting a cached_dev CHANGE uevent which includes dev.uuid
>>   and dev.label from bch_cached_dev_run() which only happens when a
>>   bcacheX device is bound to the actual backing block device (bcache0 -> vdb)
>>
>> - update bch_cached_dev_run() to invoke bch_cached_dev_emit_change() as
>>   needed; no functional code path changes here
>>
>> - Modify register_bcache to detect a re-registering of a bcache
>>   cached_dev, and in that case call bcache_cached_dev_emit_change() to
>>
>> Cc: stable@xxxxxxxxxxxxxxx
>> Signed-off-by: Ryan Harper <ryan.harper@xxxxxxxxxxxxx>
>> Signed-off-by: Joseph Salisbury <joseph.salisbury@xxxxxxxxxxxxx>
>> ---
>>  drivers/md/bcache/bcache.h |  1 +
>>  drivers/md/bcache/super.c  | 53 +++++++++++++++++++++++++++++++++++++---------
>>  2 files changed, 44 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
>> index 02619ca..8ed7e7a 100644
>> --- a/drivers/md/bcache/bcache.h
>> +++ b/drivers/md/bcache/bcache.h
>> @@ -906,6 +906,7 @@ int bch_flash_dev_create(struct cache_set *c, uint64_t size);
>>
>>  int bch_cached_dev_attach(struct cached_dev *, struct cache_set *);
>>  void bch_cached_dev_detach(struct cached_dev *);
>> +void bch_cached_dev_emit_change(struct cached_dev *);
>>  void bch_cached_dev_run(struct cached_dev *);
>>  void bcache_device_stop(struct bcache_device *);
>>
>> diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
>> index 04608da..9ff0aac 100644
>> --- a/drivers/md/bcache/super.c
>> +++ b/drivers/md/bcache/super.c
>> @@ -834,7 +834,7 @@ static void calc_cached_dev_sectors(struct cache_set *c)
>>      c->cached_dev_sectors = sectors;
>>  }
>>
>> -void bch_cached_dev_run(struct cached_dev *dc)
>> +void bch_cached_dev_emit_change(struct cached_dev *dc)
>>  {
>>      struct bcache_device *d = &dc->disk;
>>      char buf[SB_LABEL_SIZE + 1];
>> @@ -849,9 +849,18 @@ void bch_cached_dev_run(struct cached_dev *dc)
>>      buf[SB_LABEL_SIZE] = '\0';
>>      env[2] = kasprintf(GFP_KERNEL, "CACHED_LABEL=%s", buf);
>>
>> +    /* won't show up in the uevent file, use udevadm monitor -e instead
>> +     * only class / kset properties are persistent */
>> +    kobject_uevent_env(&disk_to_dev(d->disk)->kobj, KOBJ_CHANGE, env);
>> +    kfree(env[1]);
>> +    kfree(env[2]);
>> +
>> +}
>> +
>> +void bch_cached_dev_run(struct cached_dev *dc)
>> +{
>> +    struct bcache_device *d = &dc->disk;
>>      if (atomic_xchg(&dc->running, 1)) {
>> -        kfree(env[1]);
>> -        kfree(env[2]);
>>          return;
>>      }
>>
>> @@ -867,11 +876,9 @@ void bch_cached_dev_run(struct cached_dev *dc)
>>
>>      add_disk(d->disk);
>>      bd_link_disk_holder(dc->bdev, dc->disk.disk);
>> -    /* won't show up in the uevent file, use udevadm monitor -e instead
>> -     * only class / kset properties are persistent */
>> -    kobject_uevent_env(&disk_to_dev(d->disk)->kobj, KOBJ_CHANGE, env);
>> -    kfree(env[1]);
>> -    kfree(env[2]);
>> +
>> +    /* emit change event */
>> +    bch_cached_dev_emit_change(dc);
>>
>>      if (sysfs_create_link(&d->kobj, &disk_to_dev(d->disk)->kobj, "dev") ||
>>          sysfs_create_link(&disk_to_dev(d->disk)->kobj, &d->kobj, "bcache"))
>> @@ -1916,6 +1923,21 @@ static bool bch_is_open_backing(struct block_device *bdev) {
>>      return false;
>>  }
>>
>> +static struct cached_dev *bch_find_cached_dev(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 dc;
>> +    list_for_each_entry_safe(dc, t, &uncached_devices, list)
>> +        if (dc->bdev == bdev)
>> +            return dc;
>> +
>> +    return NULL;
>> +}
>> +
>>  static bool bch_is_open_cache(struct block_device *bdev) {
>>      struct cache_set *c, *tc;
>>      struct cache *ca;
>> @@ -1941,6 +1963,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
>>      struct cache_sb *sb = NULL;
>>      struct block_device *bdev = NULL;
>>      struct page *sb_page = NULL;
>> +    struct cached_dev *dc = NULL;
>>
>>      if (!try_module_get(THIS_MODULE))
>>          return -EBUSY;
>> @@ -1957,10 +1980,20 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
>>          if (bdev == ERR_PTR(-EBUSY)) {
>>              bdev = lookup_bdev(strim(path), 0);
>>              mutex_lock(&bch_register_lock);
>> -            if (!IS_ERR(bdev) && bch_is_open(bdev))
>> +            if (!IS_ERR(bdev) && bch_is_open(bdev)) {
>>                  err = "device already registered";
>> -            else
>> +                /* emit CHANGE event for backing devices to export
>> +                 * CACHED_{UUID/LABEL} values to udev */
>> +                if (bch_is_open_backing(bdev)) {
>> +                    dc = bch_find_cached_dev(bdev);
>> +                    if (dc) {
>> +                        bch_cached_dev_emit_change(dc);
>> +                        err = "device already registered (emitting change event)";
>> +                    }
>> +                }
>> +            } else {
>>                  err = "device busy";
>> +            }
>>              mutex_unlock(&bch_register_lock);
>>              if (!IS_ERR(bdev))
>>                  bdput(bdev);
>> --
>> 2.7.4
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-bcache" in
>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
> Thanks
> Tang Junhui
--
To unsubscribe from this list: send the line "unsubscribe linux-bcache" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux ARM Kernel]     [Linux Filesystem Development]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux