Skip to content

Commit f0fddce

Browse files
committed
Merge tag 'for-5.14-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: "A few fixes and one patch to help some block layer API cleanups: - skip missing device when running fstrim - fix unpersisted i_size on fsync after expanding truncate - fix lock inversion problem when doing qgroup extent tracing - replace bdgrab/bdput usage, replace gendisk by block_device" * tag 'for-5.14-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: store a block_device in struct btrfs_ordered_extent btrfs: fix lock inversion problem when doing qgroup extent tracing btrfs: check for missing device in btrfs_trim_fs btrfs: fix unpersisted i_size on fsync after expanding truncate
2 parents 704f4cb + c7c3a6d commit f0fddce

12 files changed

Lines changed: 79 additions & 47 deletions

File tree

fs/btrfs/backref.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,15 +1488,15 @@ static int btrfs_find_all_roots_safe(struct btrfs_trans_handle *trans,
14881488
int btrfs_find_all_roots(struct btrfs_trans_handle *trans,
14891489
struct btrfs_fs_info *fs_info, u64 bytenr,
14901490
u64 time_seq, struct ulist **roots,
1491-
bool ignore_offset)
1491+
bool ignore_offset, bool skip_commit_root_sem)
14921492
{
14931493
int ret;
14941494

1495-
if (!trans)
1495+
if (!trans && !skip_commit_root_sem)
14961496
down_read(&fs_info->commit_root_sem);
14971497
ret = btrfs_find_all_roots_safe(trans, fs_info, bytenr,
14981498
time_seq, roots, ignore_offset);
1499-
if (!trans)
1499+
if (!trans && !skip_commit_root_sem)
15001500
up_read(&fs_info->commit_root_sem);
15011501
return ret;
15021502
}

fs/btrfs/backref.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ int btrfs_find_all_leafs(struct btrfs_trans_handle *trans,
4747
const u64 *extent_item_pos, bool ignore_offset);
4848
int btrfs_find_all_roots(struct btrfs_trans_handle *trans,
4949
struct btrfs_fs_info *fs_info, u64 bytenr,
50-
u64 time_seq, struct ulist **roots, bool ignore_offset);
50+
u64 time_seq, struct ulist **roots, bool ignore_offset,
51+
bool skip_commit_root_sem);
5152
char *btrfs_ref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
5253
u32 name_len, unsigned long name_off,
5354
struct extent_buffer *eb_in, u64 parent,

fs/btrfs/delayed-ref.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -974,7 +974,7 @@ int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans,
974974
kmem_cache_free(btrfs_delayed_tree_ref_cachep, ref);
975975

976976
if (qrecord_inserted)
977-
btrfs_qgroup_trace_extent_post(fs_info, record);
977+
btrfs_qgroup_trace_extent_post(trans, record);
978978

979979
return 0;
980980
}
@@ -1069,7 +1069,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans,
10691069

10701070

10711071
if (qrecord_inserted)
1072-
return btrfs_qgroup_trace_extent_post(fs_info, record);
1072+
return btrfs_qgroup_trace_extent_post(trans, record);
10731073
return 0;
10741074
}
10751075

