Skip to content

Commit b44ffa4

Browse files
committed
NFSD: Block DESTROY_CLIENTID only when there are ongoing async COPY operations
Currently __destroy_client() consults the nfs4_client's async_copies list to determine whether there are ongoing async COPY operations. However, NFSD now keeps copy state in that list even when the async copy has completed, to enable OFFLOAD_STATUS to find the COPY results for a while after the COPY has completed. DESTROY_CLIENTID should not be blocked if the client's async_copies list contains state for only completed copy operations. Reviewed-by: Jeff Layton <[email protected]> Signed-off-by: Chuck Lever <[email protected]>
1 parent 5c41f32 commit b44ffa4

File tree

3 files changed

+32
-1
lines changed

3 files changed

+32
-1
lines changed

fs/nfsd/nfs4proc.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,6 +1278,36 @@ nfsd4_clone(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
12781278
return status;
12791279
}
12801280

1281+
/**
1282+
* nfsd4_has_active_async_copies - Check for ongoing copy operations
1283+
* @clp: Client to be checked
1284+
*
1285+
* NFSD maintains state for async COPY operations after they complete,
1286+
* and this state remains in the nfs4_client's async_copies list.
1287+
* Ongoing copies should block the destruction of the nfs4_client, but
1288+
* completed copies should not.
1289+
*
1290+
* Return values:
1291+
* %true: At least one active async COPY is ongoing
1292+
* %false: No active async COPY operations were found
1293+
*/
1294+
bool nfsd4_has_active_async_copies(struct nfs4_client *clp)
1295+
{
1296+
struct nfsd4_copy *copy;
1297+
bool result = false;
1298+
1299+
spin_lock(&clp->async_lock);
1300+
list_for_each_entry(copy, &clp->async_copies, copies) {
1301+
if (!test_bit(NFSD4_COPY_F_COMPLETED, &copy->cp_flags) &&
1302+
!test_bit(NFSD4_COPY_F_STOPPED, &copy->cp_flags)) {
1303+
result = true;
1304+
break;
1305+
}
1306+
}
1307+
spin_unlock(&clp->async_lock);
1308+
return result;
1309+
}
1310+
12811311
static void nfs4_put_copy(struct nfsd4_copy *copy)
12821312
{
12831313
if (!refcount_dec_and_test(&copy->refcount))

fs/nfsd/nfs4state.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3472,7 +3472,7 @@ static bool client_has_state(struct nfs4_client *clp)
34723472
#endif
34733473
|| !list_empty(&clp->cl_delegations)
34743474
|| !list_empty(&clp->cl_sessions)
3475-
|| !list_empty(&clp->async_copies);
3475+
|| nfsd4_has_active_async_copies(clp);
34763476
}
34773477

34783478
static __be32 copy_impl_id(struct nfs4_client *clp,

fs/nfsd/state.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,7 @@ extern void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp,
738738
extern bool nfsd4_run_cb(struct nfsd4_callback *cb);
739739
extern void nfsd4_shutdown_callback(struct nfs4_client *);
740740
extern void nfsd4_shutdown_copy(struct nfs4_client *clp);
741+
bool nfsd4_has_active_async_copies(struct nfs4_client *clp);
741742
extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(struct xdr_netobj name,
742743
struct xdr_netobj princhash, struct nfsd_net *nn);
743744
extern bool nfs4_has_reclaimed_state(struct xdr_netobj name, struct nfsd_net *nn);

0 commit comments

Comments
 (0)