summaryrefslogtreecommitdiffstats
path: root/xlators/mount
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2013-07-17 11:17:04 -0400
committerAnand Avati <avati@redhat.com>2013-07-18 21:16:06 -0700
commit70e5090326f029e6bcebd398572b39d3705d0bf3 (patch)
treea6233368628410e183bff6de489c66e56c74d4dc /xlators/mount
parentdeb19de9f613611b374b1ff4d0f3a83079604c5a (diff)
mount/fuse: unlink the inode on revalidate if entry not found
If an inode/dentry is linked via a client and removed via a separate client, the inode/dentry mapping in the initial client remains. A lookup of the removed name on the initial client typically returns ENOENT once the associated caches expire. If the initial client has multiple dentries linked to the same inode, however, lookups on the non-removed dentry create windows of time where lookups on the stale/removed name return successfully. This occurs because the stale mapping resolves to the still valid inode and tricks md-cache into returning valid lookup data. To correct this situation, unlink the stale inode mapping on a failed (ENOENT) revalidation lookup (i.e., when fuse has resolved the inode but a lookup returns ENOENT). Note that with this change, the state still occurs until an md-cache window has expired, allowed a lookup to pass through to the server and given the fuse translator an opportunity to clean up. Change-Id: I47dde2f11e2ef5b8dd51e9ac8be0f36cdb5081a3 BUG: 985074 Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-on: http://review.gluster.org/5337 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Anand Avati <avati@redhat.com>
Diffstat (limited to 'xlators/mount')
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index ce33009..0291859 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -464,6 +464,13 @@ fuse_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret == -1 && state->is_revalidate == 1) {
itable = state->itable;
+ /*
+ * A stale mapping might exist for a dentry/inode that has been
+ * removed from another client.
+ */
+ if (op_errno == ENOENT)
+ inode_unlink(state->loc.inode, state->loc.parent,
+ state->loc.name);
inode_unref (state->loc.inode);
state->loc.inode = inode_new (itable);
state->is_revalidate = 2;