.. | .. |
---|
381 | 381 | static void free_fs_devices(struct btrfs_fs_devices *fs_devices) |
---|
382 | 382 | { |
---|
383 | 383 | struct btrfs_device *device; |
---|
| 384 | + |
---|
384 | 385 | WARN_ON(fs_devices->opened); |
---|
385 | 386 | while (!list_empty(&fs_devices->devices)) { |
---|
386 | 387 | device = list_entry(fs_devices->devices.next, |
---|
.. | .. |
---|
715 | 716 | blkdev_put(bdev, flags); |
---|
716 | 717 | |
---|
717 | 718 | 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; |
---|
718 | 727 | } |
---|
719 | 728 | |
---|
720 | 729 | /* |
---|
.. | .. |
---|
1227 | 1236 | |
---|
1228 | 1237 | mutex_lock(&uuid_mutex); |
---|
1229 | 1238 | close_fs_devices(fs_devices); |
---|
1230 | | - if (!fs_devices->opened) |
---|
| 1239 | + if (!fs_devices->opened) { |
---|
1231 | 1240 | 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 | + |
---|
1232 | 1254 | |
---|
1233 | 1255 | list_for_each_entry_safe(fs_devices, tmp, &list, seed_list) { |
---|
1234 | 1256 | close_fs_devices(fs_devices); |
---|
.. | .. |
---|
1396 | 1418 | * later supers, using BTRFS_SUPER_MIRROR_MAX instead |
---|
1397 | 1419 | */ |
---|
1398 | 1420 | bytenr = btrfs_sb_offset(0); |
---|
1399 | | - flags |= FMODE_EXCL; |
---|
1400 | 1421 | |
---|
| 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 | + */ |
---|
1401 | 1432 | bdev = blkdev_get_by_path(path, flags, holder); |
---|
1402 | 1433 | if (IS_ERR(bdev)) |
---|
1403 | 1434 | return ERR_CAST(bdev); |
---|
.. | .. |
---|
1579 | 1610 | goto out; |
---|
1580 | 1611 | } |
---|
1581 | 1612 | |
---|
1582 | | - while (1) { |
---|
| 1613 | + while (search_start < search_end) { |
---|
1583 | 1614 | l = path->nodes[0]; |
---|
1584 | 1615 | slot = path->slots[0]; |
---|
1585 | 1616 | if (slot >= btrfs_header_nritems(l)) { |
---|
.. | .. |
---|
1601 | 1632 | |
---|
1602 | 1633 | if (key.type != BTRFS_DEV_EXTENT_KEY) |
---|
1603 | 1634 | goto next; |
---|
| 1635 | + |
---|
| 1636 | + if (key.offset > search_end) |
---|
| 1637 | + break; |
---|
1604 | 1638 | |
---|
1605 | 1639 | if (key.offset > search_start) { |
---|
1606 | 1640 | hole_size = key.offset - search_start; |
---|
.. | .. |
---|
1662 | 1696 | else |
---|
1663 | 1697 | ret = 0; |
---|
1664 | 1698 | |
---|
| 1699 | + ASSERT(max_hole_start + max_hole_size <= search_end); |
---|
1665 | 1700 | out: |
---|
1666 | 1701 | btrfs_free_path(path); |
---|
1667 | 1702 | *start = max_hole_start; |
---|
.. | .. |
---|
4432 | 4467 | } |
---|
4433 | 4468 | } |
---|
4434 | 4469 | |
---|
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)); |
---|
4437 | 4471 | atomic_dec(&fs_info->balance_cancel_req); |
---|
4438 | 4472 | mutex_unlock(&fs_info->balance_mutex); |
---|
4439 | 4473 | return 0; |
---|