-/*
- * copyfile. copy the vnode (fvp) to the vnode (tvp)
- * using a sequence of reads and writes. both (fvp)
- * and (tvp) are locked on entry and exit.
- */
-static int
-union_copyfile(p, cred, fvp, tvp)
- struct proc *p;
- struct ucred *cred;
- struct vnode *fvp;
- struct vnode *tvp;
-{
- char *buf;
- struct uio uio;
- struct iovec iov;
- int error = 0;
- off_t offset;
-
- /*
- * strategy:
- * allocate a buffer of size MAXBSIZE.
- * loop doing reads and writes, keeping track
- * of the current uio offset.
- * give up at the first sign of trouble.
- */
-
- uio.uio_procp = p;
- uio.uio_segflg = UIO_SYSSPACE;
- offset = 0;
-
- VOP_UNLOCK(fvp); /* XXX */
- LEASE_CHECK(fvp, p, cred, LEASE_READ);
- VOP_LOCK(fvp); /* XXX */
- VOP_UNLOCK(tvp); /* XXX */
- LEASE_CHECK(tvp, p, cred, LEASE_WRITE);
- VOP_LOCK(tvp); /* XXX */
-
- buf = malloc(MAXBSIZE, M_TEMP, M_WAITOK);
- do {
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- iov.iov_base = buf;
- iov.iov_len = MAXBSIZE;
- uio.uio_resid = iov.iov_len;
- uio.uio_offset = offset;
- uio.uio_rw = UIO_READ;
- error = VOP_READ(fvp, &uio, 0, cred);
-
- if (error == 0) {
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- iov.iov_base = buf;
- iov.iov_len = MAXBSIZE - uio.uio_resid;
- uio.uio_rw = UIO_WRITE;
- uio.uio_resid = iov.iov_len;
- uio.uio_offset = offset;
-
- do {
- error = VOP_WRITE(tvp, &uio, 0, cred);
- } while (error == 0 && uio.uio_resid > 0);
- if (error == 0)
- offset = uio.uio_offset;
- }
- } while ((uio.uio_resid == 0) && (error == 0));
-
- free(buf, M_TEMP);
- return (error);
-}
-