Skip to content

Commit 4c6459f

Browse files
committed
Merge branch 'for-linus-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs fixes from Chris Mason: "The most user visible change here is a fix for our recent superblock validation checks that were causing problems on non-4k pagesized systems" * 'for-linus-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: Btrfs: btrfs_check_super_valid: Allow 4096 as stripesize btrfs: remove build fixup for qgroup_account_snapshot btrfs: use new error message helper in qgroup_account_snapshot btrfs: avoid blocking open_ctree from cleaner_kthread Btrfs: don't BUG_ON() in btrfs_orphan_add btrfs: account for non-CoW'd blocks in btrfs_abort_transaction Btrfs: check if extent buffer is aligned to sectorsize btrfs: Use correct format specifier
2 parents d9e6614 + de18c16 commit 4c6459f

File tree

11 files changed

+61
-43
lines changed

11 files changed

+61
-43
lines changed

fs/btrfs/check-integrity.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2645,7 +2645,7 @@ static void btrfsic_dump_tree_sub(const struct btrfsic_state *state,
26452645
* This algorithm is recursive because the amount of used stack space
26462646
* is very small and the max recursion depth is limited.
26472647
*/
2648-
indent_add = sprintf(buf, "%c-%llu(%s/%llu/%d)",
2648+
indent_add = sprintf(buf, "%c-%llu(%s/%llu/%u)",
26492649
btrfsic_get_block_type(state, block),
26502650
block->logical_bytenr, block->dev_state->name,
26512651
block->dev_bytenr, block->mirror_num);

fs/btrfs/ctree.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1554,6 +1554,7 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans,
15541554
trans->transid, root->fs_info->generation);
15551555

15561556
if (!should_cow_block(trans, root, buf)) {
1557+
trans->dirty = true;
15571558
*cow_ret = buf;
15581559
return 0;
15591560
}
@@ -2512,6 +2513,8 @@ read_block_for_search(struct btrfs_trans_handle *trans,
25122513
if (!btrfs_buffer_uptodate(tmp, 0, 0))
25132514
ret = -EIO;
25142515
free_extent_buffer(tmp);
2516+
} else {
2517+
ret = PTR_ERR(tmp);
25152518
}
25162519
return ret;
25172520
}
@@ -2775,8 +2778,10 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
27752778
* then we don't want to set the path blocking,
27762779
* so we test it here
27772780
*/
2778-
if (!should_cow_block(trans, root, b))
2781+
if (!should_cow_block(trans, root, b)) {
2782+
trans->dirty = true;
27792783
goto cow_done;
2784+
}
27802785

27812786
/*
27822787
* must have write locks on this node and the

fs/btrfs/disk-io.c

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,7 +1098,7 @@ void readahead_tree_block(struct btrfs_root *root, u64 bytenr)
10981098
struct inode *btree_inode = root->fs_info->btree_inode;
10991099

11001100
buf = btrfs_find_create_tree_block(root, bytenr);
1101-
if (!buf)
1101+
if (IS_ERR(buf))
11021102
return;
11031103
read_extent_buffer_pages(&BTRFS_I(btree_inode)->io_tree,
11041104
buf, 0, WAIT_NONE, btree_get_extent, 0);
@@ -1114,7 +1114,7 @@ int reada_tree_block_flagged(struct btrfs_root *root, u64 bytenr,
11141114
int ret;
11151115

11161116
buf = btrfs_find_create_tree_block(root, bytenr);
1117-
if (!buf)
1117+
if (IS_ERR(buf))
11181118
return 0;
11191119

11201120
set_bit(EXTENT_BUFFER_READAHEAD, &buf->bflags);
@@ -1172,8 +1172,8 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
11721172
int ret;
11731173

11741174
buf = btrfs_find_create_tree_block(root, bytenr);
1175-
if (!buf)
1176-
return ERR_PTR(-ENOMEM);
1175+
if (IS_ERR(buf))
1176+
return buf;
11771177

11781178
ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid);
11791179
if (ret) {
@@ -1806,6 +1806,13 @@ static int cleaner_kthread(void *arg)
18061806
if (btrfs_need_cleaner_sleep(root))
18071807
goto sleep;
18081808

1809+
/*
1810+
* Do not do anything if we might cause open_ctree() to block
1811+
* before we have finished mounting the filesystem.
1812+
*/
1813+
if (!root->fs_info->open)
1814+
goto sleep;
1815+
18091816
if (!mutex_trylock(&root->fs_info->cleaner_mutex))
18101817
goto sleep;
18111818

