diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2021-04-06 20:11:28 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:08:59 -0400 |
commit | b6d4f474e4e785a9090992b0f301e57870f73711 (patch) | |
tree | 7acee8ba16a5096ba618fe212d1bae61554cf6fc /fs | |
parent | 2177147b39098e6f08b3d8d45bbcf7dedd7ebdad (diff) |
bcachefs: Move some dirent checks to bch2_dirent_invalid()
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/bcachefs/dirent.c | 18 | ||||
-rw-r--r-- | fs/bcachefs/fsck.c | 31 |
2 files changed, 13 insertions, 36 deletions
diff --git a/fs/bcachefs/dirent.c b/fs/bcachefs/dirent.c index cf4ce2e7f29c..ec4666143f23 100644 --- a/fs/bcachefs/dirent.c +++ b/fs/bcachefs/dirent.c @@ -84,16 +84,24 @@ const char *bch2_dirent_invalid(const struct bch_fs *c, struct bkey_s_c k) if (!len) return "empty name"; - /* - * older versions of bcachefs were buggy and creating dirent - * keys that were bigger than necessary: - */ - if (bkey_val_u64s(k.k) > dirent_val_u64s(len + 7)) + if (bkey_val_u64s(k.k) > dirent_val_u64s(len)) return "value too big"; if (len > BCH_NAME_MAX) return "dirent name too big"; + if (len == 1 && !memcmp(d.v->d_name, ".", 1)) + return "invalid name"; + + if (len == 2 && !memcmp(d.v->d_name, "..", 2)) + return "invalid name"; + + if (memchr(d.v->d_name, '/', len)) + return "invalid name"; + + if (le64_to_cpu(d.v->d_inum) == d.k->p.inode) + return "dirent points to own directory"; + return NULL; } diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index d65b3e100f78..36baff8409cd 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -569,7 +569,6 @@ static int check_dirents(struct bch_fs *c) struct btree_trans trans; struct btree_iter *iter; struct bkey_s_c k; - unsigned name_len; char buf[200]; int ret = 0; @@ -628,36 +627,6 @@ retry: d = bkey_s_c_to_dirent(k); d_inum = le64_to_cpu(d.v->d_inum); - name_len = bch2_dirent_name_bytes(d); - - if (fsck_err_on(!name_len, c, "empty dirent") || - fsck_err_on(name_len == 1 && - !memcmp(d.v->d_name, ".", 1), c, - ". dirent") || - fsck_err_on(name_len == 2 && - !memcmp(d.v->d_name, "..", 2), c, - ".. dirent") || - fsck_err_on(name_len == 2 && - !memcmp(d.v->d_name, "..", 2), c, - ".. dirent") || - fsck_err_on(memchr(d.v->d_name, '/', name_len), c, - "dirent name has invalid chars")) { - ret = remove_dirent(&trans, d); - if (ret) - goto err; - continue; - } - - if (fsck_err_on(d_inum == d.k->p.inode, c, - "dirent points to own directory:\n%s", - (bch2_bkey_val_to_text(&PBUF(buf), c, - k), buf))) { - ret = remove_dirent(&trans, d); - if (ret) - goto err; - continue; - } - ret = __bch2_inode_find_by_inum_trans(&trans, d_inum, &target, 0); if (ret && ret != -ENOENT) break; |