Commit 7b65c810 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-6.9-part2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fix from David Sterba:
 "Fix a problem found in 6.7 after adding the temp-fsid feature which
  changed device tracking in memory and broke grub-probe. This is used
  on initrd-less systems. There were several iterations of the fix and
  it took longer than expected"

* tag 'for-6.9-part2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: do not skip re-registration for the mounted device
parents 1b3e2513 d565fffa
......@@ -1303,6 +1303,47 @@ int btrfs_forget_devices(dev_t devt)
return ret;
}
static bool btrfs_skip_registration(struct btrfs_super_block *disk_super,
const char *path, dev_t devt,
bool mount_arg_dev)
{
struct btrfs_fs_devices *fs_devices;
/*
* Do not skip device registration for mounted devices with matching
* maj:min but different paths. Booting without initrd relies on
* /dev/root initially, later replaced with the actual root device.
* A successful scan ensures grub2-probe selects the correct device.
*/
list_for_each_entry(fs_devices, &fs_uuids, fs_list) {
struct btrfs_device *device;
mutex_lock(&fs_devices->device_list_mutex);
if (!fs_devices->opened) {
mutex_unlock(&fs_devices->device_list_mutex);
continue;
}
list_for_each_entry(device, &fs_devices->devices, dev_list) {
if (device->bdev && (device->bdev->bd_dev == devt) &&
strcmp(device->name->str, path) != 0) {
mutex_unlock(&fs_devices->device_list_mutex);
/* Do not skip registration. */
return false;
}
}
mutex_unlock(&fs_devices->device_list_mutex);
}
if (!mount_arg_dev && btrfs_super_num_devices(disk_super) == 1 &&
!(btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_SEEDING))
return true;
return false;
}
/*
* Look for a btrfs signature on a device. This may be called out of the mount path
* and we are not allowed to call set_blocksize during the scan. The superblock
......@@ -1320,6 +1361,7 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, blk_mode_t flags,
struct btrfs_device *device = NULL;
struct file *bdev_file;
u64 bytenr, bytenr_orig;
dev_t devt;
int ret;
lockdep_assert_held(&uuid_mutex);
......@@ -1359,19 +1401,13 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, blk_mode_t flags,
goto error_bdev_put;
}
if (!mount_arg_dev && btrfs_super_num_devices(disk_super) == 1 &&
!(btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_SEEDING)) {
dev_t devt;
devt = file_bdev(bdev_file)->bd_dev;
if (btrfs_skip_registration(disk_super, path, devt, mount_arg_dev)) {
pr_debug("BTRFS: skip registering single non-seed device %s (%d:%d)\n",
path, MAJOR(devt), MINOR(devt));
ret = lookup_bdev(path, &devt);
if (ret)
btrfs_warn(NULL, "lookup bdev failed for path %s: %d",
path, ret);
else
btrfs_free_stale_devices(devt, NULL);
btrfs_free_stale_devices(devt, NULL);
pr_debug("BTRFS: skip registering single non-seed device %s (%d:%d)\n",
path, MAJOR(devt), MINOR(devt));
device = NULL;
goto free_disk_super;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment