mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 19:51:31 -04:00
Merge branch 'for-3.3' of git://linux-nfs.org/~bfields/linux
* 'for-3.3' of git://linux-nfs.org/~bfields/linux: (31 commits) nfsd4: nfsd4_create_clid_dir return value is unused NFSD: Change name of extended attribute containing junction svcrpc: don't revert to SVC_POOL_DEFAULT on nfsd shutdown svcrpc: fix double-free on shutdown of nfsd after changing pool mode nfsd4: be forgiving in the absence of the recovery directory nfsd4: fix spurious 4.1 post-reboot failures NFSD: forget_delegations should use list_for_each_entry_safe NFSD: Only reinitilize the recall_lru list under the recall lock nfsd4: initialize special stateid's at compile time NFSd: use network-namespace-aware cache registering routines SUNRPC: create svc_xprt in proper network namespace svcrpc: update outdated BKL comment nfsd41: allow non-reclaim open-by-fh's in 4.1 svcrpc: avoid memory-corruption on pool shutdown svcrpc: destroy server sockets all at once svcrpc: make svc_delete_xprt static nfsd: Fix oops when parsing a 0 length export nfsd4: Use kmemdup rather than duplicating its implementation nfsd4: add a separate (lockowner, inode) lookup nfsd4: fix CONFIG_NFSD_FAULT_INJECTION compile error ...
This commit is contained in:
commit
0b48d42235
26 changed files with 624 additions and 169 deletions
|
|
@ -1641,6 +1641,7 @@ int cache_register_net(struct cache_detail *cd, struct net *net)
|
|||
sunrpc_destroy_cache_detail(cd);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cache_register_net);
|
||||
|
||||
int cache_register(struct cache_detail *cd)
|
||||
{
|
||||
|
|
@ -1653,6 +1654,7 @@ void cache_unregister_net(struct cache_detail *cd, struct net *net)
|
|||
remove_cache_proc_entries(cd, net);
|
||||
sunrpc_destroy_cache_detail(cd);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cache_unregister_net);
|
||||
|
||||
void cache_unregister(struct cache_detail *cd)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ svc_pool_map_alloc_arrays(struct svc_pool_map *m, unsigned int maxpools)
|
|||
|
||||
fail_free:
|
||||
kfree(m->to_pool);
|
||||
m->to_pool = NULL;
|
||||
fail:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
@ -285,9 +286,10 @@ svc_pool_map_put(void)
|
|||
mutex_lock(&svc_pool_map_mutex);
|
||||
|
||||
if (!--m->count) {
|
||||
m->mode = SVC_POOL_DEFAULT;
|
||||
kfree(m->to_pool);
|
||||
m->to_pool = NULL;
|
||||
kfree(m->pool_to);
|
||||
m->pool_to = NULL;
|
||||
m->npools = 0;
|
||||
}
|
||||
|
||||
|
|
@ -527,17 +529,20 @@ svc_destroy(struct svc_serv *serv)
|
|||
printk("svc_destroy: no threads for serv=%p!\n", serv);
|
||||
|
||||
del_timer_sync(&serv->sv_temptimer);
|
||||
|
||||
svc_close_all(&serv->sv_tempsocks);
|
||||
/*
|
||||
* The set of xprts (contained in the sv_tempsocks and
|
||||
* sv_permsocks lists) is now constant, since it is modified
|
||||
* only by accepting new sockets (done by service threads in
|
||||
* svc_recv) or aging old ones (done by sv_temptimer), or
|
||||
* configuration changes (excluded by whatever locking the
|
||||
* caller is using--nfsd_mutex in the case of nfsd). So it's
|
||||
* safe to traverse those lists and shut everything down:
|
||||
*/
|
||||
svc_close_all(serv);
|
||||
|
||||
if (serv->sv_shutdown)
|
||||
serv->sv_shutdown(serv);
|
||||
|
||||
svc_close_all(&serv->sv_permsocks);
|
||||
|
||||
BUG_ON(!list_empty(&serv->sv_permsocks));
|
||||
BUG_ON(!list_empty(&serv->sv_tempsocks));
|
||||
|
||||
cache_clean_deferred(serv);
|
||||
|
||||
if (svc_serv_is_pooled(serv))
|
||||
|
|
@ -683,8 +688,8 @@ found_pool:
|
|||
* Create or destroy enough new threads to make the number
|
||||
* of threads the given number. If `pool' is non-NULL, applies
|
||||
* only to threads in that pool, otherwise round-robins between
|
||||
* all pools. Must be called with a svc_get() reference and
|
||||
* the BKL or another lock to protect access to svc_serv fields.
|
||||
* all pools. Caller must ensure that mutual exclusion between this and
|
||||
* server startup or shutdown.
|
||||
*
|
||||
* Destroying threads relies on the service threads filling in
|
||||
* rqstp->rq_task, which only the nfs ones do. Assumes the serv
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt);
|
|||
static int svc_deferred_recv(struct svc_rqst *rqstp);
|
||||
static struct cache_deferred_req *svc_defer(struct cache_req *req);
|
||||
static void svc_age_temp_xprts(unsigned long closure);
|
||||
static void svc_delete_xprt(struct svc_xprt *xprt);
|
||||
|
||||
/* apparently the "standard" is that clients close
|
||||
* idle connections after 5 minutes, servers after
|
||||
|
|
@ -147,8 +148,8 @@ EXPORT_SYMBOL_GPL(svc_xprt_put);
|
|||
* Called by transport drivers to initialize the transport independent
|
||||
* portion of the transport instance.
|
||||
*/
|
||||
void svc_xprt_init(struct svc_xprt_class *xcl, struct svc_xprt *xprt,
|
||||
struct svc_serv *serv)
|
||||
void svc_xprt_init(struct net *net, struct svc_xprt_class *xcl,
|
||||
struct svc_xprt *xprt, struct svc_serv *serv)
|
||||
{
|
||||
memset(xprt, 0, sizeof(*xprt));
|
||||
xprt->xpt_class = xcl;
|
||||
|
|
@ -163,7 +164,7 @@ void svc_xprt_init(struct svc_xprt_class *xcl, struct svc_xprt *xprt,
|
|||
spin_lock_init(&xprt->xpt_lock);
|
||||
set_bit(XPT_BUSY, &xprt->xpt_flags);
|
||||
rpc_init_wait_queue(&xprt->xpt_bc_pending, "xpt_bc_pending");
|
||||
xprt->xpt_net = get_net(&init_net);
|
||||
xprt->xpt_net = get_net(net);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(svc_xprt_init);
|
||||
|
||||
|
|
@ -878,7 +879,7 @@ static void call_xpt_users(struct svc_xprt *xprt)
|
|||
/*
|
||||
* Remove a dead transport
|
||||
*/
|
||||
void svc_delete_xprt(struct svc_xprt *xprt)
|
||||
static void svc_delete_xprt(struct svc_xprt *xprt)
|
||||
{
|
||||
struct svc_serv *serv = xprt->xpt_server;
|
||||
struct svc_deferred_req *dr;
|
||||
|
|
@ -893,14 +894,7 @@ void svc_delete_xprt(struct svc_xprt *xprt)
|
|||
spin_lock_bh(&serv->sv_lock);
|
||||
if (!test_and_set_bit(XPT_DETACHED, &xprt->xpt_flags))
|
||||
list_del_init(&xprt->xpt_list);
|
||||
/*
|
||||
* The only time we're called while xpt_ready is still on a list
|
||||
* is while the list itself is about to be destroyed (in
|
||||
* svc_destroy). BUT svc_xprt_enqueue could still be attempting
|
||||
* to add new entries to the sp_sockets list, so we can't leave
|
||||
* a freed xprt on it.
|
||||
*/
|
||||
list_del_init(&xprt->xpt_ready);
|
||||
BUG_ON(!list_empty(&xprt->xpt_ready));
|
||||
if (test_bit(XPT_TEMP, &xprt->xpt_flags))
|
||||
serv->sv_tmpcnt--;
|
||||
spin_unlock_bh(&serv->sv_lock);
|
||||
|
|
@ -928,24 +922,50 @@ void svc_close_xprt(struct svc_xprt *xprt)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(svc_close_xprt);
|
||||
|
||||
void svc_close_all(struct list_head *xprt_list)
|
||||
static void svc_close_list(struct list_head *xprt_list)
|
||||
{
|
||||
struct svc_xprt *xprt;
|
||||
struct svc_xprt *tmp;
|
||||
|
||||
/*
|
||||
* The server is shutting down, and no more threads are running.
|
||||
* svc_xprt_enqueue() might still be running, but at worst it
|
||||
* will re-add the xprt to sp_sockets, which will soon get
|
||||
* freed. So we don't bother with any more locking, and don't
|
||||
* leave the close to the (nonexistent) server threads:
|
||||
*/
|
||||
list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) {
|
||||
list_for_each_entry(xprt, xprt_list, xpt_list) {
|
||||
set_bit(XPT_CLOSE, &xprt->xpt_flags);
|
||||
svc_delete_xprt(xprt);
|
||||
set_bit(XPT_BUSY, &xprt->xpt_flags);
|
||||
}
|
||||
}
|
||||
|
||||
void svc_close_all(struct svc_serv *serv)
|
||||
{
|
||||
struct svc_pool *pool;
|
||||
struct svc_xprt *xprt;
|
||||
struct svc_xprt *tmp;
|
||||
int i;
|
||||
|
||||
svc_close_list(&serv->sv_tempsocks);
|
||||
svc_close_list(&serv->sv_permsocks);
|
||||
|
||||
for (i = 0; i < serv->sv_nrpools; i++) {
|
||||
pool = &serv->sv_pools[i];
|
||||
|
||||
spin_lock_bh(&pool->sp_lock);
|
||||
while (!list_empty(&pool->sp_sockets)) {
|
||||
xprt = list_first_entry(&pool->sp_sockets, struct svc_xprt, xpt_ready);
|
||||
list_del_init(&xprt->xpt_ready);
|
||||
}
|
||||
spin_unlock_bh(&pool->sp_lock);
|
||||
}
|
||||
/*
|
||||
* At this point the sp_sockets lists will stay empty, since
|
||||
* svc_enqueue will not add new entries without taking the
|
||||
* sp_lock and checking XPT_BUSY.
|
||||
*/
|
||||
list_for_each_entry_safe(xprt, tmp, &serv->sv_tempsocks, xpt_list)
|
||||
svc_delete_xprt(xprt);
|
||||
list_for_each_entry_safe(xprt, tmp, &serv->sv_permsocks, xpt_list)
|
||||
svc_delete_xprt(xprt);
|
||||
|
||||
BUG_ON(!list_empty(&serv->sv_permsocks));
|
||||
BUG_ON(!list_empty(&serv->sv_tempsocks));
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle defer and revisit of requests
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -739,7 +739,8 @@ static void svc_udp_init(struct svc_sock *svsk, struct svc_serv *serv)
|
|||
{
|
||||
int err, level, optname, one = 1;
|
||||
|
||||
svc_xprt_init(&svc_udp_class, &svsk->sk_xprt, serv);
|
||||
svc_xprt_init(sock_net(svsk->sk_sock->sk), &svc_udp_class,
|
||||
&svsk->sk_xprt, serv);
|
||||
clear_bit(XPT_CACHE_AUTH, &svsk->sk_xprt.xpt_flags);
|
||||
svsk->sk_sk->sk_data_ready = svc_udp_data_ready;
|
||||
svsk->sk_sk->sk_write_space = svc_write_space;
|
||||
|
|
@ -1343,7 +1344,8 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)
|
|||
{
|
||||
struct sock *sk = svsk->sk_sk;
|
||||
|
||||
svc_xprt_init(&svc_tcp_class, &svsk->sk_xprt, serv);
|
||||
svc_xprt_init(sock_net(svsk->sk_sock->sk), &svc_tcp_class,
|
||||
&svsk->sk_xprt, serv);
|
||||
set_bit(XPT_CACHE_AUTH, &svsk->sk_xprt.xpt_flags);
|
||||
if (sk->sk_state == TCP_LISTEN) {
|
||||
dprintk("setting up TCP socket for listening\n");
|
||||
|
|
@ -1659,7 +1661,7 @@ static struct svc_xprt *svc_bc_create_socket(struct svc_serv *serv,
|
|||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
xprt = &svsk->sk_xprt;
|
||||
svc_xprt_init(&svc_tcp_bc_class, xprt, serv);
|
||||
svc_xprt_init(net, &svc_tcp_bc_class, xprt, serv);
|
||||
|
||||
serv->sv_bc_xprt = xprt;
|
||||
|
||||
|
|
|
|||
|
|
@ -453,7 +453,7 @@ static struct svcxprt_rdma *rdma_create_xprt(struct svc_serv *serv,
|
|||
|
||||
if (!cma_xprt)
|
||||
return NULL;
|
||||
svc_xprt_init(&svc_rdma_class, &cma_xprt->sc_xprt, serv);
|
||||
svc_xprt_init(&init_net, &svc_rdma_class, &cma_xprt->sc_xprt, serv);
|
||||
INIT_LIST_HEAD(&cma_xprt->sc_accept_q);
|
||||
INIT_LIST_HEAD(&cma_xprt->sc_dto_q);
|
||||
INIT_LIST_HEAD(&cma_xprt->sc_rq_dto_q);
|
||||
|
|
|
|||
Loading…
Reference in a new issue