diff options
author | Joshua Ashton <joshua@froggi.es> | 2023-08-12 22:26:29 +0100 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:10:10 -0400 |
commit | 01a7e74fe14179cba90bf3f52ad3188a1d6819d2 (patch) | |
tree | 494b7ca69d8ba0ebf9ebff827d9b8b53319ca481 /fs/bcachefs/dirent.c | |
parent | f854ce4d0a3f7281b5b99b28dd028abe21c1b0c8 (diff) |
bcachefs: Introduce bch2_dirent_get_name
A nice cleanup that avoids a bunch of open-coding name/string usage
around dirent usage.
Will be used by casefolding impl in future commits.
Signed-off-by: Joshua Ashton <joshua@froggi.es>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/dirent.c')
-rw-r--r-- | fs/bcachefs/dirent.c | 52 |
1 files changed, 30 insertions, 22 deletions
diff --git a/fs/bcachefs/dirent.c b/fs/bcachefs/dirent.c index 065ea59ee9fa..a87c4e5f089d 100644 --- a/fs/bcachefs/dirent.c +++ b/fs/bcachefs/dirent.c @@ -13,7 +13,7 @@ #include <linux/dcache.h> -unsigned bch2_dirent_name_bytes(struct bkey_s_c_dirent d) +static unsigned bch2_dirent_name_bytes(struct bkey_s_c_dirent d) { unsigned len = bkey_val_bytes(d.k) - offsetof(struct bch_dirent, d_name); @@ -21,6 +21,11 @@ unsigned bch2_dirent_name_bytes(struct bkey_s_c_dirent d) return strnlen(d.v->d_name, len); } +struct qstr bch2_dirent_get_name(struct bkey_s_c_dirent d) +{ + return (struct qstr) QSTR_INIT(d.v->d_name, bch2_dirent_name_bytes(d)); +} + static u64 bch2_dirent_hash(const struct bch_hash_info *info, const struct qstr *name) { @@ -41,7 +46,7 @@ static u64 dirent_hash_key(const struct bch_hash_info *info, const void *key) static u64 dirent_hash_bkey(const struct bch_hash_info *info, struct bkey_s_c k) { struct bkey_s_c_dirent d = bkey_s_c_to_dirent(k); - struct qstr name = QSTR_INIT(d.v->d_name, bch2_dirent_name_bytes(d)); + struct qstr name = bch2_dirent_get_name(d); return bch2_dirent_hash(info, &name); } @@ -49,20 +54,20 @@ static u64 dirent_hash_bkey(const struct bch_hash_info *info, struct bkey_s_c k) static bool dirent_cmp_key(struct bkey_s_c _l, const void *_r) { struct bkey_s_c_dirent l = bkey_s_c_to_dirent(_l); - int len = bch2_dirent_name_bytes(l); - const struct qstr *r = _r; + const struct qstr l_name = bch2_dirent_get_name(l); + const struct qstr *r_name = _r; - return len - r->len ?: memcmp(l.v->d_name, r->name, len); + return l_name.len - r_name->len ?: memcmp(l_name.name, r_name->name, l_name.len); } static bool dirent_cmp_bkey(struct bkey_s_c _l, struct bkey_s_c _r) { struct bkey_s_c_dirent l = bkey_s_c_to_dirent(_l); struct bkey_s_c_dirent r = bkey_s_c_to_dirent(_r); - int l_len = bch2_dirent_name_bytes(l); - int r_len = bch2_dirent_name_bytes(r); + const struct qstr l_name = bch2_dirent_get_name(l); + const struct qstr r_name = bch2_dirent_get_name(r); - return l_len - r_len ?: memcmp(l.v->d_name, r.v->d_name, l_len); + return l_name.len - r_name.len ?: memcmp(l_name.name, r_name.name, l_name.len); } static bool dirent_is_visible(subvol_inum inum, struct bkey_s_c k) @@ -89,37 +94,36 @@ int bch2_dirent_invalid(const struct bch_fs *c, struct bkey_s_c k, struct printbuf *err) { struct bkey_s_c_dirent d = bkey_s_c_to_dirent(k); - unsigned len; + struct qstr d_name = bch2_dirent_get_name(d); - len = bch2_dirent_name_bytes(d); - if (!len) { + if (!d_name.len) { prt_printf(err, "empty name"); return -BCH_ERR_invalid_bkey; } - if (bkey_val_u64s(k.k) > dirent_val_u64s(len)) { + if (bkey_val_u64s(k.k) > dirent_val_u64s(d_name.len)) { prt_printf(err, "value too big (%zu > %u)", - bkey_val_u64s(k.k), dirent_val_u64s(len)); + bkey_val_u64s(k.k), dirent_val_u64s(d_name.len)); return -BCH_ERR_invalid_bkey; } - if (len > BCH_NAME_MAX) { + if (d_name.len > BCH_NAME_MAX) { prt_printf(err, "dirent name too big (%u > %u)", - len, BCH_NAME_MAX); + d_name.len, BCH_NAME_MAX); return -BCH_ERR_invalid_bkey; } - if (len == 1 && !memcmp(d.v->d_name, ".", 1)) { + if (d_name.len == 1 && !memcmp(d_name.name, ".", 1)) { prt_printf(err, "invalid name"); return -BCH_ERR_invalid_bkey; } - if (len == 2 && !memcmp(d.v->d_name, "..", 2)) { + if (d_name.len == 2 && !memcmp(d_name.name, "..", 2)) { prt_printf(err, "invalid name"); return -BCH_ERR_invalid_bkey; } - if (memchr(d.v->d_name, '/', len)) { + if (memchr(d_name.name, '/', d_name.len)) { prt_printf(err, "invalid name"); return -BCH_ERR_invalid_bkey; } @@ -137,10 +141,11 @@ void bch2_dirent_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c k) { struct bkey_s_c_dirent d = bkey_s_c_to_dirent(k); + struct qstr d_name = bch2_dirent_get_name(d); prt_printf(out, "%.*s -> %llu type %s", - bch2_dirent_name_bytes(d), - d.v->d_name, + d_name.len, + d_name.name, d.v->d_type != DT_SUBVOL ? le64_to_cpu(d.v->d_inum) : le32_to_cpu(d.v->d_child_subvol), @@ -507,6 +512,7 @@ int bch2_readdir(struct bch_fs *c, subvol_inum inum, struct dir_context *ctx) subvol_inum target; u32 snapshot; struct bkey_buf sk; + struct qstr name; int ret; bch2_bkey_buf_init(&sk); @@ -537,9 +543,11 @@ retry: dirent = bkey_i_to_s_c_dirent(sk.k); bch2_trans_unlock(&trans); + name = bch2_dirent_get_name(dirent); + ctx->pos = dirent.k->p.offset; - if (!dir_emit(ctx, dirent.v->d_name, - bch2_dirent_name_bytes(dirent), + if (!dir_emit(ctx, name.name, + name.len, target.inum, vfs_d_type(dirent.v->d_type))) break; |