aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/file.c
diff options
context:
space:
mode:
authorXiubo Li <xiubli@redhat.com>2022-05-10 09:47:01 +0800
committerIlya Dryomov <idryomov@gmail.com>2022-08-03 00:54:12 +0200
commit4868e537fa867f82e38e37429d61d7bb8357d79b (patch)
treebadea4f6181c6755959c8a44c4b84f527da23cad /fs/ceph/file.c
parentfs/dcache: export d_same_name() helper (diff)
downloadlinux-dev-4868e537fa867f82e38e37429d61d7bb8357d79b.tar.xz
linux-dev-4868e537fa867f82e38e37429d61d7bb8357d79b.zip
ceph: wait for the first reply of inflight async unlink
In async unlink case the kclient won't wait for the first reply from MDS and just drop all the links and unhash the dentry and then succeeds immediately. For any new create/link/rename,etc requests followed by using the same file names we must wait for the first reply of the inflight unlink request, or the MDS possibly will fail these following requests with -EEXIST if the inflight async unlink request was delayed for some reasons. And the worst case is that for the none async openc request it will successfully open the file if the CDentry hasn't been unlinked yet, but later the previous delayed async unlink request will remove the CDenty. That means the just created file is possiblly deleted later by accident. We need to wait for the inflight async unlink requests to finish when creating new files/directories by using the same file names. Link: https://tracker.ceph.com/issues/55332 Signed-off-by: Xiubo Li <xiubli@redhat.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph/file.c')
-rw-r--r--fs/ceph/file.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index da59e836a06e..0f3424dc618b 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -569,7 +569,7 @@ static void ceph_async_create_cb(struct ceph_mds_client *mdsc,
char *path = ceph_mdsc_build_path(req->r_dentry, &pathlen,
&base, 0);
- pr_warn("ceph: async create failure path=(%llx)%s result=%d!\n",
+ pr_warn("async create failure path=(%llx)%s result=%d!\n",
base, IS_ERR(path) ? "<<bad>>" : path, result);
ceph_mdsc_free_path(path, pathlen);
@@ -740,6 +740,10 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
if (dentry->d_name.len > NAME_MAX)
return -ENAMETOOLONG;
+ err = ceph_wait_on_conflict_unlink(dentry);
+ if (err)
+ return err;
+
if (flags & O_CREAT) {
if (ceph_quota_is_max_files_exceeded(dir))
return -EDQUOT;