Skip to content

Commit 3f92c7b

Browse files
neilbrownbrauner
authored andcommitted
ceph: return the correct dentry on mkdir
ceph already splices the correct dentry (in splice_dentry()) from the result of mkdir but does nothing more with it. Now that ->mkdir can return a dentry, return the correct dentry. Note that previously ceph_mkdir() could call ceph_init_inode_acls() on the inode from the wrong dentry, which would be NULL. This is safe as ceph_init_inode_acls() checks for NULL, but is not strictly correct. With this patch, the inode for the returned dentry is passed to ceph_init_inode_acls(). Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com> Signed-off-by: NeilBrown <neilb@suse.de> Link: https://lore.kernel.org/r/20250227013949.536172-4-neilb@suse.de Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 3f90030 commit 3f92c7b

1 file changed

Lines changed: 16 additions & 8 deletions

File tree

fs/ceph/dir.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,6 +1099,7 @@ static struct dentry *ceph_mkdir(struct mnt_idmap *idmap, struct inode *dir,
10991099
struct ceph_client *cl = mdsc->fsc->client;
11001100
struct ceph_mds_request *req;
11011101
struct ceph_acl_sec_ctx as_ctx = {};
1102+
struct dentry *ret;
11021103
int err;
11031104
int op;
11041105

@@ -1116,32 +1117,32 @@ static struct dentry *ceph_mkdir(struct mnt_idmap *idmap, struct inode *dir,
11161117
ceph_vinop(dir), dentry, dentry, mode);
11171118
op = CEPH_MDS_OP_MKDIR;
11181119
} else {
1119-
err = -EROFS;
1120+
ret = ERR_PTR(-EROFS);
11201121
goto out;
11211122
}
11221123

11231124
if (op == CEPH_MDS_OP_MKDIR &&
11241125
ceph_quota_is_max_files_exceeded(dir)) {
1125-
err = -EDQUOT;
1126+
ret = ERR_PTR(-EDQUOT);
11261127
goto out;
11271128
}
11281129
if ((op == CEPH_MDS_OP_MKSNAP) && IS_ENCRYPTED(dir) &&
11291130
!fscrypt_has_encryption_key(dir)) {
1130-
err = -ENOKEY;
1131+
ret = ERR_PTR(-ENOKEY);
11311132
goto out;
11321133
}
11331134

11341135

11351136
req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
11361137
if (IS_ERR(req)) {
1137-
err = PTR_ERR(req);
1138+
ret = ERR_CAST(req);
11381139
goto out;
11391140
}
11401141

11411142
mode |= S_IFDIR;
11421143
req->r_new_inode = ceph_new_inode(dir, dentry, &mode, &as_ctx);
11431144
if (IS_ERR(req->r_new_inode)) {
1144-
err = PTR_ERR(req->r_new_inode);
1145+
ret = ERR_CAST(req->r_new_inode);
11451146
req->r_new_inode = NULL;
11461147
goto out_req;
11471148
}
@@ -1165,15 +1166,22 @@ static struct dentry *ceph_mkdir(struct mnt_idmap *idmap, struct inode *dir,
11651166
!req->r_reply_info.head->is_target &&
11661167
!req->r_reply_info.head->is_dentry)
11671168
err = ceph_handle_notrace_create(dir, dentry);
1169+
ret = ERR_PTR(err);
11681170
out_req:
1171+
if (!IS_ERR(ret) && req->r_dentry != dentry)
1172+
/* Some other dentry was spliced in */
1173+
ret = dget(req->r_dentry);
11691174
ceph_mdsc_put_request(req);
11701175
out:
1171-
if (!err)
1176+
if (!IS_ERR(ret)) {
1177+
if (ret)
1178+
dentry = ret;
11721179
ceph_init_inode_acls(d_inode(dentry), &as_ctx);
1173-
else
1180+
} else {
11741181
d_drop(dentry);
1182+
}
11751183
ceph_release_acl_sec_ctx(&as_ctx);
1176-
return ERR_PTR(err);
1184+
return ret;
11771185
}
11781186

11791187
static int ceph_link(struct dentry *old_dentry, struct inode *dir,

0 commit comments

Comments
 (0)