summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
authorAnand Avati <avati@redhat.com>2013-08-12 09:41:06 -0700
committerAnand Avati <avati@redhat.com>2013-09-09 17:19:09 -0700
commit64c84723064ed9ef9f2a7755d3afffd1ecf08af4 (patch)
tree4afc9f2a32e8f1c6a3103d5b67c3fa6a9bf8e4c8 /xlators
parentd3c5463bdc8597ce3a70fded6c80f20e900752f4 (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. Also, introduce and use context count for inode table. 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> Reviewed-on: http://review.gluster.org/5806
Diffstat (limited to 'xlators')
-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
3 files changed, 66 insertions, 8 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index 8c4edb1e8f3..00f2a625ae1 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -51,6 +51,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)
{
@@ -2600,6 +2633,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 =
@@ -5314,7 +5349,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 b7f1f1d13fe..9292dae76c2 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);