diff options
| -rwxr-xr-x | tests/bugs/bug-983477.t | 4 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 37 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/fuse-resolve.c | 30 | ||||
| -rw-r--r-- | xlators/performance/md-cache/src/md-cache.c | 7 | 
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);  | 
