/* * Generic NLM call, async version. */ int nlmclnt_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback) { struct nlm_host *host = req->a_host; struct rpc_clnt *clnt; struct nlm_args *argp = &req->a_args; struct nlm_res *resp = &req->a_res; int status; dprintk("lockd: call procedure %s on %s (async)\n", nlm_procname(proc), host->h_name); /* If we have no RPC client yet, create one. */ if ((clnt = nlm_bind_host(host)) == NULL) return -ENOLCK; /* bootstrap and kick off the async RPC call */ status = rpc_do_call(clnt, proc, argp, resp, RPC_TASK_ASYNC, callback, req); /* If the async call is proceeding, increment host refcount */ if (status >= 0 && (req->a_flags & RPC_TASK_ASYNC)) host->h_count++; return status; }
static inline int nfs_readpage_async(struct dentry *dentry, struct inode *inode, struct page *page) { unsigned long address = page_address(page); struct nfs_rreq *req; int result = -1, flags; dprintk("NFS: nfs_readpage_async(%p)\n", page); if (NFS_CONGESTED(inode)) goto out_defer; /* N.B. Do we need to test? Never called for swapfile inode */ flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); req = (struct nfs_rreq *) rpc_allocate(flags, sizeof(*req)); if (!req) goto out_defer; /* Initialize request */ /* N.B. Will the dentry remain valid for life of request? */ nfs_readreq_setup(req, NFS_FH(dentry), page->offset, (void *) address, PAGE_SIZE); req->ra_inode = inode; req->ra_page = page; /* count has been incremented by caller */ /* Start the async call */ dprintk("NFS: executing async READ request.\n"); result = rpc_do_call(NFS_CLIENT(inode), NFSPROC_READ, &req->ra_args, &req->ra_res, flags, nfs_readpage_result, req); if (result < 0) goto out_free; result = 0; out: return result; out_defer: dprintk("NFS: deferring async READ request.\n"); goto out; out_free: dprintk("NFS: failed to enqueue async READ request.\n"); kfree(req); goto out; }