Пример #1
0
int
v7fs_read(void *v)
{
	struct vop_read_args /* {
				struct vnode *a_vp;
				struct uio *a_uio;
				int a_ioflag;
				kauth_cred_t a_cred;
				} */ *a = v;
	struct vnode *vp = a->a_vp;
	struct uio *uio = a->a_uio;
	struct v7fs_node *v7node = vp->v_data;
	struct v7fs_inode *inode = &v7node->inode;
	vsize_t sz, filesz = v7fs_inode_filesize(inode);
	const int advice = IO_ADV_DECODE(a->a_ioflag);
	int error = 0;

	DPRINTF("type=%d inode=%d\n", vp->v_type, v7node->inode.inode_number);

	while (uio->uio_resid > 0) {
		if ((sz = MIN(filesz - uio->uio_offset, uio->uio_resid)) == 0)
			break;

		error = ubc_uiomove(&vp->v_uobj, uio, sz, advice, UBC_READ |
		    UBC_PARTIALOK | UBC_UNMAP_FLAG(v));
		if (error) {
			break;
		}
		DPRINTF("read %zubyte\n", sz);
	}
	v7node->update_atime = true;

	return error;
}
Пример #2
0
int
v7fs_write(void *v)
{
	struct vop_write_args /* {
				 struct vnode *a_vp;
				 struct uio *a_uio;
				 int  a_ioflag;
				 kauth_cred_t a_cred;
				 } */ *a = v;
	struct vnode *vp = a->a_vp;
	struct uio *uio = a->a_uio;
	int advice = IO_ADV_DECODE(a->a_ioflag);
	struct v7fs_node *v7node = vp->v_data;
	struct v7fs_inode *inode = &v7node->inode;
	struct v7fs_self *fs = v7node->v7fsmount->core;
	vsize_t sz;
	int error = 0;

	if (uio->uio_resid == 0)
		return 0;

	sz = v7fs_inode_filesize(inode);
	DPRINTF("(i)%ld (v)%zu ofs=%zu + res=%zu = %zu\n", sz, vp->v_size,
	    uio->uio_offset, uio->uio_resid, uio->uio_offset + uio->uio_resid);

	/* Append mode file offset is managed by kernel. */
	if (a->a_ioflag & IO_APPEND)
		uio->uio_offset = sz;

	/* If write region is over filesize, expand. */
	size_t newsize= uio->uio_offset + uio->uio_resid;
	ssize_t expand = newsize - sz;
 	if (expand > 0) {
		if ((error = v7fs_datablock_expand(fs, inode, expand)))
			return error;
		uvm_vnp_setsize(vp, newsize);
	}

	while (uio->uio_resid > 0) {
		sz = uio->uio_resid;
		if ((error = ubc_uiomove(&vp->v_uobj, uio, sz, advice,
			    UBC_WRITE | UBC_UNMAP_FLAG(v))))
			break;
		DPRINTF("write %zubyte\n", sz);
	}
	v7node->update_mtime = true;

	return error;
}
Пример #3
0
int
sysvbfs_write(void *arg)
{
	struct vop_write_args /* {
		struct vnode *a_vp;
		struct uio *a_uio;
		int  a_ioflag;
		kauth_cred_t a_cred;
	} */ *a = arg;
	struct vnode *v = a->a_vp;
	struct uio *uio = a->a_uio;
	int advice = IO_ADV_DECODE(a->a_ioflag);
	struct sysvbfs_node *bnode = v->v_data;
	bool extended = false;
	vsize_t sz;
	int err = 0;

	if (a->a_vp->v_type != VREG)
		return EISDIR;

	if (a->a_ioflag & IO_APPEND)
		uio->uio_offset = bnode->size;

	if (uio->uio_resid == 0)
		return 0;

	if (bnode->size < uio->uio_offset + uio->uio_resid) {
		sysvbfs_file_setsize(v, uio->uio_offset + uio->uio_resid);
		extended = true;
	}

	while (uio->uio_resid > 0) {
		sz = uio->uio_resid;
		err = ubc_uiomove(&v->v_uobj, uio, sz, advice,
		    UBC_WRITE | UBC_UNMAP_FLAG(v));
		if (err)
			break;
		DPRINTF("%s: write %ldbyte\n", __func__, sz);
	}
	if (err)
		sysvbfs_file_setsize(v, bnode->size - uio->uio_resid);

	VN_KNOTE(v, NOTE_WRITE | (extended ? NOTE_EXTEND : 0));

	return err;
}
Пример #4
0
int
sysvbfs_read(void *arg)
{
	struct vop_read_args /* {
		struct vnode *a_vp;
		struct uio *a_uio;
		int a_ioflag;
		kauth_cred_t a_cred;
	} */ *a = arg;
	struct vnode *v = a->a_vp;
	struct uio *uio = a->a_uio;
	struct sysvbfs_node *bnode = v->v_data;
	struct bfs_inode *inode = bnode->inode;
	vsize_t sz, filesz = bfs_file_size(inode);
	int err;
	const int advice = IO_ADV_DECODE(a->a_ioflag);

	DPRINTF("%s: type=%d\n", __func__, v->v_type);
	switch (v->v_type) {
	case VREG:
		break;
	case VDIR:
		return EISDIR;
	default:
		return EINVAL;
	}

	while (uio->uio_resid > 0) {
		if ((sz = MIN(filesz - uio->uio_offset, uio->uio_resid)) == 0)
			break;

		err = ubc_uiomove(&v->v_uobj, uio, sz, advice,
		    UBC_READ | UBC_PARTIALOK | UBC_UNMAP_FLAG(v));
		if (err)
			break;
		DPRINTF("%s: read %ldbyte\n", __func__, sz);
	}

	return sysvbfs_update(v, NULL, NULL, UPDATE_WAIT);
}
Пример #5
0
/*
 * are things locked??? they need to be to avoid this being
 * deleted or changed (data block pointer blocks moving about.)
 */
