@@ -268,6 +268,35 @@ free_blocked_lock(struct nfsd4_blocked_lock *nbl)
268
268
kfree (nbl );
269
269
}
270
270
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
+
271
300
static int
272
301
nfsd4_cb_notify_lock_done (struct nfsd4_callback * cb , struct rpc_task * task )
273
302
{
@@ -1866,6 +1895,7 @@ static __be32 mark_client_expired_locked(struct nfs4_client *clp)
1866
1895
static void
1867
1896
__destroy_client (struct nfs4_client * clp )
1868
1897
{
1898
+ int i ;
1869
1899
struct nfs4_openowner * oo ;
1870
1900
struct nfs4_delegation * dp ;
1871
1901
struct list_head reaplist ;
@@ -1895,6 +1925,16 @@ __destroy_client(struct nfs4_client *clp)
1895
1925
nfs4_get_stateowner (& oo -> oo_owner );
1896
1926
release_openowner (oo );
1897
1927
}
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
+ }
1898
1938
nfsd4_return_all_client_layouts (clp );
1899
1939
nfsd4_shutdown_callback (clp );
1900
1940
if (clp -> cl_cb_conn .cb_xprt )
@@ -6355,6 +6395,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
6355
6395
}
6356
6396
spin_unlock (& clp -> cl_lock );
6357
6397
free_ol_stateid_reaplist (& reaplist );
6398
+ remove_blocked_locks (lo );
6358
6399
nfs4_put_stateowner (& lo -> lo_owner );
6359
6400
6360
6401
return status ;
@@ -7140,6 +7181,8 @@ nfs4_state_destroy_net(struct net *net)
7140
7181
}
7141
7182
}
7142
7183
7184
+ WARN_ON (!list_empty (& nn -> blocked_locks_lru ));
7185
+
7143
7186
for (i = 0 ; i < CLIENT_HASH_SIZE ; i ++ ) {
7144
7187
while (!list_empty (& nn -> unconf_id_hashtbl [i ])) {
7145
7188
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)
7206
7249
struct nfs4_delegation * dp = NULL ;
7207
7250
struct list_head * pos , * next , reaplist ;
7208
7251
struct nfsd_net * nn = net_generic (net , nfsd_net_id );
7209
- struct nfsd4_blocked_lock * nbl ;
7210
7252
7211
7253
cancel_delayed_work_sync (& nn -> laundromat_work );
7212
7254
locks_end_grace (& nn -> nfsd4_manager );
@@ -7227,24 +7269,6 @@ nfs4_state_shutdown_net(struct net *net)
7227
7269
nfs4_put_stid (& dp -> dl_stid );
7228
7270
}
7229
7271
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
-
7248
7272
nfsd4_client_tracking_exit (net );
7249
7273
nfs4_state_destroy_net (net );
7250
7274
}
0 commit comments