aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2015-02-04 02:10:48 -0500
committerIlya Dryomov <idryomov@gmail.com>2015-02-19 05:31:40 -0500
commit4d41cef279f72f3965140fffa6b48f2a7d51408c (patch)
treea1f4d52a98108b57002941a47965320c712428f4 /fs
parent5cba372c0fe78d24e83d9e0556ecbeb219625c15 (diff)
ceph: return error for traceless reply race
When we receives traceless reply for request that created new inode, we re-send a lookup request to MDS get information of the newly created inode. (VFS expects FS' callback return an inode in create case) This breaks one request into two requests. Other client may modify or move to the new inode in the middle. When the race happens, ceph_handle_notrace_create() unconditionally links the dentry for 'create' operation to the inode returned by lookup. This may confuse VFS when the inode is a directory (VFS does not allow multiple linkages for directory inode). This patch makes ceph_handle_notrace_create() when it detect a race. This event should be rare and it happens only when we talk to old MDS. Recent MDS does not send traceless reply for request that creates new inode. Signed-off-by: Yan, Zheng <zyan@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ceph/dir.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 77eeb768f95a..0411dbb15815 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -670,14 +670,17 @@ int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry)
670 /* 670 /*
671 * We created the item, then did a lookup, and found 671 * We created the item, then did a lookup, and found
672 * it was already linked to another inode we already 672 * it was already linked to another inode we already
673 * had in our cache (and thus got spliced). Link our 673 * had in our cache (and thus got spliced). To not
674 * dentry to that inode, but don't hash it, just in 674 * confuse VFS (especially when inode is a directory),
675 * case the VFS wants to dereference it. 675 * we don't link our dentry to that inode, return an
676 * error instead.
677 *
678 * This event should be rare and it happens only when
679 * we talk to old MDS. Recent MDS does not send traceless
680 * reply for request that creates new inode.
676 */ 681 */
677 BUG_ON(!result->d_inode);
678 d_instantiate(dentry, result->d_inode);
679 d_drop(result); 682 d_drop(result);
680 return 0; 683 return -ESTALE;
681 } 684 }
682 return PTR_ERR(result); 685 return PTR_ERR(result);
683} 686}