Ejemplo n.º 1
0
/* xfs_igetinode now returns an unlocked inode. This is fine, since we
 * have a refcount on the holding vnode.
 */
int
xfs_igetinode(struct vfs *vfsp, dev_t dev, ino_t inode,
	      struct xfs_inode **ipp)
{
    struct xfs_inode *ip;
    vnode_t *vp;
    vattr_t vattr;
    int error;

    AFS_STATCNT(igetinode);

    *ipp = NULL;
    if (error = xfs_getinode(vfsp, dev, inode, &ip)) {
	return error;
    }

    xfs_iunlock(ip, XFS_ILOCK_SHARED);
    vp = XFS_ITOV(ip);
    vattr.va_mask = AT_STAT;
    AFS_VOP_GETATTR(vp, &vattr, 0, OSI_GET_CURRENT_CRED(), error);
    if (error) {
	SET_XFS_ERROR(4, vp->v_vfsp->vfs_dev, inode);
	VN_RELE(vp);
	return error;
    }
    if (vattr.va_nlink == 0 || vattr.va_type != VREG) {
	SET_XFS_ERROR(5, vp->v_vfsp->vfs_dev, inode);
	VN_RELE(vp);
	return ENOENT;
    }

    *ipp = ip;
    return 0;
}
Ejemplo n.º 2
0
static void
BStore(struct brequest *ab)
{
    struct vcache *tvc;
    afs_int32 code;
    struct vrequest *treq = NULL;
#if defined(AFS_SGI_ENV)
    struct cred *tmpcred;
#endif

    AFS_STATCNT(BStore);
    if ((code = afs_CreateReq(&treq, ab->cred)))
	return;
    tvc = ab->vc;
#if defined(AFS_SGI_ENV)
    /*
     * Since StoreOnLastReference can end up calling osi_SyncVM which
     * calls into VM code that assumes that u.u_cred has the
     * correct credentials, we set our to theirs for this xaction
     */
    tmpcred = OSI_GET_CURRENT_CRED();
    OSI_SET_CURRENT_CRED(ab->cred);

    /*
     * To avoid recursion since the WriteLock may be released during VM
     * operations, we hold the VOP_RWLOCK across this transaction as
     * do the other callers of StoreOnLastReference
     */
    AFS_RWLOCK((vnode_t *) tvc, 1);
#endif
    ObtainWriteLock(&tvc->lock, 209);
    code = afs_StoreOnLastReference(tvc, treq);
    ReleaseWriteLock(&tvc->lock);
#if defined(AFS_SGI_ENV)
    OSI_SET_CURRENT_CRED(tmpcred);
    AFS_RWUNLOCK((vnode_t *) tvc, 1);
#endif
    /* now set final return code, and wakeup anyone waiting */
    if ((ab->flags & BUVALID) == 0) {

	/* To explain code_raw/code_checkcode:
	 * Anyone that's waiting won't have our treq, so they won't be able to
	 * call afs_CheckCode themselves on the return code we provide here.
	 * But if we give back only the afs_CheckCode value, they won't know
	 * what the "raw" value was. So give back both values, so the waiter
	 * can know the "raw" value for interpreting the value internally, as
	 * well as the afs_CheckCode value to give to the OS. */
	ab->code_raw = code;
	ab->code_checkcode = afs_CheckCode(code, treq, 430);

	ab->flags |= BUVALID;
	if (ab->flags & BUWAIT) {
	    ab->flags &= ~BUWAIT;
	    afs_osi_Wakeup(ab);
	}
    }
    afs_DestroyReq(treq);
}
Ejemplo n.º 3
0
static void
BStore(struct brequest *ab)
{
    struct vcache *tvc;
    afs_int32 code;
    struct vrequest treq;
#if defined(AFS_SGI_ENV)
    struct cred *tmpcred;
#endif

    AFS_STATCNT(BStore);
    if ((code = afs_InitReq(&treq, ab->cred)))
	return;
    code = 0;
    tvc = ab->vc;
#if defined(AFS_SGI_ENV)
    /*
     * Since StoreOnLastReference can end up calling osi_SyncVM which
     * calls into VM code that assumes that u.u_cred has the
     * correct credentials, we set our to theirs for this xaction
     */
    tmpcred = OSI_GET_CURRENT_CRED();
    OSI_SET_CURRENT_CRED(ab->cred);

    /*
     * To avoid recursion since the WriteLock may be released during VM
     * operations, we hold the VOP_RWLOCK across this transaction as
     * do the other callers of StoreOnLastReference
     */
    AFS_RWLOCK((vnode_t *) tvc, 1);
#endif
    ObtainWriteLock(&tvc->lock, 209);
    code = afs_StoreOnLastReference(tvc, &treq);
    ReleaseWriteLock(&tvc->lock);
#if defined(AFS_SGI_ENV)
    OSI_SET_CURRENT_CRED(tmpcred);
    AFS_RWUNLOCK((vnode_t *) tvc, 1);
#endif
    /* now set final return code, and wakeup anyone waiting */
    if ((ab->flags & BUVALID) == 0) {
	ab->code = afs_CheckCode(code, &treq, 43);	/* set final code, since treq doesn't go across processes */
	ab->flags |= BUVALID;
	if (ab->flags & BUWAIT) {
	    ab->flags &= ~BUWAIT;
	    afs_osi_Wakeup(ab);
	}
    }
}
Ejemplo n.º 4
0
int
afs_frlock(OSI_VN_DECL(vp), int cmd, struct flock *lfp, int flag,
	   off_t offset,
#ifdef AFS_SGI65_ENV
	   vrwlock_t vrwlock,
#endif
	   cred_t * cr)
{
    int error;
    OSI_VN_CONVERT(vp);
#ifdef AFS_SGI65_ENV
    struct flid flid;
    int pid;
    get_current_flid(&flid);
    pid = flid.fl_pid;
#endif

    /*
     * Since AFS doesn't support byte-wise locks (and simply
     * says yes! we handle byte locking locally only.
     * This makes lots of things work much better
     * XXX This doesn't properly handle moving from a
     * byte-wise lock up to a full file lock (we should
     * remove the byte locks ..) Of course neither did the
     * regular AFS way ...
     *
     * For GETLK we do a bit more - we first check any byte-wise
     * locks - if none then check for full AFS file locks
     */
    if (cmd == F_GETLK || lfp->l_whence != 0 || lfp->l_start != 0
	|| (lfp->l_len != MAXEND && lfp->l_len != 0)) {
	AFS_RWLOCK(vp, VRWLOCK_WRITE);
	AFS_GUNLOCK();
#ifdef AFS_SGI65_ENV
	error =
	    fs_frlock(OSI_VN_ARG(vp), cmd, lfp, flag, offset, vrwlock, cr);
#else
	error = fs_frlock(vp, cmd, lfp, flag, offset, cr);
#endif
	AFS_GLOCK();
	AFS_RWUNLOCK(vp, VRWLOCK_WRITE);
	if (error || cmd != F_GETLK)
	    return error;
	if (lfp->l_type != F_UNLCK)
	    /* found some blocking lock */
	    return 0;
	/* fall through to check for full AFS file locks */
    }

    /* map BSD style to plain - we don't call reclock() 
     * and its only there that the difference is important
     */
    switch (cmd) {
    case F_GETLK:
    case F_RGETLK:
	break;
    case F_SETLK:
    case F_RSETLK:
	break;
    case F_SETBSDLK:
	cmd = F_SETLK;
	break;
    case F_SETLKW:
    case F_RSETLKW:
	break;
    case F_SETBSDLKW:
	cmd = F_SETLKW;
	break;
    default:
	return EINVAL;
    }

    AFS_GUNLOCK();

    error = convoff(vp, lfp, 0, offset, SEEKLIMIT
#ifdef AFS_SGI64_ENV
		    , OSI_GET_CURRENT_CRED()
#endif /* AFS_SGI64_ENV */
	);

    AFS_GLOCK();
    if (!error) {
#ifdef AFS_SGI65_ENV
	error = afs_lockctl(vp, lfp, cmd, cr, pid);
#else
	error = afs_lockctl(vp, lfp, cmd, cr, OSI_GET_CURRENT_PID());
#endif
    }
    return error;
}