summaryrefslogtreecommitdiff
path: root/fs/ceph/mds_client.c
diff options
context:
space:
mode:
authorXiubo Li <xiubli@redhat.com>2023-04-26 05:38:57 +0300
committerIlya Dryomov <idryomov@gmail.com>2023-04-30 13:37:28 +0300
commita5ffd7b6e91a12975ae30de863437cc04387576a (patch)
tree31dfffa7449245e33eaa269a7e53e11a0d2afdae /fs/ceph/mds_client.c
parentaaf67de78807c59c35bafb5003d4fb457c764800 (diff)
downloadlinux-a5ffd7b6e91a12975ae30de863437cc04387576a.tar.xz
ceph: pass ino# instead of old_dentry if it's disconnected
When exporting the kceph to NFS it may pass a DCACHE_DISCONNECTED dentry for the link operation. Then it will parse this dentry as a snapdir, and the mds will fail the link request as -EROFS. MDS allow clients to pass a ino# instead of a path. Link: https://tracker.ceph.com/issues/59515 Signed-off-by: Xiubo Li <xiubli@redhat.com> Reviewed-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph/mds_client.c')
-rw-r--r--fs/ceph/mds_client.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 54e3c2ab21d2..29cf00220b09 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -2570,6 +2570,7 @@ static struct ceph_msg *create_request_message(struct ceph_mds_session *session,
u64 ino1 = 0, ino2 = 0;
int pathlen1 = 0, pathlen2 = 0;
bool freepath1 = false, freepath2 = false;
+ struct dentry *old_dentry = NULL;
int len;
u16 releases;
void *p, *end;
@@ -2587,7 +2588,10 @@ static struct ceph_msg *create_request_message(struct ceph_mds_session *session,
}
/* If r_old_dentry is set, then assume that its parent is locked */
- ret = set_request_path_attr(NULL, req->r_old_dentry,
+ if (req->r_old_dentry &&
+ !(req->r_old_dentry->d_flags & DCACHE_DISCONNECTED))
+ old_dentry = req->r_old_dentry;
+ ret = set_request_path_attr(NULL, old_dentry,
req->r_old_dentry_dir,
req->r_path2, req->r_ino2.ino,
&path2, &pathlen2, &ino2, &freepath2, true);