Esempio n. 1
0
/**
 * @brief Compare two NFSv4 owners
 *
 * @param[in] owner1 One owner
 * @param[in] owner2 Another owner
 *
 * @retval 0 on equality.
 * @retval 1 on inequality.
 */
int compare_nfs4_owner(state_owner_t *owner1, state_owner_t *owner2)
{
	if (isFullDebug(COMPONENT_STATE) && isDebug(COMPONENT_HASHTABLE)) {
		char str1[LOG_BUFF_LEN / 2];
		char str2[LOG_BUFF_LEN / 2];
		struct display_buffer dspbuf1 = {sizeof(str1), str1, str1};
		struct display_buffer dspbuf2 = {sizeof(str2), str2, str2};

		display_nfs4_owner(&dspbuf1, owner1);
		display_nfs4_owner(&dspbuf2, owner2);
		LogFullDebug(COMPONENT_STATE, "{%s} vs {%s}", str1, str2);
	}

	if (owner1 == NULL || owner2 == NULL)
		return 1;

	if (owner1 == owner2)
		return 0;

	if (owner1->so_type != owner2->so_type)
		return 1;

	if (owner1->so_owner.so_nfs4_owner.so_clientid !=
	    owner2->so_owner.so_nfs4_owner.so_clientid)
		return 1;

	if (owner1->so_owner_len != owner2->so_owner_len)
		return 1;

	return memcmp(owner1->so_owner_val, owner2->so_owner_val,
		      owner1->so_owner_len);
}
Esempio n. 2
0
int display_nfs4_owner(state_owner_t *powner, char *str)
{
  char         * strtmp = str;

  strtmp += sprintf(strtmp, "%s %p:",
                    state_owner_type_to_str(powner->so_type),
                    powner);

  strtmp += sprintf(strtmp, " clientid={%"PRIx64"} owner=",
                    powner->so_owner.so_nfs4_owner.so_clientid);

  strtmp += DisplayOpaqueValue(powner->so_owner_val,
                               powner->so_owner_len,
                               strtmp);

  strtmp += sprintf(strtmp, " confirmed=%u counter=%u seqid=%u refcount=%d",
                    powner->so_owner.so_nfs4_owner.so_confirmed,
                    powner->so_owner.so_nfs4_owner.so_counter,
                    powner->so_owner.so_nfs4_owner.so_seqid,
                    powner->so_refcount);

  if(powner->so_owner.so_nfs4_owner.so_related_owner != NULL)
    {
      strtmp += sprintf(strtmp, " related_owner={");
      strtmp += display_nfs4_owner(powner->so_owner.so_nfs4_owner.so_related_owner, strtmp);
      strtmp += sprintf(strtmp, "}");
    }

  return strtmp - str;
}
Esempio n. 3
0
/**
 * @brief Display an NFSv4 owner key
 *
 * @param[in]  buff Key to display
 * @param[out] str  Output buffer
 *
 * @return Length of output string.
 */
int display_nfs4_owner_key(struct gsh_buffdesc *buff, char *str)
{
	struct display_buffer dspbuf = {HASHTABLE_DISPLAY_STRLEN, str, str};

	display_nfs4_owner(&dspbuf, buff->addr);
	return display_buffer_len(&dspbuf);
}
Esempio n. 4
0
/**
 * @brief Display NFSv4 owner
 *
 * @param[in]  owner The state owner
 * @param[out] str   Output string
 *
 * @return The length of the output string.
 */
