Patch "ceph: don't set req->r_locked_dir in ceph_d_revalidate" has been added to the 4.8-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
ceph: don't set req->r_locked_dir in ceph_d_revalidate
to the 4.8-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
ceph-don-t-set-req-r_locked_dir-in-ceph_d_revalidate.patch
and it can be found in the queue-4.8 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
c3f4688a08fd86f1bf8e055724c84b7a40a09733Mon Sep 17 00:00:00 2001
From: Jeff Layton <[email protected]>
Date: Wed, 30 Nov 2016 15:56:46 -0500
Subject: ceph: don't set req->r_locked_dir in ceph_d_revalidate
From: Jeff Layton <[email protected]>
commit c3f4688a08fd86f1bf8e055724c84b7a40a09733 upstream.
This function sets req->r_locked_dir which is supposed to indicate to ceph_fill_trace that the parent's i_rwsem is locked for write. Unfortunately, there is no guarantee that the dir will be locked when d_revalidate is called, so we really don't want ceph_fill_trace to do any dcache manipulation from this context. Clear req->r_locked_dir since it's clearly not safe to do that.
What we really want to know with d_revalidate is whether the dentry still points to the same inode. ceph_fill_trace installs a pointer to the inode in req->r_target_inode, so we can just compare that to d_inode(dentry) to see if it's the same one after the lookup.
Also, since we aren't generally interested in the parent here, we can switch to using a GETATTR to hint that to the MDS, which also means that we only need to reserve one cap.
Finally, just remove the d_unhashed check. That's really outside the purview of a filesystem's d_revalidate. If the thing became unhashed while we're checking it, then that's up to the VFS to handle anyway.
--- fs/ceph/dir.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-)
fs/ceph/dir.c +14 -10
@@ -1257,26 +1257,30 @@ static int ceph_d_revalidate(struct dentreturn -ECHILD ; op =ceph_snap (dir) ==CEPH_SNAPDIR ? -CEPH_MDS_OP_LOOKUPSNAP :CEPH_MDS_OP_LOOKUP ; +CEPH_MDS_OP_LOOKUPSNAP :CEPH_MDS_OP_GETATTR ; req =ceph_mdsc_create_request (mdsc, op,USE_ANY_MDS );if (!IS_ERR (req)) { req->r_dentry =dget (dentry); - req->r_num_caps =2 ; + req->r_num_caps = op ==CEPH_MDS_OP_GETATTR ?1 :2 ; mask =CEPH_STAT_CAP_INODE |CEPH_CAP_AUTH_SHARED ;if (ceph_security_xattr_wanted (dir)) mask |=CEPH_CAP_XATTR_SHARED ; req->r_args.getattr.mask = mask; - req->r_locked_dir = dir; err =ceph_mdsc_do_request (mdsc,NULL , req); -if (err ==0 || err == -ENOENT ) { -if (dentry == req->r_dentry) { - valid = !d_unhashed (dentry); - }else { -d_invalidate (req->r_dentry); - err = -EAGAIN ; - } +switch (err) { +case 0 : +if (d_really_is_positive (dentry) && +d_inode (dentry) == req->r_target_inode) + valid =1 ; +break ; +case -ENOENT : +if (d_really_is_negative (dentry)) + valid =1 ; +/* Fallthrough */ +default : +break ; }ceph_mdsc_put_request (req); dout("d_revalidate %p lookup result=%d\n",
Patches currently in stable-queue which might be from [email protected] are
queue-4.8/ceph-don-t-set-req-r_locked_dir-in-ceph_d_revalidate.patch queue-4.8/fuse-fix-clearing-suid-sgid-for-chown.patch