@@ -2520,7 +2527,6 @@ int open_ctree(struct super_block *sb,
25202527
int num_backups_tried = 0;
25212528
int backup_index = 0;
25222529
int max_active;
2523-
bool cleaner_mutex_locked = false;
25242530

25252531
tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
25262532
chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
@@ -2999,13 +3005,6 @@ int open_ctree(struct super_block *sb,
29993005
goto fail_sysfs;
30003006
}
30013007

3002-
/*
3003-
* Hold the cleaner_mutex thread here so that we don't block
3004-
* for a long time on btrfs_recover_relocation. cleaner_kthread
3005-
* will wait for us to finish mounting the filesystem.
3006-
*/
3007-
mutex_lock(&fs_info->cleaner_mutex);
3008-
cleaner_mutex_locked = true;
30093008
fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root,
30103009
"btrfs-cleaner");
30113010
if (IS_ERR(fs_info->cleaner_kthread))
@@ -3065,17 +3064,17 @@ int open_ctree(struct super_block *sb,
30653064
ret = btrfs_cleanup_fs_roots(fs_info);
30663065
if (ret)
30673066
goto fail_qgroup;
3068-
/* We locked cleaner_mutex before creating cleaner_kthread. */
3067+
3068+
mutex_lock(&fs_info->cleaner_mutex);
30693069
ret = btrfs_recover_relocation(tree_root);
3070+
mutex_unlock(&fs_info->cleaner_mutex);
30703071
if (ret < 0) {
30713072
btrfs_warn(fs_info, "failed to recover relocation: %d",
30723073
ret);
30733074
err = -EINVAL;
30743075
goto fail_qgroup;
30753076
}
30763077
}
3077-
mutex_unlock(&fs_info->cleaner_mutex);
3078-
cleaner_mutex_locked = false;
30793078