int
adosfs_read(void *v)
{
	struct vop_read_args /* {
		struct vnode *a_vp;
		struct uio *a_uio;
		int a_ioflag;
		kauth_cred_t a_cred;
	} */ *sp = v;
	struct vnode *vp = sp->a_vp;
	struct adosfsmount *amp;
	struct anode *ap;
	struct uio *uio;
	struct buf *bp;
	daddr_t lbn;
	int size, diff, error;
	long n, on;

#ifdef ADOSFS_DIAGNOSTIC
	advopprint(sp);
#endif
	error = 0;
	uio = sp->a_uio;
	ap = VTOA(sp->a_vp);
	amp = ap->amp;
	/*
	 * Return EOF for character devices, EIO for others
	 */
	if (sp->a_vp->v_type != VREG) {
		error = EIO;
		goto reterr;
	}
	if (uio->uio_resid == 0)
		goto reterr;
	if (uio->uio_offset < 0) {
		error = EINVAL;
		goto reterr;
	}

	/*
	 * to expensive to let general algorithm figure out that
	 * we are beyond the file.  Do it now.
	 */
	if (uio->uio_offset >= ap->fsize)
		goto reterr;

	/*
	 * taken from ufs_read()
	 */

	if (vp->v_type == VREG && IS_FFS(amp)) {
		const int advice = IO_ADV_DECODE(sp->a_ioflag);
		error = 0;

		while (uio->uio_resid > 0) {
			vsize_t bytelen = MIN(ap->fsize - uio->uio_offset,
					      uio->uio_resid);

			if (bytelen == 0) {
				break;
			}
			error = ubc_uiomove(&vp->v_uobj, uio, bytelen, advice,
			    UBC_READ | UBC_PARTIALOK | UBC_UNMAP_FLAG(vp));
			if (error) {
				break;
			}
		}
		goto out;
	}

	do {
		size = amp->dbsize;
		lbn = uio->uio_offset / size;
		on = uio->uio_offset % size;
		n = MIN(size - on, uio->uio_resid);
		diff = ap->fsize - uio->uio_offset;
		/*
		 * check for EOF
		 */
		if (diff <= 0)
			return(0);
		if (diff < n)
			n = diff;
		/*
		 * read ahead could possibly be worth something
		 * but not much as ados makes little attempt to
		 * make things contigous
		 */
		error = bread(sp->a_vp, lbn, amp->bsize, 0, &bp);
		if (error) {
			goto reterr;
		}
		if (!IS_FFS(amp)) {
			if (bp->b_resid > 0)
				error = EIO; /* OFS needs the complete block */
			else if (adoswordn(bp, 0) != BPT_DATA) {
#ifdef DIAGNOSTIC
				printf("adosfs: bad primary type blk %" PRId64 "\n",
				    bp->b_blkno / (amp->bsize / DEV_BSIZE));
#endif
				error = EINVAL;
			} else if (adoscksum(bp, ap->nwords)) {
#ifdef DIAGNOSTIC
				printf("adosfs: blk %" PRId64 " failed cksum.\n",
				    bp->b_blkno / (amp->bsize / DEV_BSIZE));
#endif
				error = EINVAL;
			}
		}

		if (error) {
			brelse(bp, 0);
			goto reterr;
		}
#ifdef ADOSFS_DIAGNOSTIC
		printf(" %" PRId64 "+%ld-%" PRId64 "+%ld", lbn, on, lbn, n);
#endif
		n = MIN(n, size - bp->b_resid);
		error = uiomove((char *)bp->b_data + on +
				amp->bsize - amp->dbsize, (int)n, uio);
		brelse(bp, 0);
	} while (error == 0 && uio->uio_resid > 0 && n != 0);

out:
reterr:
#ifdef ADOSFS_DIAGNOSTIC
	printf(" %d)", error);
#endif
	return(error);
}
/*
 * Vnode op for reading.
 */
