Commit 6411bd4a471893ab2af103d96253ba97c92d4777
1 parent
b0d3ded1a2
Exists in
master
and in
4 other branches
NFSv4: Clean up the asynchronous delegation return
Reuse the state management thread in order to return delegations when we get a callback. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Showing 1 changed file with 19 additions and 54 deletions Side-by-side Diff
fs/nfs/delegation.c
... | ... | @@ -321,6 +321,12 @@ |
321 | 321 | return err; |
322 | 322 | } |
323 | 323 | |
324 | +static void nfs_mark_return_delegation(struct nfs_client *clp, struct nfs_delegation *delegation) | |
325 | +{ | |
326 | + set_bit(NFS_DELEGATION_RETURN, &delegation->flags); | |
327 | + set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state); | |
328 | +} | |
329 | + | |
324 | 330 | /* |
325 | 331 | * Return all delegations associated to a super block |
326 | 332 | */ |
327 | 333 | |
328 | 334 | |
... | ... | @@ -376,66 +382,25 @@ |
376 | 382 | nfs_client_mark_return_all_delegations(clp); |
377 | 383 | } |
378 | 384 | |
379 | -struct recall_threadargs { | |
380 | - struct inode *inode; | |
381 | - struct nfs_client *clp; | |
382 | - const nfs4_stateid *stateid; | |
383 | - | |
384 | - struct completion started; | |
385 | - int result; | |
386 | -}; | |
387 | - | |
388 | -static int recall_thread(void *data) | |
389 | -{ | |
390 | - struct recall_threadargs *args = (struct recall_threadargs *)data; | |
391 | - struct inode *inode = igrab(args->inode); | |
392 | - struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; | |
393 | - struct nfs_inode *nfsi = NFS_I(inode); | |
394 | - struct nfs_delegation *delegation; | |
395 | - | |
396 | - daemonize("nfsv4-delegreturn"); | |
397 | - | |
398 | - nfs_msync_inode(inode); | |
399 | - down_write(&nfsi->rwsem); | |
400 | - spin_lock(&clp->cl_lock); | |
401 | - delegation = nfs_detach_delegation_locked(nfsi, args->stateid); | |
402 | - if (delegation != NULL) | |
403 | - args->result = 0; | |
404 | - else | |
405 | - args->result = -ENOENT; | |
406 | - spin_unlock(&clp->cl_lock); | |
407 | - complete(&args->started); | |
408 | - nfs_delegation_claim_opens(inode, args->stateid); | |
409 | - up_write(&nfsi->rwsem); | |
410 | - nfs_msync_inode(inode); | |
411 | - | |
412 | - if (delegation != NULL) | |
413 | - nfs_do_return_delegation(inode, delegation, 1); | |
414 | - iput(inode); | |
415 | - module_put_and_exit(0); | |
416 | -} | |
417 | - | |
418 | 385 | /* |
419 | 386 | * Asynchronous delegation recall! |
420 | 387 | */ |
421 | 388 | int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid) |
422 | 389 | { |
423 | - struct recall_threadargs data = { | |
424 | - .inode = inode, | |
425 | - .stateid = stateid, | |
426 | - }; | |
427 | - int status; | |
390 | + struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; | |
391 | + struct nfs_delegation *delegation; | |
428 | 392 | |
429 | - init_completion(&data.started); | |
430 | - __module_get(THIS_MODULE); | |
431 | - status = kernel_thread(recall_thread, &data, CLONE_KERNEL); | |
432 | - if (status < 0) | |
433 | - goto out_module_put; | |
434 | - wait_for_completion(&data.started); | |
435 | - return data.result; | |
436 | -out_module_put: | |
437 | - module_put(THIS_MODULE); | |
438 | - return status; | |
393 | + rcu_read_lock(); | |
394 | + delegation = rcu_dereference(NFS_I(inode)->delegation); | |
395 | + if (delegation == NULL || memcmp(delegation->stateid.data, stateid->data, | |
396 | + sizeof(delegation->stateid.data)) != 0) { | |
397 | + rcu_read_unlock(); | |
398 | + return -ENOENT; | |
399 | + } | |
400 | + nfs_mark_return_delegation(clp, delegation); | |
401 | + rcu_read_unlock(); | |
402 | + nfs_delegation_run_state_manager(clp); | |
403 | + return 0; | |
439 | 404 | } |
440 | 405 | |
441 | 406 | /* |