Ejemplo n.º 1
0
/*
 * Write the machine-dependent part of a core dump.
 */
int
cpu_coredump(struct proc *p, struct vnode *vp, struct ucred *cred,
    struct core *chdr)
{
	struct coreseg cseg;
	struct md_coredump md_core;
	int error;
	
	CORE_SETMAGIC(*chdr, COREMAGIC, MID_POWERPC, 0);
	chdr->c_hdrsize = ALIGN(sizeof *chdr);
	chdr->c_seghdrsize = ALIGN(sizeof cseg);
	chdr->c_cpusize = sizeof md_core;

	process_read_regs(p, &(md_core.regs));
	
	CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_POWERPC, CORE_CPU);
	cseg.c_addr = 0;
	cseg.c_size = chdr->c_cpusize;

	error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cseg, chdr->c_seghdrsize,
	    (off_t)chdr->c_hdrsize, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT,
	    cred, NULL, p);
	if (error)
		return error;

	error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&md_core, sizeof md_core,
	    (off_t)(chdr->c_hdrsize + chdr->c_seghdrsize), UIO_SYSSPACE,
	    IO_NODELOCKED|IO_UNIT, cred, NULL, p);
	if (error)
		return error;

	chdr->c_nseg++;
	return 0;
}
Ejemplo n.º 2
0
static int
splat_vnode_test3(struct file *file, void *arg)
{
	vnode_t *vp;
	char buf1[32] = "SPL VNode Interface Test File\n";
	char buf2[32] = "";
	int rc;

	if ((rc = splat_vnode_unlink_all(file, arg, SPLAT_VNODE_TEST3_NAME)))
		return rc;

	if ((rc = vn_open(SPLAT_VNODE_TEST_FILE_RW, UIO_SYSSPACE,
			  FWRITE | FREAD | FCREAT | FEXCL,
			  0644, &vp, 0, 0))) {
		splat_vprint(file, SPLAT_VNODE_TEST3_NAME,
			     "Failed to vn_open test file: %s (%d)\n",
			     SPLAT_VNODE_TEST_FILE_RW, rc);
		return -rc;
	}

        rc = vn_rdwr(UIO_WRITE, vp, buf1, strlen(buf1), 0,
                     UIO_SYSSPACE, 0, RLIM64_INFINITY, 0, NULL);
	if (rc) {
		splat_vprint(file, SPLAT_VNODE_TEST3_NAME,
			     "Failed vn_rdwr write of test file: %s (%d)\n",
			     SPLAT_VNODE_TEST_FILE_RW, rc);
		goto out;
	}

        rc = vn_rdwr(UIO_READ, vp, buf2, strlen(buf1), 0,
                     UIO_SYSSPACE, 0, RLIM64_INFINITY, 0, NULL);
	if (rc) {
		splat_vprint(file, SPLAT_VNODE_TEST3_NAME,
			     "Failed vn_rdwr read of test file: %s (%d)\n",
			     SPLAT_VNODE_TEST_FILE_RW, rc);
		goto out;
	}

	if (strncmp(buf1, buf2, strlen(buf1))) {
		rc = EINVAL;
		splat_vprint(file, SPLAT_VNODE_TEST3_NAME,
			     "Failed strncmp data written does not match "
			     "data read\nWrote: %sRead:  %s\n", buf1, buf2);
		goto out;
	}

	rc = 0;
	splat_vprint(file, SPLAT_VNODE_TEST3_NAME, "Wrote: %s", buf1);
	splat_vprint(file, SPLAT_VNODE_TEST3_NAME, "Read:  %s", buf2);
	splat_vprint(file, SPLAT_VNODE_TEST3_NAME, "Successfully wrote and "
		     "read expected data pattern to test file: %s\n",
		     SPLAT_VNODE_TEST_FILE_RW);

out:
        VOP_CLOSE(vp, 0, 0, 0, 0, 0);
	vn_remove(SPLAT_VNODE_TEST_FILE_RW, UIO_SYSSPACE, RMFILE);

        return -rc;
} /* splat_vnode_test3() */
Ejemplo n.º 3
0
/*
 * ulfs_read_dotdot: Store in *ino_ret the inode number of the parent
 * of the directory vp.
 */
static int
ulfs_read_dotdot(struct vnode *vp, kauth_cred_t cred, ino_t *ino_ret)
{
	struct lfs_dirtemplate dirbuf;
	int error;

	KASSERT(vp != NULL);
	KASSERT(ino_ret != NULL);
	KASSERT(vp->v_type == VDIR);

	error = vn_rdwr(UIO_READ, vp, &dirbuf, sizeof dirbuf, (off_t)0,
	    UIO_SYSSPACE, IO_NODELOCKED, cred, NULL, NULL);
	if (error)
		return error;

	if (ulfs_dirbuf_dotdot_namlen(&dirbuf, vp) != 2 ||
	    dirbuf.dotdot_name[0] != '.' ||
	    dirbuf.dotdot_name[1] != '.')
		/* XXX Panic?  Print warning?  */
		return ENOTDIR;

	*ino_ret = ulfs_rw32(dirbuf.dotdot_ino,
	    ULFS_IPNEEDSWAP(VTOI(vp)));
	return 0;
}
Ejemplo n.º 4
0
/*
 * symlink -- make a symbolic link
 */
