@@ -2581,6 +2581,8 @@ static struct ceph_msg *create_request_message(struct ceph_mds_session *session,
void *p, *end;
int ret;
bool legacy = !(session->s_con.peer_features & CEPH_FEATURE_FS_BTIME);
+ kuid_t caller_fsuid;
+ kgid_t caller_fsgid;
ret = set_request_path_attr(req->r_inode, req->r_dentry,
req->r_parent, req->r_path1, req->r_ino1.ino,
@@ -2649,10 +2651,22 @@ static struct ceph_msg *create_request_message(struct ceph_mds_session *session,
head->mdsmap_epoch = cpu_to_le32(mdsc->mdsmap->m_epoch);
head->op = cpu_to_le32(req->r_op);
- head->caller_uid = cpu_to_le32(from_kuid(&init_user_ns,
- req->r_cred->fsuid));
- head->caller_gid = cpu_to_le32(from_kgid(&init_user_ns,
- req->r_cred->fsgid));
+ /*
+ * Inode operations that create filesystem objects based on the
+ * caller's fs{g,u}id like ->mknod(), ->create(), ->mkdir() etc. don't
+ * have separate {g,u}id fields in their respective structs in the
+ * ceph_mds_request_args union. Instead the caller_{g,u}id field is
+ * used to set ownership of the newly created inode by the mds server.
+ * For these inode operations we need to send the mapped fs{g,u}id over
+ * the wire. For other cases we simple set req->r_mnt_idmap to the
+ * initial idmapping meaning the unmapped fs{g,u}id is sent.
+ */
+ caller_fsuid = from_vfsuid(req->r_mnt_idmap, &init_user_ns,
+ VFSUIDT_INIT(req->r_cred->fsuid));
+ caller_fsgid = from_vfsgid(req->r_mnt_idmap, &init_user_ns,
+ VFSGIDT_INIT(req->r_cred->fsgid));
+ head->caller_uid = cpu_to_le32(from_kuid(&init_user_ns, caller_fsuid));
+ head->caller_gid = cpu_to_le32(from_kgid(&init_user_ns, caller_fsgid));
head->ino = cpu_to_le64(req->r_deleg_ino);
head->args = req->r_args;