Merge branch 'nfs-for-3.2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
* 'nfs-for-3.2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (25 commits) nfs: set vs_hidden on nfs4_callback_version4 (try #2) pnfs-obj: Support for RAID5 read-4-write interface. pnfs-obj: move to ore 03: Remove old raid engine pnfs-obj: move to ore 02: move to ORE pnfs-obj: move to ore 01: ore_layout & ore_components pnfs-obj: Rename objlayout_io_state => objlayout_io_res pnfs-obj: Get rid of objlayout_{alloc,free}_io_state pnfs-obj: Return PNFS_NOT_ATTEMPTED in case of read/write_pagelist pnfs-obj: Remove redundant EOF from objlayout_io_state nfs: Remove unused variable from write.c nfs: Fix unused variable warning from file.c NFS: Remove no-op less-than-zero checks on unsigned variables. NFS: Clean up nfs4_xdr_dec_secinfo() NFS: Fix documenting comment for nfs_create_request() NFS4: fix cb_recallany decode error nfs4: serialize layoutcommit SUNRPC: remove rpcbind clients destruction on module cleanup SUNRPC: remove rpcbind clients creation during service registering NFSd: call svc rpcbind cleanup explicitly SUNRPC: cleanup service destruction ...
This commit is contained in:
@@ -129,6 +129,9 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
|
||||
for (i = 0; i < groups ; i++)
|
||||
if (cred->uc_gids[i] != GROUP_AT(acred->group_info, i))
|
||||
return 0;
|
||||
if (groups < NFS_NGROUPS &&
|
||||
cred->uc_gids[groups] != NOGROUP)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -114,6 +114,9 @@ static struct rpc_program rpcb_program;
|
||||
static struct rpc_clnt * rpcb_local_clnt;
|
||||
static struct rpc_clnt * rpcb_local_clnt4;
|
||||
|
||||
DEFINE_SPINLOCK(rpcb_clnt_lock);
|
||||
unsigned int rpcb_users;
|
||||
|
||||
struct rpcbind_args {
|
||||
struct rpc_xprt * r_xprt;
|
||||
|
||||
@@ -161,6 +164,56 @@ static void rpcb_map_release(void *data)
|
||||
kfree(map);
|
||||
}
|
||||
|
||||
static int rpcb_get_local(void)
|
||||
{
|
||||
int cnt;
|
||||
|
||||
spin_lock(&rpcb_clnt_lock);
|
||||
if (rpcb_users)
|
||||
rpcb_users++;
|
||||
cnt = rpcb_users;
|
||||
spin_unlock(&rpcb_clnt_lock);
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
void rpcb_put_local(void)
|
||||
{
|
||||
struct rpc_clnt *clnt = rpcb_local_clnt;
|
||||
struct rpc_clnt *clnt4 = rpcb_local_clnt4;
|
||||
int shutdown;
|
||||
|
||||
spin_lock(&rpcb_clnt_lock);
|
||||
if (--rpcb_users == 0) {
|
||||
rpcb_local_clnt = NULL;
|
||||
rpcb_local_clnt4 = NULL;
|
||||
}
|
||||
shutdown = !rpcb_users;
|
||||
spin_unlock(&rpcb_clnt_lock);
|
||||
|
||||
if (shutdown) {
|
||||
/*
|
||||
* cleanup_rpcb_clnt - remove xprtsock's sysctls, unregister
|
||||
*/
|
||||
if (clnt4)
|
||||
rpc_shutdown_client(clnt4);
|
||||
if (clnt)
|
||||
rpc_shutdown_client(clnt);
|
||||
}
|
||||
}
|
||||
|
||||
static void rpcb_set_local(struct rpc_clnt *clnt, struct rpc_clnt *clnt4)
|
||||
{
|
||||
/* Protected by rpcb_create_local_mutex */
|
||||
rpcb_local_clnt = clnt;
|
||||
rpcb_local_clnt4 = clnt4;
|
||||
smp_wmb();
|
||||
rpcb_users = 1;
|
||||
dprintk("RPC: created new rpcb local clients (rpcb_local_clnt: "
|
||||
"%p, rpcb_local_clnt4: %p)\n", rpcb_local_clnt,
|
||||
rpcb_local_clnt4);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns zero on success, otherwise a negative errno value
|
||||
* is returned.
|
||||
@@ -205,9 +258,7 @@ static int rpcb_create_local_unix(void)
|
||||
clnt4 = NULL;
|
||||
}
|
||||
|
||||
/* Protected by rpcb_create_local_mutex */
|
||||
rpcb_local_clnt = clnt;
|
||||
rpcb_local_clnt4 = clnt4;
|
||||
rpcb_set_local(clnt, clnt4);
|
||||
|
||||
out:
|
||||
return result;
|
||||
@@ -259,9 +310,7 @@ static int rpcb_create_local_net(void)
|
||||
clnt4 = NULL;
|
||||
}
|
||||
|
||||
/* Protected by rpcb_create_local_mutex */
|
||||
rpcb_local_clnt = clnt;
|
||||
rpcb_local_clnt4 = clnt4;
|
||||
rpcb_set_local(clnt, clnt4);
|
||||
|
||||
out:
|
||||
return result;
|
||||
@@ -271,16 +320,16 @@ out:
|
||||
* Returns zero on success, otherwise a negative errno value
|
||||
* is returned.
|
||||
*/
|
||||
static int rpcb_create_local(void)
|
||||
int rpcb_create_local(void)
|
||||
{
|
||||
static DEFINE_MUTEX(rpcb_create_local_mutex);
|
||||
int result = 0;
|
||||
|
||||
if (rpcb_local_clnt)
|
||||
if (rpcb_get_local())
|
||||
return result;
|
||||
|
||||
mutex_lock(&rpcb_create_local_mutex);
|
||||
if (rpcb_local_clnt)
|
||||
if (rpcb_get_local())
|
||||
goto out;
|
||||
|
||||
if (rpcb_create_local_unix() != 0)
|
||||
@@ -382,11 +431,6 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
|
||||
struct rpc_message msg = {
|
||||
.rpc_argp = &map,
|
||||
};
|
||||
int error;
|
||||
|
||||
error = rpcb_create_local();
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
dprintk("RPC: %sregistering (%u, %u, %d, %u) with local "
|
||||
"rpcbind\n", (port ? "" : "un"),
|
||||
@@ -522,11 +566,7 @@ int rpcb_v4_register(const u32 program, const u32 version,
|
||||
struct rpc_message msg = {
|
||||
.rpc_argp = &map,
|
||||
};
|
||||
int error;
|
||||
|
||||
error = rpcb_create_local();
|
||||
if (error)
|
||||
return error;
|
||||
if (rpcb_local_clnt4 == NULL)
|
||||
return -EPROTONOSUPPORT;
|
||||
|
||||
@@ -1060,15 +1100,3 @@ static struct rpc_program rpcb_program = {
|
||||
.version = rpcb_version,
|
||||
.stats = &rpcb_stats,
|
||||
};
|
||||
|
||||
/**
|
||||
* cleanup_rpcb_clnt - remove xprtsock's sysctls, unregister
|
||||
*
|
||||
*/
|
||||
void cleanup_rpcb_clnt(void)
|
||||
{
|
||||
if (rpcb_local_clnt4)
|
||||
rpc_shutdown_client(rpcb_local_clnt4);
|
||||
if (rpcb_local_clnt)
|
||||
rpc_shutdown_client(rpcb_local_clnt);
|
||||
}
|
||||
|
||||
@@ -61,8 +61,6 @@ static struct pernet_operations sunrpc_net_ops = {
|
||||
|
||||
extern struct cache_detail unix_gid_cache;
|
||||
|
||||
extern void cleanup_rpcb_clnt(void);
|
||||
|
||||
static int __init
|
||||
init_sunrpc(void)
|
||||
{
|
||||
@@ -102,7 +100,6 @@ out:
|
||||
static void __exit
|
||||
cleanup_sunrpc(void)
|
||||
{
|
||||
cleanup_rpcb_clnt();
|
||||
rpcauth_remove_module();
|
||||
cleanup_socket_xprt();
|
||||
svc_cleanup_xprt_sock();
|
||||
|
||||
@@ -366,6 +366,42 @@ svc_pool_for_cpu(struct svc_serv *serv, int cpu)
|
||||
return &serv->sv_pools[pidx % serv->sv_nrpools];
|
||||
}
|
||||
|
||||
static int svc_rpcb_setup(struct svc_serv *serv)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = rpcb_create_local();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Remove any stale portmap registrations */
|
||||
svc_unregister(serv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void svc_rpcb_cleanup(struct svc_serv *serv)
|
||||
{
|
||||
svc_unregister(serv);
|
||||
rpcb_put_local();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(svc_rpcb_cleanup);
|
||||
|
||||
static int svc_uses_rpcbind(struct svc_serv *serv)
|
||||
{
|
||||
struct svc_program *progp;
|
||||
unsigned int i;
|
||||
|
||||
for (progp = serv->sv_program; progp; progp = progp->pg_next) {
|
||||
for (i = 0; i < progp->pg_nvers; i++) {
|
||||
if (progp->pg_vers[i] == NULL)
|
||||
continue;
|
||||
if (progp->pg_vers[i]->vs_hidden == 0)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an RPC service
|
||||
@@ -431,8 +467,15 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
|
||||
spin_lock_init(&pool->sp_lock);
|
||||
}
|
||||
|
||||
/* Remove any stale portmap registrations */
|
||||
svc_unregister(serv);
|
||||
if (svc_uses_rpcbind(serv)) {
|
||||
if (svc_rpcb_setup(serv) < 0) {
|
||||
kfree(serv->sv_pools);
|
||||
kfree(serv);
|
||||
return NULL;
|
||||
}
|
||||
if (!serv->sv_shutdown)
|
||||
serv->sv_shutdown = svc_rpcb_cleanup;
|
||||
}
|
||||
|
||||
return serv;
|
||||
}
|
||||
@@ -500,7 +543,6 @@ svc_destroy(struct svc_serv *serv)
|
||||
if (svc_serv_is_pooled(serv))
|
||||
svc_pool_map_put();
|
||||
|
||||
svc_unregister(serv);
|
||||
kfree(serv->sv_pools);
|
||||
kfree(serv);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user