Skip to content

Commit 6afaed5

Browse files
fdmananakdave
authored andcommitted
btrfs: simplify update of last_dir_index_offset when logging a directory
When logging a directory, we always set the inode's last_dir_index_offset to the offset of the last dir index item we found. This is using an extra field in the log context structure, and it makes more sense to update it only after we insert dir index items, and we could directly update the inode's last_dir_index_offset field instead. So make this simpler by updating the inode's last_dir_index_offset only when we actually insert dir index keys in the log tree, and getting rid of the last_dir_item_offset field in the log context structure. Reported-by: David Arendt <[email protected]> Link: https://lore.kernel.org/linux-btrfs/[email protected]/ Reported-by: Maxim Mikityanskiy <[email protected]> Link: https://lore.kernel.org/linux-btrfs/[email protected]/ Reported-by: Hunter Wardlaw <[email protected]> Link: https://bugzilla.suse.com/show_bug.cgi?id=1207231 Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=216851 CC: [email protected] # 6.1+ Reviewed-by: Josef Bacik <[email protected]> Signed-off-by: Filipe Manana <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent a9ad4d8 commit 6afaed5

File tree

2 files changed

+17
-8
lines changed

2 files changed

+17
-8
lines changed

fs/btrfs/tree-log.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3576,17 +3576,19 @@ static noinline int insert_dir_log_key(struct btrfs_trans_handle *trans,
35763576
}
35773577

35783578
static int flush_dir_items_batch(struct btrfs_trans_handle *trans,
3579-
struct btrfs_root *log,
3579+
struct btrfs_inode *inode,
35803580
struct extent_buffer *src,
35813581
struct btrfs_path *dst_path,
35823582
int start_slot,
35833583
int count)
35843584
{
3585+
struct btrfs_root *log = inode->root->log_root;
35853586
char *ins_data = NULL;
35863587
struct btrfs_item_batch batch;
35873588
struct extent_buffer *dst;
35883589
unsigned long src_offset;
35893590
unsigned long dst_offset;
3591+
u64 last_index;
35903592
struct btrfs_key key;
35913593
u32 item_size;
35923594
int ret;
@@ -3644,6 +3646,19 @@ static int flush_dir_items_batch(struct btrfs_trans_handle *trans,
36443646
src_offset = btrfs_item_ptr_offset(src, start_slot + count - 1);
36453647
copy_extent_buffer(dst, src, dst_offset, src_offset, batch.total_data_size);
36463648
btrfs_release_path(dst_path);
3649+
3650+
last_index = batch.keys[count - 1].offset;
3651+
ASSERT(last_index > inode->last_dir_index_offset);
3652+
3653+
/*
3654+
* If for some unexpected reason the last item's index is not greater
3655+
* than the last index we logged, warn and return an error to fallback
3656+
* to a transaction commit.
3657+
*/
3658+
if (WARN_ON(last_index <= inode->last_dir_index_offset))
3659+
ret = -EUCLEAN;
3660+
else
3661+
inode->last_dir_index_offset = last_index;
36473662
out:
36483663
kfree(ins_data);
36493664

@@ -3693,7 +3708,6 @@ static int process_dir_items_leaf(struct btrfs_trans_handle *trans,
36933708
}
36943709

36953710
di = btrfs_item_ptr(src, i, struct btrfs_dir_item);
3696-
ctx->last_dir_item_offset = key.offset;
36973711

36983712
/*
36993713
* Skip ranges of items that consist only of dir item keys created
@@ -3756,7 +3770,7 @@ static int process_dir_items_leaf(struct btrfs_trans_handle *trans,
37563770
if (batch_size > 0) {
37573771
int ret;
37583772

3759-
ret = flush_dir_items_batch(trans, log, src, dst_path,
3773+
ret = flush_dir_items_batch(trans, inode, src, dst_path,
37603774
batch_start, batch_size);
37613775
if (ret < 0)
37623776
return ret;
@@ -4044,7 +4058,6 @@ static noinline int log_directory_changes(struct btrfs_trans_handle *trans,
40444058

40454059
min_key = BTRFS_DIR_START_INDEX;
40464060
max_key = 0;
4047-
ctx->last_dir_item_offset = inode->last_dir_index_offset;
40484061

40494062
while (1) {
40504063
ret = log_dir_items(trans, inode, path, dst_path,
@@ -4056,8 +4069,6 @@ static noinline int log_directory_changes(struct btrfs_trans_handle *trans,
40564069
min_key = max_key + 1;
40574070
}
40584071

4059-
inode->last_dir_index_offset = ctx->last_dir_item_offset;
4060-
40614072
return 0;
40624073
}
40634074

fs/btrfs/tree-log.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ struct btrfs_log_ctx {
2424
bool logging_new_delayed_dentries;
2525
/* Indicate if the inode being logged was logged before. */
2626
bool logged_before;
27-
/* Tracks the last logged dir item/index key offset. */
28-
u64 last_dir_item_offset;
2927
struct inode *inode;
3028
struct list_head list;
3129
/* Only used for fast fsyncs. */

0 commit comments

Comments
 (0)