Skip to content

Commit f9e3610

Browse files
committed
Merge tag 'for-5.15-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: - regression fix for leak of transaction handle after verity rollback failure - properly reset device last error between mounts - improve one error handling case when checksumming bios - fixup confusing displayed size of space info free space * tag 'for-5.15-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: prevent __btrfs_dump_space_info() to underflow its free space btrfs: fix mount failure due to past and transient device flush error btrfs: fix transaction handle leak after verity rollback failure btrfs: replace BUG_ON() in btrfs_csum_one_bio() with proper error handling
2 parents 831c9bd + 0619b79 commit f9e3610

File tree

4 files changed

+32
-5
lines changed

4 files changed

+32
-5
lines changed

fs/btrfs/file-item.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,18 @@ blk_status_t btrfs_csum_one_bio(struct btrfs_inode *inode, struct bio *bio,
665665

666666
if (!ordered) {
667667
ordered = btrfs_lookup_ordered_extent(inode, offset);
668-
BUG_ON(!ordered); /* Logic error */
668+
/*
669+
* The bio range is not covered by any ordered extent,
670+
* must be a code logic error.
671+
*/
672+
if (unlikely(!ordered)) {
673+
WARN(1, KERN_WARNING
674+
"no ordered extent for root %llu ino %llu offset %llu\n",
675+
inode->root->root_key.objectid,
676+
btrfs_ino(inode), offset);
677+
kvfree(sums);
678+
return BLK_STS_IOERR;
679+
}
669680
}
670681

671682
nr_sectors = BTRFS_BYTES_TO_BLKS(fs_info,

fs/btrfs/space-info.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,9 +414,10 @@ static void __btrfs_dump_space_info(struct btrfs_fs_info *fs_info,
414414
{
415415
lockdep_assert_held(&info->lock);
416416

417-
btrfs_info(fs_info, "space_info %llu has %llu free, is %sfull",
417+
/* The free space could be negative in case of overcommit */
418+
btrfs_info(fs_info, "space_info %llu has %lld free, is %sfull",
418419
info->flags,
419-
info->total_bytes - btrfs_space_info_used(info, true),
420+
(s64)(info->total_bytes - btrfs_space_info_used(info, true)),
420421
info->full ? "" : "not ");
421422
btrfs_info(fs_info,
422423
"space_info total=%llu, used=%llu, pinned=%llu, reserved=%llu, may_use=%llu, readonly=%llu zone_unusable=%llu",

fs/btrfs/verity.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ static int del_orphan(struct btrfs_trans_handle *trans, struct btrfs_inode *inod
451451
*/
452452
static int rollback_verity(struct btrfs_inode *inode)
453453
{
454-
struct btrfs_trans_handle *trans;
454+
struct btrfs_trans_handle *trans = NULL;
455455
struct btrfs_root *root = inode->root;
456456
int ret;
457457

@@ -473,6 +473,7 @@ static int rollback_verity(struct btrfs_inode *inode)
473473
trans = btrfs_start_transaction(root, 2);
474474
if (IS_ERR(trans)) {
475475
ret = PTR_ERR(trans);
476+
trans = NULL;
476477
btrfs_handle_fs_error(root->fs_info, ret,
477478
"failed to start transaction in verity rollback %llu",
478479
(u64)inode->vfs_inode.i_ino);
@@ -490,8 +491,9 @@ static int rollback_verity(struct btrfs_inode *inode)
490491
btrfs_abort_transaction(trans, ret);
491492
goto out;
492493
}
493-
btrfs_end_transaction(trans);
494494
out:
495+
if (trans)
496+
btrfs_end_transaction(trans);
495497
return ret;
496498
}
497499

fs/btrfs/volumes.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,19 @@ static void btrfs_close_one_device(struct btrfs_device *device)
11371137
atomic_set(&device->dev_stats_ccnt, 0);
11381138
extent_io_tree_release(&device->alloc_state);
11391139

1140+
/*
1141+
* Reset the flush error record. We might have a transient flush error
1142+
* in this mount, and if so we aborted the current transaction and set
1143+
* the fs to an error state, guaranteeing no super blocks can be further
1144+
* committed. However that error might be transient and if we unmount the
1145+
* filesystem and mount it again, we should allow the mount to succeed
1146+
* (btrfs_check_rw_degradable() should not fail) - if after mounting the
1147+
* filesystem again we still get flush errors, then we will again abort
1148+
* any transaction and set the error state, guaranteeing no commits of
1149+
* unsafe super blocks.
1150+
*/
1151+
device->last_flush_error = 0;
1152+
11401153
/* Verify the device is back in a pristine state */
11411154
ASSERT(!test_bit(BTRFS_DEV_STATE_FLUSH_SENT, &device->dev_state));
11421155
ASSERT(!test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state));

0 commit comments

Comments
 (0)