summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSakshi Bansal <sabansal@redhat.com>2016-03-31 15:02:03 +0530
committerNiels de Vos <ndevos@redhat.com>2016-04-07 01:39:48 -0700
commit50b93f72f9a3f5bfd1d610801aecb06823adaa63 (patch)
tree0879419553b733cd5330e7b36c1b66655bbb5226
parentecdcd519b9d7b50215072f47e00ce326d1242934 (diff)
NFS: new option nfs.rdirplus added
When this option is 'disabled', NFS falls back to standard readdir instead of readdirp Change-Id: Icaaf4da6533bee56160d4a81e42bb60f7d341945 BUG: 1302948 Signed-off-by: Sakshi Bansal <sabansal@redhat.com> Reviewed-on: http://review.gluster.org/13782 Smoke: Gluster Build System <jenkins@build.gluster.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Niels de Vos <ndevos@redhat.com>
-rw-r--r--libglusterfs/src/globals.h2
-rwxr-xr-xtests/bugs/nfs/bug-1302948.t13
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-set.c8
-rw-r--r--xlators/nfs/server/src/nfs.c17
-rw-r--r--xlators/nfs/server/src/nfs.h1
-rw-r--r--xlators/nfs/server/src/nfs3-helpers.c1
-rw-r--r--xlators/nfs/server/src/nfs3.c11
7 files changed, 52 insertions, 1 deletions
diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h
index 703a270cb40..8319c2a7333 100644
--- a/libglusterfs/src/globals.h
+++ b/libglusterfs/src/globals.h
@@ -64,6 +64,8 @@
#define GD_OP_VERSION_3_7_10 30710 /* Op-version for GlusterFS 3.7.10 */
+#define GD_OP_VERSION_3_7_12 30712 /* Op-version for GlusterFS 3.7.12 */
+
#define GD_OP_VERSION_4_0_0 40000 /* Op-version for GlusterFS 4.0.0 */
#define GD_OP_VER_PERSISTENT_AFR_XATTRS GD_OP_VERSION_3_6_0
diff --git a/tests/bugs/nfs/bug-1302948.t b/tests/bugs/nfs/bug-1302948.t
new file mode 100755
index 00000000000..a2fb0e68ff0
--- /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 db29881173e..9f97973b167 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
@@ -2230,6 +2230,14 @@ struct volopt_map_entry glusterd_volopt_map[] = {
.type = GLOBAL_DOC,
.op_version = 3
},
+ { .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 116854b9109..66bd69d2b4f 100644
--- a/xlators/nfs/server/src/nfs.c
+++ b/xlators/nfs/server/src/nfs.c
@@ -1073,6 +1073,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);
@@ -1285,6 +1288,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);
@@ -2081,6 +2092,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 82df163d494..9bcc88f5548 100644
--- a/xlators/nfs/server/src/nfs.h
+++ b/xlators/nfs/server/src/nfs.h
@@ -99,6 +99,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 cfa1ac64397..7eb491142f7 100644
--- a/xlators/nfs/server/src/nfs3-helpers.c
+++ b/xlators/nfs/server/src/nfs3-helpers.c
@@ -225,6 +225,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 e2650551814..8cf4db8174a 100644
--- a/xlators/nfs/server/src/nfs3.c
+++ b/xlators/nfs/server/src/nfs3.c
@@ -4444,6 +4444,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,
@@ -4458,6 +4460,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;
@@ -4471,7 +4480,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);