30803079
location.objectid = BTRFS_FS_TREE_OBJECTID;
30813080
location.type = BTRFS_ROOT_ITEM_KEY;
@@ -3189,10 +3188,6 @@ int open_ctree(struct super_block *sb,
31893188
filemap_write_and_wait(fs_info->btree_inode->i_mapping);
31903189

31913190
fail_sysfs:
3192-
if (cleaner_mutex_locked) {
3193-
mutex_unlock(&fs_info->cleaner_mutex);
3194-
cleaner_mutex_locked = false;
3195-
}
31963191
btrfs_sysfs_remove_mounted(fs_info);
31973192

31983193
fail_fsdev_sysfs:
@@ -4139,7 +4134,8 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
41394134
ret = -EINVAL;
41404135
}
41414136
if (!is_power_of_2(btrfs_super_stripesize(sb)) ||
4142-
btrfs_super_stripesize(sb) != sectorsize) {
4137+
((btrfs_super_stripesize(sb) != sectorsize) &&
4138+
(btrfs_super_stripesize(sb) != 4096))) {
41434139
btrfs_err(fs_info, "invalid stripesize %u",
41444140
btrfs_super_stripesize(sb));
41454141
ret = -EINVAL;

fs/btrfs/extent-tree.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8016,8 +8016,9 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
80168016
struct extent_buffer *buf;
80178017

80188018
buf = btrfs_find_create_tree_block(root, bytenr);
8019-
if (!buf)
8020-
return ERR_PTR(-ENOMEM);
8019+
if (IS_ERR(buf))
8020+
return buf;
8021+
80218022
btrfs_set_header_generation(buf, trans->transid);
80228023
btrfs_set_buffer_lockdep_class(root->root_key.objectid, buf, level);
80238024
btrfs_tree_lock(buf);
@@ -8044,7 +8045,7 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
80448045
set_extent_dirty(&trans->transaction->dirty_pages, buf->start,
80458046
buf->start + buf->len - 1, GFP_NOFS);
80468047
}
8047-
trans->blocks_used++;
8048+
trans->dirty = true;
80488049
/* this returns a buffer locked for blocking */
80498050
return buf;
80508051
}
@@ -8659,8 +8660,9 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
86598660
next = btrfs_find_tree_block(root->fs_info, bytenr);
86608661
if (!next) {
86618662
next = btrfs_find_create_tree_block(root, bytenr);
8662-
if (!next)
8663-
return -ENOMEM;
8663+
if (IS_ERR(next))
8664+
return PTR_ERR(next);
8665+
86648666
btrfs_set_buffer_lockdep_class(root->root_key.objectid, next,
86658667
level - 1);
86668668
reada = 1;

fs/btrfs/extent_io.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4892,18 +4892,25 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info,
48924892
int uptodate = 1;
48934893
int ret;
48944894

4895+
if (!IS_ALIGNED(start, fs_info->tree_root->sectorsize)) {
4896+
btrfs_err(fs_info, "bad tree block start %llu", start);
4897+
return ERR_PTR(-EINVAL);
4898+
}
4899+
48954900
eb = find_extent_buffer(fs_info, start);
48964901
if (eb)
48974902
return eb;
48984903

48994904
eb = __alloc_extent_buffer(fs_info, start, len);
49004905
if (!eb)
4901-
return NULL;
4906+
return ERR_PTR(-ENOMEM);
49024907

49034908
for (i = 0; i < num_pages; i++, index++) {
49044909
p = find_or_create_page(mapping, index, GFP_NOFS|__GFP_NOFAIL);
4905-
if (!p)
4910+
if (!p) {
4911+
exists = ERR_PTR(-ENOMEM);
49064912
goto free_eb;
4913+
}
49074914

49084915
spin_lock(&mapping->private_lock);
49094916
if (PagePrivate(p)) {
@@ -4948,8 +4955,10 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info,
49484955
set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
49494956
again:
49504957
ret = radix_tree_preload(GFP_NOFS);
4951-
if (ret)
4958+
if (ret) {
4959+
exists = ERR_PTR(ret);
49524960
goto free_eb;
4961+
}
49534962

49544963
spin_lock(&fs_info->buffer_lock);
49554964
ret = radix_tree_insert(&fs_info->buffer_radix,

fs/btrfs/inode.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3271,7 +3271,16 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode)
32713271
/* grab metadata reservation from transaction handle */
32723272
if (reserve) {
32733273
ret = btrfs_orphan_reserve_metadata(trans, inode);
3274-
BUG_ON(ret); /* -ENOSPC in reservation; Logic error? JDM */
3274+
ASSERT(!ret);
3275+
if (ret) {
3276+
atomic_dec(&root->orphan_inodes);
3277+
clear_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
3278+
&BTRFS_I(inode)->runtime_flags);
3279+
if (insert)
3280+
clear_bit(BTRFS_INODE_HAS_ORPHAN_ITEM,
3281+
&BTRFS_I(inode)->runtime_flags);
3282+
return ret;
3283+
}
32753284
}
32763285

32773286
/* insert an orphan item to track this unlinked/truncated file */

fs/btrfs/super.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ void __btrfs_abort_transaction(struct btrfs_trans_handle *trans,
235235
trans->aborted = errno;
236236
/* Nothing used. The other threads that have joined this
237237
* transaction may be able to continue. */
238-
if (!trans->blocks_used && list_empty(&trans->new_bgs)) {
238+
if (!trans->dirty && list_empty(&trans->new_bgs)) {
239239
const char *errstr;
240240

241241
errstr = btrfs_decode_error(errno);
@@ -1807,6 +1807,8 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
18071807
}
18081808
}
18091809
sb->s_flags &= ~MS_RDONLY;
1810+
1811+
fs_info->open = 1;
18101812
}
18111813
out:
18121814
wake_up_process(fs_info->transaction_kthread);

fs/btrfs/transaction.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,11 +1311,6 @@ int btrfs_defrag_root(struct btrfs_root *root)
13111311
return ret;
13121312
}
13131313

1314-
/* Bisesctability fixup, remove in 4.8 */
1315-
#ifndef btrfs_std_error
1316-
#define btrfs_std_error btrfs_handle_fs_error
1317-
#endif
1318-
13191314
/*
13201315
* Do all special snapshot related qgroup dirty hack.
13211316
*
@@ -1385,7 +1380,7 @@ static int qgroup_account_snapshot(struct btrfs_trans_handle *trans,
13851380
switch_commit_roots(trans->transaction, fs_info);
13861381
ret = btrfs_write_and_wait_transaction(trans, src);
13871382
if (ret)
1388-
btrfs_std_error(fs_info, ret,
1383+
btrfs_handle_fs_error(fs_info, ret,
13891384
"Error while writing out transaction for qgroup");
13901385

13911386
out:

fs/btrfs/transaction.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ struct btrfs_trans_handle {
110110
u64 chunk_bytes_reserved;
111111
unsigned long use_count;
112112
unsigned long blocks_reserved;
113-
unsigned long blocks_used;
114113
unsigned long delayed_ref_updates;
115114
struct btrfs_transaction *transaction;
116115
struct btrfs_block_rsv *block_rsv;
@@ -121,6 +120,7 @@ struct btrfs_trans_handle {
121120
bool can_flush_pending_bgs;
122121
bool reloc_reserved;
123122
bool sync;
123+
bool dirty;
124124
unsigned int type;
125125
/*
126126
* this root is only needed to validate that the root passed to

fs/btrfs/tree-log.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2422,8 +2422,8 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
24222422
root_owner = btrfs_header_owner(parent);
24232423

24242424
next = btrfs_find_create_tree_block(root, bytenr);
2425-
if (!next)
2426-
return -ENOMEM;
2425+
if (IS_ERR(next))
2426+
return PTR_ERR(next);
24272427

24282428
if (*level == 1) {
24292429
ret = wc->process_func(root, next, wc, ptr_gen);

fs/btrfs/volumes.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6607,8 +6607,8 @@ int btrfs_read_sys_array(struct btrfs_root *root)
66076607
* overallocate but we can keep it as-is, only the first page is used.
66086608
*/
66096609
sb = btrfs_find_create_tree_block(root, BTRFS_SUPER_INFO_OFFSET);
6610-
if (!sb)
6611-
return -ENOMEM;
6610+
if (IS_ERR(sb))
6611+
return PTR_ERR(sb);
66126612
set_extent_buffer_uptodate(sb);
66136613
btrfs_set_buffer_lockdep_class(root->root_key.objectid, sb, 0);
66146614
/*

0 commit comments

Comments
 (0)