Kernel: readi() - when reading whole sectors, transfer them directly
authorWill Sowerbutts <will@sowerbutts.com>
Wed, 11 Feb 2015 19:58:45 +0000 (19:58 +0000)
committerWill Sowerbutts <will@sowerbutts.com>
Fri, 13 Feb 2015 15:31:30 +0000 (15:31 +0000)
into user memory.

Kernel/inode.c

index ce34f2d..d0ae1a8 100644 (file)
@@ -11,6 +11,8 @@ void readi(inoptr ino, uint8_t flag)
        unsigned char *bp;
        uint16_t dev;
        bool ispipe;
+       off_t uostash;
+       usize_t ucstash;
 
        dev = ino->c_dev;
        ispipe = false;
@@ -51,19 +53,29 @@ void readi(inoptr ino, uint8_t flag)
 
              loop:
                while (toread) {
-                       if ((pblk =
-                            bmap(ino, udata.u_offset >> BLKSHIFT,
-                                 1)) != NULLBLK)
-                               bp = bread(dev, pblk, 0);
-                       else
-                               bp = zerobuf();
-
-                       amount =
-                           min(toread, BLKSIZE - (udata.u_offset&BLKMASK));
-
-                       uputsys(bp + (udata.u_offset & BLKMASK), amount);
-
-                       brelse(bp);
+                       amount = min(toread, BLKSIZE - (udata.u_offset&BLKMASK));
+                       pblk = bmap(ino, udata.u_offset >> BLKSHIFT, 1);
+
+                       if(!ispipe && amount == BLKSIZE && bfind(dev, pblk) == 0){
+                               /* we can transfer direct from disk to the userspace buffer */
+                               uostash = udata.u_offset;                   /* stash file offset */
+                               ucstash = udata.u_count;                    /* stash byte count */
+                               udata.u_count = amount;                     /* transfer one sector */
+                               udata.u_offset = ((off_t)pblk) << BLKSHIFT; /* replace with sector offset on device */
+                               ((*dev_tab[major(dev)].dev_read) (minor(dev), 1, 0)); /* read */
+                               udata.u_offset = uostash;                   /* restore file offset */
+                               udata.u_count = ucstash;                    /* restore byte count */
+                       }else{
+                               /* we transfer through the buffer pool */
+                               if (pblk == NULLBLK)
+                                       bp = zerobuf();
+                               else
+                                       bp = bread(dev, pblk, 0);
+
+                               uputsys(bp + (udata.u_offset & BLKMASK), amount);
+
+                               brelse(bp);
+                       }
 
                        udata.u_base += amount;
                        udata.u_offset += amount;
@@ -145,7 +157,7 @@ void writei(inoptr ino, uint8_t flag)
              loop:
 
                while (towrite) {
-                       amount = min(towrite, 512 - (udata.u_offset&BLKMASK));
+                       amount = min(towrite, BLKSIZE - (udata.u_offset&BLKMASK));
 
                        if ((pblk =
                             bmap(ino, udata.u_offset >> BLKSHIFT,