[PATCH 08/14] Add ngnfs_dir_get_dirent() and debugfs lookup command

Zach Brown zab at zabbo.net
Fri Feb 28 15:17:37 PST 2025


On Thu, Feb 27, 2025 at 03:16:17PM +0100, Valerie Aurora wrote:
> Add function to return ngnfs directory entries and associated debugfs
> command for debugging purposes.

> -#include "shared/format-block.h"
>  #include "shared/dir.h"
> +#include "shared/format-block.h"

(sometimes I do go around the house humming "A B C F E D G" :) )

> +static int fill_lookup_rd(struct ngnfs_btree_key *key, void *val, size_t val_size, void *arg)
> +{
> +	struct dirent_args *da = arg;
> +	struct ngnfs_dirent *dst = &da->dent;
> +	struct ngnfs_dirent *src = val;
> +
> +	if (!src)
> +		return -ENOENT;
> +
> +	if (!names_equal(src->name, src->name_len, dst->name, dst->name_len))
> +		return NGNFS_BTREE_ITER_CONTINUE;
> +
> +	da->dent_size = offsetof(struct ngnfs_dirent, name) + src->name_len;
> +	memcpy(dst, src, da->dent_size);

I don't think lookup/get_dirent should include the name with the dirent
it returns.  We only return the dirent if the name matches so they
already have it.  And this would get rid of the layers of duplicate
allocation and copies of the name.  We just have to make the API clear
that you're only getting the dirent struct without the name.

> +static int lookup_dots(struct ngnfs_fs_info *nfi, struct ngnfs_transaction *txn,
> +		       struct ngnfs_inode_txn_ref *dir, struct dirent_args *da)
> +{
> +	struct ngnfs_inode_txn_ref parent_dir;
> +	int ret;
> +
> +	if (da->hash >= NGNFS_DIRENT_MIN_HASH)
> +		return -ENOENT;
> +
> +	if (da->hash == NGNFS_DIRENT_DOT_HASH) {
> +		fill_dent(dir->ninode->ino, dir->ninode->version,
> +			  mode_to_type(le32_to_cpu(dir->ninode->mode)), ".", 1, &da->dent);
> +		return 0;
> +	}
> +
> +	/* remaining case is .. */
> +	ret = ngnfs_inode_get(nfi, txn, NBF_READ, le64_to_cpu(dir->ninode->parent_ino),
> +			      &parent_dir);
> +	if (ret < 0)
> +		return ret;
> +
> +	fill_dent(parent_dir.ninode->ino, parent_dir.ninode->version,
> +		  mode_to_type(le32_to_cpu(parent_dir.ninode->mode)), "..", 2, &da->dent);

Like readdir, I think we can get the parent gen along side the parent
ino and can fake the dir mode. 

> +static int do_lookup(struct ngnfs_fs_info *nfi, u64 dir_ino, char *name, size_t name_len,
> +		     struct dirent_args *da)
> +{
> +	struct {
> +		struct ngnfs_transaction txn;
> +		struct ngnfs_inode_txn_ref dir;
> +		struct ngnfs_btree_key key;
> +		struct ngnfs_btree_key last;
> +	} *op;
> +	int ret;
> +
> +	if (name_len > NGNFS_NAME_MAX) {
> +		ret = -ENAMETOOLONG;
> +		goto out;
> +	}
> +
> +	op = kmalloc(sizeof(*op), GFP_NOFS);
> +	if (!op) {
> +		ret = -ENOMEM;
> +		goto out;
> +	}
> +
> +	ngnfs_txn_init(&op->txn);
> +	init_dirent_args(da, name, name_len, 0, 0);

> +	init_dirent_key(&op->key, da->hash);
> +	init_dirent_key(&op->last, da->hash | NGNFS_DIRENT_COLL_BIT);

Are these two keys used?  I think they were replaced by the on-stack
keys in lookup_iter() (which should maybe be called something like
lookup_hash?).

- z



More information about the ngnfs-devel mailing list