diff options
| -rwxr-xr-x | tests/bugs/nfs/bug-1302948.t | 13 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-set.c | 8 | ||||
| -rw-r--r-- | xlators/nfs/server/src/nfs.c | 17 | ||||
| -rw-r--r-- | xlators/nfs/server/src/nfs.h | 1 | ||||
| -rw-r--r-- | xlators/nfs/server/src/nfs3-helpers.c | 1 | ||||
| -rw-r--r-- | xlators/nfs/server/src/nfs3.c | 11 | 
6 files changed, 50 insertions, 1 deletions
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 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);  | 
