linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Jan Kara <jack@suse.cz>
To: Christian Brauner <brauner@kernel.org>
Cc: linux-fsdevel@vger.kernel.org, Jeff Layton <jlayton@kernel.org>,
	 Josef Bacik <josef@toxicpanda.com>,
	Alexander Viro <viro@zeniv.linux.org.uk>,
	 Jan Kara <jack@suse.cz>,
	linux-kernel@vger.kernel.org, Hugh Dickins <hughd@google.com>,
	 linux-mm@kvack.org,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	 Tejun Heo <tj@kernel.org>, Eric Dumazet <edumazet@google.com>,
	 Jakub Kicinski <kuba@kernel.org>, Jann Horn <jannh@google.com>,
	netdev@vger.kernel.org
Subject: Re: [PATCH 04/14] kernfs: adapt to rhashtable-based simple_xattrs with lazy allocation
Date: Fri, 27 Feb 2026 16:00:37 +0100	[thread overview]
Message-ID: <3cnmtqmakpbb2uwhenrj7kdqu3uefykiykjllgfbtpkiwhaa4s@sghkevv7jned> (raw)
In-Reply-To: <20260216-work-xattr-socket-v1-4-c2efa4f74cb7@kernel.org>

On Mon 16-02-26 14:32:00, Christian Brauner wrote:
> Adapt kernfs to use the rhashtable-based xattr path and switch from an
> embedded struct to pointer-based lazy allocation.
> 
> Change kernfs_iattrs.xattrs from embedded 'struct simple_xattrs' to a
> pointer 'struct simple_xattrs *', initialized to NULL (zeroed by
> kmem_cache_zalloc). Since kernfs_iattrs is already lazily allocated
> itself, this adds a second level of lazy allocation specifically for
> the xattr store.
> 
> The xattr store is allocated on first setxattr. Read paths
> check for NULL and return -ENODATA or empty list.
> 
> Replaced xattr entries are freed via simple_xattr_free_rcu() to allow
> concurrent RCU readers to finish.
> 
> The cleanup paths in kernfs_free_rcu() and __kernfs_new_node() error
> handling conditionally free the xattr store only when allocated.
> 
> Signed-off-by: Christian Brauner <brauner@kernel.org>

...

> @@ -584,6 +582,12 @@ void kernfs_put(struct kernfs_node *kn)
>  	if (kernfs_type(kn) == KERNFS_LINK)
>  		kernfs_put(kn->symlink.target_kn);
>  
> +	if (kn->iattr && kn->iattr->xattrs) {
> +		simple_xattrs_free(kn->iattr->xattrs, NULL);
> +		kfree(kn->iattr->xattrs);
> +		kn->iattr->xattrs = NULL;
> +	}
> +
>  	spin_lock(&root->kernfs_idr_lock);
>  	idr_remove(&root->ino_idr, (u32)kernfs_ino(kn));
>  	spin_unlock(&root->kernfs_idr_lock);

