/* * We received a GRANT_RES callback. Try to find the corresponding * block. */ void nlmsvc_grant_reply(u32 cookie, u32 status) { struct nlm_block *block; struct nlm_file *file; if (!(block = nlmsvc_find_block(cookie))) return; file = block->b_file; file->f_count++; down(&file->f_sema); if ((block = nlmsvc_find_block(cookie)) != NULL) { if (status == NLM_LCK_DENIED_GRACE_PERIOD) { /* Try again in a couple of seconds */ nlmsvc_insert_block(block, jiffies + 10 * HZ); block = NULL; } else { /* Lock is now held by client, or has been rejected. * In both cases, the block should be removed. */ file->f_count++; up(&file->f_sema); if (status == NLM_LCK_GRANTED) nlmsvc_delete_block(block, 0); else nlmsvc_delete_block(block, 1); } } if (!block) up(&file->f_sema); nlm_release_file(file); }
/* * We received a GRANT_RES callback. Try to find the corresponding * block. */ void nlmsvc_grant_reply(struct svc_rqst *rqstp, struct nlm_cookie *cookie, u32 status) { struct nlm_block *block; struct nlm_file *file; dprintk("grant_reply: looking for cookie %x, host (%08x), s=%d \n", *(unsigned int *)(cookie->data), ntohl(rqstp->rq_addr.sin_addr.s_addr), status); if (!(block = nlmsvc_find_block(cookie, &rqstp->rq_addr))) return; file = block->b_file; file->f_count++; down(&file->f_sema); if ((block = nlmsvc_find_block(cookie,&rqstp->rq_addr)) != NULL) { if (status == NLM_LCK_DENIED_GRACE_PERIOD) { /* Try again in a couple of seconds */ nlmsvc_insert_block(block, 10 * HZ); block = NULL; } else { /* Lock is now held by client, or has been rejected. * In both cases, the block should be removed. */ file->f_count++; up(&file->f_sema); if (status == NLM_LCK_GRANTED) nlmsvc_delete_block(block, 0); else nlmsvc_delete_block(block, 1); } } if (!block) up(&file->f_sema); nlm_release_file(file); }
/* * This is the callback from the RPC layer when the NLM_GRANTED_MSG * RPC call has succeeded or timed out. * Like all RPC callbacks, it is invoked by the rpciod process, so it * better not sleep. Therefore, we put the blocked lock on the nlm_blocked * chain once more in order to have it removed by lockd itself (which can * then sleep on the file semaphore without disrupting e.g. the nfs client). */ static void nlmsvc_grant_callback(struct rpc_task *task) { struct nlm_rqst *call = (struct nlm_rqst *) task->tk_calldata; struct nlm_block *block; unsigned long timeout; dprintk("lockd: GRANT_MSG RPC callback\n"); if (!(block = nlmsvc_find_block(call->a_args.cookie))) { dprintk("lockd: no block for cookie %x\n", call->a_args.cookie); return; } /* Technically, we should down the file semaphore here. Since we * move the block towards the head of the queue only, no harm * can be done, though. */ if (task->tk_status < 0) { /* RPC error: Re-insert for retransmission */ timeout = jiffies + 10 * HZ; } else if (block->b_done) { /* Block already removed, kill it for real */ timeout = 0; } else { /* Call was successful, now wait for client callback */ timeout = jiffies + 60 * HZ; } nlmsvc_insert_block(block, timeout); svc_wake_up(block->b_daemon); block->b_incall = 0; nlm_release_host(call->a_host); rpc_release_task(task); }
/* * This is the callback from the RPC layer when the NLM_GRANTED_MSG * RPC call has succeeded or timed out. * Like all RPC callbacks, it is invoked by the rpciod process, so it * better not sleep. Therefore, we put the blocked lock on the nlm_blocked * chain once more in order to have it removed by lockd itself (which can * then sleep on the file semaphore without disrupting e.g. the nfs client). */ static void nlmsvc_grant_callback(struct rpc_task *task) { struct nlm_rqst *call = (struct nlm_rqst *) task->tk_calldata; struct nlm_block *block; unsigned long timeout; struct sockaddr_in *peer_addr = RPC_PEERADDR(task->tk_client); dprintk("lockd: GRANT_MSG RPC callback\n"); dprintk("callback: looking for cookie %x, host (%08x)\n", *(unsigned int *)(call->a_args.cookie.data), ntohl(peer_addr->sin_addr.s_addr)); if (!(block = nlmsvc_find_block(&call->a_args.cookie, peer_addr))) { dprintk("lockd: no block for cookie %x, host (%08x)\n", *(u32 *)(call->a_args.cookie.data), ntohl(peer_addr->sin_addr.s_addr)); return; } /* Technically, we should down the file semaphore here. Since we * move the block towards the head of the queue only, no harm * can be done, though. */ if (task->tk_status < 0) { /* RPC error: Re-insert for retransmission */ timeout = 10 * HZ; } else if (block->b_done) { /* Block already removed, kill it for real */ timeout = 0; } else { /* Call was successful, now wait for client callback */ timeout = 60 * HZ; } nlmsvc_insert_block(block, timeout); svc_wake_up(block->b_daemon); block->b_incall = 0; nlm_release_host(call->a_host); }