changeset 318:d4ff2fb275b5

tweak
author menikon
date Thu, 06 Feb 2020 17:08:13 +0900
parents 20294366d1f9
children 71c7bd0d047e
files src/impl/fs_impl.cbc src/impl/fs_impl.h src/impl/fs_impl_private.cbc
diffstat 3 files changed, 93 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/impl/fs_impl.cbc	Thu Feb 06 16:22:38 2020 +0900
+++ b/src/impl/fs_impl.cbc	Thu Feb 06 17:08:13 2020 +0900
@@ -161,9 +161,7 @@
 
 __code readifs_impl(struct fs_impl* fs, struct inode* ip, char* dst, uint off, uint n, __code next(int ret, ...)) {
     if (ip->type == T_DEV) {
-        /*
-        ここ書く
-        */ 
+        goto readi_check_diskinode(fs, ip, dst, n, next(...));
     }
 
     if (off > ip->size || off + n < off) {
--- a/src/impl/fs_impl.h	Thu Feb 06 16:22:38 2020 +0900
+++ b/src/impl/fs_impl.h	Thu Feb 06 17:08:13 2020 +0900
@@ -26,6 +26,7 @@
     __code lockinode_sleepcheck(Type* fs_impl, struct inode* ip, __code next(...));
     __code iput_check(Type* fs_impl, struct inode* ip, __code next(...));
     __code iput_inode_nolink(Type* fs_impl, struct inode* ip, __code next(...));
+    __code readi_check_diskinode(struct fs_impl* fs_impl,struct inode* ip, char* dst, uint n, next(...));
     __code readi_loopcheck(struct fs_impl* fs_impl, uint tot, uint m, char* dst, uint off, uint n, __code next(...));
     __code readi_loop(struct fs_impl* fs_impl, struct inode *ip, struct buf* bp, uint tot, uint m, char* dst, uint off, uint n, __code next(...));
     __code readi_noloop(struct fs_impl* fs_impl, uint n, __code next(int ret, ...));
--- a/src/impl/fs_impl_private.cbc	Thu Feb 06 16:22:38 2020 +0900
+++ b/src/impl/fs_impl_private.cbc	Thu Feb 06 17:08:13 2020 +0900
@@ -9,6 +9,7 @@
 #include "fs.h"
 #include "file.h"
 #interface "fs_impl.h"
+#define min(a, b) ((a) < (b) ? (a) : (b))
 
 /*
 fs_impl* createfs_impl2();
@@ -235,6 +236,10 @@
     goto next(...);
 }
 
+__code readi_check_diskinode(struct fs_impl* fs_impl,struct inode* ip, char* dst, uint n, __code next(...)){
+    goto next(...);
+}
+
 __code readi_loopcheck(struct fs_impl* fs_impl, uint tot, uint m, char* dst, uint off, uint n, __code next(...)){
     if(tot < n){
         goto readi_loop(fs_impl, ip, bp, tot, m, dst, off, n, next(...));
@@ -242,8 +247,93 @@
     goto readi_noloop(fs_impl, next(...));
 }
 
+static void bzero (int dev, int bno)
+{
+    struct buf *bp;
+
+    bp = bread(dev, bno);
+    memset(bp->data, 0, BSIZE);
+    log_write(bp);
+    brelse(bp);
+}
+
+static uint balloc (uint dev)
+{
+    int b, bi, m;
+    struct buf *bp;
+    struct superblock sb;
+
+    bp = 0;
+    readsb(dev, &sb);
+
+    for (b = 0; b < sb.size; b += BPB) {
+        bp = bread(dev, BBLOCK(b, sb.ninodes));
+
+        for (bi = 0; bi < BPB && b + bi < sb.size; bi++) {
+            m = 1 << (bi % 8);
+
+            if ((bp->data[bi / 8] & m) == 0) {  // Is block free?
+                bp->data[bi / 8] |= m;  // Mark block in use.
+                log_write(bp);
+                brelse(bp);
+                bzero(dev, b + bi);
+                return b + bi;
+            }
+        }
+
+        brelse(bp);
+    }
+
+    panic("balloc: out of blocks");
+}
+
+
+static uint bmap (struct inode *ip, uint bn)
+{
+    uint addr, *a;
+    struct buf *bp;
+
+    if (bn < NDIRECT) {
+        if ((addr = ip->addrs[bn]) == 0) {
+            ip->addrs[bn] = addr = balloc(ip->dev);
+        }
+
+        return addr;
+    }
+
+    bn -= NDIRECT;
+
+    if (bn < NINDIRECT) {
+        // Load indirect block, allocating if necessary.
+        if ((addr = ip->addrs[NDIRECT]) == 0) {
+            ip->addrs[NDIRECT] = addr = balloc(ip->dev);
+        }
+
+        bp = bread(ip->dev, addr);
+        a = (uint*) bp->data;
+
+        if ((addr = a[bn]) == 0) {
+            a[bn] = addr = balloc(ip->dev);
+            log_write(bp);
+        }
+
+        brelse(bp);
+        return addr;
+    }
+
+    panic("bmap: out of range");
+}
+
+
 __code readi_loop(struct fs_impl* fs_impl, struct inode* ip, struct buf* bp, uint tot, uint m, char* dst, uint off, uint n, __code next(...)){ //:skip
-    goto next(...);
+    bp = bread(ip->dev, bmap(ip, off / BSIZE));
+    m = min(n - tot, BSIZE - off%BSIZE);
+    memmove(dst, bp->data + off % BSIZE, m);
+    brelse(bp);
+    tot += m;
+    off += m; 
+    dst += m;
+    goto readi_loopcheck(fs_impl, tot, m, dst, off, n, next(...));
 }
 
 __code readi_noloop(struct fs_impl* fs_impl, uint n, __code next(int ret, ...)){