Skip to content

Commit 7b65c81

Browse files
committed
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
2 parents 1b3e251 + d565fff commit 7b65c81

1 file changed

Lines changed: 47 additions & 11 deletions

File tree

fs/btrfs/volumes.c

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,6 +1303,47 @@ int btrfs_forget_devices(dev_t devt)
13031303
return ret;
13041304
}
13051305

1306+
static bool btrfs_skip_registration(struct btrfs_super_block *disk_super,
1307+
const char *path, dev_t devt,
1308+
bool mount_arg_dev)
1309+
{
1310+
struct btrfs_fs_devices *fs_devices;
1311+
1312+
/*
1313+
* Do not skip device registration for mounted devices with matching
1314+
* maj:min but different paths. Booting without initrd relies on
1315+
* /dev/root initially, later replaced with the actual root device.
1316+
* A successful scan ensures grub2-probe selects the correct device.
1317+
*/
1318+
list_for_each_entry(fs_devices, &fs_uuids, fs_list) {
1319+
struct btrfs_device *device;
1320+
1321+
mutex_lock(&fs_devices->device_list_mutex);
1322+
1323+
if (!fs_devices->opened) {
1324+
mutex_unlock(&fs_devices->device_list_mutex);
1325+
continue;
1326+
}
1327+
1328+
list_for_each_entry(device, &fs_devices->devices, dev_list) {
1329+
if (device->bdev && (device->bdev->bd_dev == devt) &&
1330+
strcmp(device->name->str, path) != 0) {
1331+
mutex_unlock(&fs_devices->device_list_mutex);
1332+
1333+
/* Do not skip registration. */
1334+
return false;
1335+
}
1336+
}
1337+
mutex_unlock(&fs_devices->device_list_mutex);
1338+
}
1339+
1340+
if (!mount_arg_dev && btrfs_super_num_devices(disk_super) == 1 &&
1341+
!(btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_SEEDING))
1342+
return true;
1343+
1344+
return false;
1345+
}
1346+
13061347
/*
13071348
* Look for a btrfs signature on a device. This may be called out of the mount path
13081349
* 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,
13201361
struct btrfs_device *device = NULL;
13211362
struct file *bdev_file;
13221363
u64 bytenr, bytenr_orig;
1364+
dev_t devt;
13231365
int ret;
13241366

13251367
lockdep_assert_held(&uuid_mutex);
@@ -1359,19 +1401,13 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, blk_mode_t flags,
13591401
goto error_bdev_put;
13601402
}
13611403

1362-
if (!mount_arg_dev && btrfs_super_num_devices(disk_super) == 1 &&
1363-
!(btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_SEEDING)) {
1364-
dev_t devt;
1404+
devt = file_bdev(bdev_file)->bd_dev;
1405+
if (btrfs_skip_registration(disk_super, path, devt, mount_arg_dev)) {
1406+
pr_debug("BTRFS: skip registering single non-seed device %s (%d:%d)\n",
1407+
path, MAJOR(devt), MINOR(devt));
13651408

1366-
ret = lookup_bdev(path, &devt);
1367-
if (ret)
1368-
btrfs_warn(NULL, "lookup bdev failed for path %s: %d",
1369-
path, ret);
1370-
else
1371-
btrfs_free_stale_devices(devt, NULL);
1409+
btrfs_free_stale_devices(devt, NULL);
13721410

1373-
pr_debug("BTRFS: skip registering single non-seed device %s (%d:%d)\n",
1374-
path, MAJOR(devt), MINOR(devt));
13751411
device = NULL;
13761412
goto free_disk_super;
13771413
}

0 commit comments

Comments
 (0)