summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xlators/cluster/dht/src/dht-common.c125
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 */