Blob Blame History Raw
From a7c5283c221ac4c0daff36f21c91eb8445317cbb Mon Sep 17 00:00:00 2001
From: Sakshi Bansal <sabansal@redhat.com>
Date: Thu, 31 Mar 2016 15:02:03 +0530
Subject: [PATCH 081/104] NFS: new option nfs.rdirplus added

When this option is 'disabled', NFS falls back to standard readdir instead
of readdirp

upstream master : http://review.gluster.org/#/c/13782/
release-3.7 : http://review.gluster.org/#/c/13916/

Change-Id: Icaaf4da6533bee56160d4a81e42bb60f7d341945
BUG: 1298724
Signed-off-by: Sakshi Bansal <sabansal@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/71623
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
Tested-by: Atin Mukherjee <amukherj@redhat.com>
---
 tests/bugs/nfs/bug-1302948.t                    |   13 +++++++++++++
 xlators/mgmt/glusterd/src/glusterd-volume-set.c |    8 ++++++++
 xlators/nfs/server/src/nfs.c                    |   17 +++++++++++++++++
 xlators/nfs/server/src/nfs.h                    |    1 +
 xlators/nfs/server/src/nfs3-helpers.c           |    1 +
 xlators/nfs/server/src/nfs3.c                   |   11 ++++++++++-
 6 files changed, 50 insertions(+), 1 deletions(-)
 create mode 100755 tests/bugs/nfs/bug-1302948.t

diff --git a/tests/bugs/nfs/bug-1302948.t b/tests/bugs/nfs/bug-1302948.t
new file mode 100755
index 0000000..a2fb0e6
--- /dev/null
+++ b/tests/bugs/nfs/bug-1302948.t
@@ -0,0 +1,13 @@
+#!/bin/bash
+# TEST the nfs.rdirplus option
+. $(dirname $0)/../../include.rc
+
+cleanup
+TEST glusterd
+TEST pidof glusterd
+
+TEST $CLI volume create $V0 $H0:$B0/$V0
+TEST $CLI volume start $V0
+TEST $CLI volume set $V0 nfs.rdirplus off
+TEST $CLI volume set $V0 nfs.rdirplus on
+cleanup
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
index 274248d..466e5cb 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
@@ -2208,6 +2208,14 @@ struct volopt_map_entry glusterd_volopt_map[] = {
           .type        = GLOBAL_DOC,
           .op_version  = 2
         },
+        { .key         = "nfs.rdirplus",
+          .voltype     = "nfs/server",
+          .option      = "nfs.rdirplus",
+          .type        = GLOBAL_DOC,
+          .op_version  = GD_OP_VERSION_3_7_12,
+          .description = "When this option is set to off NFS falls back to "
+                         "standard readdir instead of readdirp"
+        },
 
         /* Cli options for Export authentication on nfs mount */
         { .key         = "nfs.exports-auth-enable",
diff --git a/xlators/nfs/server/src/nfs.c b/xlators/nfs/server/src/nfs.c
index 8b4bc75..47b9309 100644
--- a/xlators/nfs/server/src/nfs.c
+++ b/xlators/nfs/server/src/nfs.c
@@ -1054,6 +1054,9 @@ nfs_init_state (xlator_t *this)
                         goto free_foppool;
                 }
         }
+
+        GF_OPTION_INIT ("nfs.rdirplus", nfs->rdirplus, bool, free_foppool);
+
 	GF_OPTION_INIT (OPT_SERVER_RPC_STATD, nfs->rpc_statd, path, free_foppool);
 
 	GF_OPTION_INIT (OPT_SERVER_RPC_STATD_PIDFILE, nfs->rpc_statd_pid_file, path, free_foppool);
@@ -1266,6 +1269,14 @@ nfs_reconfigure_state (xlator_t *this, dict_t *options)
                         OPT_SERVER_GID_CACHE_TIMEOUT, optuint32);
         }
 
