diff options
Diffstat (limited to 'xlators/cluster/dht/src/dht-common.c')
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 125 | 
1 files changed, 108 insertions, 17 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index dd2a3f3f1e1..be9c2b64afc 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -207,36 +207,120 @@ dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                      struct iatt *postparent)  {          dht_local_t  *local         = NULL; +        int           this_call_cnt = 0;          call_frame_t *prev          = NULL; +	dht_layout_t *layout        = NULL;  	dht_conf_t   *conf          = NULL; +	int           ret  = -1; +	int           is_dir = 0; +	int           is_linkfile = 0;          local = frame->local;          prev  = cookie;  	conf = this->private; -        if (op_ret == 0) { +        LOCK (&frame->lock); +        { +		if (op_ret == -1) { +			local->op_errno = op_errno; + +			if ((op_errno != ENOTCONN)  +                            && (op_errno != ENOENT) +                            && (op_errno != ESTALE)) { +				gf_log (this->name, GF_LOG_DEBUG, +					"subvolume %s returned -1 (%s)", +					prev->this->name, strerror (op_errno)); +			} +                         +                        if (op_errno == ESTALE) { +                                /* propogate the ESTALE to parent.  +                                 * setting local->layout_mismatch would send +                                 * ESTALE to parent. */ +                                local->layout_mismatch = 1; +                        } + +			goto unlock; +		} + +		if (stbuf->ia_type != local->inode->ia_type) { +			gf_log (this->name, GF_LOG_DEBUG, +				"mismatching filetypes 0%o v/s 0%o for %s", +				(stbuf->ia_type), (local->inode->ia_type), +				local->loc.path); + +			local->op_ret = -1; +			local->op_errno = EINVAL; + +			goto unlock; +		} + +		layout = local->layout; +		 +		is_dir = check_is_dir (inode, stbuf, xattr); +		is_linkfile = check_is_linkfile (inode, stbuf, xattr); +		 +		if (is_linkfile) { +			gf_log (this->name, GF_LOG_DEBUG, +				"linkfile found in revalidate for %s", +				local->loc.path); +			local->layout_mismatch = 1; + +			goto unlock; +		} + +		if (is_dir) { +			ret = dht_layout_dir_mismatch (this, layout, +						       prev->this, &local->loc, +						       xattr); +			if (ret != 0) { +				gf_log (this->name, GF_LOG_DEBUG, +					"mismatching layouts for %s",  +					local->loc.path); +			 +				local->layout_mismatch = 1; + +				goto unlock; +			} +		}  +		  		dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);                  dht_iatt_merge (this, &local->postparent, postparent,                                  prev->this); - +		 +		local->op_ret = 0;  		local->stbuf.ia_ino = local->ia_ino;                  local->stbuf.ia_gen = local->loc.inode->generation;                  if (local->loc.parent)                          local->postparent.ia_ino = local->loc.parent->ino; + +		if (!local->xattr) +			local->xattr = dict_ref (xattr);  	} +unlock: +	UNLOCK (&frame->lock); +        this_call_cnt = dht_frame_return (frame); -        if (!IA_ISDIR (local->stbuf.ia_type) -            && (local->hashed_subvol != local->cached_subvol) -            && (local->stbuf.ia_nlink == 1) -            && (conf->unhashed_sticky_bit)) { -                local->stbuf.ia_prot.sticky = 1; -        } +        if (is_last_call (this_call_cnt)) { +		if (!IA_ISDIR (local->stbuf.ia_type) +		    && (local->hashed_subvol != local->cached_subvol) +		    && (local->stbuf.ia_nlink == 1) +		    && (conf->unhashed_sticky_bit)) { +			local->stbuf.ia_prot.sticky = 1; +		} -        DHT_STACK_UNWIND (lookup, frame, op_ret, op_errno, -                          inode, &local->stbuf, xattr, -                          &local->postparent); +		if (local->layout_mismatch) { +			local->op_ret = -1; +			local->op_errno = ESTALE; +		} + +                WIPE (&local->postparent); + +		DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno, +				  local->inode, &local->stbuf, local->xattr, +                                  &local->postparent); +	}          return 0;  } @@ -771,19 +855,26 @@ dht_lookup (call_frame_t *frame, xlator_t *this,  		local->inode    = inode_ref (loc->inode);  		local->ia_ino   = loc->inode->ino; - - +		 +		local->call_cnt = layout->cnt; +		call_cnt = local->call_cnt; +		  		/* NOTE: we don't require 'trusted.glusterfs.dht.linkto' attribute,  		 *       revalidates directly go to the cached-subvolume.  		 */  		ret = dict_set_uint32 (local->xattr_req,   				       "trusted.glusterfs.dht", 4 * 4); -                subvol = layout->list[0].xlator; +		for (i = 0; i < layout->cnt; i++) { +			subvol = layout->list[i].xlator; +			 +			STACK_WIND (frame, dht_revalidate_cbk, +				    subvol, subvol->fops->lookup, +				    loc, local->xattr_req); -                STACK_WIND (frame, dht_revalidate_cbk, -                            subvol, subvol->fops->lookup, -                            loc, local->xattr_req); +			if (!--call_cnt) +				break; +		}          } else {          do_fresh_lookup:  		/* TODO: remove the hard-coding */  | 
