[PATCH v2 17/21] backing-inode: add backing_inode_copyattr()
Joanne Koong <[email protected]> Fri, 15 May 2026 17:40:00 -0700
| Newsgroups | org.kernel.vger.linux-unionfs,dev.linux.lists.fuse-devel |
|---|---|
| Message-ID | <[email protected]> |
Move logic in ovl_copyattr() to a generic backing_inode_copyattr() function in a new fs/backing-inode.c, which other filesystems that use backing inodes (eg fuse passthrough) will use. Signed-off-by: Joanne Koong <[email protected]> --- fs/Makefile | 2 +- fs/backing-inode.c | 43 +++++++++++++++++++++++++++++++++++ fs/overlayfs/util.c | 33 +++------------------------ include/linux/backing-inode.h | 14 ++++++++++++ 4 files changed, 61 insertions(+), 31 deletions(-) create mode 100644 fs/backing-inode.c create mode 100644 include/linux/backing-inode.h diff --git a/fs/Makefile b/fs/Makefile index cf4a745e9679..3f8a227d4938 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -40,7 +40,7 @@ obj-$(CONFIG_COMPAT_BINFMT_ELF) += compat_binfmt_elf.o obj-$(CONFIG_BINFMT_ELF_FDPIC) += binfmt_elf_fdpic.o obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o -obj-$(CONFIG_FS_STACK) += backing-file.o +obj-$(CONFIG_FS_STACK) += backing-file.o backing-inode.o obj-$(CONFIG_FS_MBCACHE) += mbcache.o obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o obj-$(CONFIG_NFS_COMMON) += nfs_common/ diff --git a/fs/backing-inode.c b/fs/backing-inode.c new file mode 100644 index 000000000000..474770a1fa9d --- /dev/null +++ b/fs/backing-inode.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Common helpers for stackable filesystems and backing inodes. + */ + +#include <linux/backing-inode.h> + +/* + * backing_inode_copyattr - copy inode attributes from a backing inode + * + * When a filesystem copies inode information from a backing layer to its own + * inode, it applies the idmapping of the backing mount, ensuring that + * the inode ownership will correctly reflect the ownership of the idmapped + * backing mount. For example, an idmapped backing mount mapping id 1001 to id + * 1000 will take care to map any backing inode owned by id 1001 to id 1000. + * These mapping helpers are nops when the backing mount isn't idmapped. + */ +void backing_inode_copyattr(struct inode *inode, + const struct path *backing_path) +{ + struct inode *realinode; + struct mnt_idmap *real_idmap; + vfsuid_t vfsuid; + vfsgid_t vfsgid; + + realinode = d_inode_rcu(backing_path->dentry); + real_idmap = mnt_idmap(backing_path->mnt); + + spin_lock(&inode->i_lock); + vfsuid = i_uid_into_vfsuid(real_idmap, realinode); + vfsgid = i_gid_into_vfsgid(real_idmap, realinode); + + inode->i_uid = vfsuid_into_kuid(vfsuid); + inode->i_gid = vfsgid_into_kgid(vfsgid); + inode->i_mode = realinode->i_mode; + inode_set_atime_to_ts(inode, inode_get_atime(realinode)); + inode_set_mtime_to_ts(inode, inode_get_mtime(realinode)); + inode_set_ctime_to_ts(inode, inode_get_ctime(realinode)); + i_size_write(inode, i_size_read(realinode)); + spin_unlock(&inode->i_lock); +} +EXPORT_SYMBOL_GPL(backing_inode_copyattr); + diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 3f1b763a8bb4..3e7d66c26c10 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -16,6 +16,7 @@ #include <linux/namei.h> #include <linux/ratelimit.h> #include <linux/overflow.h> +#include <linux/backing-inode.h> #include "overlayfs.h" /* Get write access to upper mnt - may fail if upper sb was remounted ro */ @@ -1503,38 +1504,10 @@ int ovl_sync_status(struct ovl_fs *ofs) return errseq_check(&mnt->mnt_sb->s_wb_err, ofs->errseq); } -/* - * ovl_copyattr() - copy inode attributes from layer to ovl inode - * - * When overlay copies inode information from an upper or lower layer to the - * relevant overlay inode it will apply the idmapping of the upper or lower - * layer when doing so ensuring that the ovl inode ownership will correctly - * reflect the ownership of the idmapped upper or lower layer. For example, an - * idmapped upper or lower layer mapping id 1001 to id 1000 will take care to - * map any lower or upper inode owned by id 1001 to id 1000. These mapping - * helpers are nops when the relevant layer isn't idmapped. - */ void ovl_copyattr(struct inode *inode) { struct path realpath; - struct inode *realinode; - struct mnt_idmap *real_idmap; - vfsuid_t vfsuid; - vfsgid_t vfsgid; - realinode = ovl_i_path_real(inode, &realpath); - real_idmap = mnt_idmap(realpath.mnt); - - spin_lock(&inode->i_lock); - vfsuid = i_uid_into_vfsuid(real_idmap, realinode); - vfsgid = i_gid_into_vfsgid(real_idmap, realinode); - - inode->i_uid = vfsuid_into_kuid(vfsuid); - inode->i_gid = vfsgid_into_kgid(vfsgid); - inode->i_mode = realinode->i_mode; - inode_set_atime_to_ts(inode, inode_get_atime(realinode)); - inode_set_mtime_to_ts(inode, inode_get_mtime(realinode)); - inode_set_ctime_to_ts(inode, inode_get_ctime(realinode)); - i_size_write(inode, i_size_read(realinode)); - spin_unlock(&inode->i_lock); + ovl_i_path_real(inode, &realpath); + backing_inode_copyattr(inode, &realpath); } diff --git a/include/linux/backing-inode.h b/include/linux/backing-inode.h new file mode 100644 index 000000000000..6b43cba9fabd --- /dev/null +++ b/include/linux/backing-inode.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Common helpers for stackable filesystems and backing inodes. + */ + +#ifndef _LINUX_BACKING_INODE_H +#define _LINUX_BACKING_INODE_H + +#include <linux/fs.h> + +void backing_inode_copyattr(struct inode *inode, + const struct path *backing_path); + +#endif /* _LINUX_BACKING_INODE_H */ -- 2.52.0