int display_nfs4_owner(state_owner_t *owner, char *str)
{
  char *strtmp = str;

  strtmp += sprintf(strtmp, "%s %p:",
                    state_owner_type_to_str(owner->so_type),
                    owner);

  strtmp += sprintf(strtmp, " clientid={");
  strtmp += display_client_id_rec(owner->so_owner.so_nfs4_owner.so_clientrec, strtmp);
  strtmp += sprintf(strtmp, "} owner=");

  strtmp += DisplayOpaqueValue(owner->so_owner_val,
                               owner->so_owner_len,
                               strtmp);

  strtmp += sprintf(strtmp, " confirmed=%u seqid=%u",
                    owner->so_owner.so_nfs4_owner.so_confirmed,
                    owner->so_owner.so_nfs4_owner.so_seqid);

  if(owner->so_owner.so_nfs4_owner.so_related_owner != NULL)
    {
      strtmp += sprintf(strtmp, " related_owner={");
      strtmp += display_nfs4_owner(owner->so_owner.so_nfs4_owner.so_related_owner, strtmp);
      strtmp += sprintf(strtmp, "}");
    }

  strtmp += sprintf(strtmp, " refcount=%d",
                    atomic_fetch_int32_t(&owner->so_refcount));

  return strtmp - str;
}
Esempio n. 5
0
int compare_nfs4_owner(state_owner_t * powner1,
                       state_owner_t * powner2)
{
  if(isFullDebug(COMPONENT_STATE) && isDebug(COMPONENT_HASHTABLE))
    {
      char str1[HASHTABLE_DISPLAY_STRLEN];
      char str2[HASHTABLE_DISPLAY_STRLEN];

      display_nfs4_owner(powner1, str1);
      display_nfs4_owner(powner2, str2);
      LogFullDebug(COMPONENT_STATE,
                   "{%s} vs {%s}", str1, str2);
    }

  if(powner1 == NULL || powner2 == NULL)
    return 1;

  if(powner1 == powner2)
    return 0;

  if(powner1->so_type == STATE_LOCK_OWNER_NFSV4 &&
     powner2->so_type == STATE_OPEN_OWNER_NFSV4)
    return compare_nfs4_owner(powner1->so_owner.so_nfs4_owner.so_related_owner,
                              powner2);

  if(powner2->so_type == STATE_LOCK_OWNER_NFSV4 &&
     powner1->so_type == STATE_OPEN_OWNER_NFSV4)
    return compare_nfs4_owner(powner2->so_owner.so_nfs4_owner.so_related_owner,
                              powner1);

  if(powner1->so_type != powner2->so_type)
    return 1;

  if(powner1->so_owner.so_nfs4_owner.so_clientid !=
     powner2->so_owner.so_nfs4_owner.so_clientid)
    return 1;

  if(powner1->so_owner_len !=
     powner2->so_owner_len)
    return 1;

  return memcmp(powner1->so_owner_val,
                powner2->so_owner_val,
                powner1->so_owner_len);
}
Esempio n. 6
0
int display_nfs4_owner_val(hash_buffer_t * pbuff, char *str)
{
  return display_nfs4_owner((state_owner_t *) (pbuff->pdata), str);
}
Esempio n. 7
0
/**
 * @brief Display NFSv4 owner
 *
 * @param[in]  owner The state owner
 * @param[out] str   Output string
 *
 * @return the bytes remaining in the buffer.
 */
int display_nfs4_owner(struct display_buffer *dspbuf, state_owner_t *owner)
{
	int b_left;

	if (owner == NULL)
		return display_cat(dspbuf, "<NULL>");

	b_left = display_printf(dspbuf,  "%s %p:",
				state_owner_type_to_str(owner->so_type),
				owner);

	if (b_left <= 0)
		return b_left;

	b_left = display_printf(dspbuf, " clientid={");

	if (b_left <= 0)
		return b_left;

	b_left = display_client_id_rec(dspbuf, owner->so_owner.so_nfs4_owner
						.so_clientrec);

	if (b_left <= 0)
		return b_left;

	b_left = display_printf(dspbuf, "} owner=");

	if (b_left <= 0)
		return b_left;

	b_left = display_opaque_value(dspbuf,
				      owner->so_owner_val,
				      owner->so_owner_len);

	if (b_left <= 0)
		return b_left;

	b_left = display_printf(dspbuf, " confirmed=%u seqid=%u",
		    owner->so_owner.so_nfs4_owner.so_confirmed,
		    owner->so_owner.so_nfs4_owner.so_seqid);

	if (b_left <= 0)
		return b_left;

	if (owner->so_owner.so_nfs4_owner.so_related_owner != NULL) {
		b_left = display_printf(dspbuf, " related_owner={");

		if (b_left <= 0)
			return b_left;

		b_left =
		    display_nfs4_owner(dspbuf, owner->so_owner
					       .so_nfs4_owner.so_related_owner);

		if (b_left <= 0)
			return b_left;

		b_left = display_printf(dspbuf, "}");

		if (b_left <= 0)
			return b_left;
	}

	return display_printf(dspbuf, " refcount=%d",
		    atomic_fetch_int32_t(&owner->so_refcount));
}
Esempio n. 8
0
/**
 * @brief Display an NFSv4 owner key
 *
 * @param[in]  buff Key to display
 * @param[out] str  Output buffer
 *
 * @return Length of output string.
 */
