Skip to content

Commit 645102e

Browse files
committed
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
2 parents 32d43cd + 68ef3bc commit 645102e

File tree

1 file changed

+43
-19
lines changed

1 file changed

+43
-19
lines changed

fs/nfsd/nfs4state.c

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,35 @@ free_blocked_lock(struct nfsd4_blocked_lock *nbl)
268268
kfree(nbl);
269269
}
270270

271+
static void
272+
remove_blocked_locks(struct nfs4_lockowner *lo)
273+
{
274+
struct nfs4_client *clp = lo->lo_owner.so_client;
275+
struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
276+
struct nfsd4_blocked_lock *nbl;
277+
LIST_HEAD(reaplist);
278+
279+
/* Dequeue all blocked locks */
280+
spin_lock(&nn->blocked_locks_lock);
281+
while (!list_empty(&lo->lo_blocked)) {
282+
nbl = list_first_entry(&lo->lo_blocked,
283+
struct nfsd4_blocked_lock,
284+
nbl_list);
285+
list_del_init(&nbl->nbl_list);
286+
list_move(&nbl->nbl_lru, &reaplist);
287+
}
288+
spin_unlock(&nn->blocked_locks_lock);
289+
290+
/* Now free them */
291+
while (!list_empty(&reaplist)) {
292+
nbl = list_first_entry(&reaplist, struct nfsd4_blocked_lock,
293+
nbl_lru);
294+
list_del_init(&nbl->nbl_lru);
295+
posix_unblock_lock(&nbl->nbl_lock);
296+
free_blocked_lock(nbl);
297+
}
298+
}
299+
271300
static int
272301
nfsd4_cb_notify_lock_done(struct nfsd4_callback *cb, struct rpc_task *task)
273302
{
@@ -1866,6 +1895,7 @@ static __be32 mark_client_expired_locked(struct nfs4_client *clp)
18661895
static void
18671896
__destroy_client(struct nfs4_client *clp)
18681897
{
1898+
int i;
18691899
struct nfs4_openowner *oo;
18701900
struct nfs4_delegation *dp;
18711901
struct list_head reaplist;
@@ -1895,6 +1925,16 @@ __destroy_client(struct nfs4_client *clp)
18951925
nfs4_get_stateowner(&oo->oo_owner);
18961926
release_openowner(oo);
18971927
}
1928+
for (i = 0; i < OWNER_HASH_SIZE; i++) {
1929+
struct nfs4_stateowner *so, *tmp;
1930+
1931+
list_for_each_entry_safe(so, tmp, &clp->cl_ownerstr_hashtbl[i],
1932+
so_strhash) {
1933+
/* Should be no openowners at this point */
1934+
WARN_ON_ONCE(so->so_is_open_owner);
1935+
remove_blocked_locks(lockowner(so));
1936+
}
1937+
}
18981938
nfsd4_return_all_client_layouts(clp);
18991939
nfsd4_shutdown_callback(clp);
19001940
if (clp->cl_cb_conn.cb_xprt)
@@ -6355,6 +6395,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
63556395
}
63566396
spin_unlock(&clp->cl_lock);
63576397
free_ol_stateid_reaplist(&reaplist);
6398+
remove_blocked_locks(lo);
63586399
nfs4_put_stateowner(&lo->lo_owner);
63596400

63606401
return status;
@@ -7140,6 +7181,8 @@ nfs4_state_destroy_net(struct net *net)
71407181
}
71417182
}
71427183

7184+
WARN_ON(!list_empty(&nn->blocked_locks_lru));
7185+
71437186
for (i = 0; i < CLIENT_HASH_SIZE; i++) {
71447187
while (!list_empty(&nn->unconf_id_hashtbl[i])) {
71457188
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)
72067249
struct nfs4_delegation *dp = NULL;
72077250
struct list_head *pos, *next, reaplist;
72087251
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
7209-
struct nfsd4_blocked_lock *nbl;
72107252

72117253
cancel_delayed_work_sync(&nn->laundromat_work);
72127254
locks_end_grace(&nn->nfsd4_manager);
@@ -7227,24 +7269,6 @@ nfs4_state_shutdown_net(struct net *net)
72277269
nfs4_put_stid(&dp->dl_stid);
72287270
}
72297271

7230-
BUG_ON(!list_empty(&reaplist));
7231-
spin_lock(&nn->blocked_locks_lock);
7232-
while (!list_empty(&nn->blocked_locks_lru)) {
7233-
nbl = list_first_entry(&nn->blocked_locks_lru,
7234-
struct nfsd4_blocked_lock, nbl_lru);
7235-
list_move(&nbl->nbl_lru, &reaplist);
7236-
list_del_init(&nbl->nbl_list);
7237-
}
7238-
spin_unlock(&nn->blocked_locks_lock);
7239-
7240-
while (!list_empty(&reaplist)) {
7241-
nbl = list_first_entry(&reaplist,
7242-
struct nfsd4_blocked_lock, nbl_lru);
7243-
list_del_init(&nbl->nbl_lru);
7244-
posix_unblock_lock(&nbl->nbl_lock);
7245-
free_blocked_lock(nbl);
7246-
}
7247-
72487272
nfsd4_client_tracking_exit(net);
72497273
nfs4_state_destroy_net(net);
72507274
}

0 commit comments

Comments
 (0)