]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
btrfs: add device major-minor info in the struct btrfs_device
authorAnand Jain <anand.jain@oracle.com>
Wed, 12 Jan 2022 05:06:01 +0000 (13:06 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 14 Mar 2022 12:13:47 +0000 (13:13 +0100)
Internally it is common to use the major-minor number to identify a
device and, at a few locations in btrfs, we use the major-minor number
to match the device.

So when we identify a new btrfs device through device add or device
replace or device-scan/ready save the device's major-minor (dev_t) in the
struct btrfs_device so that we don't have to call lookup_bdev() again.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/dev-replace.c
fs/btrfs/volumes.c
fs/btrfs/volumes.h

index 1bd1bcee95c973d71c35acfe806f10830c03c8c6..71fd99b482832c4e635b761400bc8cc537fc3905 100644 (file)
@@ -303,6 +303,9 @@ static int btrfs_init_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
                goto error;
        }
        rcu_assign_pointer(device->name, name);
+       ret = lookup_bdev(device_path, &device->devt);
+       if (ret)
+               goto error;
 
        set_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state);
        device->generation = 0;
index b47dd13877666b4272e1add603f2526806c3c42a..ebe655eb8b4dfef4d2ce69840efa17769f24deea 100644 (file)
@@ -808,11 +808,17 @@ static noinline struct btrfs_device *device_list_add(const char *path,
        struct rcu_string *name;
        u64 found_transid = btrfs_super_generation(disk_super);
        u64 devid = btrfs_stack_device_id(&disk_super->dev_item);
+       dev_t path_devt;
+       int error;
        bool has_metadata_uuid = (btrfs_super_incompat_flags(disk_super) &
                BTRFS_FEATURE_INCOMPAT_METADATA_UUID);
        bool fsid_change_in_progress = (btrfs_super_flags(disk_super) &
                                        BTRFS_SUPER_FLAG_CHANGING_FSID_V2);
 
+       error = lookup_bdev(path, &path_devt);
+       if (error)
+               return ERR_PTR(error);
+
        if (fsid_change_in_progress) {
                if (!has_metadata_uuid)
                        fs_devices = find_fsid_inprogress(disk_super);
@@ -895,6 +901,7 @@ static noinline struct btrfs_device *device_list_add(const char *path,
                        return ERR_PTR(-ENOMEM);
                }
                rcu_assign_pointer(device->name, name);
+               device->devt = path_devt;
 
                list_add_rcu(&device->dev_list, &fs_devices->devices);
                fs_devices->num_devices++;
@@ -957,16 +964,7 @@ static noinline struct btrfs_device *device_list_add(const char *path,
                 * make sure it's the same device if the device is mounted
                 */
                if (device->bdev) {
-                       int error;
-                       dev_t path_dev;
-
-                       error = lookup_bdev(path, &path_dev);
-                       if (error) {
-                               mutex_unlock(&fs_devices->device_list_mutex);
-                               return ERR_PTR(error);
-                       }
-
-                       if (device->bdev->bd_dev != path_dev) {
+                       if (device->devt != path_devt) {
                                mutex_unlock(&fs_devices->device_list_mutex);
                                /*
                                 * device->fs_info may not be reliable here, so
@@ -999,6 +997,7 @@ static noinline struct btrfs_device *device_list_add(const char *path,
                        fs_devices->missing_devices--;
                        clear_bit(BTRFS_DEV_STATE_MISSING, &device->dev_state);
                }
+               device->devt = path_devt;
        }
 
        /*
@@ -1412,16 +1411,8 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, fmode_t flags,
        }
 
        device = device_list_add(path, disk_super, &new_device_added);
-       if (!IS_ERR(device) && new_device_added) {
-               dev_t devt;
-
-               /*
-                * It is ok to ignore if we fail to free the stale device (if
-                * any). As there is nothing much that can be done about it.
-                */
-               if (lookup_bdev(path, &devt) == 0)
-                       btrfs_free_stale_devices(devt, device);
-       }
+       if (!IS_ERR(device) && new_device_added)
+               btrfs_free_stale_devices(device->devt, device);
 
        btrfs_release_disk_super(disk_super);
 
@@ -2652,7 +2643,6 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
        int ret = 0;
        bool seeding_dev = false;
        bool locked = false;
-       dev_t devt;
 
        if (sb_rdonly(sb) && !fs_devices->seeding)
                return -EROFS;
@@ -2702,6 +2692,9 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
 
        device->fs_info = fs_info;
        device->bdev = bdev;
+       ret = lookup_bdev(device_path, &device->devt);
+       if (ret)
+               goto error_free_device;
 
        ret = btrfs_get_dev_zone_info(device, false);
        if (ret)
@@ -2845,13 +2838,10 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
         * Now that we have written a new super block to this device, check all
         * other fs_devices list if device_path alienates any other scanned
         * device.
-        * Skip forget_deivces if lookup_bdev() fails as there is nothing much
-        * that can be done about it.
         * We can ignore the return value as it typically returns -EINVAL and
         * only succeeds if the device was an alien.
         */
-       if (lookup_bdev(device_path, &devt) == 0)
-               btrfs_forget_devices(devt);
+       btrfs_forget_devices(device->devt);
 
        /* Update ctime/mtime for blkid or udev */
        update_dev_time(device_path);
index 38b898bc5f0ebf44ad78f0d044c2784c85d30dc4..bd297f23d19e7f9fccb9326f64dbb7774ae7f396 100644 (file)
@@ -72,6 +72,11 @@ struct btrfs_device {
        /* the mode sent to blkdev_get */
        fmode_t mode;
 
+       /*
+        * Device's major-minor number. Must be set even if the device is not
+        * opened (bdev == NULL), unless the device is missing.
+        */
+       dev_t devt;
        unsigned long dev_state;
        blk_status_t last_flush_error;