diff options
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 8 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server-resolve.c | 23 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix.c | 14 | 
3 files changed, 40 insertions, 5 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index ed4babd328c..4c85cd3a807 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -1451,6 +1451,14 @@ dht_lookup (call_frame_t *frame, xlator_t *this,                  local->xattr_req = dict_new ();          } +        /* Older (glusterfs 3.4) clients don't set this. If set, the server +         * sends ESTALE when ENOENT occurs. */ +        ret = dict_set_int32 (local->xattr_req, "missing-gfid-ESTALE", 1); +        if (ret < 0) { +                gf_log (this->name, GF_LOG_DEBUG, +                        "%s: Unable to set dict value for missing-gfid-ESTALE", +                        loc->path); +        }          if (uuid_is_null (loc->pargfid) && !uuid_is_null (loc->gfid) &&              !__is_root_gfid (loc->inode->gfid)) {                  local->cached_subvol = NULL; diff --git a/xlators/protocol/server/src/server-resolve.c b/xlators/protocol/server/src/server-resolve.c index b2bff5c531a..c98c1ae5529 100644 --- a/xlators/protocol/server/src/server-resolve.c +++ b/xlators/protocol/server/src/server-resolve.c @@ -235,18 +235,27 @@ resolve_entry_simple (call_frame_t *frame)          server_resolve_t   *resolve = NULL;          inode_t            *parent = NULL;          inode_t            *inode = NULL; +        int                 missing_gfid_estale = 0;          int                 ret = 0;          state = CALL_STATE (frame);          this  = frame->this;          resolve = state->resolve_now; +        if (dict_get_int32 (state->xdata, "missing-gfid-ESTALE", +                              &missing_gfid_estale)) +                gf_log (this->name, GF_LOG_DEBUG, +                        "missing-gfid-ESTALE key not present in dict"); +          parent = inode_find (state->itable, resolve->pargfid);          if (!parent) {                  /* simple resolution is indecisive. need to perform                     deep resolution */                  resolve->op_ret   = -1; -                resolve->op_errno = ESTALE; +                if (missing_gfid_estale) +                        resolve->op_errno = ESTALE; +                else +                        resolve->op_errno = ENOENT;                  ret = 1;                  goto out;          } @@ -332,18 +341,28 @@ int  resolve_inode_simple (call_frame_t *frame)  {          server_state_t     *state = NULL; +        xlator_t           *this  = NULL;          server_resolve_t   *resolve = NULL;          inode_t            *inode = NULL; +        int                 missing_gfid_estale = 0;          int                 ret = 0;          state = CALL_STATE (frame); +        this = frame->this;          resolve = state->resolve_now; +        if (dict_get_int32 (state->xdata, "missing-gfid-ESTALE", +                            &missing_gfid_estale)) +                gf_log (this->name, GF_LOG_DEBUG, +                        "missing-gfid-ESTALE key not present in dict");          inode = inode_find (state->itable, resolve->gfid);          if (!inode) {                  resolve->op_ret   = -1; -                resolve->op_errno = ESTALE; +                if (missing_gfid_estale) +                        resolve->op_errno = ESTALE; +                else +                        resolve->op_errno = ENOENT;                  ret = 1;                  goto out;          } diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 71daa3e3761..6cfa2224d94 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -99,6 +99,7 @@ posix_lookup (call_frame_t *frame, xlator_t *this,          int32_t     op_ret             = -1;          int32_t     entry_ret          = 0;          int32_t     op_errno           = 0; +        int32_t missing_gfid_estale    = 0;          dict_t *    xattr              = NULL;          char *      real_path          = NULL;          char *      par_path           = NULL; @@ -125,6 +126,8 @@ posix_lookup (call_frame_t *frame, xlator_t *this,          }          op_ret = dict_get_int32 (xdata, GF_GFIDLESS_LOOKUP, &gfidless); +        op_ret = dict_get_int32 (xdata, "missing-gfid-ESTALE", +                                 &missing_gfid_estale);          op_ret = -1;          if (uuid_is_null (loc->pargfid) || (loc->name == NULL)) {                  /* nameless lookup */ @@ -165,12 +168,17 @@ parent:                          gf_log (this->name, GF_LOG_ERROR,                                  "post-operation lstat on parent %s failed: %s",                                  par_path, strerror (op_errno)); -			if (op_errno == ENOENT) +			if (op_errno == ENOENT) {  				/* If parent directory is missing in a lookup,  				   errno should be ESTALE (bad handle) and not -				   ENOENT (missing entry) +				   ENOENT (missing entry). But do this only for +                                   3.5 clients or newer. Older clients (AFR) +                                   still expect ENOENT to function correctly.  				*/ -				op_errno = ESTALE; +                                if (missing_gfid_estale) { +				        op_errno = ESTALE; +                                } +                        }                          goto out;                  }          }  | 
