summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libglusterfs/src/inode.c18
-rw-r--r--libglusterfs/src/inode.h3
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c17
-rw-r--r--xlators/mount/fuse/src/fuse-resolve.c11
4 files changed, 39 insertions, 10 deletions
diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c
index 50ef98fba20..26e0194a761 100644
--- a/libglusterfs/src/inode.c
+++ b/libglusterfs/src/inode.c
@@ -1845,7 +1845,7 @@ out:
void
inode_set_need_lookup (inode_t *inode, xlator_t *this)
{
- uint64_t need_lookup = 1;
+ uint64_t need_lookup = LOOKUP_NEEDED;
if (!inode | !this)
return;
@@ -1855,19 +1855,29 @@ inode_set_need_lookup (inode_t *inode, xlator_t *this)
return;
}
+/* Function behaviour:
+ * Function return true if inode_ctx is not present,
+ * or value stored in inode_ctx is LOOKUP_NEEDED.
+ * If inode_ctx value is LOOKUP_NOT_NEEDED, which means
+ * inode_ctx is present for xlator this, but no lookup
+ * needed.
+ */
gf_boolean_t
inode_needs_lookup (inode_t *inode, xlator_t *this)
{
uint64_t need_lookup = 0;
gf_boolean_t ret = _gf_false;
+ int op_ret = -1;
if (!inode || !this)
return ret;
- inode_ctx_get (inode, this, &need_lookup);
- if (need_lookup) {
+ op_ret = inode_ctx_get (inode, this, &need_lookup);
+ if (op_ret == -1) {
+ ret = _gf_true;
+ } else if (need_lookup == LOOKUP_NEEDED) {
ret = _gf_true;
- need_lookup = 0;
+ need_lookup = LOOKUP_NOT_NEEDED;
inode_ctx_set (inode, this, &need_lookup);
}
diff --git a/libglusterfs/src/inode.h b/libglusterfs/src/inode.h
index 37083fae05b..114aeae78bb 100644
--- a/libglusterfs/src/inode.h
+++ b/libglusterfs/src/inode.h
@@ -14,6 +14,9 @@
#include <stdint.h>
#include <sys/types.h>
+#define LOOKUP_NEEDED 1
+#define LOOKUP_NOT_NEEDED 2
+
#define DEFAULT_INODE_MEMPOOL_ENTRIES 32 * 1024
#define INODE_PATH_FMT "<gfid:%s>"
struct _inode_table;
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index eba8a6ddb0c..8ac641d5bca 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -380,6 +380,7 @@ fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
struct fuse_entry_out feo = {0, };
fuse_private_t *priv = NULL;
inode_t *linked_inode = NULL;
+ uint64_t ctx_value = LOOKUP_NOT_NEEDED;
priv = this->private;
state = frame->root->state;
@@ -429,7 +430,8 @@ fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
linked_inode = inode_link (inode, state->loc.parent,
state->loc.name, buf);
- if (linked_inode != inode) {
+ if (linked_inode == inode) {
+ inode_ctx_set (linked_inode, this, &ctx_value);
}
inode_lookup (linked_inode);
@@ -1915,6 +1917,7 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
struct fuse_open_out foo = {0, };
struct iovec iov_out[3];
inode_t *linked_inode = NULL;
+ uint64_t ctx_value = LOOKUP_NOT_NEEDED;
state = frame->root->state;
priv = this->private;
@@ -1950,6 +1953,8 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
*/
inode_unref (fd->inode);
fd->inode = inode_ref (linked_inode);
+ } else {
+ inode_ctx_set (linked_inode, this, &ctx_value);
}
inode_lookup (linked_inode);
@@ -4168,12 +4173,13 @@ fuse_first_lookup (xlator_t *this)
int
-fuse_nameless_lookup (xlator_t *xl, uuid_t gfid, loc_t *loc)
+fuse_nameless_lookup (xlator_t *this, xlator_t *xl, uuid_t gfid, loc_t *loc)
{
int ret = -1;
dict_t *xattr_req = NULL;
struct iatt iatt = {0, };
inode_t *linked_inode = NULL;
+ uint64_t ctx_value = LOOKUP_NOT_NEEDED;
if ((loc == NULL) || (xl == NULL)) {
ret = -EINVAL;
@@ -4201,6 +4207,9 @@ fuse_nameless_lookup (xlator_t *xl, uuid_t gfid, loc_t *loc)
goto out;
linked_inode = inode_link (loc->inode, NULL, NULL, &iatt);
+ if (linked_inode == loc->inode)
+ inode_ctx_set (linked_inode, this, &ctx_value);
+
inode_unref (loc->inode);
loc->inode = linked_inode;
@@ -4240,8 +4249,8 @@ fuse_migrate_fd_open (xlator_t *this, fd_t *basefd, fd_t *oldfd,
loc.inode = inode_find (new_subvol->itable, basefd->inode->gfid);
if (loc.inode == NULL) {
- ret = fuse_nameless_lookup (new_subvol, basefd->inode->gfid,
- &loc);
+ ret = fuse_nameless_lookup (this, new_subvol,
+ basefd->inode->gfid, &loc);
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"name-less lookup of gfid (%s) failed (%s)"
diff --git a/xlators/mount/fuse/src/fuse-resolve.c b/xlators/mount/fuse/src/fuse-resolve.c
index 9e38cbe7e40..a0352bcf43f 100644
--- a/xlators/mount/fuse/src/fuse-resolve.c
+++ b/xlators/mount/fuse/src/fuse-resolve.c
@@ -45,6 +45,7 @@ fuse_resolve_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fuse_resolve_t *resolve = NULL;
inode_t *link_inode = NULL;
loc_t *resolve_loc = NULL;
+ uint64_t ctx_value = LOOKUP_NOT_NEEDED;
state = frame->root->state;
resolve = state->resolve_now;
@@ -65,7 +66,8 @@ fuse_resolve_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
link_inode = inode_link (inode, resolve_loc->parent,
resolve_loc->name, buf);
-
+ if (link_inode == inode)
+ inode_ctx_set (link_inode, this, &ctx_value);
state->loc_now->inode = link_inode;
out:
@@ -114,6 +116,7 @@ fuse_resolve_gfid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
inode_t *link_inode = NULL;
loc_t *loc_now = NULL;
inode_t *tmp_inode = NULL;
+ uint64_t ctx_value = LOOKUP_NOT_NEEDED;
state = frame->root->state;
resolve = state->resolve_now;
@@ -146,6 +149,8 @@ fuse_resolve_gfid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
link_inode = inode_link (inode, NULL, NULL, buf);
+ if (link_inode == inode)
+ inode_ctx_set (link_inode, this, &ctx_value);
loc_wipe (&resolve->resolve_loc);
@@ -226,9 +231,11 @@ fuse_resolve_parent_simple (fuse_state_t *state)
loc_t *loc = NULL;
inode_t *parent = NULL;
inode_t *inode = NULL;
+ xlator_t *this = NULL;
resolve = state->resolve_now;
loc = state->loc_now;
+ this = state->this;
loc->name = resolve->bname;
@@ -276,7 +283,7 @@ fuse_resolve_parent_simple (fuse_state_t *state)
gf_uuid_copy (loc->pargfid, resolve->pargfid);
inode = inode_grep (state->itable, parent, loc->name);
- if (inode) {
+ if (inode && !inode_needs_lookup (inode, this)) {
loc->inode = inode;
/* decisive result - resolution success */
return 0;