Skip to content

Commit aa27b32

Browse files
committed
Merge tag 'for-5.8-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: - regression fix of a leak in global block reserve accounting - fix a (hard to hit) race of readahead vs releasepage that could lead to crash - convert all remaining uses of comment fall through annotations to the pseudo keyword - fix crash when mounting a fuzzed image with -o recovery * tag 'for-5.8-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: reset tree root pointer after error in init_tree_roots btrfs: fix reclaim_size counter leak after stealing from global reserve btrfs: fix fatal extent_buffer readahead vs releasepage race btrfs: convert comments to fallthrough annotations
2 parents 9e4d769 + 0465337 commit aa27b32

File tree

7 files changed

+35
-25
lines changed

7 files changed

+35
-25
lines changed

fs/btrfs/ctree.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1196,7 +1196,7 @@ __tree_mod_log_rewind(struct btrfs_fs_info *fs_info, struct extent_buffer *eb,
11961196
switch (tm->op) {
11971197
case MOD_LOG_KEY_REMOVE_WHILE_FREEING:
11981198
BUG_ON(tm->slot < n);
1199-
/* Fallthrough */
1199+
fallthrough;
12001200
case MOD_LOG_KEY_REMOVE_WHILE_MOVING:
12011201
case MOD_LOG_KEY_REMOVE:
12021202
btrfs_set_node_key(eb, &tm->key, tm->slot);

fs/btrfs/disk-io.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2593,10 +2593,12 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
25932593
!extent_buffer_uptodate(tree_root->node)) {
25942594
handle_error = true;
25952595

2596-
if (IS_ERR(tree_root->node))
2596+
if (IS_ERR(tree_root->node)) {
25972597
ret = PTR_ERR(tree_root->node);
2598-
else if (!extent_buffer_uptodate(tree_root->node))
2598+
tree_root->node = NULL;
2599+
} else if (!extent_buffer_uptodate(tree_root->node)) {
25992600
ret = -EUCLEAN;
2601+
}
26002602

26012603
btrfs_warn(fs_info, "failed to read tree root");
26022604
continue;

fs/btrfs/extent_io.c

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5058,25 +5058,28 @@ struct extent_buffer *alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info,
50585058
static void check_buffer_tree_ref(struct extent_buffer *eb)
50595059
{
50605060
int refs;
5061-
/* the ref bit is tricky. We have to make sure it is set
5062-
* if we have the buffer dirty. Otherwise the
5063-
* code to free a buffer can end up dropping a dirty
5064-
* page
5061+
/*
5062+
* The TREE_REF bit is first set when the extent_buffer is added
5063+
* to the radix tree. It is also reset, if unset, when a new reference
5064+
* is created by find_extent_buffer.
50655065
*
5066-
* Once the ref bit is set, it won't go away while the
5067-
* buffer is dirty or in writeback, and it also won't
5068-
* go away while we have the reference count on the
5069-
* eb bumped.
5066+
* It is only cleared in two cases: freeing the last non-tree
5067+
* reference to the extent_buffer when its STALE bit is set or
5068+
* calling releasepage when the tree reference is the only reference.
50705069
*
5071-
* We can't just set the ref bit without bumping the
5072-
* ref on the eb because free_extent_buffer might
5073-
* see the ref bit and try to clear it. If this happens
5074-
* free_extent_buffer might end up dropping our original
5075-
* ref by mistake and freeing the page before we are able
5076-
* to add one more ref.
5070+
* In both cases, care is taken to ensure that the extent_buffer's
5071+
* pages are not under io. However, releasepage can be concurrently
5072+
* called with creating new references, which is prone to race
5073+
* conditions between the calls to check_buffer_tree_ref in those
5074+
* codepaths and clearing TREE_REF in try_release_extent_buffer.
50775075
*
5078-
* So bump the ref count first, then set the bit. If someone
5079-
* beat us to it, drop the ref we added.
5076+
* The actual lifetime of the extent_buffer in the radix tree is
5077+
* adequately protected by the refcount, but the TREE_REF bit and
5078+
* its corresponding reference are not. To protect against this
5079+
* class of races, we call check_buffer_tree_ref from the codepaths
5080+
* which trigger io after they set eb->io_pages. Note that once io is
5081+
* initiated, TREE_REF can no longer be cleared, so that is the
5082+
* moment at which any such race is best fixed.
50805083
*/
50815084
refs = atomic_read(&eb->refs);
50825085
if (refs >= 2 && test_bit(EXTENT_BUFFER_TREE_REF, &eb->bflags))
@@ -5527,6 +5530,11 @@ int read_extent_buffer_pages(struct extent_buffer *eb, int wait, int mirror_num)
55275530
clear_bit(EXTENT_BUFFER_READ_ERR, &eb->bflags);
55285531
eb->read_mirror = 0;
55295532
atomic_set(&eb->io_pages, num_reads);
5533+
/*
5534+
* It is possible for releasepage to clear the TREE_REF bit before we
5535+
* set io_pages. See check_buffer_tree_ref for a more detailed comment.
5536+
*/
5537+
check_buffer_tree_ref(eb);
55305538
for (i = 0; i < num_pages; i++) {
55315539
page = eb->pages[i];
55325540

fs/btrfs/ref-verify.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ static int process_leaf(struct btrfs_root *root,
509509
switch (key.type) {
510510
case BTRFS_EXTENT_ITEM_KEY:
511511
*num_bytes = key.offset;
512-
/* fall through */
512+
fallthrough;
513513
case BTRFS_METADATA_ITEM_KEY:
514514
*bytenr = key.objectid;
515515
ret = process_extent_item(fs_info, path, &key, i,

fs/btrfs/space-info.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -879,8 +879,8 @@ static bool steal_from_global_rsv(struct btrfs_fs_info *fs_info,
879879
return false;
880880
}
881881
global_rsv->reserved -= ticket->bytes;
882+
remove_ticket(space_info, ticket);
882883
ticket->bytes = 0;
883-
list_del_init(&ticket->list);
884884
wake_up(&ticket->wait);
885885
space_info->tickets_id++;
886886
if (global_rsv->reserved < global_rsv->size)

fs/btrfs/super.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
523523
case Opt_compress_force:
524524
case Opt_compress_force_type:
525525
compress_force = true;
526-
/* Fallthrough */
526+
fallthrough;
527527
case Opt_compress:
528528
case Opt_compress_type:
529529
saved_compress_type = btrfs_test_opt(info,
@@ -622,7 +622,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
622622
btrfs_set_opt(info->mount_opt, NOSSD);
623623
btrfs_clear_and_info(info, SSD,
624624
"not using ssd optimizations");
625-
/* Fallthrough */
625+
fallthrough;
626626
case Opt_nossd_spread:
627627
btrfs_clear_and_info(info, SSD_SPREAD,
628628
"not using spread ssd allocation scheme");
@@ -793,7 +793,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
793793
case Opt_recovery:
794794
btrfs_warn(info,
795795
"'recovery' is deprecated, use 'usebackuproot' instead");
796-
/* fall through */
796+
fallthrough;
797797
case Opt_usebackuproot:
798798
btrfs_info(info,
799799
"trying to use backup root at mount time");

fs/btrfs/volumes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ static inline enum btrfs_map_op btrfs_op(struct bio *bio)
408408
return BTRFS_MAP_WRITE;
409409
default:
410410
WARN_ON_ONCE(1);
411-
/* fall through */
411+
fallthrough;
412412
case REQ_OP_READ:
413413
return BTRFS_MAP_READ;
414414
}

0 commit comments

Comments
 (0)