static int
ext2_symlink(struct vop_symlink_args *ap)
{
	struct vnode *vp, **vpp = ap->a_vpp;
	struct inode *ip;
	int len, error;

	error = ext2_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp,
	    vpp, ap->a_cnp);
	if (error)
		return (error);
	vp = *vpp;
	len = strlen(ap->a_target);
	if (len < vp->v_mount->mnt_maxsymlinklen) {
		ip = VTOI(vp);
		bcopy(ap->a_target, (char *)ip->i_shortlink, len);
		ip->i_size = len;
		ip->i_flag |= IN_CHANGE | IN_UPDATE;
	} else
		error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0,
		    UIO_SYSSPACE, IO_NODELOCKED | IO_NOMACCHECK,
		    ap->a_cnp->cn_cred, NOCRED, NULL, NULL);
	if (error)
		vput(vp);
	return (error);
}
Ejemplo n.º 5
0
static int
zfs_replay_write(zfsvfs_t *zsb, lr_write_t *lr, boolean_t byteswap)
{
	char *data = (char *)(lr + 1);	/* data follows lr_write_t */
	znode_t	*zp;
	int error;
	uint64_t eod, offset, length;
    ssize_t resid;

	if (byteswap)
		byteswap_uint64_array(lr, sizeof (*lr));

	if ((error = zfs_zget(zsb, lr->lr_foid, &zp)) != 0) {
		/*
		 * As we can log writes out of order, it's possible the
		 * file has been removed. In this case just drop the write
		 * and return success.
		 */
		if (error == ENOENT)
			error = 0;
		return (error);
	}
    zfs_znode_wait_vnode(zp);

	offset = lr->lr_offset;
	length = lr->lr_length;
	eod = offset + length;	/* end of data for this write */

	/*
	 * This may be a write from a dmu_sync() for a whole block,
	 * and may extend beyond the current end of the file.
	 * We can't just replay what was written for this TX_WRITE as
	 * a future TX_WRITE2 may extend the eof and the data for that
	 * write needs to be there. So we write the whole block and
	 * reduce the eof. This needs to be done within the single dmu
	 * transaction created within vn_rdwr -> zfs_write. So a possible
	 * new end of file is passed through in zsb->z_replay_eof
	 */

	zsb->z_replay_eof = 0; /* 0 means don't change end of file */

	/* If it's a dmu_sync() block, write the whole block */
	if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) {
		uint64_t blocksize = BP_GET_LSIZE(&lr->lr_blkptr);
		if (length < blocksize) {
			offset -= offset % blocksize;
			length = blocksize;
		}
		if (zp->z_size < eod)
			zsb->z_replay_eof = eod;
	}

    error = vn_rdwr(UIO_WRITE, ZTOV(zp), data, length, offset,
                    UIO_SYSSPACE, 0, RLIM64_INFINITY, kcred, &resid);

    VN_RELE(ZTOV(zp));
	zsb->z_replay_eof = 0;	/* safety */

	return (error);
}
Ejemplo n.º 6
0
/* Generic write interface */
int
afs_osi_Write(struct osi_file *afile, afs_int32 offset, void *aptr,
	      afs_int32 asize)
{
    unsigned int resid;
    afs_int32 code;

    AFS_STATCNT(osi_Write);
    if (!afile)
	osi_Panic("afs_osi_Write called with null afile");
    if (offset != -1)
	afile->offset = offset;

    AFS_GUNLOCK();
    VOP_LOCK(afile->vnode, LK_EXCLUSIVE | LK_RETRY);
    code =
	vn_rdwr(UIO_WRITE, afile->vnode, (caddr_t) aptr, asize, afile->offset,
		AFS_UIOSYS, IO_UNIT, afs_osi_credp, &resid, osi_curproc());
    VOP_UNLOCK(afile->vnode, 0);
    AFS_GLOCK();

    if (code == 0) {
	code = asize - resid;
	afile->offset += code;
	if (afile->offset > afile->size)
	    afile->size = afile->offset;
    } else
	code = -1;

    if (afile->proc)
	(*afile->proc) (afile, code);

    return code;
}
Ejemplo n.º 7
0
static int
vfs_mountroot_readconf(struct thread *td, struct sbuf *sb)
{
	static char buf[128];
	struct nameidata nd;
	off_t ofs;
	ssize_t resid;
	int error, flags, len;

	NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/.mount.conf", td);
	flags = FREAD;
	error = vn_open(&nd, &flags, 0, NULL);
	if (error)
		return (error);

	NDFREE(&nd, NDF_ONLY_PNBUF);
	ofs = 0;
	len = sizeof(buf) - 1;
	while (1) {
		error = vn_rdwr(UIO_READ, nd.ni_vp, buf, len, ofs,
		    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred,
		    NOCRED, &resid, td);
		if (error)
			break;
		if (resid == len)
			break;
		buf[len - resid] = 0;
		sbuf_printf(sb, "%s", buf);
		ofs += len - resid;
	}

	VOP_UNLOCK(nd.ni_vp, 0);
	vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
	return (error);
}
Ejemplo n.º 8
0
static int
kfread(kfile_t *fp, char *buf, ssize_t bufsiz, ssize_t *ret_n)
{
	ssize_t		resid;
	int		err;
	ssize_t		n;

	ASSERT(modrootloaded);

	if (fp->kf_state != 0)
		return (fp->kf_state);

	err = vn_rdwr(UIO_READ, fp->kf_vp, buf, bufsiz, fp->kf_fpos,
		UIO_SYSSPACE, 0, (rlim64_t)0, kcred, &resid);
	if (err != 0) {
		KFDEBUG((CE_CONT, "%s: read error %d\n",
			fp->kf_fname, err));
		fp->kf_state = err;
		return (err);
	}

	ASSERT(resid >= 0 && resid <= bufsiz);
	n = bufsiz - resid;

	KFDEBUG1((CE_CONT, "%s: read %ld bytes ok %ld bufsiz, %ld resid\n",
		fp->kf_fname, n, bufsiz, resid));

	fp->kf_fpos += n;
	*ret_n = n;
	return (0);
}
Ejemplo n.º 9
0
/* Generic write interface */
int
afs_osi_Write(struct osi_file *afile, afs_int32 offset, void *aptr,
	      afs_int32 asize)
{
    size_t resid;
    afs_int32 code;

    AFS_STATCNT(osi_Write);
    if (!afile)
	osi_Panic("afs_osi_Write called with null afile");
    if (offset != -1)
	afile->offset = offset;

    AFS_GUNLOCK();
    code =
	vn_rdwr(UIO_WRITE, afile->vnode, aptr, asize, afile->offset,
		AFS_UIOSYS, IO_UNIT, afs_osi_credp, &resid, osi_curproc());
    AFS_GLOCK();

    if (code == 0) {
	code = asize - resid;
	afile->offset += code;
	if (afile->offset > afile->size)
	    afile->size = afile->offset;
    } else {
	if (code > 0) {
	    code = -code;
	}
    }

    if (afile->proc)
	(*afile->proc) (afile, code);

    return code;
}
Ejemplo n.º 10
0
/*
 * symlink -- make a symbolic link
 */