This is a slight change in the lifetime rules because previously kernfs
xattrs could be safely accessed only under RCU but after this change you
have to hold inode reference *and* RCU to safely access them. I don't think
anybody would be accessing xattrs without holding inode reference so this
should be safe but it would be good to mention this in the changelog.
Otherwise feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> @@ -682,7 +686,10 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
>  
>   err_out4:
>  	if (kn->iattr) {
> -		simple_xattrs_free(&kn->iattr->xattrs, NULL);
> +		if (kn->iattr->xattrs) {
> +			simple_xattrs_free(kn->iattr->xattrs, NULL);
> +			kfree(kn->iattr->xattrs);
> +		}
>  		kmem_cache_free(kernfs_iattrs_cache, kn->iattr);
>  	}
>   err_out3:
> diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
> index a36aaee98dce..dfc3315b5afc 100644
> --- a/fs/kernfs/inode.c
> +++ b/fs/kernfs/inode.c
> @@ -45,7 +45,6 @@ static struct kernfs_iattrs *__kernfs_iattrs(struct kernfs_node *kn, bool alloc)
>  	ret->ia_mtime = ret->ia_atime;
>  	ret->ia_ctime = ret->ia_atime;
>  
> -	simple_xattrs_init(&ret->xattrs);
>  	atomic_set(&ret->nr_user_xattrs, 0);
>  	atomic_set(&ret->user_xattr_size, 0);
>  
> @@ -146,7 +145,8 @@ ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size)
>  	if (!attrs)
>  		return -ENOMEM;
>  
> -	return simple_xattr_list(d_inode(dentry), &attrs->xattrs, buf, size);
> +	return simple_xattr_list(d_inode(dentry), READ_ONCE(attrs->xattrs),
> +				 buf, size);
>  }
>  
>  static inline void set_default_inode_attr(struct inode *inode, umode_t mode)
> @@ -298,27 +298,38 @@ int kernfs_xattr_get(struct kernfs_node *kn, const char *name,
>  		     void *value, size_t size)
>  {
>  	struct kernfs_iattrs *attrs = kernfs_iattrs_noalloc(kn);
> +	struct simple_xattrs *xattrs;
> +
>  	if (!attrs)
>  		return -ENODATA;
>  
> -	return simple_xattr_get(&attrs->xattrs, name, value, size);
> +	xattrs = READ_ONCE(attrs->xattrs);
> +	if (!xattrs)
> +		return -ENODATA;
> +
> +	return simple_xattr_get(xattrs, name, value, size);
>  }
>  
>  int kernfs_xattr_set(struct kernfs_node *kn, const char *name,
>  		     const void *value, size_t size, int flags)
>  {
>  	struct simple_xattr *old_xattr;
> +	struct simple_xattrs *xattrs;
>  	struct kernfs_iattrs *attrs;
>  
>  	attrs = kernfs_iattrs(kn);
>  	if (!attrs)
>  		return -ENOMEM;
>  
> -	old_xattr = simple_xattr_set(&attrs->xattrs, name, value, size, flags);
> +	xattrs = simple_xattrs_lazy_alloc(&attrs->xattrs, value, flags);
> +	if (IS_ERR_OR_NULL(xattrs))
> +		return PTR_ERR(xattrs);
> +
> +	old_xattr = simple_xattr_set(xattrs, name, value, size, flags);
>  	if (IS_ERR(old_xattr))
>  		return PTR_ERR(old_xattr);
>  
> -	simple_xattr_free(old_xattr);
> +	simple_xattr_free_rcu(old_xattr);
>  	return 0;
>  }
>  
> @@ -376,7 +387,7 @@ static int kernfs_vfs_user_xattr_add(struct kernfs_node *kn,
>  
>  	ret = 0;
>  	size = old_xattr->size;
> -	simple_xattr_free(old_xattr);
> +	simple_xattr_free_rcu(old_xattr);
>  dec_size_out:
>  	atomic_sub(size, sz);
>  dec_count_out:
> @@ -403,7 +414,7 @@ static int kernfs_vfs_user_xattr_rm(struct kernfs_node *kn,
>  
>  	atomic_sub(old_xattr->size, sz);
>  	atomic_dec(nr);
> -	simple_xattr_free(old_xattr);
> +	simple_xattr_free_rcu(old_xattr);
>  	return 0;
>  }
>  
> @@ -415,6 +426,7 @@ static int kernfs_vfs_user_xattr_set(const struct xattr_handler *handler,
>  {
>  	const char *full_name = xattr_full_name(handler, suffix);
>  	struct kernfs_node *kn = inode->i_private;
> +	struct simple_xattrs *xattrs;
>  	struct kernfs_iattrs *attrs;
>  
>  	if (!(kernfs_root(kn)->flags & KERNFS_ROOT_SUPPORT_USER_XATTR))
> @@ -424,11 +436,15 @@ static int kernfs_vfs_user_xattr_set(const struct xattr_handler *handler,
>  	if (!attrs)
>  		return -ENOMEM;
>  
> +	xattrs = simple_xattrs_lazy_alloc(&attrs->xattrs, value, flags);
> +	if (IS_ERR_OR_NULL(xattrs))
> +		return PTR_ERR(xattrs);
> +
>  	if (value)
> -		return kernfs_vfs_user_xattr_add(kn, full_name, &attrs->xattrs,
> +		return kernfs_vfs_user_xattr_add(kn, full_name, xattrs,
>  						 value, size, flags);
>  	else
> -		return kernfs_vfs_user_xattr_rm(kn, full_name, &attrs->xattrs,
> +		return kernfs_vfs_user_xattr_rm(kn, full_name, xattrs,
>  						value, size, flags);
>  
>  }
> diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h
> index 6061b6f70d2a..1324ed8c0661 100644
> --- a/fs/kernfs/kernfs-internal.h
> +++ b/fs/kernfs/kernfs-internal.h
> @@ -26,7 +26,7 @@ struct kernfs_iattrs {
>  	struct timespec64	ia_mtime;
>  	struct timespec64	ia_ctime;
>  
> -	struct simple_xattrs	xattrs;
> +	struct simple_xattrs	*xattrs;
>  	atomic_t		nr_user_xattrs;
>  	atomic_t		user_xattr_size;
>  };
> 
> -- 
> 2.47.3
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR


  reply	other threads:[~2026-02-27 15:00 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-16 13:31 [PATCH 00/14] xattr: rework simple xattrs and support user.* xattrs on sockets Christian Brauner
2026-02-16 13:31 ` [PATCH 01/14] xattr: add rcu_head and rhash_head to struct simple_xattr Christian Brauner
2026-02-27 14:43   ` Jan Kara
2026-02-16 13:31 ` [PATCH 02/14] xattr: add rhashtable-based simple_xattr infrastructure Christian Brauner
2026-02-27 14:43   ` Jan Kara
2026-02-16 13:31 ` [PATCH 03/14] shmem: adapt to rhashtable-based simple_xattrs with lazy allocation Christian Brauner
2026-02-27 14:48   ` Jan Kara
2026-02-16 13:32 ` [PATCH 04/14] kernfs: " Christian Brauner
2026-02-27 15:00   ` Jan Kara [this message]
2026-02-16 13:32 ` [PATCH 05/14] pidfs: adapt to rhashtable-based simple_xattrs Christian Brauner
2026-02-27 15:09   ` Jan Kara
2026-02-27 15:16     ` Jan Kara
2026-02-16 13:32 ` [PATCH 06/14] xattr: remove rbtree-based simple_xattr infrastructure Christian Brauner
2026-02-27 15:14   ` Jan Kara
2026-02-16 13:32 ` [PATCH 07/14] xattr: add xattr_permission_error() Christian Brauner
2026-02-27 15:15   ` Jan Kara
2026-02-16 13:32 ` [PATCH 08/14] xattr: switch xattr_permission() to switch statement Christian Brauner
2026-02-27 15:17   ` Jan Kara
2026-02-16 13:32 ` [PATCH 09/14] xattr: move user limits for xattrs to generic infra Christian Brauner
2026-02-21  0:03   ` Darrick J. Wong
2026-02-23 12:13     ` Christian Brauner
2026-02-27 15:20   ` Jan Kara
2026-02-16 13:32 ` [PATCH 10/14] xattr,net: support limited amount of extended attributes on sockfs sockets Christian Brauner
2026-02-27 15:25   ` Jan Kara
2026-02-16 13:32 ` [PATCH 11/14] xattr: support extended attributes on sockets Christian Brauner
2026-02-27 15:26   ` Jan Kara
2026-02-16 13:32 ` [PATCH 12/14] selftests/xattr: path-based AF_UNIX socket xattr tests Christian Brauner
2026-02-27 15:29   ` Jan Kara
2026-02-16 13:32 ` [PATCH 13/14] selftests/xattr: sockfs " Christian Brauner
2026-02-27 15:30   ` Jan Kara
2026-02-16 13:32 ` [PATCH 14/14] selftests/xattr: test xattrs on various socket families Christian Brauner
2026-02-27 15:32   ` Jan Kara
2026-02-20  0:44 ` [PATCH 00/14] xattr: rework simple xattrs and support user.* xattrs on sockets Darrick J. Wong
2026-02-20  9:23   ` Christian Brauner
2026-02-21  0:14     ` Darrick J. Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3cnmtqmakpbb2uwhenrj7kdqu3uefykiykjllgfbtpkiwhaa4s@sghkevv7jned \
    --to=jack@suse.cz \
    --cc=brauner@kernel.org \
    --cc=edumazet@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=hughd@google.com \
    --cc=jannh@google.com \
    --cc=jlayton@kernel.org \
    --cc=josef@toxicpanda.com \
    --cc=kuba@kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=netdev@vger.kernel.org \
    --cc=tj@kernel.org \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox