take advantage of contig block info returned from BMAP
authorMike Hibler <hibler@ucbvax.Berkeley.EDU>
Sat, 2 Apr 1994 07:45:30 +0000 (23:45 -0800)
committerMike Hibler <hibler@ucbvax.Berkeley.EDU>
Sat, 2 Apr 1994 07:45:30 +0000 (23:45 -0800)
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

usr/src/sys/dev/vn.c

index 12230b7..c65cbb4 100644 (file)
@@ -11,7 +11,7 @@
  *
  * 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%
  */
 
 /*
  */
 
 /*
@@ -54,6 +54,7 @@
 #include <dev/vnioctl.h>
 
 #ifdef DEBUG
 #include <dev/vnioctl.h>
 
 #ifdef DEBUG
+int dovncluster = 1;
 int vndebug = 0x00;
 #define VDB_FOLLOW     0x01
 #define VDB_INIT       0x02
 int vndebug = 0x00;
 #define VDB_FOLLOW     0x01
 #define VDB_INIT       0x02
@@ -140,7 +141,7 @@ vnstrategy(bp)
        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;
-       int sz, flags;
+       int sz, flags, error;
        extern void vniodone();
 
 #ifdef DEBUG
        extern void vniodone();
 
 #ifdef DEBUG
@@ -171,17 +172,30 @@ vnstrategy(bp)
        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;
-               int off, s;
+               int off, s, nra;
 
 
-               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);
 #endif
 #endif
+
+               nbp = getvnbuf();
                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;
@@ -203,16 +217,16 @@ vnstrategy(bp)
                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);
@@ -380,7 +394,7 @@ vnioctl(dev, cmd, data, flag, p)
                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);
@@ -421,9 +435,12 @@ vnsetcred(vn, cred)
 {
        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));
@@ -433,7 +450,10 @@ vnsetcred(vn, cred)
        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);
 }
 
 /*
 }
 
 /*
@@ -476,10 +496,6 @@ vnclear(vn)
        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;