Skip to content

Commit cc6cf82

Browse files
committed
Merge tag 'for-5.13-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: "A few more fixes that people hit during testing. Zoned mode fix: - fix 32bit value wrapping when calculating superblock offsets Error handling fixes: - properly check filesystema and device uuids - properly return errors when marking extents as written - do not write supers if we have an fs error" * tag 'for-5.13-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: promote debugging asserts to full-fledged checks in validate_super btrfs: return value from btrfs_mark_extent_written() in case of error btrfs: zoned: fix zone number to sector/physical calculation btrfs: do not write supers if we have an fs error
2 parents 2f67381 + aefd7f7 commit cc6cf82

File tree

4 files changed

+54
-15
lines changed

4 files changed

+54
-15
lines changed

fs/btrfs/disk-io.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2648,6 +2648,24 @@ static int validate_super(struct btrfs_fs_info *fs_info,
26482648
ret = -EINVAL;
26492649
}
26502650

2651+
if (memcmp(fs_info->fs_devices->fsid, fs_info->super_copy->fsid,
2652+
BTRFS_FSID_SIZE)) {
2653+
btrfs_err(fs_info,
2654+
"superblock fsid doesn't match fsid of fs_devices: %pU != %pU",
2655+
fs_info->super_copy->fsid, fs_info->fs_devices->fsid);
2656+
ret = -EINVAL;
2657+
}
2658+
2659+
if (btrfs_fs_incompat(fs_info, METADATA_UUID) &&
2660+
memcmp(fs_info->fs_devices->metadata_uuid,
2661+
fs_info->super_copy->metadata_uuid, BTRFS_FSID_SIZE)) {
2662+
btrfs_err(fs_info,
2663+
"superblock metadata_uuid doesn't match metadata uuid of fs_devices: %pU != %pU",
2664+
fs_info->super_copy->metadata_uuid,
2665+
fs_info->fs_devices->metadata_uuid);
2666+
ret = -EINVAL;
2667+
}
2668+
26512669
if (memcmp(fs_info->fs_devices->metadata_uuid, sb->dev_item.fsid,
26522670
BTRFS_FSID_SIZE) != 0) {
26532671
btrfs_err(fs_info,
@@ -3279,14 +3297,6 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
32793297

32803298
disk_super = fs_info->super_copy;
32813299

3282-
ASSERT(!memcmp(fs_info->fs_devices->fsid, fs_info->super_copy->fsid,
3283-
BTRFS_FSID_SIZE));
3284-
3285-
if (btrfs_fs_incompat(fs_info, METADATA_UUID)) {
3286-
ASSERT(!memcmp(fs_info->fs_devices->metadata_uuid,
3287-
fs_info->super_copy->metadata_uuid,
3288-
BTRFS_FSID_SIZE));
3289-
}
32903300

32913301
features = btrfs_super_flags(disk_super);
32923302
if (features & BTRFS_SUPER_FLAG_CHANGING_FSID_V2) {

fs/btrfs/file.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,7 +1094,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
10941094
int del_nr = 0;
10951095
int del_slot = 0;
10961096
int recow;
1097-
int ret;
1097+
int ret = 0;
10981098
u64 ino = btrfs_ino(inode);
10991099

11001100
path = btrfs_alloc_path();
@@ -1315,7 +1315,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
13151315
}
13161316
out:
13171317
btrfs_free_path(path);
1318-
return 0;
1318+
return ret;
13191319
}
13201320

13211321
/*

fs/btrfs/tree-log.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3302,6 +3302,22 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
33023302
* begins and releases it only after writing its superblock.
33033303
*/
33043304
mutex_lock(&fs_info->tree_log_mutex);
3305+
3306+
/*
3307+
* The previous transaction writeout phase could have failed, and thus
3308+
* marked the fs in an error state. We must not commit here, as we
3309+
* could have updated our generation in the super_for_commit and
3310+
* writing the super here would result in transid mismatches. If there
3311+
* is an error here just bail.
3312+
*/
3313+
if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) {
3314+
ret = -EIO;
3315+
btrfs_set_log_full_commit(trans);
3316+
btrfs_abort_transaction(trans, ret);
3317+
mutex_unlock(&fs_info->tree_log_mutex);
3318+
goto out_wake_log_root;
3319+
}
3320+
33053321
btrfs_set_super_log_root(fs_info->super_for_commit, log_root_start);
33063322
btrfs_set_super_log_root_level(fs_info->super_for_commit, log_root_level);
33073323
ret = write_all_supers(fs_info, 1);

fs/btrfs/zoned.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,18 @@ static inline u32 sb_zone_number(int shift, int mirror)
150150
return (u32)zone;
151151
}
152152

153+
static inline sector_t zone_start_sector(u32 zone_number,
154+
struct block_device *bdev)
155+
{
156+
return (sector_t)zone_number << ilog2(bdev_zone_sectors(bdev));
157+
}
158+
159+
static inline u64 zone_start_physical(u32 zone_number,
160+
struct btrfs_zoned_device_info *zone_info)
161+
{
162+
return (u64)zone_number << zone_info->zone_size_shift;
163+
}
164+
153165
/*
154166
* Emulate blkdev_report_zones() for a non-zoned device. It slices up the block
155167
* device into static sized chunks and fake a conventional zone on each of
@@ -405,8 +417,8 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device)
405417
if (sb_zone + 1 >= zone_info->nr_zones)
406418
continue;
407419

408-
sector = sb_zone << (zone_info->zone_size_shift - SECTOR_SHIFT);
409-
ret = btrfs_get_dev_zones(device, sector << SECTOR_SHIFT,
420+
ret = btrfs_get_dev_zones(device,
421+
zone_start_physical(sb_zone, zone_info),
410422
&zone_info->sb_zones[sb_pos],
411423
&nr_zones);
412424
if (ret)
@@ -721,7 +733,7 @@ int btrfs_sb_log_location_bdev(struct block_device *bdev, int mirror, int rw,
721733
if (sb_zone + 1 >= nr_zones)
722734
return -ENOENT;
723735

724-
ret = blkdev_report_zones(bdev, sb_zone << zone_sectors_shift,
736+
ret = blkdev_report_zones(bdev, zone_start_sector(sb_zone, bdev),
725737
BTRFS_NR_SB_LOG_ZONES, copy_zone_info_cb,
726738
zones);
727739
if (ret < 0)
@@ -826,7 +838,7 @@ int btrfs_reset_sb_log_zones(struct block_device *bdev, int mirror)
826838
return -ENOENT;
827839

828840
return blkdev_zone_mgmt(bdev, REQ_OP_ZONE_RESET,
829-
sb_zone << zone_sectors_shift,
841+
zone_start_sector(sb_zone, bdev),
830842
zone_sectors * BTRFS_NR_SB_LOG_ZONES, GFP_NOFS);
831843
}
832844

@@ -878,7 +890,8 @@ u64 btrfs_find_allocatable_zones(struct btrfs_device *device, u64 hole_start,
878890
if (!(end <= sb_zone ||
879891
sb_zone + BTRFS_NR_SB_LOG_ZONES <= begin)) {
880892
have_sb = true;
881-
pos = ((u64)sb_zone + BTRFS_NR_SB_LOG_ZONES) << shift;
893+
pos = zone_start_physical(
894+
sb_zone + BTRFS_NR_SB_LOG_ZONES, zinfo);
882895
break;
883896
}
884897

0 commit comments

Comments
 (0)