예제 #1
0
파일: tserialize.c 프로젝트: eugmes/diod
static void
test_rgetlock (void)
{
    Npfcall *fc, *fc2;

    if (!(fc = np_create_rgetlock (P9_LOCK_TYPE_WRLCK, 2, 3, 4, "xyz")))
        msg_exit ("out of memory");
    fc2 = _rcv_buf (fc, P9_RGETLOCK,  __FUNCTION__);

    assert (fc->u.rgetlock.type == fc2->u.rgetlock.type);
    assert (fc->u.rgetlock.start == fc2->u.rgetlock.start);
    assert (fc->u.rgetlock.length == fc2->u.rgetlock.length);
    assert (fc->u.rgetlock.proc_id == fc2->u.rgetlock.proc_id);
    assert (np_str9cmp (&fc->u.rgetlock.client_id, &fc2->u.rgetlock.client_id) == 0);

    free (fc);
    free (fc2);
}
예제 #2
0
파일: ops.c 프로젝트: alepharchives/diod
Npfcall*
diod_getlock (Npfid *fid, u8 type, u64 start, u64 length, u32 proc_id,
             Npstr *client_id)
{
    Fid *f = fid->aux;
    Npfcall *ret;
    char *cid = NULL;
    int ftype;

    if ((f->flags & DIOD_FID_FLAGS_ROFS)) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if (!f->ioctx) {
        msg ("diod_getlock: fid is not open");
        np_uerror (EBADF);
        goto error;
    }
    if (!(cid = np_strdup (client_id))) {
        np_uerror (ENOMEM);
        goto error;
    }
    if (type != P9_LOCK_TYPE_RDLCK && type != P9_LOCK_TYPE_WRLCK) {
        np_uerror (EINVAL);
        goto error;
    }
    ftype = (type == P9_LOCK_TYPE_RDLCK) ? LOCK_SH : LOCK_EX;
    ftype = ioctx_testlock (f->ioctx, ftype);    
    type = (ftype == LOCK_EX) ? P9_LOCK_TYPE_WRLCK : P9_LOCK_TYPE_UNLCK;
    if (!((ret = np_create_rgetlock(type, start, length, proc_id, cid)))) {
        np_uerror (ENOMEM);
        goto error;
    }
    free (cid);
    return ret;
error:
    errn (np_rerror (), "diod_getlock %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn),
          path_s (f->path));
error_quiet:
    if (cid)
        free (cid);
    return NULL;
}
예제 #3
0
파일: ops.c 프로젝트: eugmes/diod
Npfcall*
diod_getlock (Npfid *fid, u8 type, u64 start, u64 length, u32 proc_id,
             Npstr *client_id)
{
    Fid *f = fid->aux;
    Npfcall *ret;
    char *cid = NULL;
    struct stat sb;

    if ((f->xflags & XFLAGS_RO)) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if (!(cid = np_strdup (client_id))) {
        np_uerror (ENOMEM);
        goto error;
    }
    if (fstat(f->fd, &sb) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    switch (type) {
        case P9_LOCK_TYPE_RDLCK:
            switch (f->lock_type) {
                case LOCK_EX:
                case LOCK_SH:
                    type = P9_LOCK_TYPE_UNLCK;
                    break;
                case LOCK_UN:
                    if (flock (f->fd, LOCK_SH | LOCK_NB) >= 0) {
                        (void)flock (f->fd, LOCK_UN);
                        type = P9_LOCK_TYPE_UNLCK;
                    } else
                        type = P9_LOCK_TYPE_WRLCK;
                    break;
            }
            break;
        case P9_LOCK_TYPE_WRLCK:
            switch (f->lock_type) {
                case LOCK_EX:
                    type = P9_LOCK_TYPE_UNLCK;
                    break;
                case LOCK_SH:
                    /* Rather than upgrade the lock to LOCK_EX and risk
                     * not reacquiring the LOCK_SH afterwards, lie about
                     * the lock being available.  Getlock is racy anyway.
                     */
                    type = P9_LOCK_TYPE_UNLCK;
                    break;
                case LOCK_UN:
                    if (flock (f->fd, LOCK_EX | LOCK_NB) >= 0) {
                        (void)flock (f->fd, LOCK_UN);
                        type = P9_LOCK_TYPE_UNLCK;
                    } else
                        type = P9_LOCK_TYPE_WRLCK; /* could also be LOCK_SH actually */
            }
            break;
        default:
            np_uerror (EINVAL);
            goto error;
    }
    if (type != P9_LOCK_TYPE_UNLCK && type != F_UNLCK) {
        /* FIXME: need to fake up start, length, proc_id, cid? */
    }
    if (!((ret = np_create_rgetlock(type, start, length, proc_id, cid)))) {
        np_uerror (ENOMEM);
        goto error;
    }
    free (cid);
    return ret;
error:
    errn (np_rerror (), "diod_getlock %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path);
error_quiet:
    if (cid)
        free (cid);
    return NULL;
}