From bb5382208696196aead94c011b3f9fa13a04da68 Mon Sep 17 00:00:00 2001 From: Jeff Darcy Date: Mon, 3 Dec 2012 06:40:11 -0500 Subject: nfs: do opendir for "naked" readdirp to force self-heal checks Instead of an opendir, the first thing the Linux NFS client usually sends us is a readdirp at offset zero, effectively bypassing our self-heal checks. Detect this condition and issue our own opendir to compensate. Change-Id: I69463370abd6235d705bf80b8c77fae4a61096ae BUG: 830665 Signed-off-by: Jeff Darcy Reviewed-on: http://review.gluster.org/4067 Tested-by: Gluster Build System Reviewed-by: Anand Avati --- xlators/nfs/server/src/nfs3.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'xlators/nfs') diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c index 7c01d030..3a4ad4c0 100644 --- a/xlators/nfs/server/src/nfs3.c +++ b/xlators/nfs/server/src/nfs3.c @@ -4270,12 +4270,30 @@ nfs3err: } +int32_t +nfs3svc_readdir_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, fd_t *fd, + dict_t *xdata) +{ + /* + * We don't really need this, it's just an artifact of forcing the + * opendir to happen. + */ + if (fd) { + fd_unref(fd); + } + + return 0; +} + + int nfs3_readdir_open_resume (void *carg) { nfsstat3 stat = NFS3ERR_SERVERFAULT; int ret = -EFAULT; nfs3_call_state_t *cs = NULL; + nfs_user_t nfu = {0, }; if (!carg) return ret; @@ -4288,6 +4306,22 @@ nfs3_readdir_open_resume (void *carg) goto nfs3err; } + /* + * NFS client will usually send us a readdirp without an opendir, + * which would cause us to skip our usual self-heal checks which occur + * in opendir for native protocol. To make sure those checks do happen, + * our most reliable option is to do our own opendir for any readdirp + * at the beginning of the directory. + */ + if (cs->cookie == 0) { + nfs_request_user_init (&nfu, cs->req); + ret = nfs_opendir (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, + nfs3svc_readdir_opendir_cbk, cs); + if (ret < 0) { + gf_log (GF_NFS3, GF_LOG_ERROR, "auto-opendir failed"); + } + } + ret = nfs3_readdir_read_resume (cs); if (ret < 0) stat = nfs3_errno_to_nfsstat3 (-ret); -- cgit