fs/btrfs/extent-tree.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6019,6 +6019,9 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range)
60196019
mutex_lock(&fs_info->fs_devices->device_list_mutex);
60206020
devices = &fs_info->fs_devices->devices;
60216021
list_for_each_entry(device, devices, dev_list) {
6022+
if (test_bit(BTRFS_DEV_STATE_MISSING, &device->dev_state))
6023+
continue;
6024+
60226025
ret = btrfs_trim_free_extents(device, &group_trimmed);
60236026
if (ret) {
60246027
dev_failed++;

fs/btrfs/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2992,7 +2992,7 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
29922992
goto out;
29932993
}
29942994

2995-
if (ordered_extent->disk)
2995+
if (ordered_extent->bdev)
29962996
btrfs_rewrite_logical_zoned(ordered_extent);
29972997

29982998
btrfs_free_io_failure_record(inode, start, end);

fs/btrfs/ordered-data.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,6 @@ static int __btrfs_add_ordered_extent(struct btrfs_inode *inode, u64 file_offset
190190
entry->truncated_len = (u64)-1;
191191
entry->qgroup_rsv = ret;
192192
entry->physical = (u64)-1;
193-
entry->disk = NULL;
194-
entry->partno = (u8)-1;
195193

196194
ASSERT(type == BTRFS_ORDERED_REGULAR ||
197195
type == BTRFS_ORDERED_NOCOW ||

fs/btrfs/ordered-data.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,7 @@ struct btrfs_ordered_extent {
145145
* command in a workqueue context
146146
*/
147147
u64 physical;
148-
struct gendisk *disk;
149-
u8 partno;
148+
struct block_device *bdev;
150149
};
151150

152151
/*

fs/btrfs/qgroup.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1704,17 +1704,39 @@ int btrfs_qgroup_trace_extent_nolock(struct btrfs_fs_info *fs_info,
17041704
return 0;
17051705
}
17061706

1707-
int btrfs_qgroup_trace_extent_post(struct btrfs_fs_info *fs_info,
1707+
int btrfs_qgroup_trace_extent_post(struct btrfs_trans_handle *trans,
17081708
struct btrfs_qgroup_extent_record *qrecord)
17091709
{
17101710
struct ulist *old_root;
17111711
u64 bytenr = qrecord->bytenr;
17121712
int ret;
17131713

1714-
ret = btrfs_find_all_roots(NULL, fs_info, bytenr, 0, &old_root, false);
1714+
/*
1715+
* We are always called in a context where we are already holding a
1716+
* transaction handle. Often we are called when adding a data delayed
1717+
* reference from btrfs_truncate_inode_items() (truncating or unlinking),
1718+
* in which case we will be holding a write lock on extent buffer from a
1719+
* subvolume tree. In this case we can't allow btrfs_find_all_roots() to
1720+
* acquire fs_info->commit_root_sem, because that is a higher level lock
1721+
* that must be acquired before locking any extent buffers.
1722+
*
1723+
* So we want btrfs_find_all_roots() to not acquire the commit_root_sem
1724+
* but we can't pass it a non-NULL transaction handle, because otherwise
1725+
* it would not use commit roots and would lock extent buffers, causing
1726+
* a deadlock if it ends up trying to read lock the same extent buffer
1727+
* that was previously write locked at btrfs_truncate_inode_items().
1728+
*
1729+
* So pass a NULL transaction handle to btrfs_find_all_roots() and
1730+
* explicitly tell it to not acquire the commit_root_sem - if we are
1731+
* holding a transaction handle we don't need its protection.
1732+
*/
1733+
ASSERT(trans != NULL);
1734+
1735+
ret = btrfs_find_all_roots(NULL, trans->fs_info, bytenr, 0, &old_root,
1736+
false, true);
17151737
if (ret < 0) {
1716-
fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
1717-
btrfs_warn(fs_info,
1738+
trans->fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
1739+
btrfs_warn(trans->fs_info,
17181740
"error accounting new delayed refs extent (err code: %d), quota inconsistent",
17191741
ret);
17201742
return 0;
@@ -1758,7 +1780,7 @@ int btrfs_qgroup_trace_extent(struct btrfs_trans_handle *trans, u64 bytenr,
17581780
kfree(record);
17591781
return 0;
17601782
}
1761-
return btrfs_qgroup_trace_extent_post(fs_info, record);
1783+
return btrfs_qgroup_trace_extent_post(trans, record);
17621784
}
17631785

17641786
int btrfs_qgroup_trace_leaf_items(struct btrfs_trans_handle *trans,
@@ -2629,7 +2651,7 @@ int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans)
26292651
/* Search commit root to find old_roots */
26302652
ret = btrfs_find_all_roots(NULL, fs_info,
26312653
record->bytenr, 0,
2632-
&record->old_roots, false);
2654+
&record->old_roots, false, false);
26332655
if (ret < 0)
26342656
goto cleanup;
26352657
}
@@ -2645,7 +2667,7 @@ int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans)
26452667
* current root. It's safe inside commit_transaction().
26462668
*/
26472669
ret = btrfs_find_all_roots(trans, fs_info,
2648-
record->bytenr, BTRFS_SEQ_LAST, &new_roots, false);
2670+
record->bytenr, BTRFS_SEQ_LAST, &new_roots, false, false);
26492671
if (ret < 0)
26502672
goto cleanup;
26512673
if (qgroup_to_skip) {
@@ -3179,7 +3201,7 @@ static int qgroup_rescan_leaf(struct btrfs_trans_handle *trans,
31793201
num_bytes = found.offset;
31803202

31813203
ret = btrfs_find_all_roots(NULL, fs_info, found.objectid, 0,
3182-
&roots, false);
3204+
&roots, false, false);
31833205
if (ret < 0)
31843206
goto out;
31853207
/* For rescan, just pass old_roots as NULL */

fs/btrfs/qgroup.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ int btrfs_qgroup_trace_extent_nolock(
298298
* using current root, then we can move all expensive backref walk out of
299299
* transaction committing, but not now as qgroup accounting will be wrong again.
300300
*/
301-
int btrfs_qgroup_trace_extent_post(struct btrfs_fs_info *fs_info,
301+
int btrfs_qgroup_trace_extent_post(struct btrfs_trans_handle *trans,
302302
struct btrfs_qgroup_extent_record *qrecord);
303303

304304
/*

fs/btrfs/tests/qgroup-tests.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ static int test_no_shared_qgroup(struct btrfs_root *root,
224224
* quota.
225225
*/
226226
ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots,
227-
false);
227+
false, false);
228228
if (ret) {
229229
ulist_free(old_roots);
230230
test_err("couldn't find old roots: %d", ret);
@@ -237,7 +237,7 @@ static int test_no_shared_qgroup(struct btrfs_root *root,
237237
return ret;
238238

239239
ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots,
240-
false);
240+
false, false);
241241
if (ret) {
242242
ulist_free(old_roots);
243243
ulist_free(new_roots);
@@ -261,7 +261,7 @@ static int test_no_shared_qgroup(struct btrfs_root *root,
261261
new_roots = NULL;
262262

263263
ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots,
264-
false);
264+
false, false);
265265
if (ret) {
266266
ulist_free(old_roots);
267267
test_err("couldn't find old roots: %d", ret);
@@ -273,7 +273,7 @@ static int test_no_shared_qgroup(struct btrfs_root *root,
273273
return -EINVAL;
274274

275275
ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots,
276-
false);
276+
false, false);
277277
if (ret) {
278278
ulist_free(old_roots);
279279
ulist_free(new_roots);
@@ -325,7 +325,7 @@ static int test_multiple_refs(struct btrfs_root *root,
325325
}
326326

327327
ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots,
328-
false);
328+
false, false);
329329
if (ret) {
330330
ulist_free(old_roots);
331331
test_err("couldn't find old roots: %d", ret);
@@ -338,7 +338,7 @@ static int test_multiple_refs(struct btrfs_root *root,
338338
return ret;
339339

340340
ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots,
341-
false);
341+
false, false);
342342
if (ret) {
343343
ulist_free(old_roots);
344344
ulist_free(new_roots);
@@ -360,7 +360,7 @@ static int test_multiple_refs(struct btrfs_root *root,
360360
}
361361

362362
ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots,
363-
false);
363+
false, false);
364364
if (ret) {
365365
ulist_free(old_roots);
366366
test_err("couldn't find old roots: %d", ret);
@@ -373,7 +373,7 @@ static int test_multiple_refs(struct btrfs_root *root,
373373
return ret;
374374

375375
ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots,
376-
false);
376+
false, false);
377377
if (ret) {
378378
ulist_free(old_roots);
379379
ulist_free(new_roots);
@@ -401,7 +401,7 @@ static int test_multiple_refs(struct btrfs_root *root,
401401
}
402402

403403
ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots,
404-
false);
404+
false, false);
405405
if (ret) {
406406
ulist_free(old_roots);
407407
test_err("couldn't find old roots: %d", ret);
@@ -414,7 +414,7 @@ static int test_multiple_refs(struct btrfs_root *root,
414414
return ret;
415415

416416
ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots,
417-
false);
417+
false, false);
418418
if (ret) {
419419
ulist_free(old_roots);
420420
ulist_free(new_roots);

0 commit comments

Comments
 (0)