int
ufs_symlink(void *v)
{
	struct vop_symlink_args *ap = v;
	struct vnode *vp, **vpp = ap->a_vpp;
	struct inode *ip;
	int len, error;

	error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp,
			      vpp, ap->a_cnp);
	if (error)
		return (error);
	VN_KNOTE(ap->a_dvp, NOTE_WRITE);
	vp = *vpp;
	len = strlen(ap->a_target);
	if (len < vp->v_mount->mnt_maxsymlinklen) {
		ip = VTOI(vp);
		bcopy(ap->a_target, (char *)SHORTLINK(ip), len);
		DIP_ASSIGN(ip, size, len);
		ip->i_flag |= IN_CHANGE | IN_UPDATE;
	} else
		error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0,
		    UIO_SYSSPACE, IO_NODELOCKED, ap->a_cnp->cn_cred, NULL,
		    curproc);
	vput(vp);
	return (error);
}
Ejemplo n.º 11
0
int
randomdev_write_file(const char *filename, void *buf, size_t length)
{
	struct nameidata nd;
	struct thread* td = curthread;
	int error;
	ssize_t resid;
	int flags;

	NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, td);
	flags = FWRITE | O_CREAT | O_TRUNC;
	error = vn_open(&nd, &flags, 0, NULL);
	if (error == 0) {
		NDFREE(&nd, NDF_ONLY_PNBUF);
		if (nd.ni_vp->v_type != VREG)
			error = ENOEXEC;
		else
			error = vn_rdwr(UIO_WRITE, nd.ni_vp, buf, length, 0, UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, &resid, td);

		VOP_UNLOCK(nd.ni_vp, 0);
		vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
	}

	return (error);
}
Ejemplo n.º 12
0
static void
sd_log(vfs_context_t ctx, const char *fmt, ...) 
{
	int resid, log_error, len;
	char logbuf[100];
	va_list arglist;

	/* If the log isn't open yet, open it */
	if (sd_logvp == NULLVP) {
		if (sd_openlog(ctx) != 0) {
			/* Couldn't open, we fail out */
			return;
		}
	}

	va_start(arglist, fmt);
	len = vsnprintf(logbuf, sizeof(logbuf), fmt, arglist);
	log_error = vn_rdwr(UIO_WRITE, sd_logvp, (caddr_t)logbuf, len, sd_log_offset,
			UIO_SYSSPACE, IO_UNIT | IO_NOAUTH, vfs_context_ucred(ctx), &resid, vfs_context_proc(ctx));
	if (log_error == EIO || log_error == 0) {
		sd_log_offset += (len - resid);
	}

	va_end(arglist);

}
Ejemplo n.º 13
0
/*
 * symlink -- make a symbolic link
 */
