diff options
author | Brian Foster <bfoster@redhat.com> | 2013-07-17 11:17:04 -0400 |
---|---|---|
committer | Anand Avati <avati@redhat.com> | 2013-07-18 21:16:06 -0700 |
commit | 70e5090326f029e6bcebd398572b39d3705d0bf3 (patch) | |
tree | a6233368628410e183bff6de489c66e56c74d4dc /xlators/mount/fuse | |
parent | deb19de9f613611b374b1ff4d0f3a83079604c5a (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/fuse')
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 7 |
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 ce33009d8e3..0291859c055 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; |