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; cache_entry_t *pentry; fsal_attrib_list_t attr; nlm_lock_entry_t *nlm_entry; cache_inode_status_t cache_status; cache_inode_fsal_data_t fsal_data; LogFullDebug(COMPONENT_NFSPROTO, "REQUEST PROCESSING: Calling nlm_Test"); if(in_nlm_grace_period()) { pres->res_nlm4test.test_stat.stat = NLM4_DENIED_GRACE_PERIOD; return NFS_REQ_OK; } /* Convert file handle into a cache entry */ arg = &parg->arg_nlm4_test; if(!nfs3_FhandleToFSAL((nfs_fh3 *) & (arg->alock.fh), &fsal_data.handle, pcontext)) { /* handle is not valid */ pres->res_nlm4test.test_stat.stat = NLM4_STALE_FH; /* * Should we do a REQ_OK so that the client get * a response ? FIXME!! */ return NFS_REQ_DROP; } /* Now get the cached inode attributes */ fsal_data.cookie = DIR_START; if((pentry = cache_inode_get(&fsal_data, &attr, ht, pclient, pcontext, &cache_status)) == NULL) { /* handle is not valid */ pres->res_nlm4test.test_stat.stat = NLM4_STALE_FH; return NFS_REQ_OK; } nlm_entry = nlm_overlapping_entry(&(arg->alock), arg->exclusive); if(!nlm_entry) { pres->res_nlm4test.test_stat.stat = NLM4_GRANTED; } else { pres->res_nlm4test.test_stat.stat = NLM4_DENIED; nlm_lock_entry_to_nlm_holder(nlm_entry, &pres->res_nlm4test.test_stat.nlm4_testrply_u.holder); nlm_lock_entry_dec_ref(nlm_entry); } return NFS_REQ_OK; }
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_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 */ ) { int lck_cnt, lck_state; nlm4_unlockargs *arg; cache_entry_t *pentry; fsal_attrib_list_t attr; nlm_lock_entry_t *nlm_entry; cache_inode_status_t cache_status; cache_inode_fsal_data_t fsal_data; LogFullDebug(COMPONENT_NFSPROTO, "REQUEST PROCESSING: Calling nlm4_Lock"); if(in_nlm_grace_period()) { pres->res_nlm4test.test_stat.stat = NLM4_DENIED_GRACE_PERIOD; return NFS_REQ_OK; } /* Convert file handle into a cache entry */ arg = &parg->arg_nlm4_unlock; if(!nfs3_FhandleToFSAL((nfs_fh3 *) & (arg->alock.fh), &fsal_data.handle, pcontext)) { /* handle is not valid */ pres->res_nlm4.stat.stat = NLM4_STALE_FH; /* * Should we do a REQ_OK so that the client get * a response ? FIXME!! */ return NFS_REQ_DROP; } /* Now get the cached inode attributes */ fsal_data.cookie = DIR_START; if((pentry = cache_inode_get(&fsal_data, &attr, ht, pclient, pcontext, &cache_status)) == NULL) { /* handle is not valid */ pres->res_nlm4.stat.stat = NLM4_STALE_FH; return NFS_REQ_OK; } /* * nlm_find_lock_entry with state NLM4_GRANTED will search for lock * in both blocked and granted state. We can get an unlock request * even for a lock in blocked state because grant rpc response could * get dropped and the client can think that lock is granted but the * server still consider it locked. */ nlm_entry = nlm_find_lock_entry(&(arg->alock), 0, NLM4_GRANTED); if(!nlm_entry) { pres->res_nlm4.stat.stat = NLM4_DENIED_NOLOCKS; return NFS_REQ_OK; } lck_state = nlm_lock_entry_get_state(nlm_entry); pres->res_nlm4.stat.stat = NLM4_GRANTED; lck_cnt = nlm_delete_lock_entry(&(arg->alock)); nlm_unmonitor_host(arg->alock.caller_name); /* * Now check whether we have blocked locks. * if found grant them the lock */ if(lck_state == NLM4_GRANTED) nlm_grant_blocked_locks(&(arg->alock.fh)); nlm_lock_entry_dec_ref(nlm_entry); 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_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; }