forked from Minki/linux
Just one fix for an occasional panic from Jeff Layton.
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJasXu4AAoJECebzXlCjuG+fNcP/3QYZwLdIYe0pZSIn/9V6sW1 PwmxhTkBOEkeP4RTArI/4spZk3mrTqv7SC+ACYKbkD910uDC8cY3ElcwKxi82NL7 9M4gNGnscKJtUye2LhoamZZLOLDIzr302pEv0IIh3v11sAu0rK1K0bqHSfI1ga/q r3S1sRtad+UktVH+jJ8MNE4NBfXC/xTqPz6Z+wd30CPmJKaA7Oqle7Wd3479zj0c A7l+EtleFo/bctHwY7yp+lVs1Yqr3ShS+qu+YAknBTnGco9JJFJsZM6x33DFMZC4 EvFPO0gh4PuN/SkgT4zBvBlSXQjuqUWTU98ohqP7ugTtd0dXEIpR4DLLwWScA2KV z+YIJIKUh8Ryh8KI+J50Ed9WseVlmACHOBTJjLW7KnSYtey3+mgh5kp6Vcd9IxHc Gju7YgDK5FOV2JykaHQ/qCaSyL6ao1firapSrtZK4N27LpJ05FreK6qnLJtHmiwU pqVHyfrH4kfho1T0Nr/bw4bnugBKZVXBbBQLKp2twgJhYkUkP+vxV8QMX3h531hB jsQV9OIVPkdTjr5L0BmQMJ4GugM1Zr4mIunY6Mw0z5ax1JeBUelWeQccqL1YCSGL TZr+0N9yOuzQHX+e+mZ8vFYqfUTRF/Xfkn1+ZV3ZQU/yY8oBkDbQddaLoo1hjLUx 2dpR3xIhzyDkP59jrK4M =oGAf -----END PGP SIGNATURE----- Merge tag 'nfsd-4.16-1' of git://linux-nfs.org/~bfields/linux Pull nfsd fix from Bruce Fields: "Just one fix for an occasional panic from Jeff Layton" * tag 'nfsd-4.16-1' of git://linux-nfs.org/~bfields/linux: nfsd: remove blocked locks on client teardown
This commit is contained in:
commit
645102eac1
@ -268,6 +268,35 @@ free_blocked_lock(struct nfsd4_blocked_lock *nbl)
|
|||||||
kfree(nbl);
|
kfree(nbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
remove_blocked_locks(struct nfs4_lockowner *lo)
|
||||||
|
{
|
||||||
|
struct nfs4_client *clp = lo->lo_owner.so_client;
|
||||||
|
struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
|
||||||
|
struct nfsd4_blocked_lock *nbl;
|
||||||
|
LIST_HEAD(reaplist);
|
||||||
|
|
||||||
|
/* Dequeue all blocked locks */
|
||||||
|
spin_lock(&nn->blocked_locks_lock);
|
||||||
|
while (!list_empty(&lo->lo_blocked)) {
|
||||||
|
nbl = list_first_entry(&lo->lo_blocked,
|
||||||
|
struct nfsd4_blocked_lock,
|
||||||
|
nbl_list);
|
||||||
|
list_del_init(&nbl->nbl_list);
|
||||||
|
list_move(&nbl->nbl_lru, &reaplist);
|
||||||
|
}
|
||||||
|
spin_unlock(&nn->blocked_locks_lock);
|
||||||
|
|
||||||
|
/* Now free them */
|
||||||
|
while (!list_empty(&reaplist)) {
|
||||||
|
nbl = list_first_entry(&reaplist, struct nfsd4_blocked_lock,
|
||||||
|
nbl_lru);
|
||||||
|
list_del_init(&nbl->nbl_lru);
|
||||||
|
posix_unblock_lock(&nbl->nbl_lock);
|
||||||
|
free_blocked_lock(nbl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nfsd4_cb_notify_lock_done(struct nfsd4_callback *cb, struct rpc_task *task)
|
nfsd4_cb_notify_lock_done(struct nfsd4_callback *cb, struct rpc_task *task)
|
||||||
{
|
{
|
||||||
@ -1866,6 +1895,7 @@ static __be32 mark_client_expired_locked(struct nfs4_client *clp)
|
|||||||
static void
|
static void
|
||||||
__destroy_client(struct nfs4_client *clp)
|
__destroy_client(struct nfs4_client *clp)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
struct nfs4_openowner *oo;
|
struct nfs4_openowner *oo;
|
||||||
struct nfs4_delegation *dp;
|
struct nfs4_delegation *dp;
|
||||||
struct list_head reaplist;
|
struct list_head reaplist;
|
||||||
@ -1895,6 +1925,16 @@ __destroy_client(struct nfs4_client *clp)
|
|||||||
nfs4_get_stateowner(&oo->oo_owner);
|
nfs4_get_stateowner(&oo->oo_owner);
|
||||||
release_openowner(oo);
|
release_openowner(oo);
|
||||||
}
|
}
|
||||||
|
for (i = 0; i < OWNER_HASH_SIZE; i++) {
|
||||||
|
struct nfs4_stateowner *so, *tmp;
|
||||||
|
|
||||||
|
list_for_each_entry_safe(so, tmp, &clp->cl_ownerstr_hashtbl[i],
|
||||||
|
so_strhash) {
|
||||||
|
/* Should be no openowners at this point */
|
||||||
|
WARN_ON_ONCE(so->so_is_open_owner);
|
||||||
|
remove_blocked_locks(lockowner(so));
|
||||||
|
}
|
||||||
|
}
|
||||||
nfsd4_return_all_client_layouts(clp);
|
nfsd4_return_all_client_layouts(clp);
|
||||||
nfsd4_shutdown_callback(clp);
|
nfsd4_shutdown_callback(clp);
|
||||||
if (clp->cl_cb_conn.cb_xprt)
|
if (clp->cl_cb_conn.cb_xprt)
|
||||||
@ -6355,6 +6395,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
|
|||||||
}
|
}
|
||||||
spin_unlock(&clp->cl_lock);
|
spin_unlock(&clp->cl_lock);
|
||||||
free_ol_stateid_reaplist(&reaplist);
|
free_ol_stateid_reaplist(&reaplist);
|
||||||
|
remove_blocked_locks(lo);
|
||||||
nfs4_put_stateowner(&lo->lo_owner);
|
nfs4_put_stateowner(&lo->lo_owner);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@ -7140,6 +7181,8 @@ nfs4_state_destroy_net(struct net *net)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WARN_ON(!list_empty(&nn->blocked_locks_lru));
|
||||||
|
|
||||||
for (i = 0; i < CLIENT_HASH_SIZE; i++) {
|
for (i = 0; i < CLIENT_HASH_SIZE; i++) {
|
||||||
while (!list_empty(&nn->unconf_id_hashtbl[i])) {
|
while (!list_empty(&nn->unconf_id_hashtbl[i])) {
|
||||||
clp = list_entry(nn->unconf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
|
clp = list_entry(nn->unconf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
|
||||||
@ -7206,7 +7249,6 @@ nfs4_state_shutdown_net(struct net *net)
|
|||||||
struct nfs4_delegation *dp = NULL;
|
struct nfs4_delegation *dp = NULL;
|
||||||
struct list_head *pos, *next, reaplist;
|
struct list_head *pos, *next, reaplist;
|
||||||
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
|
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
|
||||||
struct nfsd4_blocked_lock *nbl;
|
|
||||||
|
|
||||||
cancel_delayed_work_sync(&nn->laundromat_work);
|
cancel_delayed_work_sync(&nn->laundromat_work);
|
||||||
locks_end_grace(&nn->nfsd4_manager);
|
locks_end_grace(&nn->nfsd4_manager);
|
||||||
@ -7227,24 +7269,6 @@ nfs4_state_shutdown_net(struct net *net)
|
|||||||
nfs4_put_stid(&dp->dl_stid);
|
nfs4_put_stid(&dp->dl_stid);
|
||||||
}
|
}
|
||||||
|
|
||||||
BUG_ON(!list_empty(&reaplist));
|
|
||||||
spin_lock(&nn->blocked_locks_lock);
|
|
||||||
while (!list_empty(&nn->blocked_locks_lru)) {
|
|
||||||
nbl = list_first_entry(&nn->blocked_locks_lru,
|
|
||||||
struct nfsd4_blocked_lock, nbl_lru);
|
|
||||||
list_move(&nbl->nbl_lru, &reaplist);
|
|
||||||
list_del_init(&nbl->nbl_list);
|
|
||||||
}
|
|
||||||
spin_unlock(&nn->blocked_locks_lock);
|
|
||||||
|
|
||||||
while (!list_empty(&reaplist)) {
|
|
||||||
nbl = list_first_entry(&reaplist,
|
|
||||||
struct nfsd4_blocked_lock, nbl_lru);
|
|
||||||
list_del_init(&nbl->nbl_lru);
|
|
||||||
posix_unblock_lock(&nbl->nbl_lock);
|
|
||||||
free_blocked_lock(nbl);
|
|
||||||
}
|
|
||||||
|
|
||||||
nfsd4_client_tracking_exit(net);
|
nfsd4_client_tracking_exit(net);
|
||||||
nfs4_state_destroy_net(net);
|
nfs4_state_destroy_net(net);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user