void nlm_process_conflict(nlm4_holder * nlm_holder, state_owner_t * holder, state_lock_desc_t * conflict, cache_inode_client_t * pclient) { if(conflict != NULL) { nlm_holder->exclusive = conflict->sld_type == STATE_LOCK_W; nlm_holder->l_offset = conflict->sld_offset; nlm_holder->l_len = conflict->sld_length; } else { /* For some reason, don't have an actual conflict, * just make it exclusive over the whole file * (which would conflict with any lock requested). */ nlm_holder->exclusive = TRUE; nlm_holder->l_offset = 0; nlm_holder->l_len = 0; } if(holder != NULL) { if(holder->so_type == STATE_LOCK_OWNER_NLM) nlm_holder->svid = holder->so_owner.so_nlm_owner.so_nlm_svid; else nlm_holder->svid = 0; fill_netobj(&nlm_holder->oh, holder->so_owner_val, holder->so_owner_len); } else { /* If we don't have an NLM owner, not much we can do. */ nlm_holder->svid = 0; fill_netobj(&nlm_holder->oh, unknown_owner.so_owner_val, unknown_owner.so_owner_len); } /* Release any lock owner reference passed back from SAL */ if(holder != NULL) dec_state_owner_ref(holder, pclient); }
state_status_t nlm_granted_callback(cache_entry_t * pentry, state_lock_entry_t * lock_entry, state_status_t * pstatus) { fsal_op_context_t fsal_context, *pcontext = &fsal_context; state_block_data_t * block_data = lock_entry->sle_block_data; state_nlm_block_data_t * nlm_block_data = &block_data->sbd_block_data.sbd_nlm_block_data; state_cookie_entry_t * cookie_entry = NULL; state_async_queue_t * arg; nlm4_testargs * inarg; state_nlm_owner_t * nlm_grant_owner = &lock_entry->sle_owner->so_owner.so_nlm_owner; state_nlm_client_t * nlm_grant_client = nlm_grant_owner->so_client; granted_cookie_t nlm_grant_cookie; state_status_t dummy_status; if(nlm_block_data_to_fsal_context(block_data, &fsal_context) != TRUE) { *pstatus = STATE_INCONSISTENT_ENTRY; return *pstatus; } arg = gsh_malloc(sizeof(*arg)); if(arg == NULL) { /* If we fail allocation the best is to delete the block entry * so that client can try again and get the lock. May be * by then we are able to allocate objects */ *pstatus = STATE_MALLOC_ERROR; return *pstatus; } memset(arg, 0, sizeof(*arg)); /* Get a cookie to use for this grant */ next_granted_cookie(&nlm_grant_cookie); /* Add a cookie to the blocked lock pending grant. * It will also request lock from FSAL. * Could return STATE_LOCK_BLOCKED because FSAL would have had to block. */ if(state_add_grant_cookie(pentry, pcontext, &nlm_grant_cookie, sizeof(nlm_grant_cookie), lock_entry, &cookie_entry, pstatus) != STATE_SUCCESS) { free_grant_arg(arg); return *pstatus; } /* Fill in the arguments for the NLMPROC4_GRANTED_MSG call */ inc_nlm_client_ref(nlm_grant_client); arg->state_async_func = nlm4_send_grant_msg; arg->state_async_data.state_nlm_async_data.nlm_async_host = nlm_grant_client; arg->state_async_data.state_nlm_async_data.nlm_async_key = cookie_entry; inarg = &arg->state_async_data.state_nlm_async_data.nlm_async_args.nlm_async_grant; if(!copy_netobj(&inarg->alock.fh, &nlm_block_data->sbd_nlm_fh)) goto grant_fail_malloc; if(!fill_netobj(&inarg->alock.oh, lock_entry->sle_owner->so_owner_val, lock_entry->sle_owner->so_owner_len)) goto grant_fail_malloc; if(!fill_netobj(&inarg->cookie, (char *) &nlm_grant_cookie, sizeof(nlm_grant_cookie))) goto grant_fail_malloc; inarg->alock.caller_name = gsh_strdup(nlm_grant_client->slc_nlm_caller_name); if(!inarg->alock.caller_name) goto grant_fail_malloc; inarg->exclusive = lock_entry->sle_lock.lock_type == FSAL_LOCK_W; inarg->alock.svid = nlm_grant_owner->so_nlm_svid; inarg->alock.l_offset = lock_entry->sle_lock.lock_start; inarg->alock.l_len = lock_entry->sle_lock.lock_length; if(isDebug(COMPONENT_NLM)) { char buffer[1024]; netobj_to_string(&inarg->cookie, buffer, sizeof(buffer)); LogDebug(COMPONENT_NLM, "Sending GRANTED for arg=%p svid=%d start=%llx len=%llx cookie=%s", arg, inarg->alock.svid, (unsigned long long) inarg->alock.l_offset, (unsigned long long) inarg->alock.l_len, buffer); } /* Now try to schedule NLMPROC4_GRANTED_MSG call */ *pstatus = state_async_schedule(arg); if(*pstatus != STATE_SUCCESS) goto grant_fail; return *pstatus; grant_fail_malloc: *pstatus = STATE_MALLOC_ERROR; grant_fail: /* Something went wrong after we added a grant cookie, need to clean up */ dec_nlm_client_ref(nlm_grant_client); /* Clean up NLMPROC4_GRANTED_MSG arguments */ free_grant_arg(arg); /* Cancel the pending grant to release the cookie */ if(state_cancel_grant(pcontext, cookie_entry, &dummy_status) != STATE_SUCCESS) { /* Not much we can do other than log that something bad happened. */ LogCrit(COMPONENT_NLM, "Unable to clean up GRANTED lock after error"); } return *pstatus; }