zram: close udev startup race condition as default groups
authorMinchan Kim <minchan@kernel.org>
Fri, 23 Nov 2018 06:30:06 +0000 (15:30 +0900)
committerivanmeler <i_ivan@windowslive.com>
Wed, 13 Apr 2022 21:13:29 +0000 (21:13 +0000)
commit fef912bf860e upstream.
commit 98af4d4df889 upstream.

I got a report from Howard Chen that he saw zram and sysfs race(ie,
zram block device file is created but sysfs for it isn't yet)
when he tried to create new zram devices via hotadd knob.

v4.20 kernel fixes it by [1, 2] but it's too large size to merge
into -stable so this patch fixes the problem by registering defualt
group by Greg KH's approach[3].

This patch should be applied to every stable tree [3.16+] currently
existing from kernel.org because the problem was introduced at 2.6.37
by [4].

[1] fef912bf860e, block: genhd: add 'groups' argument to device_add_disk
[2] 98af4d4df889, zram: register default groups with device_add_disk()
[3] http://kroah.com/log/blog/2013/06/26/how-to-create-a-sysfs-file-correctly/
[4] 33863c21e69e9, Staging: zram: Replace ioctls with sysfs interface

Cc: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Cc: Hannes Reinecke <hare@suse.com>
Tested-by: Howard Chen <howardsoc@google.com>
Signed-off-by: Minchan Kim <minchan@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/block/zram/zram_drv.c

index 5cc39583ad8d4f8be766eee59a9a3dad5473fe79..15fefabb3582ed7782b77fc1f8f6fd59ae3bfaba 100644 (file)
@@ -1639,6 +1639,11 @@ static const struct attribute_group zram_disk_attr_group = {
        .attrs = zram_disk_attrs,
 };
 
+static const struct attribute_group *zram_disk_attr_groups[] = {
+       &zram_disk_attr_group,
+       NULL,
+};
+
 /*
  * Allocate and initialize new zram device. the function returns
  * '>= 0' device_id upon success, and negative value otherwise.
@@ -1720,24 +1725,15 @@ static int zram_add(void)
 
        zram->disk->queue->backing_dev_info.capabilities |=
                                        BDI_CAP_STABLE_WRITES;
+       disk_to_dev(zram->disk)->groups = zram_disk_attr_groups;
        add_disk(zram->disk);
 
-       ret = sysfs_create_group(&disk_to_dev(zram->disk)->kobj,
-                               &zram_disk_attr_group);
-       if (ret < 0) {
-               pr_err("Error creating sysfs group for device %d\n",
-                               device_id);
-               goto out_free_disk;
-       }
        strlcpy(zram->compressor, default_compressor, sizeof(zram->compressor));
 
        zram_debugfs_register(zram);
        pr_info("Added device: %s\n", zram->disk->disk_name);
        return device_id;
 
-out_free_disk:
-       del_gendisk(zram->disk);
-       put_disk(zram->disk);
 out_free_queue:
        blk_cleanup_queue(queue);
 out_free_idr:
@@ -1766,15 +1762,6 @@ static int zram_remove(struct zram *zram)
        mutex_unlock(&bdev->bd_mutex);
 
        zram_debugfs_unregister(zram);
-       /*
-        * Remove sysfs first, so no one will perform a disksize
-        * store while we destroy the devices. This also helps during
-        * hot_remove -- zram_reset_device() is the last holder of
-        * ->init_lock, no later/concurrent disksize_store() or any
-        * other sysfs handlers are possible.
-        */
-       sysfs_remove_group(&disk_to_dev(zram->disk)->kobj,
-                       &zram_disk_attr_group);
 
        /* Make sure all the pending I/O are finished */
        fsync_bdev(bdev);