+        GF_OPTION_RECONF ("nfs.rdirplus", optbool,
+                                          options, bool, out);
+        if (nfs->rdirplus != optbool) {
+                nfs->rdirplus = optbool;
+                gf_msg (GF_NFS, GF_LOG_INFO, 0, NFS_MSG_RECONFIG_VALUE,
+                        "Reconfigured nfs.rdirplus with value %d", optbool);
+        }
+
         /* reconfig nfs.dynamic-volumes */
         ret = dict_get_str_boolean (options, "nfs.dynamic-volumes",
                                              GF_NFS_DVM_OFF);
@@ -2061,6 +2072,12 @@ struct volume_options options[] = {
           .description = "Sets the TTL of an entry in the auth cache. Value is "
                          "in seconds."
         },
+        { .key  = {"nfs.rdirplus"},
+          .type = GF_OPTION_TYPE_BOOL,
+          .default_value = "on",
+          .description = "When this option is set to off NFS falls back to "
+                         "standard readdir instead of readdirp"
+        },
 
         { .key  = {NULL} },
 };
diff --git a/xlators/nfs/server/src/nfs.h b/xlators/nfs/server/src/nfs.h
index 15aec5d..85ad24a 100644
--- a/xlators/nfs/server/src/nfs.h
+++ b/xlators/nfs/server/src/nfs.h
@@ -104,6 +104,7 @@ struct nfs_state {
         gf_boolean_t            register_portmap;
         char                    *rpc_statd;
         char                    *rpc_statd_pid_file;
+        gf_boolean_t            rdirplus;
 };
 
 struct nfs_inode_ctx {
diff --git a/xlators/nfs/server/src/nfs3-helpers.c b/xlators/nfs/server/src/nfs3-helpers.c
index ed673a1..bf2594f 100644
--- a/xlators/nfs/server/src/nfs3-helpers.c
+++ b/xlators/nfs/server/src/nfs3-helpers.c
@@ -230,6 +230,7 @@ nfs3_errno_to_nfsstat3 (int errnum)
                 stat = NFS3ERR_SERVERFAULT;
                 break;
 
+        case ENOTSUP:
         case ENOSYS:
                 stat = NFS3ERR_NOTSUPP;
                 break;
diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c
index 267795b..4035491 100644
--- a/xlators/nfs/server/src/nfs3.c
+++ b/xlators/nfs/server/src/nfs3.c
@@ -4449,6 +4449,8 @@ nfs3_readdir (rpcsvc_request_t *req, struct nfs3_fh *fh, cookie3 cookie,
         int                     ret = -EFAULT;
         struct nfs3_state       *nfs3 = NULL;
         nfs3_call_state_t       *cs = NULL;
+        struct nfs_state        *nfs = NULL;
+        gf_boolean_t            is_readdirp = !!maxcount;
 
         if ((!req) || (!fh)) {
                 gf_msg (GF_NFS3, GF_LOG_ERROR, EINVAL, NFS_MSG_INVALID_ENTRY,
@@ -4463,6 +4465,13 @@ nfs3_readdir (rpcsvc_request_t *req, struct nfs3_fh *fh, cookie3 cookie,
         nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err);
         nfs3_volume_started_check (nfs3, vol, ret, out);
         nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
+        nfs = nfs_state (nfs3->nfsx);
+
+        if (is_readdirp && !nfs->rdirplus) {
+                ret = -ENOTSUP;
+                stat = nfs3_errno_to_nfsstat3 (-ret);
+                goto nfs3err;
+        }
 
         cs->cookieverf = cverf;
         cs->dircount = dircount;
@@ -4476,7 +4485,7 @@ nfs3_readdir (rpcsvc_request_t *req, struct nfs3_fh *fh, cookie3 cookie,
 
 nfs3err:
         if (ret < 0) {
-                if (maxcount == 0) {
+                if (!is_readdirp) {
                         nfs3_log_common_res (rpcsvc_request_xid (req),
                                              NFS3_READDIR, stat, -ret,
                                              cs ? cs->resolvedloc.path : NULL);
-- 
1.7.1