Esempio n. 1
0
static struct blocking_lock_record *onefs_cbrl_find_blr(uint64_t id)
{
	struct blocking_lock_record *blr;
	struct onefs_cbrl_blr_state *bs;

	onefs_cbrl_enumerate_blq("onefs_cbrl_find_blr");

	for (blr = blocking_lock_queue; blr; blr = blr->next) {
		bs = (struct onefs_cbrl_blr_state *)blr->blr_private;

		/* We don't control all of the BLRs on the BLQ. */
		if (bs == NULL)
			continue;

		if (bs->id == id) {
			DEBUG(10, ("found %s\n",
			    onefs_cbrl_blr_state_str(blr)));
			break;
		}
	}

	if (blr == NULL) {
		DEBUG(5, ("Could not find CBRL BLR for id %llu\n", id));
		return NULL;
	}

	return blr;
}
Esempio n. 2
0
static struct blocking_lock_record *onefs_cbrl_find_blr(uint64_t id)
{
	struct smbd_server_connection *sconn = smbd_server_conn;
	struct blocking_lock_record *blr;
	struct onefs_cbrl_blr_state *bs;

	onefs_cbrl_enumerate_blq("onefs_cbrl_find_blr");

	if (sconn->using_smb2) {
		struct smbd_smb2_request *smb2req;
		for (smb2req = sconn->smb2.requests; smb2req; smb2req = nextreq) {
			blr = get_pending_smb2req_blr(smb2req);
			if (!blr) {
				continue;
			}
			bs = (struct onefs_cbrl_blr_state *)blr->blr_private;
			if (bs == NULL)	{
				continue;
			}
			if (bs->id == id) {
				DEBUG(10, ("found %s\n",
				    onefs_cbrl_blr_state_str(blr)));
				break;
			}
		}
	} else {
		for (blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = blr->next) {
			bs = (struct onefs_cbrl_blr_state *)blr->blr_private;

			/* We don't control all of the BLRs on the BLQ. */
			if (bs == NULL)
				continue;

			if (bs->id == id) {
				DEBUG(10, ("found %s\n",
				    onefs_cbrl_blr_state_str(blr)));
				break;
			}
		}
	}

	if (blr == NULL) {
		DEBUG(5, ("Could not find CBRL BLR for id %llu\n", id));
		return NULL;
	}

	return blr;
}
Esempio n. 3
0
/**
 * @param[in]     br_lck        Contains the fsp.
 * @param[in]     plock         Lock request.
 * @param[in]     blocking_lock Only used for figuring out the error.
 * @param[in,out] blr           The BLR for the already-deferred operation.
 */
NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle,
				struct byte_range_lock *br_lck,
				struct lock_struct *plock,
				bool blocking_lock,
				struct blocking_lock_record *blr)
{
	int fd = br_lck->fsp->fh->fd;
	uint64_t id = 0;
	enum cbrl_lock_type type;
	bool async = false;
	bool pending = false;
	bool pending_async = false;
	int error;
	struct onefs_cbrl_blr_state *bs;
	NTSTATUS status;

	START_PROFILE(syscall_brl_lock);

	SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
	SMB_ASSERT(plock->lock_type != UNLOCK_LOCK);

	onefs_cbrl_enumerate_blq("onefs_brl_lock_windows");

	/* Will only initialize the first time its called. */
	onefs_init_cbrl();

	switch (plock->lock_type) {
		case WRITE_LOCK:
			type = CBRL_LK_EX;
			break;
		case READ_LOCK:
			type = CBRL_LK_SH;
			break;
		case PENDING_WRITE_LOCK:
			/* Called when a blocking lock request is added - do an
			 * async lock. */
			type = CBRL_LK_EX;
			pending = true;
			async = true;
			break;
		case PENDING_READ_LOCK:
			/* Called when a blocking lock request is added - do an
			 * async lock. */
			type = CBRL_LK_SH;
			pending = true;
			async = true;
			break;
		default:
			/* UNLOCK_LOCK: should only be used for a POSIX_LOCK */
			smb_panic("Invalid plock->lock_type passed in to "
			    "onefs_brl_lock_windows");
	}

	/* Figure out if we're actually doing the lock or a no-op. We need to
	 * do a no-op when process_blocking_lock_queue calls back into us.
	 *
	 * We know process_* is calling into us if a blr is passed in and
	 * pending is false. */
	if (!pending && blr) {
		/* Check the BLR state. */
		bs = (struct onefs_cbrl_blr_state *)blr->blr_private;
		SMB_ASSERT(bs);

		/* ASYNC still in progress: The process_* calls will keep
		 * calling even if we haven't gotten the lock. Keep erroring
		 * without calling ifs_cbrl, or getting/setting an id. */
		if (bs->state == ONEFS_CBRL_ASYNC) {
			goto failure;
		}
		else if (bs->state == ONEFS_CBRL_ERROR) {
			END_PROFILE(syscall_brl_lock);
			return NT_STATUS_NO_MEMORY;
		}

		SMB_ASSERT(bs->state == ONEFS_CBRL_NONE);
		async = true;
	}

	if (async) {
		SMB_ASSERT(blocking_lock);
		SMB_ASSERT(blr);
		id = onefs_get_new_id();
	}

	DEBUG(10, ("Calling ifs_cbrl(LOCK)...\n"));
	error = ifs_cbrl(fd, CBRL_OP_LOCK, type, plock->start,
	    plock->size, async, id, plock->context.smbpid, plock->context.tid,
	    plock->fnum);
	if (!error) {
		goto success;
	} else if (errno == EWOULDBLOCK) {
		SMB_ASSERT(!async);
	} else if (errno == EINPROGRESS) {
		SMB_ASSERT(async);

		if (pending) {
			/* Talloc a new BLR private state. */
			blr->blr_private = talloc(blr, struct onefs_cbrl_blr_state);
			pending_async = true;
		}

		/* Store the new id in the BLR private state. */
		bs = (struct onefs_cbrl_blr_state *)blr->blr_private;
		bs->id = id;
		bs->state = ONEFS_CBRL_ASYNC;
	} else {