struct mnt_idmap is immutable once alloc_mnt_idmap() has set it up. The
only thing that changes afterwards is the reference count. Model
mnt_idmap_{get,put}() after struct cred's reference count handling and
take a const pointer.This model is forced upon us because ceph stores the idmapping in mds requests and need to be able to take and put references. mnt_idmap_get() keeps returning a non-const pointer for now because struct vfsmount still stores a non-const pointer. We can only change that at the end of the series once every user of mnt_idmap() has been ported. Signed-off-by: Christian Brauner (Amutable) <[email protected]> --- fs/internal.h | 4 ++-- fs/mnt_idmapping.c | 16 ++++++++++------ include/linux/mnt_idmapping.h | 4 ++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/fs/internal.h b/fs/internal.h index c658c8a5ebd5..581aaa2d6510 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -327,8 +327,8 @@ ssize_t __kernel_write_iter(struct file *file, struct iov_iter *from, loff_t *po * fs/attr.c */ struct mnt_idmap *alloc_mnt_idmap(struct user_namespace *mnt_userns); -struct mnt_idmap *mnt_idmap_get(struct mnt_idmap *idmap); -void mnt_idmap_put(struct mnt_idmap *idmap); +struct mnt_idmap *mnt_idmap_get(const struct mnt_idmap *idmap); +void mnt_idmap_put(const struct mnt_idmap *idmap); struct stashed_operations { struct dentry *(*stash_dentry)(struct dentry **stashed, struct dentry *dentry); diff --git a/fs/mnt_idmapping.c b/fs/mnt_idmapping.c index cb61fbdb52e9..cc6c5f1cfba8 100644 --- a/fs/mnt_idmapping.c +++ b/fs/mnt_idmapping.c @@ -312,12 +312,14 @@ struct mnt_idmap *alloc_mnt_idmap(struct user_namespace *mnt_userns) * * Return: @idmap with reference count bumped if @not_mnt_idmap isn't passed. */ -struct mnt_idmap *mnt_idmap_get(struct mnt_idmap *idmap) +struct mnt_idmap *mnt_idmap_get(const struct mnt_idmap *idmap) { + struct mnt_idmap *nonconst_idmap = (struct mnt_idmap *)idmap; + if (idmap != &nop_mnt_idmap && idmap != &invalid_mnt_idmap) - refcount_inc(&idmap->count); + refcount_inc(&nonconst_idmap->count); - return idmap; + return nonconst_idmap; } EXPORT_SYMBOL_GPL(mnt_idmap_get); @@ -328,11 +330,13 @@ EXPORT_SYMBOL_GPL(mnt_idmap_get); * If this is a non-initial idmapping, put the reference count when a mount is * released and free it if we're the last user. */ -void mnt_idmap_put(struct mnt_idmap *idmap) +void mnt_idmap_put(const struct mnt_idmap *idmap) { + struct mnt_idmap *nonconst_idmap = (struct mnt_idmap *)idmap; + if (idmap != &nop_mnt_idmap && idmap != &invalid_mnt_idmap && - refcount_dec_and_test(&idmap->count)) - free_mnt_idmap(idmap); + refcount_dec_and_test(&nonconst_idmap->count)) + free_mnt_idmap(nonconst_idmap); } EXPORT_SYMBOL_GPL(mnt_idmap_put); diff --git a/include/linux/mnt_idmapping.h b/include/linux/mnt_idmapping.h index e71a6070a8f8..e5bee8b41094 100644 --- a/include/linux/mnt_idmapping.h +++ b/include/linux/mnt_idmapping.h @@ -121,8 +121,8 @@ static inline bool vfsgid_eq_kgid(vfsgid_t vfsgid, kgid_t kgid) int vfsgid_in_group_p(vfsgid_t vfsgid); -struct mnt_idmap *mnt_idmap_get(struct mnt_idmap *idmap); -void mnt_idmap_put(struct mnt_idmap *idmap); +struct mnt_idmap *mnt_idmap_get(const struct mnt_idmap *idmap); +void mnt_idmap_put(const struct mnt_idmap *idmap); vfsuid_t make_vfsuid(struct mnt_idmap *idmap, struct user_namespace *fs_userns, kuid_t kuid); -- 2.53.0

