summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-04-06 20:11:28 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:59 -0400
commitb6d4f474e4e785a9090992b0f301e57870f73711 (patch)
tree7acee8ba16a5096ba618fe212d1bae61554cf6fc /fs
parent2177147b39098e6f08b3d8d45bbcf7dedd7ebdad (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.c18
-rw-r--r--fs/bcachefs/fsck.c31
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;