Commit 6411bd4a471893ab2af103d96253ba97c92d4777

Authored by Trond Myklebust
1 parent b0d3ded1a2

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

... ... @@ -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 /*