| .. | .. |
|---|
| 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; |
|---|