diff options
| author | Christian Brauner <brauner@kernel.org> | 2026-02-16 14:31:59 +0100 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2026-02-23 13:06:38 +0100 |
| commit | 52b364fed6e1578e551fee20c76fecb3fc0e10ed (patch) | |
| tree | a32cf3a68a18d63802d21bcd7b402c3227b04830 /include | |
| parent | b32c4a213698ab351b44da2fd1b2a5976c7fa033 (diff) | |
| download | linux-52b364fed6e1578e551fee20c76fecb3fc0e10ed.tar.gz linux-52b364fed6e1578e551fee20c76fecb3fc0e10ed.zip | |
shmem: adapt to rhashtable-based simple_xattrs with lazy allocation
Adapt tmpfs/shmem to use the rhashtable-based xattr path and switch
from an embedded struct to pointer-based lazy allocation.
Change shmem_inode_info.xattrs from embedded 'struct simple_xattrs' to
a pointer 'struct simple_xattrs *', initialized to NULL. This avoids
the rhashtable overhead for every tmpfs inode, which helps when a lot of
inodes exist.
The xattr store is allocated on first use:
- shmem_initxattrs(): Allocates via simple_xattrs_alloc() when
security modules set initial xattrs during inode creation.
- shmem_xattr_handler_set(): Allocates on first setxattr, with a
short-circuit for removal when no xattrs are stored yet.
All read paths (shmem_xattr_handler_get, shmem_listxattr) check for
NULL xattrs pointer and return -ENODATA or 0 respectively.
Replaced xattr entries are freed via simple_xattr_free_rcu() to allow
concurrent RCU readers to finish.
shmem_evict_inode() conditionally frees the xattr store only when
allocated.
Also change simple_xattr_add() from void to int to propagate
rhashtable insertion failures. shmem_initxattrs() is the only caller.
Link: https://patch.msgid.link/20260216-work-xattr-socket-v1-3-c2efa4f74cb7@kernel.org
Acked-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/shmem_fs.h | 2 | ||||
| -rw-r--r-- | include/linux/xattr.h | 4 |
2 files changed, 3 insertions, 3 deletions
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index a8273b32e041..f6a2d3402d76 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -48,7 +48,7 @@ struct shmem_inode_info { }; struct timespec64 i_crtime; /* file creation time */ struct shared_policy policy; /* NUMA memory alloc policy */ - struct simple_xattrs xattrs; /* list of xattrs */ + struct simple_xattrs *xattrs; /* list of xattrs */ pgoff_t fallocend; /* highest fallocate endindex */ unsigned int fsflags; /* for FS_IOC_[SG]ETFLAGS */ atomic_t stop_eviction; /* hold when working on inode */ diff --git a/include/linux/xattr.h b/include/linux/xattr.h index 832a44358661..6e619e185e90 100644 --- a/include/linux/xattr.h +++ b/include/linux/xattr.h @@ -142,8 +142,8 @@ struct simple_xattr *simple_xattr_set(struct simple_xattrs *xattrs, size_t size, int flags); ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs, char *buffer, size_t size); -void simple_xattr_add(struct simple_xattrs *xattrs, - struct simple_xattr *new_xattr); +int simple_xattr_add(struct simple_xattrs *xattrs, + struct simple_xattr *new_xattr); int xattr_list_one(char **buffer, ssize_t *remaining_size, const char *name); DEFINE_CLASS(simple_xattr, |
