Esempio n. 1
0
int
afs_MemHandleLink(struct vcache *avc, struct vrequest *areq)
{
    struct dcache *tdc;
    char *tp, *rbuf;
    afs_size_t offset, len;
    afs_int32 tlen, alen;
    afs_int32 code;

    AFS_STATCNT(afs_MemHandleLink);
    /* two different formats, one for links protected 644, have a "." at
     * the end of the file name, which we turn into a null.  Others, 
     * protected 755, we add a null to the end of */
    if (!avc->linkData) {
	void *addr;
	tdc = afs_GetDCache(avc, (afs_size_t) 0, areq, &offset, &len, 0);
	if (!tdc) {
	    return EIO;
	}
	/* otherwise we have the data loaded, go for it */
	if (len > 1024) {
	    afs_PutDCache(tdc);
	    return EFAULT;
	}
	if (avc->f.m.Mode & 0111)
	    alen = len + 1;	/* regular link */
	else
	    alen = len;		/* mt point */
	rbuf = osi_AllocLargeSpace(AFS_LRALLOCSIZ);
	ObtainReadLock(&tdc->lock);
	addr = afs_MemCacheOpen(&tdc->f.inode);
	tlen = len;
	code = afs_MemReadBlk(addr, 0, rbuf, tlen);
	afs_MemCacheClose(addr);
	ReleaseReadLock(&tdc->lock);
	afs_PutDCache(tdc);
	rbuf[alen - 1] = 0;
	alen = strlen(rbuf) + 1;
	tp = afs_osi_Alloc(alen);	/* make room for terminating null */
	osi_Assert(tp != NULL);
	memcpy(tp, rbuf, alen);
	osi_FreeLargeSpace(rbuf);
	if (code != len) {
	    afs_osi_Free(tp, alen);
	    return EIO;
	}
	avc->linkData = tp;
    }
    return 0;
}
Esempio n. 2
0
int
afs_MemReadUIO(afs_dcache_id_t *ainode, struct uio *uioP)
{
    struct memCacheEntry *mceP =
	(struct memCacheEntry *)afs_MemCacheOpen(ainode);
    int length = mceP->size - AFS_UIO_OFFSET(uioP);
    afs_int32 code;

    AFS_STATCNT(afs_MemReadUIO);
    ObtainReadLock(&mceP->afs_memLock);
    length = (length < AFS_UIO_RESID(uioP)) ? length : AFS_UIO_RESID(uioP);
    AFS_UIOMOVE(mceP->data + AFS_UIO_OFFSET(uioP), length, UIO_READ, uioP, code);
    ReleaseReadLock(&mceP->afs_memLock);
    return code;
}
Esempio n. 3
0
int
afs_MemWriteUIO(afs_dcache_id_t *ainode, struct uio *uioP)
{
    struct memCacheEntry *mceP =
	(struct memCacheEntry *)afs_MemCacheOpen(ainode);
    afs_int32 code;

    AFS_STATCNT(afs_MemWriteUIO);
    ObtainWriteLock(&mceP->afs_memLock, 312);
    if (AFS_UIO_RESID(uioP) + AFS_UIO_OFFSET(uioP) > mceP->dataSize) {
	char *oldData = mceP->data;

	mceP->data = afs_osi_Alloc(AFS_UIO_RESID(uioP) + AFS_UIO_OFFSET(uioP));
	if (mceP->data == NULL) {	/* no available memory */
	    mceP->data = oldData;	/* revert back change that was made */
	    ReleaseWriteLock(&mceP->afs_memLock);
	    afs_warn("afs: afs_MemWriteBlk mem alloc failure (%ld bytes)\n",
		     (long)(AFS_UIO_RESID(uioP) + AFS_UIO_OFFSET(uioP)));
	    return -ENOMEM;
	}

	AFS_GUNLOCK();
	memcpy(mceP->data, oldData, mceP->size);
	AFS_GLOCK();

	afs_osi_Free(oldData, mceP->dataSize);
	mceP->dataSize = AFS_UIO_RESID(uioP) + AFS_UIO_OFFSET(uioP);
    }
    if (mceP->size < AFS_UIO_OFFSET(uioP))
	memset(mceP->data + mceP->size, 0,
	       (int)(AFS_UIO_OFFSET(uioP) - mceP->size));
    AFS_UIOMOVE(mceP->data + AFS_UIO_OFFSET(uioP), AFS_UIO_RESID(uioP), UIO_WRITE,
		uioP, code);
    if (AFS_UIO_OFFSET(uioP) > mceP->size)
	mceP->size = AFS_UIO_OFFSET(uioP);

    ReleaseWriteLock(&mceP->afs_memLock);
    return code;
}