int display_nfs4_owner_key(struct gsh_buffdesc *buff, char *str)
{
	return display_nfs4_owner((state_owner_t *) (buff->addr), str);
}
Esempio n. 9
0
/**
 * @brief Display owner from hash table
 *
 * @param[in]  buff Buffer
 * @param[out] str  Output buffer
 *
 * @return Length of the output string.
 */
int display_nfs4_owner_val(struct gsh_buffdesc *buff, char *str)
{
	return display_nfs4_owner(buff->addr, str);
}
Esempio n. 10
0
/**
 * @brief Create a new delegation state then get the delegation.
 *
 * Create a new delegation state for this client and file.
 * Then attempt to get a LEASE lock to delegate the file
 * according to whether the client opened READ or READ/WRITE.
 *
 * @note state_lock must be held for WRITE
 *
 * @param[in] data Compound data for this request
 * @param[in] op NFS arguments for the request
 * @param[in] open_state Open state for the inode to be delegated.
 * @param[in] openowner Open owner of the open state.
 * @param[in] client Client that will own the delegation.
 * @param[in/out] resok Delegation attempt result to be returned to client.
 * @param[in] prerecall flag for reclaims.
 */
static void get_delegation(compound_data_t *data, OPEN4args *args,
			   state_t *open_state, state_owner_t *openowner,
			   nfs_client_id_t *client, OPEN4resok *resok,
			   bool prerecall)
{
	state_status_t state_status;
	union state_data state_data;
	open_delegation_type4 deleg_type;
	state_owner_t *clientowner = &client->cid_owner;
	struct state_refer refer;
	state_t *new_state = NULL;
	struct state_hdl *ostate;
	open_write_delegation4 *writeres =
		&resok->delegation.open_delegation4_u.write;
	open_read_delegation4 *readres =
		&resok->delegation.open_delegation4_u.read;
	open_none_delegation4 *whynone =
		&resok->delegation.open_delegation4_u.od_whynone;

	ostate = data->current_obj->state_hdl;
	if (!ostate) {
		LogFullDebug(COMPONENT_NFS_V4_LOCK, "Could not get file state");
		whynone->ond_why = WND4_RESOURCE;
		return;
	}

	/* Record the sequence info */
	if (data->minorversion > 0) {
		memcpy(refer.session,
		       data->session->session_id,
		       sizeof(sessionid4));
		refer.sequence = data->sequence;
		refer.slot = data->slot;
	}

	if (args->share_access & OPEN4_SHARE_ACCESS_WRITE) {
		deleg_type = OPEN_DELEGATE_WRITE;
	} else {
		assert(args->share_access & OPEN4_SHARE_ACCESS_READ);
		deleg_type = OPEN_DELEGATE_READ;
	}

	LogDebug(COMPONENT_STATE, "Attempting to grant %s delegation",
		 deleg_type == OPEN_DELEGATE_WRITE ? "WRITE" : "READ");

	init_new_deleg_state(&state_data, deleg_type, client);

	/* Add the delegation state */
	state_status = state_add_impl(data->current_obj, STATE_TYPE_DELEG,
				      &state_data,
				      clientowner, &new_state,
				      data->minorversion > 0 ? &refer : NULL);
	if (state_status != STATE_SUCCESS) {
		LogDebug(COMPONENT_NFS_V4_LOCK,
			 "get delegation call failed to add state with status %s",
			 state_err_str(state_status));
		whynone->ond_why = WND4_RESOURCE;
		return;
	}
	new_state->state_seqid++;

	LogFullDebugOpaque(COMPONENT_STATE,
			   "delegation state added, stateid: %s",
			   100, new_state->stateid_other, OTHERSIZE);

	/* acquire_lease_lock() gets the delegation from FSAL */
	state_status = acquire_lease_lock(ostate, clientowner, new_state);
	if (state_status != STATE_SUCCESS) {
		if (args->claim.claim != CLAIM_PREVIOUS) {
			LogDebug(COMPONENT_NFS_V4_LOCK,
				 "get delegation call added state but failed to lock with status %s",
				 state_err_str(state_status));
			state_del_locked(new_state);
			dec_state_t_ref(new_state);
			if (state_status == STATE_LOCK_CONFLICT)
				whynone->ond_why = WND4_CONTENTION;
			else
				whynone->ond_why = WND4_RESOURCE;
			return;
		}
		prerecall = true;
	}

	resok->delegation.delegation_type = deleg_type;
	ostate->file.fdeleg_stats.fds_deleg_type = deleg_type;
	if (deleg_type == OPEN_DELEGATE_WRITE) {
		nfs_space_limit4 *space_limit = &writeres->space_limit;

		space_limit->limitby = NFS_LIMIT_SIZE;
		space_limit->nfs_space_limit4_u.filesize =
				DELEG_SPACE_LIMIT_FILESZ;
		COPY_STATEID(&writeres->stateid, new_state);
		writeres->recall = prerecall;
		get_deleg_perm(&writeres->permissions, deleg_type);
	} else {
		assert(deleg_type == OPEN_DELEGATE_READ);
		COPY_STATEID(&readres->stateid, new_state);
		readres->recall = prerecall;
		get_deleg_perm(&readres->permissions, deleg_type);
	}

	if (isDebug(COMPONENT_NFS_V4_LOCK)) {
		char str1[LOG_BUFF_LEN / 2] = "\0";
		char str2[LOG_BUFF_LEN / 2] = "\0";
		struct display_buffer dspbuf1 = {sizeof(str1), str1, str1};
		struct display_buffer dspbuf2 = {sizeof(str2), str2, str2};

		display_nfs4_owner(&dspbuf1, openowner);
		display_nfs4_owner(&dspbuf2, clientowner);

		LogDebug(COMPONENT_NFS_V4_LOCK,
			 "get delegation openowner %s clientowner %s status %s",
			 str1, str2, state_err_str(state_status));
	}

	dec_state_t_ref(new_state);
}
Esempio n. 11
0
/**
 * @brief Display NFSv4 owner
 *
 * @param[in]  owner The state owner
 * @param[out] str   Output string
 *
 * @return the bytes remaining in the buffer.
 */
