Commit 4889bc05 authored by Anand Jain's avatar Anand Jain Committed by David Sterba
Browse files

btrfs: add device major-minor info in the struct btrfs_device



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: default avatarAnand Jain <anand.jain@oracle.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 16cab91a
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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;
+15 −25
Original line number Diff line number Diff line
@@ -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);
+5 −0
Original line number Diff line number Diff line
@@ -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;