int
ext2fs_symlink(void *v)
{
	struct vop_symlink_args *ap = v;
	struct vnode *vp, **vpp = ap->a_vpp;
	struct inode *ip;
	int len, error;

	error = ext2fs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp,
			      vpp, ap->a_cnp);
	if (error)
		return (error);
	vp = *vpp;
	len = strlen(ap->a_target);
	if (len < vp->v_mount->mnt_maxsymlinklen) {
		ip = VTOI(vp);
		bcopy(ap->a_target, (char *)ip->i_e2din->e2di_shortlink, len);
		error = ext2fs_setsize(ip, len);
		if (error)
			goto bad;
		ip->i_flag |= IN_CHANGE | IN_UPDATE;
	} else
		error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0,
		    UIO_SYSSPACE, IO_NODELOCKED, ap->a_cnp->cn_cred, NULL,
		    curproc);
bad:	
	vput(vp);
	return (error);
}
Ejemplo n.º 14
0
static int
zfs_replay_write(zfsvfs_t *zfsvfs, lr_write_t *lr, boolean_t byteswap)
{
	char *data = (char *)(lr + 1);	/* data follows lr_write_t */
	znode_t	*zp;
	int error;
	ssize_t resid;

	if (byteswap)
		byteswap_uint64_array(lr, sizeof (*lr));

	if ((error = zfs_zget(zfsvfs, lr->lr_foid, &zp)) != 0) {
		/*
		 * As we can log writes out of order, it's possible the
		 * file has been removed. In this case just drop the write
		 * and return success.
		 */
		if (error == ENOENT)
			error = 0;
		return (error);
	}

	error = vn_rdwr(UIO_WRITE, ZTOV(zp), data, lr->lr_length,
	    lr->lr_offset, UIO_SYSSPACE, 0, RLIM64_INFINITY, kcred, &resid);

	VN_RELE(ZTOV(zp));

	return (error);
}
Ejemplo n.º 15
0
/*
 * Crack open a '#!' line.
 */
static int
getintphead(struct vnode *vp, struct intpdata *idatap)
{
	int error;
	char *cp, *linep = idatap->intp;
	ssize_t resid;

	/*
	 * Read the entire line and confirm that it starts with '#!'.
	 */
	if (error = vn_rdwr(UIO_READ, vp, linep, INTPSZ, (offset_t)0,
	    UIO_SYSSPACE, 0, (rlim64_t)0, CRED(), &resid))
		return (error);
	if (resid > INTPSZ-2 || linep[0] != '#' || linep[1] != '!')
		return (ENOEXEC);
	/*
	 * Blank all white space and find the newline.
	 */
	for (cp = &linep[2]; cp < &linep[INTPSZ] && *cp != '\n'; cp++)
		if (*cp == '\t')
			*cp = ' ';
	if (cp >= &linep[INTPSZ])
		return (ENOEXEC);
	ASSERT(*cp == '\n');
	*cp = '\0';

	/*
	 * Locate the beginning and end of the interpreter name.
	 * In addition to the name, one additional argument may
	 * optionally be included here, to be prepended to the
	 * arguments provided on the command line.  Thus, for
	 * example, you can say
	 *
	 * 	#! /usr/bin/awk -f
	 */
	for (cp = &linep[2]; *cp == ' '; cp++)
		;
	if (*cp == '\0')
		return (ENOEXEC);
	idatap->intp_name = cp;
	while (*cp && *cp != ' ')
		cp++;
	if (*cp == '\0')
		idatap->intp_arg = NULL;
	else {
		*cp++ = '\0';
		while (*cp == ' ')
			cp++;
		if (*cp == '\0')
			idatap->intp_arg = NULL;
		else {
			idatap->intp_arg = cp;
			while (*cp && *cp != ' ')
				cp++;
			*cp = '\0';
		}
	}
	return (0);
}
Ejemplo n.º 16
0
int
cpu_coredump(struct proc *p, struct vnode *vp, struct ucred *cred,
    struct core *chdr)
{
	int error;
	struct {
		struct reg regs;
		struct fpreg fpregs;
	} cpustate;
	struct coreseg cseg;

	CORE_SETMAGIC(*chdr, COREMAGIC, MID_MACHINE, 0);
	chdr->c_hdrsize = ALIGN(sizeof(*chdr));
	chdr->c_seghdrsize = ALIGN(sizeof(cseg));
	chdr->c_cpusize = sizeof(cpustate);

	/* Save integer registers. */
	error = process_read_regs(p, &cpustate.regs);
	if (error)
		return error;
	/* Save floating point registers. */
	error = process_read_fpregs(p, &cpustate.fpregs);
	if (error)
		return error;

	CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU);
	cseg.c_addr = 0;
	cseg.c_size = chdr->c_cpusize;

	error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cseg, chdr->c_seghdrsize,
	    (off_t)chdr->c_hdrsize, UIO_SYSSPACE,
	    IO_NODELOCKED|IO_UNIT, cred, NULL, p);
	if (error)
		return error;

	error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cpustate, sizeof(cpustate),
	    (off_t)(chdr->c_hdrsize + chdr->c_seghdrsize), UIO_SYSSPACE,
	    IO_NODELOCKED|IO_UNIT, cred, NULL, p);
	if (error)
		return error;

	chdr->c_nseg++;

	return error;
}
Ejemplo n.º 17
0
int
kern_write_file(struct kern_direct_file_io_ref_t * ref, off_t offset, caddr_t addr, vm_size_t len)
{
    return (vn_rdwr(UIO_WRITE, ref->vp,
			addr, len, offset,
			UIO_SYSSPACE, IO_SYNC|IO_NODELOCKED|IO_UNIT, 
                        vfs_context_ucred(ref->ctx), (int *) 0,
			vfs_context_proc(ref->ctx)));
}
Ejemplo n.º 18
0
int
kern_read_file(struct kern_direct_file_io_ref_t * ref, off_t offset, void * addr, size_t len, int ioflag)
{
    return (vn_rdwr(UIO_READ, ref->vp,
			addr, len, offset,
			UIO_SYSSPACE, ioflag|IO_SYNC|IO_NODELOCKED|IO_UNIT, 
                        vfs_context_ucred(ref->ctx), (int *) 0,
			vfs_context_proc(ref->ctx)));
}
Ejemplo n.º 19
0
static int
zfs_replay_write(zfsvfs_t *zfsvfs, lr_write_t *lr, boolean_t byteswap)
{
	char *data = (char *)(lr + 1);	/* data follows lr_write_t */
	znode_t	*zp;
	int error;
	ssize_t resid;
	uint64_t orig_eof, eod, offset, length;

	if (byteswap)
		byteswap_uint64_array(lr, sizeof (*lr));

	if ((error = zfs_zget(zfsvfs, lr->lr_foid, &zp)) != 0) {
		/*
		 * As we can log writes out of order, it's possible the
		 * file has been removed. In this case just drop the write
		 * and return success.
		 */
		if (error == ENOENT)
			error = 0;
		return (error);
	}

	offset = lr->lr_offset;
	length = lr->lr_length;
	eod = offset + length;		/* end of data for this write */

	orig_eof = zp->z_phys->zp_size;

	/* If it's a dmu_sync() block, write the whole block */
	if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) {
		uint64_t blocksize = BP_GET_LSIZE(&lr->lr_blkptr);
		if (length < blocksize) {
			offset -= offset % blocksize;
			length = blocksize;
		}
	}

	error = vn_rdwr(UIO_WRITE, ZTOV(zp), data, length, offset,
	    UIO_SYSSPACE, 0, RLIM64_INFINITY, kcred, &resid);

	/*
	 * This may be a write from a dmu_sync() for a whole block,
	 * and may extend beyond the current end of the file.
	 * We can't just replay what was written for this TX_WRITE as
	 * a future TX_WRITE2 may extend the eof and the data for that
	 * write needs to be there. So we write the whole block and
	 * reduce the eof.
	 */
	if (orig_eof < zp->z_phys->zp_size) /* file length grew ? */
		zp->z_phys->zp_size = eod;

	VN_RELE(ZTOV(zp));

	return (error);
}
Ejemplo n.º 20
0
static void
vdev_file_io_start(zio_t *zio)
{
    vdev_t *vd = zio->io_vd;
    vdev_file_t *vf = vd->vdev_tsd;
    ssize_t resid = 0;


    if (zio->io_type == ZIO_TYPE_IOCTL) {

        if (!vdev_readable(vd)) {
            zio->io_error = SET_ERROR(ENXIO);
			zio_interrupt(zio);
            return;
        }

        switch (zio->io_cmd) {
        case DKIOCFLUSHWRITECACHE:
            if (!vnode_getwithvid(vf->vf_vnode, vf->vf_vid)) {
                zio->io_error = VOP_FSYNC(vf->vf_vnode, FSYNC | FDSYNC,
                                          kcred, NULL);
                vnode_put(vf->vf_vnode);
            }
            break;
        default:
            zio->io_error = SET_ERROR(ENOTSUP);
        }

		zio_interrupt(zio);
        return;
    }

	ASSERT(zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE);

    if (!vnode_getwithvid(vf->vf_vnode, vf->vf_vid)) {

		/*
		VERIFY3U(taskq_dispatch(vdev_file_taskq, vdev_file_io_strategy, zio,
	    TQ_PUSHPAGE), !=, 0);
		*/

        zio->io_error = vn_rdwr(zio->io_type == ZIO_TYPE_READ ?
                           UIO_READ : UIO_WRITE, vf->vf_vnode, zio->io_data,
                           zio->io_size, zio->io_offset, UIO_SYSSPACE,
                           0, RLIM64_INFINITY, kcred, &resid);
        vnode_put(vf->vf_vnode);
    }

    if (resid != 0 && zio->io_error == 0)
        zio->io_error = SET_ERROR(ENOSPC);

    zio_interrupt(zio);

    return;
}
Ejemplo n.º 21
0
int
vmcmd_readvn(struct lwp *l, struct exec_vmcmd *cmd)
{
	struct proc *p = l->l_proc;
	int error;
	vm_prot_t prot, maxprot;

	error = vn_rdwr(UIO_READ, cmd->ev_vp, (void *)cmd->ev_addr,
	    cmd->ev_len, cmd->ev_offset, UIO_USERSPACE, IO_UNIT,
	    l->l_cred, NULL, l);
	if (error)
		return error;

	prot = cmd->ev_prot;
	maxprot = VM_PROT_ALL;
#ifdef PAX_MPROTECT
	pax_mprotect(l, &prot, &maxprot);
#endif /* PAX_MPROTECT */

#ifdef PMAP_NEED_PROCWR
	/*
	 * we had to write the process, make sure the pages are synched
	 * with the instruction cache.
	 */
	if (prot & VM_PROT_EXECUTE)
		pmap_procwr(p, cmd->ev_addr, cmd->ev_len);
#endif

	/*
	 * we had to map in the area at PROT_ALL so that vn_rdwr()
	 * could write to it.   however, the caller seems to want
	 * it mapped read-only, so now we are going to have to call
	 * uvm_map_protect() to fix up the protection.  ICK.
	 */
	if (maxprot != VM_PROT_ALL) {
		error = uvm_map_protect(&p->p_vmspace->vm_map,
				trunc_page(cmd->ev_addr),
				round_page(cmd->ev_addr + cmd->ev_len),
				maxprot, true);
		if (error)
			return (error);
	}

	if (prot != maxprot) {
		error = uvm_map_protect(&p->p_vmspace->vm_map,
				trunc_page(cmd->ev_addr),
				round_page(cmd->ev_addr + cmd->ev_len),
				prot, false);
		if (error)
			return (error);
	}

	return 0;
}
Ejemplo n.º 22
0
/*
 * Check if source directory is in the path of the target directory.
 * Target is supplied locked, source is unlocked.
 * The target is always vput before returning.
 */
