ceph: allow idmapped setattr inode op
authorChristian Brauner <brauner@kernel.org>
Mon, 7 Aug 2023 13:26:23 +0000 (15:26 +0200)
committerIlya Dryomov <idryomov@gmail.com>
Fri, 3 Nov 2023 22:28:34 +0000 (23:28 +0100)
Enable __ceph_setattr() to handle idmapped mounts. This is just a matter
of passing down the mount's idmapping.

[ aleksandr.mikhalitsyn: adapted to b27c82e12965 ("attr: port attribute
  changes to new types") ]

Signed-off-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
Reviewed-by: Xiubo Li <xiubli@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
fs/ceph/inode.c

index 927a336350fc9df9b95c28df2fdc67df5b0c9d46..b1b92a948a3b84542777ecd2d440124493aaf5b9 100644 (file)
@@ -2544,33 +2544,37 @@ retry:
 #endif /* CONFIG_FS_ENCRYPTION */
 
        if (ia_valid & ATTR_UID) {
+               kuid_t fsuid = from_vfsuid(idmap, i_user_ns(inode), attr->ia_vfsuid);
+
                doutc(cl, "%p %llx.%llx uid %d -> %d\n", inode,
                      ceph_vinop(inode),
                      from_kuid(&init_user_ns, inode->i_uid),
                      from_kuid(&init_user_ns, attr->ia_uid));
                if (issued & CEPH_CAP_AUTH_EXCL) {
-                       inode->i_uid = attr->ia_uid;
+                       inode->i_uid = fsuid;
                        dirtied |= CEPH_CAP_AUTH_EXCL;
                } else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
-                          !uid_eq(attr->ia_uid, inode->i_uid)) {
+                          !uid_eq(fsuid, inode->i_uid)) {
                        req->r_args.setattr.uid = cpu_to_le32(
-                               from_kuid(&init_user_ns, attr->ia_uid));
+                               from_kuid(&init_user_ns, fsuid));
                        mask |= CEPH_SETATTR_UID;
                        release |= CEPH_CAP_AUTH_SHARED;
                }
        }
        if (ia_valid & ATTR_GID) {
+               kgid_t fsgid = from_vfsgid(idmap, i_user_ns(inode), attr->ia_vfsgid);
+
                doutc(cl, "%p %llx.%llx gid %d -> %d\n", inode,
                      ceph_vinop(inode),
                      from_kgid(&init_user_ns, inode->i_gid),
                      from_kgid(&init_user_ns, attr->ia_gid));
                if (issued & CEPH_CAP_AUTH_EXCL) {
-                       inode->i_gid = attr->ia_gid;
+                       inode->i_gid = fsgid;
                        dirtied |= CEPH_CAP_AUTH_EXCL;
                } else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
-                          !gid_eq(attr->ia_gid, inode->i_gid)) {
+                          !gid_eq(fsgid, inode->i_gid)) {
                        req->r_args.setattr.gid = cpu_to_le32(
-                               from_kgid(&init_user_ns, attr->ia_gid));
+                               from_kgid(&init_user_ns, fsgid));
                        mask |= CEPH_SETATTR_GID;
                        release |= CEPH_CAP_AUTH_SHARED;
                }
@@ -2799,7 +2803,7 @@ int ceph_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
        if (err)
                return err;
 
-       err = setattr_prepare(&nop_mnt_idmap, dentry, attr);
+       err = setattr_prepare(idmap, dentry, attr);
        if (err != 0)
                return err;
 
@@ -2814,7 +2818,7 @@ int ceph_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
        err = __ceph_setattr(idmap, inode, attr, NULL);
 
        if (err >= 0 && (attr->ia_valid & ATTR_MODE))
-               err = posix_acl_chmod(&nop_mnt_idmap, dentry, attr->ia_mode);
+               err = posix_acl_chmod(idmap, dentry, attr->ia_mode);
 
        return err;
 }