diff options
author | Raghavendra Talur <rtalur@redhat.com> | 2015-03-20 18:35:26 +0530 |
---|---|---|
committer | Shyamsundar Ranganathan <srangana@redhat.com> | 2015-05-04 13:25:36 -0700 |
commit | fed5b758ced8077486dbb923351cb0d06f04567c (patch) | |
tree | 3a3fe9fba97844ce31f0d357201b704078e0c276 /xlators | |
parent | e7640557a674f6f073dccfa1a677aaa49b2e0b8f (diff) |
cluster/dht: Unwind with proper op_ret
1. Expected behavior of get_real_filename feature.
A getxattr on a existing dir with glusterfs.get_real_filename:<filename>
as key should result in one of the following things.
a. A value returned for that key having the real filename (a file whose
match is a case insensitive match to the filename passed in key).
b. op_ret = -1 and errno set to ENOENT meaning that no such file exists
under the specified dir in any case.
c. op_ret = -1 and errno set to ENODATA. This is a case assuming no
xlator interprets the glusterfs.get_real_filename key and it get
passed down to the posix xlator. Naturally, posix xlator would not
find any xattr with this key and would return ENODATA. This will be
interpreted specially by the caller as the feature not being supported
by underlying glusterfs.
2. What assumptions are wrong?
Initially the key used to be user.glusterfs.get_real_filename.
In that case, when posix xlator did a getxattr call it would have
received ENODATA as error. However, the key has now changed to
glusterfs.get_real_filename. This leads to a EOPNOTSUPP error instead.
Considering the above information, this is a rewrite of
get_real_filename logic in dht.
Change-Id: I012e9150047fc8563be91b0d112a368ac1cbf598
BUG: 1204140
Signed-off-by: Raghavendra Talur <rtalur@redhat.com>
Reviewed-on: http://review.gluster.org/9956
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: N Balachandran <nbalacha@redhat.com>
Reviewed-by: Shyamsundar Ranganathan <srangana@redhat.com>
(cherry picked from commit 331e705b6a458600c0b5cbcf2b0f7b9e1167bdc2)
Reviewed-on: http://review.gluster.org/10403
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 98 |
1 files changed, 86 insertions, 12 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index f92b0ca6409..e793c8561c0 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -2678,20 +2678,94 @@ dht_getxattr_get_real_filename_cbk (call_frame_t *frame, void *cookie, local = frame->local; - if (op_ret != -1) { - if (local->xattr) - dict_unref (local->xattr); - local->xattr = dict_ref (xattr); - - if (local->xattr_req) - dict_unref (local->xattr_req); - local->xattr_req = dict_ref (xdata); - } + LOCK (&frame->lock); + { + if (local->op_errno == ENODATA || + local->op_errno == EOPNOTSUPP) { + /* Nothing to do here, we have already found + * a subvol which does not have the get_real_filename + * optimization. If condition is for simple logic. + */ + goto unlock; + } + + if (op_ret == -1) { + + if (op_errno == ENODATA || op_errno == EOPNOTSUPP) { + /* This subvol does not have the optimization. + * Better let the user know we don't support it. + * Remove previous results if any. + */ + + if (local->xattr) { + dict_unref (local->xattr); + local->xattr = NULL; + } + + if (local->xattr_req) { + dict_unref (local->xattr_req); + local->xattr_req = NULL; + } + + local->op_ret = op_ret; + local->op_errno = op_errno; + gf_log (this->name, GF_LOG_WARNING, "At least " + "one of the bricks does not support " + "this operation. Please upgrade all " + "bricks."); + goto unlock; + } + + if (op_errno == ENOENT) { + /* Do nothing, our defaults are set to this. + */ + goto unlock; + } + + /* This is a place holder for every other error + * case. I am not sure of how to interpret + * ENOTCONN etc. As of now, choosing to ignore + * down subvol and return a good result(if any) + * from other subvol. + */ + gf_log (this->name, GF_LOG_WARNING, + "Failed to get real filename. " + "error:%s", strerror (op_errno)); + goto unlock; + + } + + + /* This subvol has the required file. + * There could be other subvols which have returned + * success already, choosing to return the latest good + * result. + */ + if (local->xattr) + dict_unref (local->xattr); + local->xattr = dict_ref (xattr); + + if (local->xattr_req) { + dict_unref (local->xattr_req); + local->xattr_req = NULL; + } + if (xdata) + local->xattr_req = dict_ref (xdata); + + local->op_ret = op_ret; + local->op_errno = 0; + gf_log (this->name, GF_LOG_DEBUG, "Found a matching " + "file."); + } +unlock: + UNLOCK (&frame->lock); + this_call_cnt = dht_frame_return (frame); if (is_last_call (this_call_cnt)) { - DHT_STACK_UNWIND (getxattr, frame, local->op_ret, op_errno, - local->xattr, local->xattr_req); + DHT_STACK_UNWIND (getxattr, frame, local->op_ret, + local->op_errno, local->xattr, + local->xattr_req); } return 0; @@ -2715,7 +2789,7 @@ dht_getxattr_get_real_filename (call_frame_t *frame, xlator_t *this, cnt = local->call_cnt = layout->cnt; local->op_ret = -1; - local->op_errno = ENODATA; + local->op_errno = ENOENT; for (i = 0; i < cnt; i++) { subvol = layout->list[i].xlator; |