int
ext2_checkpath(struct inode *source, struct inode *target, struct ucred *cred)
{
	struct vnode *vp;
	int error, rootino, namlen;
	struct dirtemplate dirbuf;

	vp = ITOV(target);
	if (target->i_number == source->i_number) {
		error = EEXIST;
		goto out;
	}
	rootino = ROOTINO;
	error = 0;
	if (target->i_number == rootino)
		goto out;

	for (;;) {
		if (vp->v_type != VDIR) {
			error = ENOTDIR;
			break;
		}
		error = vn_rdwr(UIO_READ, vp, (caddr_t)&dirbuf,
				sizeof (struct dirtemplate), (off_t)0,
				UIO_SYSSPACE, IO_NODELOCKED, cred, NULL);
		if (error != 0)
			break;
		namlen = dirbuf.dotdot_type;	/* like ufs little-endian */
		if (namlen != 2 ||
		    dirbuf.dotdot_name[0] != '.' ||
		    dirbuf.dotdot_name[1] != '.') {
			error = ENOTDIR;
			break;
		}
		if (dirbuf.dotdot_ino == source->i_number) {
			error = EINVAL;
			break;
		}
		if (dirbuf.dotdot_ino == rootino)
			break;
		vput(vp);
		if ((error = VFS_VGET(vp->v_mount, NULL, dirbuf.dotdot_ino, &vp)) != 0) {
			vp = NULL;
			break;
		}
	}

out:
	if (error == ENOTDIR)
		kprintf("checkpath: .. not a directory\n");
	if (vp != NULL)
		vput(vp);
	return (error);
}
Ejemplo n.º 23
0
static int
kfwrite(kfile_t *fp, char *buf, ssize_t bufsiz, ssize_t *ret_n)
{
	rlim64_t	rlimit;
	ssize_t		resid;
	int		err;
	ssize_t		len;
	ssize_t		n = 0;

	ASSERT(modrootloaded);

	if (fp->kf_state != 0)
		return (fp->kf_state);

	len = bufsiz;
	rlimit = bufsiz + 1;
	for (;;) {
		err = vn_rdwr(UIO_WRITE, fp->kf_vp, buf, len, fp->kf_fpos,
			UIO_SYSSPACE, FSYNC, rlimit, kcred, &resid);
		if (err) {
			KFDEBUG((CE_CONT, "%s: write error %d\n",
				fp->kf_fname, err));
			fp->kf_state = err;
			return (err);
		}

		KFDEBUG1((CE_CONT, "%s: write %ld bytes ok %ld resid\n",
			fp->kf_fname, len-resid, resid));

		ASSERT(resid >= 0 && resid <= len);

		n += (len - resid);
		if (resid == 0)
			break;

		if (resid == len) {
			KFDEBUG((CE_CONT, "%s: filesystem full?\n",
				fp->kf_fname));
			fp->kf_state = ENOSPC;
			return (ENOSPC);
		}

		len -= resid;
		buf += len;
		fp->kf_fpos += len;
		len = resid;
	}

	ASSERT(n == bufsiz);
	KFDEBUG1((CE_CONT, "%s: wrote %ld bytes ok\n", fp->kf_fname, n));

	*ret_n = n;
	return (0);
}
Ejemplo n.º 24
0
static int
spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl)
{
	size_t buflen;
	char *buf;
	vnode_t *vp;
	int oflags = FWRITE | FTRUNC | FCREAT | FOFFMAX;
	char *temp;
	int err;

	/*
	 * If the nvlist is empty (NULL), then remove the old cachefile.
	 */
	if (nvl == NULL) {
		err = vn_remove(dp->scd_path, UIO_SYSSPACE, RMFILE);
		return (err);
	}

	/*
	 * Pack the configuration into a buffer.
	 */
	VERIFY(nvlist_size(nvl, &buflen, NV_ENCODE_XDR) == 0);

	buf = kmem_alloc(buflen, KM_SLEEP);
	temp = kmem_zalloc(MAXPATHLEN, KM_SLEEP);

	VERIFY(nvlist_pack(nvl, &buf, &buflen, NV_ENCODE_XDR,
	    KM_SLEEP) == 0);

	/*
	 * Write the configuration to disk.  We need to do the traditional
	 * 'write to temporary file, sync, move over original' to make sure we
	 * always have a consistent view of the data.
	 */
	(void) snprintf(temp, MAXPATHLEN, "%s.tmp", dp->scd_path);

	err = vn_open(temp, UIO_SYSSPACE, oflags, 0644, &vp, CRCREAT, 0);
	if (err == 0) {
		err = vn_rdwr(UIO_WRITE, vp, buf, buflen, 0, UIO_SYSSPACE,
		    0, RLIM64_INFINITY, kcred, NULL);
		if (err == 0)
			err = VOP_FSYNC(vp, FSYNC, kcred, NULL);
		if (err == 0)
			err = vn_rename(temp, dp->scd_path, UIO_SYSSPACE);
		(void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL);
	}

	(void) vn_remove(temp, UIO_SYSSPACE, RMFILE);

	kmem_free(buf, buflen);
	kmem_free(temp, MAXPATHLEN);
	return (err);
}
Ejemplo n.º 25
0
/*
 * Check if a directory is empty or not.
 * Inode supplied must be locked.
 *
 * Using a struct dirtemplate here is not precisely
 * what we want, but better than using a struct direct.
 *
 * NB: does not handle corrupted directories.
 */
