diff options
| -rw-r--r-- | libglusterfs/src/inode.c | 22 | ||||
| -rw-r--r-- | libglusterfs/src/inode.h | 1 | ||||
| -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 | 
6 files changed, 80 insertions, 21 deletions
diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c index 6f1c8ec3f25..1cc59666adb 100644 --- a/libglusterfs/src/inode.c +++ b/libglusterfs/src/inode.c @@ -310,7 +310,7 @@ __inode_destroy (inode_t *inode)                  goto noctx;          } -        for (index = 0; index < inode->table->xl->graph->xl_count; index++) { +        for (index = 0; index < inode->table->ctxcount; index++) {                  if (inode->_ctx[index].xl_key) {                          xl = (xlator_t *)(long)inode->_ctx[index].xl_key;                          old_THIS = THIS; @@ -528,8 +528,7 @@ __inode_create (inode_table_t *table)          INIT_LIST_HEAD (&newi->hash);          INIT_LIST_HEAD (&newi->dentry_list); -        newi->_ctx = GF_CALLOC (1, (sizeof (struct _inode_ctx) * -                                    table->xl->graph->xl_count), +        newi->_ctx = GF_CALLOC (1, (sizeof (struct _inode_ctx) * table->ctxcount),                                  gf_common_mt_inode_ctx);          if (newi->_ctx == NULL) { @@ -1316,6 +1315,7 @@ inode_table_new (size_t lru_limit, xlator_t *xl)                  return NULL;          new->xl = xl; +        new->ctxcount = xl->graph->xl_count + 1;          new->lru_limit = lru_limit; @@ -1466,7 +1466,7 @@ __inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p,          if (!inode || !xlator)                  return -1; -        for (index = 0; index < xlator->graph->xl_count; index++) { +        for (index = 0; index < inode->table->ctxcount; index++) {                  if (!inode->_ctx[index].xl_key) {                          if (set_idx == -1)                                  set_idx = index; @@ -1523,12 +1523,12 @@ __inode_ctx_get2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,          if (!inode || !xlator)                  return -1; -        for (index = 0; index < xlator->graph->xl_count; index++) { +        for (index = 0; index < inode->table->ctxcount; index++) {                  if (inode->_ctx[index].xl_key == xlator)                          break;          } -        if (index == xlator->graph->xl_count) { +        if (index == inode->table->ctxcount) {                  ret = -1;                  goto out;          } @@ -1575,12 +1575,12 @@ inode_ctx_del2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,          LOCK (&inode->lock);          { -                for (index = 0; index < xlator->graph->xl_count; index++) { +                for (index = 0; index < inode->table->ctxcount; index++) {                          if (inode->_ctx[index].xl_key == xlator)                                  break;                  } -                if (index == xlator->graph->xl_count) { +                if (index == inode->table->ctxcount) {                          ret = -1;                          goto unlock;                  } @@ -1628,14 +1628,14 @@ inode_dump (inode_t *inode, char *prefix)                  gf_proc_dump_write("ref", "%u", inode->ref);                  gf_proc_dump_write("ia_type", "%d", inode->ia_type);                  if (inode->_ctx) { -                        inode_ctx = GF_CALLOC (inode->table->xl->graph->xl_count, +                        inode_ctx = GF_CALLOC (inode->table->ctxcount,                                                 sizeof (*inode_ctx),                                                 gf_common_mt_inode_ctx);                          if (inode_ctx == NULL) {                                  goto unlock;                          } -                        for (i = 0; i < inode->table->xl->graph->xl_count; i++) { +                        for (i = 0; i < inode->table->ctxcount; i++) {                                  inode_ctx[i] = inode->_ctx[i];                          }                  } @@ -1652,7 +1652,7 @@ unlock:          UNLOCK(&inode->lock);          if (inode_ctx && (dump_options.xl_options.dump_inodectx == _gf_true)) { -                for (i = 0; i < inode->table->xl->graph->xl_count; i++) { +                for (i = 0; i < inode->table->ctxcount; i++) {                          if (inode_ctx[i].xl_key) {                                  xl = (xlator_t *)(long)inode_ctx[i].xl_key;                                  if (xl->dumpops && xl->dumpops->inodectx) diff --git a/libglusterfs/src/inode.h b/libglusterfs/src/inode.h index 199ce44849a..cf766a31bc6 100644 --- a/libglusterfs/src/inode.h +++ b/libglusterfs/src/inode.h @@ -56,6 +56,7 @@ struct _inode_table {          struct mem_pool   *inode_pool;  /* memory pool for inodes */          struct mem_pool   *dentry_pool; /* memory pool for dentrys */          struct mem_pool   *fd_mem_pool; /* memory pool for fd_t */ +        int                ctxcount;    /* number of slots in inode->ctx */  }; 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 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);  | 
