Skip to content

Commit c72deb0

Browse files
Hongbo LiKent Overstreet
authored andcommitted
bcachefs: bcachefs_metadata_version_directory_size
This adds another metadata version for accounting directory size. For the new version of the filesystem, when new subdirectory items are created or deleted, the parent directory's size will change accordingly. For the old version of the existed file system, running fsck will automatically upgrade the metadata version, and it will do the check and recalculationg of the directory size. Signed-off-by: Hongbo Li <lihongbo22@huawei.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
1 parent e614a6c commit c72deb0

File tree

4 files changed

+49
-3
lines changed

4 files changed

+49
-3
lines changed

fs/bcachefs/bcachefs_format.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,8 @@ struct bch_sb_field_ext {
685685
x(reflink_p_may_update_opts, BCH_VERSION(1, 16)) \
686686
x(inode_depth, BCH_VERSION(1, 17)) \
687687
x(persistent_inode_cursors, BCH_VERSION(1, 18)) \
688-
x(autofix_errors, BCH_VERSION(1, 19))
688+
x(autofix_errors, BCH_VERSION(1, 19)) \
689+
x(directory_size, BCH_VERSION(1, 20))
689690

690691
enum bcachefs_metadata_version {
691692
bcachefs_metadata_version_min = 9,

fs/bcachefs/fsck.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,37 @@ static int get_snapshot_root_inode(struct btree_trans *trans,
11161116
return ret;
11171117
}
11181118

1119+
static int check_directory_size(struct btree_trans *trans,
1120+
struct bch_inode_unpacked *inode_u,
1121+
struct bkey_s_c inode_k, bool *write_inode)
1122+
{
1123+
struct btree_iter iter;
1124+
struct bkey_s_c k;
1125+
u64 new_size = 0;
1126+
int ret;
1127+
1128+
for_each_btree_key_max_norestart(trans, iter, BTREE_ID_dirents,
1129+
SPOS(inode_k.k->p.offset, 0, inode_k.k->p.snapshot),
1130+
POS(inode_k.k->p.offset, U64_MAX),
1131+
0, k, ret) {
1132+
if (k.k->type != KEY_TYPE_dirent)
1133+
continue;
1134+
1135+
struct bkey_s_c_dirent dirent = bkey_s_c_to_dirent(k);
1136+
struct qstr name = bch2_dirent_get_name(dirent);
1137+
1138+
new_size += dirent_occupied_size(&name);
1139+
}
1140+
bch2_trans_iter_exit(trans, &iter);
1141+
1142+
if (!ret && inode_u->bi_size != new_size) {
1143+
inode_u->bi_size = new_size;
1144+
*write_inode = true;
1145+
}
1146+
1147+
return ret;
1148+
}
1149+
11191150
static int check_inode(struct btree_trans *trans,
11201151
struct btree_iter *iter,
11211152
struct bkey_s_c k,
@@ -1304,6 +1335,16 @@ static int check_inode(struct btree_trans *trans,
13041335
u.bi_journal_seq = journal_cur_seq(&c->journal);
13051336
do_update = true;
13061337
}
1338+
1339+
if (S_ISDIR(u.bi_mode)) {
1340+
ret = check_directory_size(trans, &u, k, &do_update);
1341+
1342+
fsck_err_on(ret,
1343+
trans, directory_size_mismatch,
1344+
"directory inode %llu:%u with the mismatch directory size",
1345+
u.bi_inum, k.k->p.snapshot);
1346+
ret = 0;
1347+
}
13071348
do_update:
13081349
if (do_update) {
13091350
ret = __bch2_fsck_write_inode(trans, &u);

fs/bcachefs/sb-downgrade.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,10 @@
9090
BIT_ULL(BCH_RECOVERY_PASS_check_allocations), \
9191
BCH_FSCK_ERR_accounting_mismatch, \
9292
BCH_FSCK_ERR_accounting_key_replicas_nr_devs_0, \
93-
BCH_FSCK_ERR_accounting_key_junk_at_end)
93+
BCH_FSCK_ERR_accounting_key_junk_at_end) \
94+
x(directory_size, \
95+
BIT_ULL(BCH_RECOVERY_PASS_check_inodes), \
96+
BCH_FSCK_ERR_directory_size_mismatch) \
9497

9598
#define DOWNGRADE_TABLE() \
9699
x(bucket_stripe_sectors, \

fs/bcachefs/sb-errors_format.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,8 @@ enum bch_fsck_flags {
313313
x(logged_op_but_clean, 283, FSCK_AUTOFIX) \
314314
x(compression_opt_not_marked_in_sb, 295, FSCK_AUTOFIX) \
315315
x(compression_type_not_marked_in_sb, 296, FSCK_AUTOFIX) \
316-
x(MAX, 303, 0)
316+
x(directory_size_mismatch, 303, FSCK_AUTOFIX) \
317+
x(MAX, 304, 0)
317318

318319
enum bch_sb_error_id {
319320
#define x(t, n, ...) BCH_FSCK_ERR_##t = n,

0 commit comments

Comments
 (0)