int
ufs_dirempty(struct inode *ip, ufsino_t parentino, struct ucred *cred)
{
	off_t off, m;
	struct dirtemplate dbuf;
	struct direct *dp = (struct direct *)&dbuf;
	int error, namlen;
	size_t count;
#define	MINDIRSIZ (sizeof (struct dirtemplate) / 2)

	m = DIP(ip, size);
	for (off = 0; off < m; off += dp->d_reclen) {
		error = vn_rdwr(UIO_READ, ITOV(ip), (caddr_t)dp, MINDIRSIZ, off,
		   UIO_SYSSPACE, IO_NODELOCKED, cred, &count, curproc);
		/*
		 * Since we read MINDIRSIZ, residual must
		 * be 0 unless we're at end of file.
		 */
		if (error || count != 0)
			return (0);
		/* avoid infinite loops */
		if (dp->d_reclen == 0)
			return (0);
		/* skip empty entries */
		if (dp->d_ino == 0)
			continue;
		/* accept only "." and ".." */
#		if (BYTE_ORDER == LITTLE_ENDIAN)
			if (ITOV(ip)->v_mount->mnt_maxsymlinklen > 0)
				namlen = dp->d_namlen;
			else
				namlen = dp->d_type;
#		else
			namlen = dp->d_namlen;
#		endif
		if (namlen > 2)
			return (0);
		if (dp->d_name[0] != '.')
			return (0);
		/*
		 * At this point namlen must be 1 or 2.
		 * 1 implies ".", 2 implies ".." if second
		 * char is also "."
		 */
		if (namlen == 1 && dp->d_ino == ip->i_number)
			continue;
		if (dp->d_name[1] == '.' && dp->d_ino == parentino)
			continue;
		return (0);
	}
	return (1);
}
Ejemplo n.º 26
0
int
vm_record_file_write(vnode_t vp, uint64_t offset, char *buf, int size)
{
	int error = 0;
	vfs_context_t ctx;

	ctx = vfs_context_kernel();
		
	error = vn_rdwr(UIO_WRITE, vp, (caddr_t)buf, size, offset,
		UIO_SYSSPACE, IO_NODELOCKED, vfs_context_ucred(ctx), (int *) 0, vfs_context_proc(ctx));

	return (error);
}
Ejemplo n.º 27
0
static int
verify_file(struct ucred *cred, struct vnode *vp)
{
	char buffer[256];
	char hash[SHA256_DIGEST_LENGTH > uECC_BYTES ? SHA256_DIGEST_LENGTH : uECC_BYTES];
	char signature[2*uECC_BYTES];

	int error, len;
	ssize_t resid;
	off_t i, size;
	SHA256_CTX ctx;
	struct stat stat;

	i = 0;
	error = vn_stat(vp, &stat, cred, NOCRED, curthread);
	size = stat.st_size;
	if (error)
		return (EPERM);

	len = sizeof(signature);
	error = vn_extattr_get(vp, IO_NODELOCKED, EXTATTR_NAMESPACE_SYSTEM, 
	    "signature", &len, signature, curthread);
	if (error)
		return (EPERM);

#ifdef DEBUG
	printf("Signature: ");
	print_hex(signature, sizeof(signature));
#endif
	SHA256_Init(&ctx);
	while(i < size && !error) {
		len = size - i > sizeof(buffer) ? sizeof(buffer) : size - i;
		error = vn_rdwr(UIO_READ, vp, buffer, len, i,
		    UIO_SYSSPACE, IO_NODELOCKED, cred, NOCRED,
		    &resid, curthread);
		SHA256_Update(&ctx, buffer, len);
		i += len;
	}
	if (error)
		return (EPERM);

	SHA256_Final(hash, &ctx);
#ifdef DEBUG
	printf("Hash: ");
	print_hex(hash, sizeof(hash));
#endif
	if (!uECC_verify(pubkey, hash, signature))
		return (EPERM);

	return (0);
}
Ejemplo n.º 28
0
/*
 * Helper function for findroot():
 * Return non-zero if wedge device matches bootinfo.
 */
