diff options
author | Niels de Vos <ndevos@redhat.com> | 2014-08-18 12:11:35 +0200 |
---|---|---|
committer | Niels de Vos <ndevos@redhat.com> | 2014-08-19 05:23:09 -0700 |
commit | 9b5231e5c98b8cfa116838287c7a14042702795f (patch) | |
tree | f3f2d212163eef5c9152ab45a26befb60c698ca5 | |
parent | 6630fff4812f4e8617336b98d8e3ac35976e5990 (diff) |
NFS: stripe-xlator should pass EOF at end of READDIR
NFS READDIR replies are made of a header, a sequence of
entries, and a EOF flag. When GlusterFS's NFS server is
used along with stripe xlator, it fails to set the EOF
flag, which violates NFS RFC and confuses some clients.
The bug is caused because nfs xlator sets EOF if it gets
op_errno set to ENOENT. That value is produced in storage
xlator and propagated through server, client, and other
xlators until stripe xlator handles it. stripe only passed
op_errno if op_ret < 0, which is not the case here. This
change set adds a special case for that situation to fix
the problem.
Change-Id: Ie6db94b0515292387cfb04c1e4a9363f34fcd19a
BUG: 1130969
Reported-by: Emmanuel Dreyfus <manu@netbsd.org>
Signed-off-by: Niels de Vos <ndevos@redhat.com>
Reviewed-on: http://review.gluster.org/8493
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Santosh Pradhan <spradhan@redhat.com>
Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
Reviewed-by: Emmanuel Dreyfus <manu@netbsd.org>
Tested-by: Emmanuel Dreyfus <manu@netbsd.org>
-rw-r--r-- | xlators/cluster/stripe/src/stripe.c | 19 |
1 files changed, 8 insertions, 11 deletions
diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c index dd7a58aa15a..20b889b35e1 100644 --- a/xlators/cluster/stripe/src/stripe.c +++ b/xlators/cluster/stripe/src/stripe.c @@ -4856,26 +4856,23 @@ stripe_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, LOCK (&frame->lock); { - if (op_ret == -1) { - gf_log (this->name, GF_LOG_WARNING, - "%s returned error %s", - prev->this->name, strerror (op_errno)); - local->op_errno = op_errno; - local->op_ret = op_ret; - goto unlock; - } else { - local->op_ret = op_ret; + local->op_errno = op_errno; + local->op_ret = op_ret; + + if (op_ret != -1) { list_splice_init (&orig_entries->list, &local->entries.list); local->wind_count = op_ret; } } -unlock: UNLOCK (&frame->lock); - if (op_ret == -1) + if (op_ret == -1) { + gf_log (this->name, GF_LOG_WARNING, "%s returned error %s", + prev->this->name, strerror (op_errno)); goto out; + } xattrs = dict_new (); if (xattrs) |