diff options
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 64 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.h | 4 | 
2 files changed, 60 insertions, 8 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index bc7214e1c7a..cc409c9103d 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -1291,7 +1291,6 @@ dht_lookup_dir_cbk(call_frame_t *frame, void *cookie, xlator_t *this,      {          /* TODO: assert equal mode on stbuf->st_mode and             local->stbuf->st_mode -             else mkdir/chmod/chown and fix          */          ret = dht_layout_merge(this, layout, prev, op_ret, op_errno, xattr); @@ -1299,9 +1298,13 @@ dht_lookup_dir_cbk(call_frame_t *frame, void *cookie, xlator_t *this,          if (op_ret == -1) {              local->op_errno = op_errno;              gf_msg_debug(this->name, op_errno, -                         "lookup of %s on %s returned error", local->loc.path, +                         "%s: lookup on %s returned error", local->loc.path,                           prev->name); +            /* The GFID is missing on this subvol. Force a heal. */ +            if (op_errno == ENODATA) { +                local->need_selfheal = 1; +            }              goto unlock;          } @@ -1401,6 +1404,15 @@ unlock:          if (local->need_selfheal) {              local->need_selfheal = 0; +            /* Set the gfid-req so posix will set the GFID*/ +            if (!gf_uuid_is_null(local->gfid)) { +                ret = dict_set_static_bin(local->xattr_req, "gfid-req", +                                          local->gfid, 16); +            } else { +                if (!gf_uuid_is_null(local->gfid_req)) +                    ret = dict_set_static_bin(local->xattr_req, "gfid-req", +                                              local->gfid_req, 16); +            }              dht_lookup_everywhere(frame, this, &local->loc);              return 0;          } @@ -1590,6 +1602,13 @@ dht_revalidate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,                      local->need_lookup_everywhere = 1;                  }              } + +            /* The GFID is missing on this subvol*/ +            if ((op_errno == ENODATA) && +                (IA_ISDIR(local->loc.inode->ia_type))) { +                local->need_lookup_everywhere = 1; +            } +              goto unlock;          } @@ -1818,6 +1837,13 @@ unlock:              /* We know that current cached subvol is no more                 valid, get the new one */              local->cached_subvol = NULL; +            if (local->xattr_req) { +                if (!gf_uuid_is_null(local->gfid)) { +                    ret = dict_set_static_bin(local->xattr_req, "gfid-req", +                                              local->gfid, 16); +                } +            } +              dht_lookup_everywhere(frame, this, &local->loc);              return 0;          } @@ -2253,6 +2279,16 @@ dht_lookup_everywhere_done(call_frame_t *frame, xlator_t *this)          DHT_STACK_UNWIND(lookup, frame, -1, EIO, NULL, NULL, NULL, NULL);          return 0;      } +    if (local->op_ret && local->gfid_missing) { +        if (gf_uuid_is_null(local->gfid_req)) { +            DHT_STACK_UNWIND(lookup, frame, -1, ENODATA, NULL, NULL, NULL, +                             NULL); +            return 0; +        } +        /* A hack */ +        dht_lookup_directory(frame, this, &local->loc); +        return 0; +    }      if (local->dir_count) {          dht_lookup_directory(frame, this, &local->loc); @@ -2572,6 +2608,8 @@ dht_lookup_everywhere_cbk(call_frame_t *frame, void *cookie, xlator_t *this,          if (op_ret == -1) {              if (op_errno != ENOENT)                  local->op_errno = op_errno; +            if (op_errno == ENODATA) +                local->gfid_missing = _gf_true;              goto unlock;          } @@ -3067,7 +3105,11 @@ dht_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,              }          } else { -            if (op_errno == ENOTCONN) { +            /* posix returns ENODATA if the gfid is not set but the client and +             * server protocol layers do not send the stbuf. We need to +             * heal this so check if this is a directory on the other subvols. +             */ +            if ((op_errno == ENOTCONN) || (op_errno == ENODATA)) {                  dht_lookup_directory(frame, this, &local->loc);                  return 0;              } @@ -3419,6 +3461,16 @@ dht_do_fresh_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc)          goto err;      } +    /* Fuse sets a random value in gfid-req. If the gfid is missing +     * on one or more subvols, posix will set the gfid to this value, +     * causing GFID mismatches for directories. +     */ +    ret = dict_get_gfuuid(local->xattr_req, "gfid-req", &local->gfid_req); +    if (ret) { +        gf_msg_debug(this->name, 0, "%s: No gfid-req available", loc->path); +    } else { +        dict_del(local->xattr_req, "gfid-req"); +    }      /* This should have been set in dht_lookup */      hashed_subvol = local->hashed_subvol; @@ -3454,10 +3506,8 @@ dht_do_fresh_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc)      /* if we have the hashed_subvol, send the lookup there first so       * as to see whether we have a file or a directory */ -    gf_msg_debug(this->name, 0, -                 "Calling fresh lookup for %s on" -                 " %s", -                 loc->path, hashed_subvol->name); +    gf_msg_debug(this->name, 0, "%s: Calling fresh lookup on %s", loc->path, +                 hashed_subvol->name);      STACK_WIND_COOKIE(frame, dht_lookup_cbk, hashed_subvol, hashed_subvol,                        hashed_subvol->fops->lookup, loc, local->xattr_req); diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h index 6fb1c16d0d8..c516271228e 100644 --- a/xlators/cluster/dht/src/dht-common.h +++ b/xlators/cluster/dht/src/dht-common.h @@ -323,7 +323,7 @@ struct dht_local {      uint32_t uid;      uint32_t gid; -    pid_t    pid; +    pid_t pid;      /* needed by nufa */      int32_t flags; @@ -341,6 +341,7 @@ struct dht_local {      /* gfid related */      uuid_t gfid; +    uuid_t gfid_req;      /* flag used to make sure we need to return estale in         {lookup,revalidate}_cbk */ @@ -385,6 +386,7 @@ struct dht_local {      loc_t loc2_copy;      gf_boolean_t locked;      gf_boolean_t dont_create_linkto; +    gf_boolean_t gfid_missing;  };  typedef struct dht_local dht_local_t;  | 