static int
match_bootwedge(device_t dv, struct btinfo_bootwedge *biw)
{
	MD5_CTX ctx;
	struct vnode *tmpvn;
	int error;
	uint8_t bf[DEV_BSIZE];
	uint8_t hash[16];
	int found = 0;
	daddr_t blk;
	uint64_t nblks;

	/*
	 * If the boot loader didn't specify the sector, abort.
	 */
	if (biw->matchblk == -1) {
		DPRINTF(("%s: no sector specified for %s\n", __func__,
			device_xname(dv)));
		return 0;
	}

	if ((tmpvn = opendisk(dv)) == NULL) {
		DPRINTF(("%s: can't open %s\n", __func__, device_xname(dv)));
		return 0;
	}

	MD5Init(&ctx);
	for (blk = biw->matchblk, nblks = biw->matchnblks;
	     nblks != 0; nblks--, blk++) {
		error = vn_rdwr(UIO_READ, tmpvn, (void *) bf,
		    sizeof(bf), blk * DEV_BSIZE, UIO_SYSSPACE,
		    0, NOCRED, NULL, NULL);
		if (error) {
			printf("%s: unable to read block %" PRId64 " "
			    "of dev %s (%d)\n", __func__,
			    blk, device_xname(dv), error);
			goto closeout;
		}
		MD5Update(&ctx, bf, sizeof(bf));
	}
	MD5Final(hash, &ctx);

	/* Compare with the provided hash. */
	found = memcmp(biw->matchhash, hash, sizeof(hash)) == 0;
	DPRINTF(("%s: %s found=%d\n", __func__, device_xname(dv), found));

 closeout:
	VOP_CLOSE(tmpvn, FREAD, NOCRED);
	vput(tmpvn);
	return found;
}
Ejemplo n.º 29
0
/*
 * ext2fs_rename_replace_dotdot: Change the target of the `..' entry of
 * the directory vp from fdvp to tdvp.
 */
static int
ext2fs_rename_replace_dotdot(struct vnode *vp,
    struct vnode *fdvp, struct vnode *tdvp,
    kauth_cred_t cred)
{
	struct ext2fs_dirtemplate dirbuf;
	int error;

	/* XXX Does it make sense to do this before the sanity checks below?  */
	KASSERT(0 < VTOI(fdvp)->i_e2fs_nlink);
	VTOI(fdvp)->i_e2fs_nlink--;
	VTOI(fdvp)->i_flag |= IN_CHANGE;

	error = vn_rdwr(UIO_READ, vp, &dirbuf, sizeof dirbuf, (off_t)0,
	    UIO_SYSSPACE, IO_NODELOCKED, cred, NULL, NULL);
	if (error)
		return error;

	if (dirbuf.dotdot_namlen != 2 ||
	    dirbuf.dotdot_name[0] != '.' ||
	    dirbuf.dotdot_name[1] != '.') {
		ufs_dirbad(VTOI(vp), (doff_t)12, "bad `..' entry");
		return 0;
	}

	if (fs2h32(dirbuf.dotdot_ino) != VTOI(fdvp)->i_number) {
		ufs_dirbad(VTOI(vp), (doff_t)12,
		    "`..' does not point at parent");
		return 0;
	}

	dirbuf.dotdot_ino = h2fs32(VTOI(tdvp)->i_number);
	/* XXX WTF?  Why not check error?  */
	(void)vn_rdwr(UIO_WRITE, vp, &dirbuf, sizeof dirbuf, (off_t)0,
	    UIO_SYSSPACE, (IO_NODELOCKED | IO_SYNC), cred, NULL, NULL);

	return 0;
}
Ejemplo n.º 30
0
static int
in_write(struct vnode *vp, offset_t *vo, caddr_t buf, int count)
{
	int error;
	ssize_t resid;
	rlim64_t rlimit = *vo + count + 1;

	error = vn_rdwr(UIO_WRITE, vp, buf, count, *vo,
	    UIO_SYSSPACE, 0, rlimit, CRED(), &resid);

	*vo += (offset_t)(count - resid);

	return (error);
}