hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/btrfs/volumes.c
....@@ -381,6 +381,7 @@
381381 static void free_fs_devices(struct btrfs_fs_devices *fs_devices)
382382 {
383383 struct btrfs_device *device;
384
+
384385 WARN_ON(fs_devices->opened);
385386 while (!list_empty(&fs_devices->devices)) {
386387 device = list_entry(fs_devices->devices.next,
....@@ -715,6 +716,14 @@
715716 blkdev_put(bdev, flags);
716717
717718 return -EINVAL;
719
+}
720
+
721
+u8 *btrfs_sb_fsid_ptr(struct btrfs_super_block *sb)
722
+{
723
+ bool has_metadata_uuid = (btrfs_super_incompat_flags(sb) &
724
+ BTRFS_FEATURE_INCOMPAT_METADATA_UUID);
725
+
726
+ return has_metadata_uuid ? sb->metadata_uuid : sb->fsid;
718727 }
719728
720729 /*
....@@ -1227,8 +1236,21 @@
12271236
12281237 mutex_lock(&uuid_mutex);
12291238 close_fs_devices(fs_devices);
1230
- if (!fs_devices->opened)
1239
+ if (!fs_devices->opened) {
12311240 list_splice_init(&fs_devices->seed_list, &list);
1241
+
1242
+ /*
1243
+ * If the struct btrfs_fs_devices is not assembled with any
1244
+ * other device, it can be re-initialized during the next mount
1245
+ * without the needing device-scan step. Therefore, it can be
1246
+ * fully freed.
1247
+ */
1248
+ if (fs_devices->num_devices == 1) {
1249
+ list_del(&fs_devices->fs_list);
1250
+ free_fs_devices(fs_devices);
1251
+ }
1252
+ }
1253
+
12321254
12331255 list_for_each_entry_safe(fs_devices, tmp, &list, seed_list) {
12341256 close_fs_devices(fs_devices);
....@@ -1396,8 +1418,17 @@
13961418 * later supers, using BTRFS_SUPER_MIRROR_MAX instead
13971419 */
13981420 bytenr = btrfs_sb_offset(0);
1399
- flags |= FMODE_EXCL;
14001421
1422
+ /*
1423
+ * Avoid using flag |= FMODE_EXCL here, as the systemd-udev may
1424
+ * initiate the device scan which may race with the user's mount
1425
+ * or mkfs command, resulting in failure.
1426
+ * Since the device scan is solely for reading purposes, there is
1427
+ * no need for FMODE_EXCL. Additionally, the devices are read again
1428
+ * during the mount process. It is ok to get some inconsistent
1429
+ * values temporarily, as the device paths of the fsid are the only
1430
+ * required information for assembling the volume.
1431
+ */
14011432 bdev = blkdev_get_by_path(path, flags, holder);
14021433 if (IS_ERR(bdev))
14031434 return ERR_CAST(bdev);
....@@ -1579,7 +1610,7 @@
15791610 goto out;
15801611 }
15811612
1582
- while (1) {
1613
+ while (search_start < search_end) {
15831614 l = path->nodes[0];
15841615 slot = path->slots[0];
15851616 if (slot >= btrfs_header_nritems(l)) {
....@@ -1601,6 +1632,9 @@
16011632
16021633 if (key.type != BTRFS_DEV_EXTENT_KEY)
16031634 goto next;
1635
+
1636
+ if (key.offset > search_end)
1637
+ break;
16041638
16051639 if (key.offset > search_start) {
16061640 hole_size = key.offset - search_start;
....@@ -1662,6 +1696,7 @@
16621696 else
16631697 ret = 0;
16641698
1699
+ ASSERT(max_hole_start + max_hole_size <= search_end);
16651700 out:
16661701 btrfs_free_path(path);
16671702 *start = max_hole_start;
....@@ -4432,8 +4467,7 @@
44324467 }
44334468 }
44344469
4435
- BUG_ON(fs_info->balance_ctl ||
4436
- test_bit(BTRFS_FS_BALANCE_RUNNING, &fs_info->flags));
4470
+ ASSERT(!test_bit(BTRFS_FS_BALANCE_RUNNING, &fs_info->flags));
44374471 atomic_dec(&fs_info->balance_cancel_req);
44384472 mutex_unlock(&fs_info->balance_mutex);
44394473 return 0;