From a47beb0dee2ab40b695fffcc46c650cc8ec34dc1 Mon Sep 17 00:00:00 2001 From: Sakshi Bansal Date: Thu, 31 Mar 2016 15:02:03 +0530 Subject: NFS: new option nfs.rdirplus added When this option is 'disabled', NFS falls back to standard readdir instead of readdirp Backport of http://review.gluster.org/#/c/13782/ > Change-Id: Icaaf4da6533bee56160d4a81e42bb60f7d341945 > BUG: 1302948 > Signed-off-by: Sakshi Bansal Change-Id: Icaaf4da6533bee56160d4a81e42bb60f7d341945 BUG: 1312721 Signed-off-by: Sakshi Bansal Reviewed-on: http://review.gluster.org/13916 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Niels de Vos --- 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 ++++++++++- 5 files changed, 37 insertions(+), 1 deletion(-) (limited to 'xlators') diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c index eac64008c9a..d15ee835a4e 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 = 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 8b4bc75ea00..47b9309db43 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 15aec5d7da9..85ad24ad07d 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 ed673a12489..bf2594f261d 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 267795b92c9..4035491359f 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); -- cgit