sigh...when will I learn, don't do IO to buffers on the stack!
get rid of the "if 0"ed FSYNC call, it doesn't apply anymore anyway
SCCS-vsn: sys/dev/vn.c 8.5
*
* from: Utah $Hdr: vn.c 1.8 92/12/20$
*
*
* from: Utah $Hdr: vn.c 1.8 92/12/20$
*
- * @(#)vn.c 8.4 (Berkeley) %G%
+ * @(#)vn.c 8.5 (Berkeley) %G%
#include <dev/vnioctl.h>
#ifdef DEBUG
#include <dev/vnioctl.h>
#ifdef DEBUG
int vndebug = 0x00;
#define VDB_FOLLOW 0x01
#define VDB_INIT 0x02
int vndebug = 0x00;
#define VDB_FOLLOW 0x01
#define VDB_INIT 0x02
register struct buf *nbp;
register int bn, bsize, resid;
register caddr_t addr;
register struct buf *nbp;
register int bn, bsize, resid;
register caddr_t addr;
extern void vniodone();
#ifdef DEBUG
extern void vniodone();
#ifdef DEBUG
for (resid = bp->b_resid; resid; resid -= sz) {
struct vnode *vp;
daddr_t nbn;
for (resid = bp->b_resid; resid; resid -= sz) {
struct vnode *vp;
daddr_t nbn;
- nbp = getvnbuf();
- off = bn % bsize;
- sz = min(bsize - off, resid);
- (void) VOP_BMAP(vn->sc_vp, bn / bsize, &vp, &nbn, NULL);
+ nra = 0;
+ error = VOP_BMAP(vn->sc_vp, bn / bsize, &vp, &nbn, &nra);
+ if (error == 0 && (long)nbn == -1)
+ error = EIO;
+#ifdef DEBUG
+ if (!dovncluster)
+ nra = 0;
+#endif
+
+ if (off = bn % bsize)
+ sz = bsize - off;
+ else
+ sz = (1 + nra) * bsize;
+ if (resid < sz)
+ sz = resid;
#ifdef DEBUG
if (vndebug & VDB_IO)
#ifdef DEBUG
if (vndebug & VDB_IO)
- printf("vnstrategy: vp %x/%x bn %x/%x\n",
- vn->sc_vp, vp, bn, nbn);
+ printf("vnstrategy: vp %x/%x bn %x/%x sz %x\n",
+ vn->sc_vp, vp, bn, nbn, sz);
nbp->b_flags = flags;
nbp->b_bcount = sz;
nbp->b_bufsize = bp->b_bufsize;
nbp->b_flags = flags;
nbp->b_bcount = sz;
nbp->b_bufsize = bp->b_bufsize;
nbp->b_validoff = bp->b_validoff;
nbp->b_validend = bp->b_validend;
/*
nbp->b_validoff = bp->b_validoff;
nbp->b_validend = bp->b_validend;
/*
- * There is a hole in the file...punt.
+ * If there was an error or a hole in the file...punt.
* Note that we deal with this after the nbp allocation.
* This ensures that we properly clean up any operations
* that we have already fired off.
*
* Note that we deal with this after the nbp allocation.
* This ensures that we properly clean up any operations
* that we have already fired off.
*
- * XXX we could deal with this but it would be
+ * XXX we could deal with holes here but it would be
* a hassle (in the write case).
*/
* a hassle (in the write case).
*/
- if ((long)nbn == -1) {
- nbp->b_error = EIO;
+ if (error) {
+ nbp->b_error = error;
nbp->b_flags |= B_ERROR;
bp->b_resid -= (resid - sz);
biodone(nbp);
nbp->b_flags |= B_ERROR;
bp->b_resid -= (resid - sz);
biodone(nbp);
vn->sc_vp = nd.ni_vp;
vn->sc_size = btodb(vattr.va_size); /* note truncation */
if (error = vnsetcred(vn, p->p_ucred)) {
vn->sc_vp = nd.ni_vp;
vn->sc_size = btodb(vattr.va_size); /* note truncation */
if (error = vnsetcred(vn, p->p_ucred)) {
- (void) vn_close(vn->sc_vp, FREAD|FWRITE, p->p_ucred, p);
+ (void) vn_close(nd.ni_vp, FREAD|FWRITE, p->p_ucred, p);
return(error);
}
vnthrottle(vn, vn->sc_vp);
return(error);
}
vnthrottle(vn, vn->sc_vp);
{
struct uio auio;
struct iovec aiov;
{
struct uio auio;
struct iovec aiov;
- char tmpbuf[DEV_BSIZE];
+ char *tmpbuf;
+ int error;
vn->sc_cred = crdup(cred);
vn->sc_cred = crdup(cred);
+ tmpbuf = malloc(DEV_BSIZE, M_TEMP, M_WAITOK);
+
/* XXX: Horrible kludge to establish credentials for NFS */
aiov.iov_base = tmpbuf;
aiov.iov_len = min(DEV_BSIZE, dbtob(vn->sc_size));
/* XXX: Horrible kludge to establish credentials for NFS */
aiov.iov_base = tmpbuf;
aiov.iov_len = min(DEV_BSIZE, dbtob(vn->sc_size));
auio.uio_rw = UIO_READ;
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_resid = aiov.iov_len;
auio.uio_rw = UIO_READ;
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_resid = aiov.iov_len;
- return(VOP_READ(vn->sc_vp, &auio, 0, vn->sc_cred));
+ error = VOP_READ(vn->sc_vp, &auio, 0, vn->sc_cred);
+
+ free(tmpbuf, M_TEMP);
+ return (error);
vn->sc_flags &= ~VNF_INITED;
if (vp == (struct vnode *)0)
panic("vnioctl: null vp");
vn->sc_flags &= ~VNF_INITED;
if (vp == (struct vnode *)0)
panic("vnioctl: null vp");
-#if 0
- /* XXX - this doesn't work right now */
- (void) VOP_FSYNC(vp, 0, vn->sc_cred, MNT_WAIT, p);
-#endif
(void) vn_close(vp, FREAD|FWRITE, vn->sc_cred, p);
crfree(vn->sc_cred);
vn->sc_vp = (struct vnode *)0;
(void) vn_close(vp, FREAD|FWRITE, vn->sc_cred, p);
crfree(vn->sc_cred);
vn->sc_vp = (struct vnode *)0;