int display_nfs4_owner(struct display_buffer *dspbuf, state_owner_t *owner)
{
	int b_left;
	time_t texpire;
	struct state_nfs4_owner_t *nfs4_owner = &owner->so_owner.so_nfs4_owner;

	if (owner == NULL)
		return display_cat(dspbuf, "<NULL>");

	b_left = display_printf(dspbuf,  "%s %p:",
				state_owner_type_to_str(owner->so_type),
				owner);

	if (b_left <= 0)
		return b_left;

	b_left = display_printf(dspbuf, " clientid={");

	if (b_left <= 0)
		return b_left;

	b_left = display_client_id_rec(dspbuf, nfs4_owner->so_clientrec);

	if (b_left <= 0)
		return b_left;

	b_left = display_printf(dspbuf, "} owner=");

	if (b_left <= 0)
		return b_left;

	b_left = display_opaque_value(dspbuf,
				      owner->so_owner_val,
				      owner->so_owner_len);

	if (b_left <= 0)
		return b_left;

	b_left = display_printf(dspbuf, " confirmed=%u seqid=%u",
				nfs4_owner->so_confirmed,
				nfs4_owner->so_seqid);

	if (b_left <= 0)
		return b_left;

	if (nfs4_owner->so_related_owner != NULL) {
		b_left = display_printf(dspbuf, " related_owner={");

		if (b_left <= 0)
			return b_left;

		b_left =
		    display_nfs4_owner(dspbuf, nfs4_owner->so_related_owner);

		if (b_left <= 0)
			return b_left;

		b_left = display_printf(dspbuf, "}");

		if (b_left <= 0)
			return b_left;
	}

	texpire = atomic_fetch_time_t(&nfs4_owner->so_cache_expire);

	if (texpire != 0) {
		b_left = display_printf(dspbuf,
					" cached(expires in %d secs)",
					texpire - time(NULL));

		if (b_left <= 0)
			return b_left;
	}

	return display_printf(dspbuf, " refcount=%d",
		    atomic_fetch_int32_t(&owner->so_refcount));
}