Esempio n. 1
0
static fsal_status_t lock_op(struct fsal_obj_handle *obj_hdl,
			     const struct req_op_context *opctx,
			     void * p_owner,
			     fsal_lock_op_t lock_op,
			     fsal_lock_param_t *request_lock,
			     fsal_lock_param_t *conflicting_lock)
{
	int rc = 0;
	fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 };
	struct glusterfs_handle *objhandle =
	    container_of(obj_hdl, struct glusterfs_handle, handle);
	struct flock flock;
	int cmd;
	int saverrno = 0;
#ifdef GLTIMING
	struct timespec s_time, e_time;

	now(&s_time);
#endif

	if (objhandle->openflags == FSAL_O_CLOSED) {
		LogDebug(COMPONENT_FSAL,
			 "ERROR: Attempting to lock with no file descriptor open");
		status.major = ERR_FSAL_FAULT;
		goto out;
	}

	if (lock_op == FSAL_OP_LOCKT) {
		cmd = F_GETLK;
	} else if (lock_op == FSAL_OP_LOCK || lock_op == FSAL_OP_UNLOCK) {
		cmd = F_SETLK;
	} else {
		LogDebug(COMPONENT_FSAL,
			 "ERROR: Unsupported lock operation %d\n", lock_op);
		status.major = ERR_FSAL_NOTSUPP;
		goto out;
	}

	if (request_lock->lock_type == FSAL_LOCK_R) {
		flock.l_type = F_RDLCK;
	} else if (request_lock->lock_type == FSAL_LOCK_W) {
		flock.l_type = F_WRLCK;
	} else {
		LogDebug(COMPONENT_FSAL,
			 "ERROR: The requested lock type was not read or write.");
		status.major = ERR_FSAL_NOTSUPP;
		goto out;
	}

	/* TODO: Override R/W and just provide U? */
	if (lock_op == FSAL_OP_UNLOCK)
		flock.l_type = F_UNLCK;

	flock.l_len = request_lock->lock_length;
	flock.l_start = request_lock->lock_start;
	flock.l_whence = SEEK_SET;

	rc = glfs_posix_lock (objhandle->glfd, cmd, &flock);
	if (rc != 0 && lock_op == FSAL_OP_LOCK
	    && conflicting_lock && (errno == EACCES || errno == EAGAIN)) {
		/* process conflicting lock */
		saverrno = errno;
		cmd = F_GETLK;
		rc = glfs_posix_lock (objhandle->glfd, cmd, &flock);
		if (rc) {
			LogCrit(COMPONENT_FSAL,
				"Failed to get conflicting lock post lock"
				" failure");
			status = gluster2fsal_error(errno);
			goto out;
		}

		conflicting_lock->lock_length = flock.l_len;
		conflicting_lock->lock_start = flock.l_start;
		conflicting_lock->lock_type = flock.l_type;

		status = gluster2fsal_error(saverrno);
		goto out;
	} else if (rc != 0) {
		status = gluster2fsal_error(errno);
		goto out;
	}

	if (conflicting_lock != NULL) {
		if (lock_op == FSAL_OP_LOCKT && flock.l_type != F_UNLCK) {
			conflicting_lock->lock_length = flock.l_len;
			conflicting_lock->lock_start = flock.l_start;
			conflicting_lock->lock_type = flock.l_type;
		} else {
			conflicting_lock->lock_length = 0;
			conflicting_lock->lock_start = 0;
			conflicting_lock->lock_type = FSAL_NO_LOCK;
		}
	}

 out:
#ifdef GLTIMING
	now(&e_time);
	latency_update(&s_time, &e_time, lat_lock_op);
#endif
	return status;
}
Esempio n. 2
0
int
lock_test(glfs_fd_t *glfd1, glfs_fd_t *glfd2, bool should_fail, int l1_start,
          int l1_len, char *l1_owner, int lo1_len, int l2_start, int l2_len,
          char *l2_owner, int lo2_len)
{
    int ret = -1, f_ret = -1;
    struct flock lock1 =
                     {
                         0,
                     },
                 lock2 = {
                     0,
                 };

lock1:
    if (!glfd1)
        goto lock2;

    /* lock on glfd1 */
    lock1.l_type = F_WRLCK;
    lock1.l_whence = SEEK_SET;
    lock1.l_start = l1_start;
    lock1.l_len = l1_len;

    ret = glfs_fd_set_lkowner(glfd1, l1_owner, lo1_len);
    LOG_ERR("glfs_fd_set_lkowner on glfd1", ret);

    ret = glfs_posix_lock(glfd1, F_SETLK, &lock1);
    LOG_ERR("glfs_posix_lock on glfd1", ret);

lock2:
    if (!glfd2)
        goto out;

    /* lock on glfd2 */
    lock2.l_type = F_WRLCK;
    lock2.l_whence = SEEK_SET;
    lock2.l_start = l2_start;
    lock2.l_len = l2_len;

    ret = glfs_fd_set_lkowner(glfd2, l2_owner, lo2_len);
    LOG_ERR("glfs_fd_set_lkowner on glfd2", ret);

    ret = glfs_posix_lock(glfd2, F_SETLK, &lock2);

    if (should_fail && ret) {
        f_ret = 0;
    } else if (!ret && !should_fail) {
        f_ret = 0;
    } else {
        f_ret = -1;
    }
out:
    fprintf(stderr,
            "Lock test on glfd1 (start(%d), len(%d),"
            " lk_owner(%s)) and glfd2 (start(%d), len(%d), "
            "lk_owner(%s)) - expected(%s) - result(%s)\n",
            l1_start, l1_len, l1_owner, l2_start, l2_len, l2_owner,
            (should_fail ? "FAIL" : "SUCCESS"), (ret ? "FAIL" : "SUCCESS"));
    return f_ret;
}