int
filecore_read(void *v)
{
	struct vop_read_args /* {
		struct vnode *a_vp;
		struct uio *a_uio;
		int a_ioflag;
		kauth_cred_t a_cred;
	} */ *ap = v;
	struct vnode *vp = ap->a_vp;
	struct uio *uio = ap->a_uio;
	struct filecore_node *ip = VTOI(vp);
	struct filecore_mnt *fcmp;
	struct buf *bp;
	daddr_t lbn, rablock;
	off_t diff;
	int error = 0;
	long size, n, on;

	if (uio->uio_resid == 0)
		return (0);
	if (uio->uio_offset < 0)
		return (EINVAL);
	if (uio->uio_offset >= ip->i_size)
		return (0);
	ip->i_flag |= IN_ACCESS;
	fcmp = ip->i_mnt;

	if (vp->v_type == VREG) {
		const int advice = IO_ADV_DECODE(ap->a_ioflag);
		error = 0;

		while (uio->uio_resid > 0) {
			vsize_t bytelen = MIN(ip->i_size - uio->uio_offset,
					      uio->uio_resid);

			if (bytelen == 0) {
				break;
			}
			error = ubc_uiomove(&vp->v_uobj, uio, bytelen, advice,
			    UBC_READ | UBC_PARTIALOK | UBC_UNMAP_FLAG(vp));
			if (error) {
				break;
			}
		}
		goto out;
	}

	do {
		lbn = filecore_lblkno(fcmp, uio->uio_offset);
		on = filecore_blkoff(fcmp, uio->uio_offset);
		n = MIN(filecore_blksize(fcmp, ip, lbn) - on, uio->uio_resid);
		diff = (off_t)ip->i_size - uio->uio_offset;
		if (diff <= 0)
			return (0);
		if (diff < n)
			n = diff;
		size = filecore_blksize(fcmp, ip, lbn);
		rablock = lbn + 1;
		if (ip->i_dirent.attr & FILECORE_ATTR_DIR) {
			error = filecore_dbread(ip, &bp);
			on = uio->uio_offset;
			n = MIN(FILECORE_DIR_SIZE - on, uio->uio_resid);
			size = FILECORE_DIR_SIZE;
		} else {
			error = bread(vp, lbn, size, NOCRED, 0, &bp);
#ifdef FILECORE_DEBUG_BR
			printf("bread(%p, %llx, %ld, CRED, %p)=%d\n",
			    vp, (long long)lbn, size, bp, error);
#endif
		}
		if (error) {
			return (error);
		}
		n = MIN(n, size - bp->b_resid);

		error = uiomove((char *)(bp->b_data) + on, (int)n, uio);
#ifdef FILECORE_DEBUG_BR
		printf("brelse(%p) vn2\n", bp);
#endif
		brelse(bp, 0);
	} while (error == 0 && uio->uio_resid > 0 && n != 0);

out:
	return (error);
}
Пример #7
0
/*
 * Vnode op for reading.
 */
int
cd9660_read(void *v)
{
	struct vop_read_args /* {
		struct vnode *a_vp;
		struct uio *a_uio;
		int a_ioflag;
		kauth_cred_t a_cred;
	} */ *ap = v;
	struct vnode *vp = ap->a_vp;
	struct uio *uio = ap->a_uio;
	struct iso_node *ip = VTOI(vp);
	struct iso_mnt *imp;
	struct buf *bp;
	daddr_t lbn, rablock;
	off_t diff;
	int rasize, error = 0;
	long size, n, on;

	if (uio->uio_resid == 0)
		return (0);
	if (uio->uio_offset < 0)
		return (EINVAL);
	if (uio->uio_offset >= ip->i_size)
		return 0;
	ip->i_flag |= IN_ACCESS;
	imp = ip->i_mnt;

	if (vp->v_type == VREG) {
		const int advice = IO_ADV_DECODE(ap->a_ioflag);
		error = 0;

		while (uio->uio_resid > 0) {
			vsize_t bytelen = MIN(ip->i_size - uio->uio_offset,
					      uio->uio_resid);

			if (bytelen == 0)
				break;
			error = ubc_uiomove(&vp->v_uobj, uio, bytelen, advice,
			    UBC_READ | UBC_PARTIALOK | UBC_UNMAP_FLAG(vp));
			if (error)
				break;
		}
		goto out;
	}

	do {
		lbn = cd9660_lblkno(imp, uio->uio_offset);
		on = cd9660_blkoff(imp, uio->uio_offset);
		n = MIN(imp->logical_block_size - on, uio->uio_resid);
		diff = (off_t)ip->i_size - uio->uio_offset;
		if (diff <= 0)
			return (0);
		if (diff < n)
			n = diff;
		size = cd9660_blksize(imp, ip, lbn);
		rablock = lbn + 1;
		if (cd9660_lblktosize(imp, rablock) < ip->i_size) {
			rasize = cd9660_blksize(imp, ip, rablock);
			error = breadn(vp, lbn, size, &rablock,
				       &rasize, 1, NOCRED, 0, &bp);
		} else {
			error = bread(vp, lbn, size, NOCRED, 0, &bp);
		}
		if (error) {
			return (error);
		}
		n = MIN(n, size - bp->b_resid);

		error = uiomove((char *)bp->b_data + on, (int)n, uio);
		brelse(bp, 0);
	} while (error == 0 && uio->uio_resid > 0 && n != 0);

out:
	return (error);
}