Commit 4bf590e0 authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust

NFS: Add nfs_client behavior flags

"noresvport" and "discrtry" can be passed to nfs_create_rpc_client()
by setting flags in the passed-in nfs_client.  This change makes it
easy to add new flags.

Note that these settings are now "sticky" over the lifetime of a
struct nfs_client, and may even be copied when an nfs_client is
cloned.
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 8cab4c39
...@@ -131,6 +131,7 @@ const struct rpc_program nfsacl_program = { ...@@ -131,6 +131,7 @@ const struct rpc_program nfsacl_program = {
#endif /* CONFIG_NFS_V3_ACL */ #endif /* CONFIG_NFS_V3_ACL */
struct nfs_client_initdata { struct nfs_client_initdata {
unsigned long init_flags;
const char *hostname; const char *hostname;
const struct sockaddr *addr; const struct sockaddr *addr;
size_t addrlen; size_t addrlen;
...@@ -542,8 +543,7 @@ static struct nfs_client * ...@@ -542,8 +543,7 @@ static struct nfs_client *
nfs_get_client(const struct nfs_client_initdata *cl_init, nfs_get_client(const struct nfs_client_initdata *cl_init,
const struct rpc_timeout *timeparms, const struct rpc_timeout *timeparms,
const char *ip_addr, const char *ip_addr,
rpc_authflavor_t authflavour, rpc_authflavor_t authflavour)
int noresvport)
{ {
struct nfs_client *clp, *new = NULL; struct nfs_client *clp, *new = NULL;
struct nfs_net *nn = net_generic(cl_init->net, nfs_net_id); struct nfs_net *nn = net_generic(cl_init->net, nfs_net_id);
...@@ -565,9 +565,10 @@ nfs_get_client(const struct nfs_client_initdata *cl_init, ...@@ -565,9 +565,10 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
if (new) { if (new) {
list_add(&new->cl_share_link, &nn->nfs_client_list); list_add(&new->cl_share_link, &nn->nfs_client_list);
spin_unlock(&nn->nfs_client_lock); spin_unlock(&nn->nfs_client_lock);
new->cl_flags = cl_init->init_flags;
return cl_init->rpc_ops->init_client(new, return cl_init->rpc_ops->init_client(new,
timeparms, ip_addr, timeparms, ip_addr,
authflavour, noresvport); authflavour);
} }
spin_unlock(&nn->nfs_client_lock); spin_unlock(&nn->nfs_client_lock);
...@@ -651,8 +652,7 @@ static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, ...@@ -651,8 +652,7 @@ static void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
*/ */
static int nfs_create_rpc_client(struct nfs_client *clp, static int nfs_create_rpc_client(struct nfs_client *clp,
const struct rpc_timeout *timeparms, const struct rpc_timeout *timeparms,
rpc_authflavor_t flavor, rpc_authflavor_t flavor)
int discrtry, int noresvport)
{ {
struct rpc_clnt *clnt = NULL; struct rpc_clnt *clnt = NULL;
struct rpc_create_args args = { struct rpc_create_args args = {
...@@ -667,9 +667,9 @@ static int nfs_create_rpc_client(struct nfs_client *clp, ...@@ -667,9 +667,9 @@ static int nfs_create_rpc_client(struct nfs_client *clp,
.authflavor = flavor, .authflavor = flavor,
}; };
if (discrtry) if (test_bit(NFS_CS_DISCRTRY, &clp->cl_flags))
args.flags |= RPC_CLNT_CREATE_DISCRTRY; args.flags |= RPC_CLNT_CREATE_DISCRTRY;
if (noresvport) if (test_bit(NFS_CS_NORESVPORT, &clp->cl_flags))
args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
if (!IS_ERR(clp->cl_rpcclient)) if (!IS_ERR(clp->cl_rpcclient))
...@@ -809,14 +809,12 @@ static int nfs_init_server_rpcclient(struct nfs_server *server, ...@@ -809,14 +809,12 @@ static int nfs_init_server_rpcclient(struct nfs_server *server,
* @timeparms: timeout parameters for underlying RPC transport * @timeparms: timeout parameters for underlying RPC transport
* @ip_addr: IP presentation address (not used) * @ip_addr: IP presentation address (not used)
* @authflavor: authentication flavor for underlying RPC transport * @authflavor: authentication flavor for underlying RPC transport
* @noresvport: set if RPC transport can use an ephemeral source port
* *
* Returns pointer to an NFS client, or an ERR_PTR value. * Returns pointer to an NFS client, or an ERR_PTR value.
*/ */
struct nfs_client *nfs_init_client(struct nfs_client *clp, struct nfs_client *nfs_init_client(struct nfs_client *clp,
const struct rpc_timeout *timeparms, const struct rpc_timeout *timeparms,
const char *ip_addr, rpc_authflavor_t authflavour, const char *ip_addr, rpc_authflavor_t authflavour)
int noresvport)
{ {
int error; int error;
...@@ -830,8 +828,7 @@ struct nfs_client *nfs_init_client(struct nfs_client *clp, ...@@ -830,8 +828,7 @@ struct nfs_client *nfs_init_client(struct nfs_client *clp,
* Create a client RPC handle for doing FSSTAT with UNIX auth only * Create a client RPC handle for doing FSSTAT with UNIX auth only
* - RFC 2623, sec 2.3.2 * - RFC 2623, sec 2.3.2
*/ */
error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX, error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX);
0, noresvport);
if (error < 0) if (error < 0)
goto error; goto error;
nfs_mark_client_ready(clp, NFS_CS_READY); nfs_mark_client_ready(clp, NFS_CS_READY);
...@@ -881,10 +878,11 @@ static int nfs_init_server(struct nfs_server *server, ...@@ -881,10 +878,11 @@ static int nfs_init_server(struct nfs_server *server,
nfs_init_timeout_values(&timeparms, data->nfs_server.protocol, nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,
data->timeo, data->retrans); data->timeo, data->retrans);
if (data->flags & NFS_MOUNT_NORESVPORT)
set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
/* Allocate or find a client reference we can use */ /* Allocate or find a client reference we can use */
clp = nfs_get_client(&cl_init, &timeparms, NULL, RPC_AUTH_UNIX, clp = nfs_get_client(&cl_init, &timeparms, NULL, RPC_AUTH_UNIX);
data->flags & NFS_MOUNT_NORESVPORT);
if (IS_ERR(clp)) { if (IS_ERR(clp)) {
dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp)); dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp));
return PTR_ERR(clp); return PTR_ERR(clp);
...@@ -1364,15 +1362,13 @@ static int nfs4_init_client_minor_version(struct nfs_client *clp) ...@@ -1364,15 +1362,13 @@ static int nfs4_init_client_minor_version(struct nfs_client *clp)
* @timeparms: timeout parameters for underlying RPC transport * @timeparms: timeout parameters for underlying RPC transport
* @ip_addr: callback IP address in presentation format * @ip_addr: callback IP address in presentation format
* @authflavor: authentication flavor for underlying RPC transport * @authflavor: authentication flavor for underlying RPC transport
* @noresvport: set if RPC transport can use an ephemeral source port
* *
* Returns pointer to an NFS client, or an ERR_PTR value. * Returns pointer to an NFS client, or an ERR_PTR value.
*/ */
struct nfs_client *nfs4_init_client(struct nfs_client *clp, struct nfs_client *nfs4_init_client(struct nfs_client *clp,
const struct rpc_timeout *timeparms, const struct rpc_timeout *timeparms,
const char *ip_addr, const char *ip_addr,
rpc_authflavor_t authflavour, rpc_authflavor_t authflavour)
int noresvport)
{ {
char buf[INET6_ADDRSTRLEN + 1]; char buf[INET6_ADDRSTRLEN + 1];
int error; int error;
...@@ -1386,8 +1382,8 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp, ...@@ -1386,8 +1382,8 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp,
/* Check NFS protocol revision and initialize RPC op vector */ /* Check NFS protocol revision and initialize RPC op vector */
clp->rpc_ops = &nfs_v4_clientops; clp->rpc_ops = &nfs_v4_clientops;
error = nfs_create_rpc_client(clp, timeparms, authflavour, __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags);
1, noresvport); error = nfs_create_rpc_client(clp, timeparms, authflavour);
if (error < 0) if (error < 0)
goto error; goto error;
...@@ -1455,9 +1451,11 @@ static int nfs4_set_client(struct nfs_server *server, ...@@ -1455,9 +1451,11 @@ static int nfs4_set_client(struct nfs_server *server,
dprintk("--> nfs4_set_client()\n"); dprintk("--> nfs4_set_client()\n");
if (server->flags & NFS_MOUNT_NORESVPORT)
set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
/* Allocate or find a client reference we can use */ /* Allocate or find a client reference we can use */
clp = nfs_get_client(&cl_init, timeparms, ip_addr, authflavour, clp = nfs_get_client(&cl_init, timeparms, ip_addr, authflavour);
server->flags & NFS_MOUNT_NORESVPORT);
if (IS_ERR(clp)) { if (IS_ERR(clp)) {
error = PTR_ERR(clp); error = PTR_ERR(clp);
goto error; goto error;
...@@ -1512,7 +1510,7 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp, ...@@ -1512,7 +1510,7 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp,
*/ */
nfs_init_timeout_values(&ds_timeout, ds_proto, ds_timeo, ds_retrans); nfs_init_timeout_values(&ds_timeout, ds_proto, ds_timeo, ds_retrans);
clp = nfs_get_client(&cl_init, &ds_timeout, mds_clp->cl_ipaddr, clp = nfs_get_client(&cl_init, &ds_timeout, mds_clp->cl_ipaddr,
mds_clp->cl_rpcclient->cl_auth->au_flavor, 0); mds_clp->cl_rpcclient->cl_auth->au_flavor);
dprintk("<-- %s %p\n", __func__, clp); dprintk("<-- %s %p\n", __func__, clp);
return clp; return clp;
......
...@@ -240,8 +240,7 @@ extern int nfs4_init_ds_session(struct nfs_client *clp); ...@@ -240,8 +240,7 @@ extern int nfs4_init_ds_session(struct nfs_client *clp);
void nfs_close_context(struct nfs_open_context *ctx, int is_sync); void nfs_close_context(struct nfs_open_context *ctx, int is_sync);
extern struct nfs_client *nfs_init_client(struct nfs_client *clp, extern struct nfs_client *nfs_init_client(struct nfs_client *clp,
const struct rpc_timeout *timeparms, const struct rpc_timeout *timeparms,
const char *ip_addr, rpc_authflavor_t authflavour, const char *ip_addr, rpc_authflavor_t authflavour);
int noresvport);
/* dir.c */ /* dir.c */
extern int nfs_access_cache_shrinker(struct shrinker *shrink, extern int nfs_access_cache_shrinker(struct shrinker *shrink,
...@@ -376,8 +375,7 @@ extern void __nfs4_read_done_cb(struct nfs_read_data *); ...@@ -376,8 +375,7 @@ extern void __nfs4_read_done_cb(struct nfs_read_data *);
extern struct nfs_client *nfs4_init_client(struct nfs_client *clp, extern struct nfs_client *nfs4_init_client(struct nfs_client *clp,
const struct rpc_timeout *timeparms, const struct rpc_timeout *timeparms,
const char *ip_addr, const char *ip_addr,
rpc_authflavor_t authflavour, rpc_authflavor_t authflavour);
int noresvport);
extern int _nfs4_call_sync(struct rpc_clnt *clnt, extern int _nfs4_call_sync(struct rpc_clnt *clnt,
struct nfs_server *server, struct nfs_server *server,
struct rpc_message *msg, struct rpc_message *msg,
......
...@@ -35,6 +35,9 @@ struct nfs_client { ...@@ -35,6 +35,9 @@ struct nfs_client {
#define NFS_CS_RENEWD 3 /* - renewd started */ #define NFS_CS_RENEWD 3 /* - renewd started */
#define NFS_CS_STOP_RENEW 4 /* no more state to renew */ #define NFS_CS_STOP_RENEW 4 /* no more state to renew */
#define NFS_CS_CHECK_LEASE_TIME 5 /* need to check lease time */ #define NFS_CS_CHECK_LEASE_TIME 5 /* need to check lease time */
unsigned long cl_flags; /* behavior switches */
#define NFS_CS_NORESVPORT 0 /* - use ephemeral src port */
#define NFS_CS_DISCRTRY 1 /* - disconnect on RPC retry */
struct sockaddr_storage cl_addr; /* server identifier */ struct sockaddr_storage cl_addr; /* server identifier */
size_t cl_addrlen; size_t cl_addrlen;
char * cl_hostname; /* hostname of server */ char * cl_hostname; /* hostname of server */
......
...@@ -1399,7 +1399,7 @@ struct nfs_rpc_ops { ...@@ -1399,7 +1399,7 @@ struct nfs_rpc_ops {
struct iattr *iattr); struct iattr *iattr);
struct nfs_client * struct nfs_client *
(*init_client) (struct nfs_client *, const struct rpc_timeout *, (*init_client) (struct nfs_client *, const struct rpc_timeout *,
const char *, rpc_authflavor_t, int); const char *, rpc_authflavor_t);
}; };
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment