summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnand Avati <avati@redhat.com>2013-08-12 09:41:06 -0700
committerAnand Avati <avati@redhat.com>2013-08-23 12:09:58 -0700
commit2991503d014f634da5cd10bcb851e986a3dcd5c2 (patch)
tree62a30fc0ad9c479985a3acda27cc36df4e03bc83
parent32fb404ef2fda7368c11c591bfa4dcf269cbd320 (diff)
mount/fuse: perform lookup() on inodes linked through readdirplus
Some xlators still require lookup() fop to be sent for proper working. This patch remembers inodes which have been linked through readdiprlus and makes the resolver send lookups on them. Change-Id: Ibe8a04a659539d90dfc794521b51bf2bda017a0b BUG: 979910 Signed-off-by: Anand Avati <avati@redhat.com> Reviewed-on: http://review.gluster.org/5267 Reviewed-by: Amar Tumballi <amarts@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com>
-rwxr-xr-xtests/bugs/bug-983477.t4
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c37
-rw-r--r--xlators/mount/fuse/src/fuse-resolve.c30
-rw-r--r--xlators/performance/md-cache/src/md-cache.c7
4 files changed, 68 insertions, 10 deletions
diff --git a/tests/bugs/bug-983477.t b/tests/bugs/bug-983477.t
index dfb0f381d4c..6384209e1f8 100755
--- a/tests/bugs/bug-983477.t
+++ b/tests/bugs/bug-983477.t
@@ -32,10 +32,10 @@ EXPECT_WITHIN 20 "0" get_use_readdirp_value $V0
TEST cd -
TEST umount $M0
-#By default it is disabled.
+#By default it is enabled.
TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0
TEST cd $M0
-EXPECT_WITHIN 20 "0" get_use_readdirp_value $V0
+EXPECT_WITHIN 20 "1" get_use_readdirp_value $V0
TEST cd -
TEST umount $M0
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index c93b17df971..1413c306e25 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -52,6 +52,39 @@ fuse_invalidate(xlator_t *this, inode_t *inode)
return 0;
}
+void
+fuse_inode_set_need_lookup (inode_t *inode, xlator_t *this)
+{
+ uint64_t need_lookup = 1;
+
+ if (!inode || !this)
+ return;
+
+ inode_ctx_set (inode, this, &need_lookup);
+
+ return;
+}
+
+
+gf_boolean_t
+fuse_inode_needs_lookup (inode_t *inode, xlator_t *this)
+{
+ uint64_t need_lookup = 0;
+ gf_boolean_t ret = _gf_false;
+
+ if (!inode || !this)
+ return ret;
+
+ inode_ctx_get (inode, this, &need_lookup);
+ if (need_lookup)
+ ret = _gf_true;
+ need_lookup = 0;
+ inode_ctx_set (inode, this, &need_lookup);
+
+ return ret;
+}
+
+
fuse_fd_ctx_t *
__fuse_fd_ctx_check_n_create (xlator_t *this, fd_t *fd)
{
@@ -2633,6 +2666,8 @@ fuse_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
feo->nodeid = inode_to_fuse_nodeid (linked_inode);
+ fuse_inode_set_need_lookup (linked_inode, this);
+
inode_unref (linked_inode);
feo->entry_valid =
@@ -5439,7 +5474,7 @@ struct volume_options options[] = {
},
{ .key = {"use-readdirp"},
.type = GF_OPTION_TYPE_BOOL,
- .default_value = "no"
+ .default_value = "yes"
},
{ .key = {NULL} },
};
diff --git a/xlators/mount/fuse/src/fuse-resolve.c b/xlators/mount/fuse/src/fuse-resolve.c
index 88ce32ab9cd..8565ce0e478 100644
--- a/xlators/mount/fuse/src/fuse-resolve.c
+++ b/xlators/mount/fuse/src/fuse-resolve.c
@@ -26,6 +26,8 @@ int fuse_migrate_fd (xlator_t *this, fd_t *fd, xlator_t *old_subvol,
fuse_fd_ctx_t *
fuse_fd_ctx_get (xlator_t *this, fd_t *fd);
+gf_boolean_t fuse_inode_needs_lookup (inode_t *inode, xlator_t *this);
+
static int
fuse_resolve_loc_touchup (fuse_state_t *state)
{
@@ -201,7 +203,11 @@ fuse_resolve_gfid (fuse_state_t *state)
uuid_copy (resolve_loc->gfid, resolve->gfid);
}
- resolve_loc->inode = inode_new (state->itable);
+ /* inode may already exist in case we are looking up an inode which was
+ linked through readdirplus */
+ resolve_loc->inode = inode_find (state->itable, resolve_loc->gfid);
+ if (!resolve_loc->inode)
+ resolve_loc->inode = inode_new (state->itable);
ret = loc_path (resolve_loc, NULL);
if (ret <= 0) {
@@ -239,6 +245,9 @@ fuse_resolve_parent_simple (fuse_state_t *state)
parent = resolve->parhint;
if (parent->table == state->itable) {
+ if (fuse_inode_needs_lookup (parent, THIS))
+ return 1;
+
/* no graph switches since */
loc->parent = inode_ref (parent);
uuid_copy (loc->pargfid, parent->gfid);
@@ -265,6 +274,10 @@ fuse_resolve_parent_simple (fuse_state_t *state)
/* non decisive result - parent missing */
return 1;
}
+ if (fuse_inode_needs_lookup (parent, THIS)) {
+ inode_unref (parent);
+ return 1;
+ }
loc->parent = parent;
uuid_copy (loc->pargfid, resolve->pargfid);
@@ -314,15 +327,18 @@ fuse_resolve_inode_simple (fuse_state_t *state)
loc = state->loc_now;
inode = resolve->hint;
- if (inode->table == state->itable) {
+ if (inode->table == state->itable)
inode_ref (inode);
- goto found;
+ else
+ inode = inode_find (state->itable, resolve->gfid);
+
+ if (inode) {
+ if (!fuse_inode_needs_lookup (inode, THIS))
+ goto found;
+ /* inode was linked through readdirplus */
+ inode_unref (inode);
}
- inode = inode_find (state->itable, resolve->gfid);
- if (inode)
- goto found;
-
return 1;
found:
loc->inode = inode;
diff --git a/xlators/performance/md-cache/src/md-cache.c b/xlators/performance/md-cache/src/md-cache.c
index ba8b1b87925..9e211da1c1f 100644
--- a/xlators/performance/md-cache/src/md-cache.c
+++ b/xlators/performance/md-cache/src/md-cache.c
@@ -799,6 +799,13 @@ mdc_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
if (!local)
goto uncached;
+ if (!loc->name)
+ /* A nameless discovery is dangerous to cache. We
+ perform nameless lookup with the intention of
+ re-establishing an inode "properly"
+ */
+ goto uncached;
+
loc_copy (&local->loc, loc);
ret = mdc_inode_iatt_get (this, loc->inode, &stbuf);