summaryrefslogtreecommitdiff
path: root/fs/bcachefs/dirent.c
diff options
context:
space:
mode:
authorJoshua Ashton <joshua@froggi.es>2023-08-12 22:26:29 +0100
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:10:10 -0400
commit01a7e74fe14179cba90bf3f52ad3188a1d6819d2 (patch)
tree494b7ca69d8ba0ebf9ebff827d9b8b53319ca481 /fs/bcachefs/dirent.c
parentf854ce4d0a3f7281b5b99b28dd028abe21c1b0c8 (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.c52
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;