int nlm4_Unlock(nfs_arg_t * parg /* IN */ , exportlist_t * pexport /* IN */ , fsal_op_context_t * pcontext /* IN */ , cache_inode_client_t * pclient /* INOUT */ , hash_table_t * ht /* INOUT */ , struct svc_req *preq /* IN */ , nfs_res_t * pres /* OUT */ ) { nlm4_unlockargs * arg = &parg->arg_nlm4_unlock; cache_entry_t * pentry; state_status_t state_status = CACHE_INODE_SUCCESS; char buffer[MAXNETOBJ_SZ * 2]; state_nsm_client_t * nsm_client; state_nlm_client_t * nlm_client; state_owner_t * nlm_owner; state_lock_desc_t lock; int rc; netobj_to_string(&arg->cookie, buffer, sizeof(buffer)); LogDebug(COMPONENT_NLM, "REQUEST PROCESSING: Calling nlm4_Unlock svid=%d off=%llx len=%llx cookie=%s", (int) arg->alock.svid, (unsigned long long) arg->alock.l_offset, (unsigned long long) arg->alock.l_len, buffer); if(!copy_netobj(&pres->res_nlm4test.cookie, &arg->cookie)) { pres->res_nlm4.stat.stat = NLM4_FAILED; LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Unlock %s", lock_result_str(pres->res_nlm4.stat.stat)); return NFS_REQ_OK; } if(in_nlm_grace_period()) { pres->res_nlm4.stat.stat = NLM4_DENIED_GRACE_PERIOD; LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Unlock %s", lock_result_str(pres->res_nlm4.stat.stat)); return NFS_REQ_OK; } rc = nlm_process_parameters(preq, FALSE, /* exlcusive doesn't matter */ &arg->alock, &lock, ht, &pentry, pcontext, pclient, CARE_NOT, /* unlock doesn't care if owner is found */ &nsm_client, &nlm_client, &nlm_owner, NULL); if(rc >= 0) { /* Present the error back to the client */ pres->res_nlm4.stat.stat = (nlm4_stats)rc; LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Unlock %s", lock_result_str(pres->res_nlm4.stat.stat)); return NFS_REQ_OK; } if(state_unlock(pentry, pcontext, nlm_owner, NULL, &lock, pclient, &state_status) != STATE_SUCCESS) { /* Unlock could fail in the FSAL and make a bit of a mess, especially if * we are in out of memory situation. Such an error is logged by * Cache Inode. */ pres->res_nlm4test.test_stat.stat = nlm_convert_state_error(state_status); } else { pres->res_nlm4.stat.stat = NLM4_GRANTED; } /* Release the NLM Client and NLM Owner references we have */ dec_nsm_client_ref(nsm_client); dec_nlm_client_ref(nlm_client); dec_state_owner_ref(nlm_owner, pclient); LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Unlock %s", lock_result_str(pres->res_nlm4.stat.stat)); return NFS_REQ_OK; }
int nlm4_Test(nfs_arg_t * parg /* IN */ , exportlist_t * pexport /* IN */ , fsal_op_context_t * pcontext /* IN */ , cache_inode_client_t * pclient /* INOUT */ , hash_table_t * ht /* INOUT */ , struct svc_req *preq /* IN */ , nfs_res_t * pres /* OUT */ ) { nlm4_testargs * arg = &parg->arg_nlm4_test; cache_entry_t * pentry; state_status_t state_status = CACHE_INODE_SUCCESS; char buffer[MAXNETOBJ_SZ * 2]; state_nlm_client_t * nlm_client; state_owner_t * nlm_owner, * holder; state_lock_desc_t lock, conflict; int rc; netobj_to_string(&arg->cookie, buffer, 1024); LogDebug(COMPONENT_NLM, "REQUEST PROCESSING: Calling nlm4_Test svid=%d off=%llx len=%llx cookie=%s", (int) arg->alock.svid, (unsigned long long) arg->alock.l_offset, (unsigned long long) arg->alock.l_len, buffer); if(!copy_netobj(&pres->res_nlm4test.cookie, &arg->cookie)) { pres->res_nlm4test.test_stat.stat = NLM4_FAILED; LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Test %s", lock_result_str(pres->res_nlm4.stat.stat)); return NFS_REQ_OK; } if(in_nlm_grace_period()) { pres->res_nlm4test.test_stat.stat = NLM4_DENIED_GRACE_PERIOD; LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Test %s", lock_result_str(pres->res_nlm4.stat.stat)); return NFS_REQ_OK; } /* TODO FSF: * * TEST passes TRUE for care because we do need a non-NULL owner, but * we could expand the options to allow for a "free" owner to be * returned, that doesn't need to be in the hash table, so if the * owner isn't found in the Hash table, don't add it, just return * the "free" owner. */ rc = nlm_process_parameters(preq, arg->exclusive, &arg->alock, &lock, ht, &pentry, pcontext, pclient, CARE_NO_MONITOR, &nlm_client, &nlm_owner, NULL); if(rc >= 0) { /* Present the error back to the client */ pres->res_nlm4.stat.stat = (nlm4_stats)rc; LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Unlock %s", lock_result_str(pres->res_nlm4.stat.stat)); return NFS_REQ_OK; } if(state_test(pentry, pcontext, nlm_owner, &lock, &holder, &conflict, pclient, &state_status) != STATE_SUCCESS) { pres->res_nlm4test.test_stat.stat = nlm_convert_state_error(state_status); if(state_status == STATE_LOCK_CONFLICT) { nlm_process_conflict(&pres->res_nlm4test.test_stat.nlm4_testrply_u.holder, holder, &conflict); } } else { pres->res_nlm4.stat.stat = NLM4_GRANTED; } LogFullDebug(COMPONENT_NLM, "Back from state_test"); /* Release the NLM Client and NLM Owner references we have */ dec_nlm_client_ref(nlm_client); dec_nlm_owner_ref(nlm_owner); LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Test %s", lock_result_str(pres->res_nlm4.stat.stat)); return NFS_REQ_OK; }
int nlm4_Lock(nfs_arg_t * parg /* IN */ , exportlist_t * pexport /* IN */ , fsal_op_context_t * pcontext /* IN */ , cache_inode_client_t * pclient /* INOUT */ , hash_table_t * ht /* INOUT */ , struct svc_req * preq /* IN */ , nfs_res_t * pres /* OUT */ ) { nlm4_lockargs * arg = &parg->arg_nlm4_lock; cache_entry_t * pentry; state_status_t state_status = CACHE_INODE_SUCCESS; char buffer[MAXNETOBJ_SZ * 2]; state_nsm_client_t * nsm_client; state_nlm_client_t * nlm_client; state_owner_t * nlm_owner, * holder; state_lock_desc_t lock, conflict; int rc; state_block_data_t * pblock_data; netobj_to_string(&arg->cookie, buffer, 1024); LogDebug(COMPONENT_NLM, "REQUEST PROCESSING: Calling nlm4_Lock svid=%d off=%llx len=%llx cookie=%s", (int) arg->alock.svid, (unsigned long long) arg->alock.l_offset, (unsigned long long) arg->alock.l_len, buffer); if(!copy_netobj(&pres->res_nlm4test.cookie, &arg->cookie)) { pres->res_nlm4.stat.stat = NLM4_FAILED; LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Test %s", lock_result_str(pres->res_nlm4.stat.stat)); return NFS_REQ_OK; } /* allow only reclaim lock request during recovery */ if(in_nlm_grace_period() && !arg->reclaim) { pres->res_nlm4.stat.stat = NLM4_DENIED_GRACE_PERIOD; LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Lock %s", lock_result_str(pres->res_nlm4.stat.stat)); return NFS_REQ_OK; } if(!in_nlm_grace_period() && arg->reclaim) { pres->res_nlm4.stat.stat = NLM4_DENIED_GRACE_PERIOD; LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Lock %s", lock_result_str(pres->res_nlm4.stat.stat)); return NFS_REQ_OK; } rc = nlm_process_parameters(preq, arg->exclusive, &arg->alock, &lock, ht, &pentry, pcontext, pclient, CARE_MONITOR, &nsm_client, &nlm_client, &nlm_owner, &pblock_data); if(rc >= 0) { /* Present the error back to the client */ pres->res_nlm4.stat.stat = (nlm4_stats)rc; LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Unlock %s", lock_result_str(pres->res_nlm4.stat.stat)); return NFS_REQ_OK; } /* Cast the state number into a state pointer to protect * locks from a client that has rebooted from the SM_NOTIFY * that will release old locks */ if(state_lock(pentry, pcontext, nlm_owner, (void *) (ptrdiff_t) arg->state, arg->block, pblock_data, &lock, &holder, &conflict, pclient, &state_status) != STATE_SUCCESS) { pres->res_nlm4test.test_stat.stat = nlm_convert_state_error(state_status); if(state_status == STATE_LOCK_CONFLICT) { nlm_process_conflict(&pres->res_nlm4test.test_stat.nlm4_testrply_u.holder, holder, &conflict, pclient); } /* If we didn't block, release the block data */ if(state_status != STATE_LOCK_BLOCKED && pblock_data != NULL) Mem_Free(pblock_data); } else { pres->res_nlm4.stat.stat = NLM4_GRANTED; } /* Release the NLM Client and NLM Owner references we have */ dec_nsm_client_ref(nsm_client); dec_nlm_client_ref(nlm_client); dec_state_owner_ref(nlm_owner, pclient); LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Lock %s", lock_result_str(pres->res_nlm4.stat.stat)); return NFS_REQ_OK; }
int nlm4_Unlock(nfs_arg_t *args, struct svc_req *req, nfs_res_t *res) { nlm4_unlockargs *arg = &args->arg_nlm4_unlock; struct fsal_obj_handle *obj; state_status_t state_status = STATE_SUCCESS; char buffer[MAXNETOBJ_SZ * 2] = "\0"; state_nsm_client_t *nsm_client; state_nlm_client_t *nlm_client; state_owner_t *nlm_owner; fsal_lock_param_t lock; int rc; state_t *state; /* NLM doesn't have a BADHANDLE error, nor can rpc_execute deal with * responding to an NLM_*_MSG call, so we check here if the export is * NULL and if so, handle the response. */ if (op_ctx->ctx_export == NULL) { res->res_nlm4.stat.stat = NLM4_STALE_FH; LogInfo(COMPONENT_NLM, "INVALID HANDLE: nlm4_Unlock"); return NFS_REQ_OK; } netobj_to_string(&arg->cookie, buffer, sizeof(buffer)); LogDebug(COMPONENT_NLM, "REQUEST PROCESSING: Calling nlm4_Unlock svid=%d off=%llx len=%llx cookie=%s", (int)arg->alock.svid, (unsigned long long)arg->alock.l_offset, (unsigned long long)arg->alock.l_len, buffer); copy_netobj(&res->res_nlm4test.cookie, &arg->cookie); if (nfs_in_grace()) { res->res_nlm4.stat.stat = NLM4_DENIED_GRACE_PERIOD; LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Unlock %s", lock_result_str(res->res_nlm4.stat.stat)); return NFS_REQ_OK; } /* unlock doesn't care if owner is found */ rc = nlm_process_parameters(req, false, &arg->alock, &lock, &obj, CARE_NOT, &nsm_client, &nlm_client, &nlm_owner, NULL, 0, &state); if (rc >= 0) { /* resent the error back to the client */ res->res_nlm4.stat.stat = (nlm4_stats) rc; LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Unlock %s", lock_result_str(res->res_nlm4.stat.stat)); return NFS_REQ_OK; } if (state != NULL) state_status = state_unlock(obj, state, nlm_owner, false, 0, &lock); if (state_status != STATE_SUCCESS) { /* Unlock could fail in the FSAL and make a bit of a mess, * especially if we are in out of memory situation. Such an * error is logged by Cache Inode. */ res->res_nlm4test.test_stat.stat = nlm_convert_state_error(state_status); } else { res->res_nlm4.stat.stat = NLM4_GRANTED; } /* Release the NLM Client and NLM Owner references we have */ if (state != NULL) dec_state_t_ref(state); dec_nsm_client_ref(nsm_client); dec_nlm_client_ref(nlm_client); dec_state_owner_ref(nlm_owner); obj->obj_ops.put_ref(obj); LogDebug(COMPONENT_NLM, "REQUEST RESULT: nlm4_Unlock %s", lock_result_str(res->res_nlm4.stat.stat)); return NFS_REQ_OK; }