[PATCH 21/23] Add ngnfs_xattr_list() and debugfs command

Zach Brown zab at zabbo.net
Wed Apr 9 17:18:20 PDT 2025


On Fri, Apr 04, 2025 at 08:45:37PM +0200, Valerie Aurora wrote:
> Add ability to list extended attributes and associated debugfs
> command.

> +/*
> + * Copy one xattr name into the buf, followed by a null byte, unless the
> + * buf is zero size, in which case just increment the size counter.
> + */
> +static int fill_listxattr_rd(struct ngnfs_btree_key *key, void *val, size_t val_size, void *args)
> +{
> +	struct listxattr_args *la = args;
> +	struct ngnfs_xattr *xattr = val;
> +	size_t bytes;
> +
> +	bytes = xattr->name_len + 1;
> +	if (la->size == 0) /* just counting the bytes, not copying them */
> +		goto out;
> +
> +	if (bytes > (la->size - la->used))
> +		return -ERANGE;
> +
> +	memcpy(la->buf + la->used, xattr->name, xattr->name_len);
> +	memset(la->buf + la->used + xattr->name_len + 1, 0, 1);

It's null termination, so:

	la->buf[la->used + xattr->name_len] = '\0';

would be idiomatic and make it clear what's going on.  (And fix the
off-by-one).

> +out:
> +	la->used = la->used + xattr->name_len + 1;

	la->used += bytes;

> +/*
> + * Return a list of names of extended attributes, separated by nulls, or
> + * if the size of the buf is zero, the size that would be required to
> + * return the list.
> + */
> +ssize_t ngnfs_xattr_list(struct ngnfs_fs_info *nfi, struct ngnfs_inode_ino_gen *ig, void *buf,
> +			 size_t size)
> +{
> +	struct ngnfs_inode_txn_ref ino;
> +	struct ngnfs_transaction txn;
> +	struct ngnfs_btree_key key;
> +	struct listxattr_args la;
> +	int ret;
> +
> +	la.buf = buf;
> +	la.size = size;
> +	la.used = 0;
> +
> +	ngnfs_txn_init(&txn);
> +	init_xattr_key(&key, 0);
> +
> +	do {
> +		ret = ngnfs_inode_get(nfi, &txn, NBF_READ, ig, &ino)				?:
> +		      ngnfs_btree_read_iter(nfi, &txn, &ino.ninode->xattrs, &key,
> +					    NULL, NULL, fill_listxattr_rd, &la);
> +
> +	} while (ngnfs_txn_retry(nfi, &txn, &ret));
> +
> +	ngnfs_txn_teardown(nfi, &txn);
> +
> +	return ret ?: la.used;

For this one we definitely need to reset la.used at the start of each
retried loop.  I'm becoming more and more convinced of the "always
re-initialize" rule :).

>  int ngnfs_xattr_remove(struct ngnfs_fs_info *nfi, struct ngnfs_inode_ino_gen *ig, char *name);
>  int ngnfs_xattr_set(struct ngnfs_fs_info *nfi, struct ngnfs_inode_ino_gen *ig, char *name,
>  		    void *value, size_t val_size, int flags);
> +ssize_t ngnfs_xattr_list(struct ngnfs_fs_info *nfi, struct ngnfs_inode_ino_gen *ig, void *buf,
> +			 size_t size);

As previously, int is fine given the sizes we're working with.

- z



More information about the ngnfs-devel mailing list