bcachefs: Repair code for directory i_size
authorKent Overstreet <kent.overstreet@linux.dev>
Sat, 31 May 2025 15:58:11 +0000 (11:58 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Mon, 2 Jun 2025 16:16:35 +0000 (12:16 -0400)
We had a bug due due to an incomplete revert of the patch implementing
directory i_size (summing up the size of the dirents), leading to
completely screwy i_size values that underflow.

Most userspace programs don't seem to care (e.g. du ignores it), but it
turns out this broke sshfs, so needs to be repaired.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/fsck.c
fs/bcachefs/sb-errors_format.h

index 61d6d99875ea771dd44d1c720acaffa9e8844aed..66b7a87a375bec4c95e667a197f5ef2a6ee86364 100644 (file)
@@ -1167,6 +1167,14 @@ static int check_inode(struct btree_trans *trans,
                ret = 0;
        }
 
+       if (fsck_err_on(S_ISDIR(u.bi_mode) && u.bi_size,
+                       trans, inode_dir_has_nonzero_i_size,
+                       "directory %llu:%u with nonzero i_size %lli",
+                       u.bi_inum, u.bi_snapshot, u.bi_size)) {
+               u.bi_size = 0;
+               do_update = true;
+       }
+
        ret = bch2_inode_has_child_snapshots(trans, k.k->p);
        if (ret < 0)
                goto err;
index 0bfb151da9cfd4b58c013ca3abc34367bc4e9139..8999dab1ff9bb4ce3dab9dbacb10597acd5e8f53 100644 (file)
@@ -232,6 +232,7 @@ enum bch_fsck_flags {
        x(inode_dir_multiple_links,                             206,    FSCK_AUTOFIX)   \
        x(inode_dir_missing_backpointer,                        284,    FSCK_AUTOFIX)   \
        x(inode_dir_unlinked_but_not_empty,                     286,    FSCK_AUTOFIX)   \
+       x(inode_dir_has_nonzero_i_size,                         319,    FSCK_AUTOFIX)   \
        x(inode_multiple_links_but_nlink_0,                     207,    FSCK_AUTOFIX)   \
        x(inode_wrong_backpointer,                              208,    FSCK_AUTOFIX)   \
        x(inode_wrong_nlink,                                    209,    FSCK_AUTOFIX)   \
@@ -328,7 +329,7 @@ enum bch_fsck_flags {
        x(dirent_stray_data_after_cf_name,                      305,    0)              \
        x(rebalance_work_incorrectly_set,                       309,    FSCK_AUTOFIX)   \
        x(rebalance_work_incorrectly_unset,                     310,    FSCK_AUTOFIX)   \
-       x(MAX,                                                  319,    0)
+       x(MAX,                                                  320,    0)
 
 enum bch_sb_error_id {
 #define x(t, n, ...) BCH_FSCK_ERR_##t = n,