]> Zhao Yanbai Git Server - minix.git/commitdiff
ext2: annotate cache blocks with inode metadata 30/530/2
authorBen Gras <ben@minix3.org>
Thu, 25 Apr 2013 12:03:40 +0000 (12:03 +0000)
committerBen Gras <ben@minix3.org>
Fri, 26 Apr 2013 15:39:07 +0000 (15:39 +0000)
. allows mmap() to work on it

Change-Id: I33af8b86ebb408d971478d00ed2caacf15afc7a5

sbin/newfs_ext2fs/newfs_ext2fs.c
servers/ext2/link.c
servers/ext2/misc.c
servers/ext2/path.c
servers/ext2/proto.h
servers/ext2/read.c
servers/ext2/table.c
servers/ext2/write.c

index be9a998311d6d8335ae8fbb7bfc049fef3c9031a..f3cc5ad893cf3aa6280ca471cff54d0782e33425 100644 (file)
@@ -82,9 +82,17 @@ static void usage(void) __dead;
  * L_DFL_*.
  */
 #define SMALL_FSSIZE   ((4 * 1024 * 1024) / sectorsize)        /* 4MB */
+#ifdef __minix
+#define S_DFL_BSIZE    4096
+#else
 #define S_DFL_BSIZE    1024
+#endif
 #define MEDIUM_FSSIZE  ((512 * 1024 * 1024) / sectorsize)      /* 512MB */
+#ifdef __minix
+#define M_DFL_BSIZE    4096
+#else
 #define M_DFL_BSIZE    1024
+#endif
 #define L_DFL_BSIZE    4096
 
 /*
index b2e20ec74872c372c7a482edf433954e88c02900..939d9e9c0f03e0e9a7397d77ba359da8fc22d2e5 100644 (file)
@@ -10,6 +10,7 @@
 #include "inode.h"
 #include "super.h"
 #include <minix/vfsif.h>
+#include <sys/param.h>
 
 #define SAME 1000
 
@@ -181,7 +182,6 @@ int fs_unlink()
  *===========================================================================*/
 int fs_rdlink()
 {
-  block_t b;                   /* block containing link text */
   struct buf *bp = NULL;       /* buffer containing link text */
   char* link_text;             /* either bp->b_data or rip->i_block */
   register struct inode *rip;  /* target inode */
@@ -196,16 +196,11 @@ int fs_rdlink()
 
   if (rip->i_size >= MAX_FAST_SYMLINK_LENGTH) {
   /* normal symlink */
-       if ((b = read_map(rip, (off_t) 0)) == NO_BLOCK) {
+               if(!(bp = get_block_map(rip, 0))) {
                r = EIO;
        } else {
-               bp = get_block(rip->i_dev, b, NORMAL);
-               if (bp != NULL) {
-                       link_text = b_data(bp);
-                       r = OK;
-               } else {
-                       r = EIO;
-               }
+               link_text = b_data(bp);
+               r = OK;
        }
   } else {
         /* fast symlink, stored in inode */
@@ -715,13 +710,11 @@ off_t len;
 /* Zero a range in a block.
  * This function is used to zero a segment of a block.
  */
-  block_t b;
   struct buf *bp;
   off_t offset;
 
   if (!len) return; /* no zeroing to be done. */
-  if ( (b = read_map(rip, pos)) == NO_BLOCK) return;
-  if ( (bp = get_block(rip->i_dev, b, NORMAL)) == NULL)
+  if (!(bp = get_block_map(rip, rounddown(pos, rip->i_sp->s_block_size))))
        panic("zeroblock_range: no block");
   offset = pos % rip->i_sp->s_block_size;
   if (offset + len > rip->i_sp->s_block_size)
index 430a1f6022e62ace40b969995e600b2ff51508de..f0127889d0ac478a6f1d858e4ff12f1ebb83a1de 100644 (file)
@@ -90,3 +90,9 @@ int fs_new_driver(void)
 
   return(OK);
 }
+
+int fs_bpeek(void)      
+{
+       return lmfs_do_bpeek(&fs_m_in);
+}
+
index 724262872ef471a0f788a5af0a9200cb321c0d80..54b7aa8eff79f8a87e68728935551ae0898539d3 100644 (file)
@@ -16,6 +16,7 @@
 #include <string.h>
 #include <minix/endpoint.h>
 #include <sys/stat.h>
+#include <sys/param.h>
 #include <sys/types.h>
 #include "buf.h"
 #include "inode.h"
@@ -292,7 +293,6 @@ char *suffix;                       /* current remaining path. Has to point in the
  * new pathname.
  */
 
-  block_t blink;       /* block containing link text */
   size_t llen;         /* length of link */
   size_t slen;         /* length of suffix */
   struct buf *bp;      /* buffer containing link text */
@@ -302,9 +302,8 @@ char *suffix;                       /* current remaining path. Has to point in the
 
   if (llen >= MAX_FAST_SYMLINK_LENGTH) {
        /* normal symlink */
-       if ((blink = read_map(rip, (off_t) 0)) == NO_BLOCK)
+       if(!(bp = get_block_map(rip, 0)))
                return(EIO);
-       bp = get_block(rip->i_dev, blink, NORMAL);
        sp = b_data(bp);
   } else {
        /* fast symlink, stored in inode */
@@ -507,7 +506,6 @@ int ftype;                   /* used when ENTER and
   mode_t bits;
   off_t pos;
   unsigned new_slots;
-  block_t b;
   int extended = 0;
   int required_space = 0;
   int string_len = 0;
@@ -548,15 +546,12 @@ int ftype;                         /* used when ENTER and
   }
 
   for (; pos < ldir_ptr->i_size; pos += ldir_ptr->i_sp->s_block_size) {
-       b = read_map(ldir_ptr, pos);    /* get block number */
-
        /* Since directories don't have holes, 'b' cannot be NO_BLOCK. */
-       bp = get_block(ldir_ptr->i_dev, b, NORMAL);     /* get a dir block */
-       prev_dp = NULL; /* New block - new first dentry, so no prev. */
-
-       if (bp == NO_BLOCK)
+       if(!(bp = get_block_map(ldir_ptr,
+          rounddown(pos, ldir_ptr->i_sp->s_block_size))))
                panic("get_block returned NO_BLOCK");
-       assert(bp != NULL);
+
+       prev_dp = NULL; /* New block - new first dentry, so no prev. */
 
        /* Search a directory block.
         * Note, we set prev_dp at the end of the loop.
@@ -627,6 +622,7 @@ int ftype;                   /* used when ENTER and
                                /* 'flag' is LOOK_UP */
                                *numb = (ino_t) conv4(le_CPU, dp->d_ino);
                        }
+                       assert(lmfs_dev(bp) != NO_DEV);
                        put_block(bp, DIRECTORY_BLOCK);
                        return(r);
                }
@@ -661,6 +657,7 @@ int ftype;                   /* used when ENTER and
        }
 
        /* The whole block has been searched or ENTER has a free slot. */
+       assert(lmfs_dev(bp) != NO_DEV);
        if (e_hit) break;       /* e_hit set if ENTER can be performed now */
        put_block(bp, DIRECTORY_BLOCK); /* otherwise, continue searching dir */
   }
index 0a9f93ca19b7eefd3be6bfb3085de88b1004d1b9..46d28592050466e64d016a4ee8c8155bbf81788b 100644 (file)
@@ -44,6 +44,7 @@ int truncate_inode(struct inode *rip, off_t len);
 int fs_flush(void);
 int fs_sync(void);
 int fs_new_driver(void);
+int fs_bpeek(void);
 
 /* mount.c */
 int fs_mountpoint(void);
@@ -75,8 +76,9 @@ int read_only(struct inode *ip);
 int fs_breadwrite(void);
 int fs_readwrite(void);
 void read_ahead(void);
-block_t read_map(struct inode *rip, off_t pos);
 block_t rd_indir(struct buf *bp, int index);
+block_t read_map(struct inode *rip, off_t pos, int opportunistic);
+struct buf *get_block_map(register struct inode *rip, u64_t position);
 
 /* stadir.c */
 int fs_fstatfs(void);
index 50cc875cb1fed03a60a9dc2ba9d4db377c19db77..64935a1d4bc59220bc39a515fe54cedcff586cfb 100644 (file)
@@ -12,6 +12,7 @@
 #include "inode.h"
 #include "super.h"
 #include <minix/vfsif.h>
+#include <sys/param.h>
 #include <assert.h>
 #include <sys/param.h>
 
@@ -224,6 +225,8 @@ int *completed;                 /* number of bytes copied */
   int n, block_spec;
   block_t b;
   dev_t dev;
+  ino_t ino = VMC_NO_INODE;
+  u64_t ino_off = rounddown(position, block_size);
 
   /* rw_flag:
    *   READING: read from FS, copy to user
@@ -241,8 +244,10 @@ int *completed;                 /* number of bytes copied */
   } else {
        if (ex64hi(position) != 0)
                panic("rw_chunk: position too high");
-       b = read_map(rip, (off_t) ex64lo(position));
+       b = read_map(rip, (off_t) ex64lo(position), 0);
        dev = rip->i_dev;
+       ino = rip->i_num;
+       assert(ino != VMC_NO_INODE);
   }
 
   if (!block_spec && b == NO_BLOCK) {
@@ -272,7 +277,14 @@ int *completed;                 /* number of bytes copied */
        n = (chunk == block_size ? NO_READ : NORMAL);
        if (!block_spec && off == 0 && (off_t) ex64lo(position) >= rip->i_size)
                n = NO_READ;
-       bp = get_block(dev, b, n);
+       if(block_spec) {
+               assert(ino == VMC_NO_INODE);
+               bp = get_block(dev, b, n);
+       } else {
+               assert(ino != VMC_NO_INODE);
+               assert(!(ino_off % block_size));
+               bp = lmfs_get_block_ino(dev, b, n, ino, ino_off);
+       }
   }
 
   /* In all cases, bp now points to a valid buffer. */
@@ -305,9 +317,10 @@ int *completed;                 /* number of bytes copied */
 /*===========================================================================*
  *                             read_map                                     *
  *===========================================================================*/
-block_t read_map(rip, position)
+block_t read_map(rip, position, opportunistic)
 register struct inode *rip;     /* ptr to inode to map from */
 off_t position;                 /* position in file whose blk wanted */
+int opportunistic;
 {
 /* Given an inode and a position within the corresponding file, locate the
  * block number in which that position is to be found and return it.
@@ -323,6 +336,9 @@ off_t position;                 /* position in file whose blk wanted */
   static long doub_ind_s;
   static long triple_ind_s;
   static long out_range_s;
+  int iomode = NORMAL;
+  if(opportunistic) iomode = PREFETCH;
 
   if (first_time) {
        addr_in_block = rip->i_sp->s_block_size / BLOCK_ADDRESS_BYTES;
@@ -364,7 +380,11 @@ off_t position;                 /* position in file whose blk wanted */
                excess = excess % addr_in_block2;
        }
        if (b == NO_BLOCK) return(NO_BLOCK);
-       bp = get_block(rip->i_dev, b, NORMAL);  /* get double indirect block */
+       bp = get_block(rip->i_dev, b, iomode); /* get double indirect block */
+       if(opportunistic && lmfs_dev(bp) == NO_DEV) {
+               put_block(bp, INDIRECT_BLOCK);
+               return NO_BLOCK;
+       }
        ASSERT(lmfs_dev(bp) != NO_DEV);
        ASSERT(lmfs_dev(bp) == rip->i_dev);
        index = excess / addr_in_block;
@@ -373,7 +393,12 @@ off_t position;                 /* position in file whose blk wanted */
        index = excess % addr_in_block; /* index into single ind blk */
   }
   if (b == NO_BLOCK) return(NO_BLOCK);
-  bp = get_block(rip->i_dev, b, NORMAL);
+  bp = get_block(rip->i_dev, b, iomode);       /* get single indirect block */
+  if(opportunistic && lmfs_dev(bp) == NO_DEV) {
+       put_block(bp, INDIRECT_BLOCK);
+       return NO_BLOCK;
+  }
+
   ASSERT(lmfs_dev(bp) != NO_DEV);
   ASSERT(lmfs_dev(bp) == rip->i_dev);
   b = rd_indir(bp, index);
@@ -382,6 +407,16 @@ off_t position;                 /* position in file whose blk wanted */
   return(b);
 }
 
+struct buf *get_block_map(register struct inode *rip, u64_t position)
+{
+       block_t b = read_map(rip, position, 0); /* get block number */
+       int block_size = get_block_size(rip->i_dev);
+       if(b == NO_BLOCK)
+               return NULL;
+       position = rounddown(position, block_size);
+       assert(rip->i_num != VMC_NO_INODE);
+       return lmfs_get_block_ino(rip->i_dev, b, NORMAL, rip->i_num, position);
+}
 
 /*===========================================================================*
  *                             rd_indir                                     *
@@ -414,7 +449,7 @@ void read_ahead()
   rip = rdahed_inode;           /* pointer to inode to read ahead from */
   block_size = get_block_size(rip->i_dev);
   rdahed_inode = NULL;     /* turn off read ahead */
-  if ( (b = read_map(rip, rdahedpos)) == NO_BLOCK) return;      /* at EOF */
+  if ( (b = read_map(rip, rdahedpos, 1)) == NO_BLOCK) return;      /* at EOF */
 
   assert(rdahedpos >= 0); /* So we can safely cast it to unsigned below */
 
@@ -450,6 +485,7 @@ unsigned bytes_ahead;           /* bytes beyond position for immediate use */
   struct buf *bp = NULL;
   static unsigned int readqsize = 0;
   static struct buf **read_q = NULL;
+  u64_t position_running;
 
   if(readqsize != nr_bufs) {
        if(readqsize > 0) {
@@ -473,10 +509,23 @@ unsigned bytes_ahead;           /* bytes beyond position for immediate use */
   else
        dev = rip->i_dev;
 
+  assert(dev != NO_DEV);
   block_size = get_block_size(dev);
 
   block = baseblock;
-  bp = get_block(dev, block, PREFETCH);
+
+  fragment = position % block_size;
+  position -= fragment;
+  position_running = position;
+  bytes_ahead += fragment;
+  blocks_ahead = (bytes_ahead + block_size - 1) / block_size;
+
+  if(block_spec)
+         bp = get_block(dev, block, PREFETCH);
+  else
+         bp = lmfs_get_block_ino(dev, block, PREFETCH, rip->i_num, position);
+
+
   assert(bp != NULL);
   if (lmfs_dev(bp) != NO_DEV) return(bp);
 
@@ -500,12 +549,6 @@ unsigned bytes_ahead;           /* bytes beyond position for immediate use */
    * indirect blocks (but don't call read_map!).
    */
 
-  fragment = rem64u(position, block_size);
-  position = sub64u(position, fragment);
-  bytes_ahead += fragment;
-
-  blocks_ahead = (bytes_ahead + block_size - 1) / block_size;
-
   if (block_spec && rip->i_size == 0) {
        blocks_left = (block_t) NR_IOREQS;
   } else {
@@ -536,6 +579,7 @@ unsigned bytes_ahead;           /* bytes beyond position for immediate use */
 
   /* Acquire block buffers. */
   for (;;) {
+       block_t thisblock;
        read_q[read_q_size++] = bp;
 
        if (--blocks_ahead == 0) break;
@@ -544,8 +588,14 @@ unsigned bytes_ahead;           /* bytes beyond position for immediate use */
        if (lmfs_bufs_in_use() >= nr_bufs - 4) break;
 
        block++;
+       position_running += block_size;
 
-       bp = get_block(dev, block, PREFETCH);
+       if(!block_spec && 
+         (thisblock = read_map(rip, (off_t) ex64lo(position_running), 1)) != NO_BLOCK) {
+               bp = lmfs_get_block_ino(dev, thisblock, PREFETCH, rip->i_num, position_running);
+       } else {
+               bp = get_block(dev, block, PREFETCH);
+       }
        if (lmfs_dev(bp) != NO_DEV) {
                /* Oops, block already in the cache, get out. */
                put_block(bp, FULL_DATA_BLOCK);
@@ -553,7 +603,10 @@ unsigned bytes_ahead;           /* bytes beyond position for immediate use */
        }
   }
   lmfs_rw_scattered(dev, read_q, read_q_size, READING);
-  return(get_block(dev, baseblock, NORMAL));
+
+  if(block_spec)
+         return get_block(dev, baseblock, NORMAL);
+  return(lmfs_get_block_ino(dev, baseblock, NORMAL, rip->i_num, position));
 }
 
 
@@ -569,7 +622,6 @@ int fs_getdents(void)
   int o, r, done;
   unsigned int block_size, len, reclen;
   ino_t ino;
-  block_t b;
   cp_grant_id_t gid;
   size_t size, tmpbuf_off, userbuf_off;
   off_t pos, off, block_pos, new_pos, ent_pos;
@@ -604,9 +656,9 @@ int fs_getdents(void)
 
   for (; block_pos < rip->i_size; block_pos += block_size) {
        off_t temp_pos = block_pos;
-       b = read_map(rip, block_pos); /* get block number */
-       /* Since directories don't have holes, 'b' cannot be NO_BLOCK. */
-       bp = get_block(rip->i_dev, b, NORMAL);  /* get a dir block */
+        /* Since directories don't have holes, 'bp' cannot be NULL. */
+        bp = get_block_map(rip, block_pos);     /* get a dir block */
+        assert(bp != NULL);
        assert(bp != NULL);
 
        /* Search a directory block. */
index af77d746bbeee42ff2d41b728bd8fb2adaaf98bb..1d779a9a6cbdf37edb401677d4879904b75a3462 100644 (file)
@@ -46,11 +46,6 @@ int (*fs_call_vec[])(void) = {
     fs_rdlink,          /* 30  */
     fs_getdents,        /* 31  */
     fs_statvfs,                /* 32  */
-#if 0
     fs_readwrite,       /* 33  */
-    no_sys,
-#else
-    no_sys,
-    no_sys,
-#endif
+    fs_bpeek,           /* 34  */
 };
index ffec057ff47eb6afe9a18d2eec10a72373f4652d..fe53161e65682fa6145471d8655701f265139e39 100644 (file)
@@ -12,6 +12,8 @@
 
 #include "fs.h"
 #include <string.h>
+#include <assert.h>
+#include <sys/param.h>
 #include "buf.h"
 #include "inode.h"
 #include "super.h"
@@ -316,7 +318,7 @@ off_t position;                     /* file pointer */
   block_t b;
 
   /* Is another block available? */
-  if ( (b = read_map(rip, position)) == NO_BLOCK) {
+  if ( (b = read_map(rip, position, 0)) == NO_BLOCK) {
        /* Check if this position follows last allocated
         * block.
         */
@@ -359,7 +361,8 @@ off_t position;                     /* file pointer */
        }
   }
 
-  bp = get_block(rip->i_dev, b, NO_READ);
+  bp = lmfs_get_block_ino(rip->i_dev, b, NO_READ, rip->i_num,
+       rounddown(position, rip->i_sp->s_block_size));
   zero_block(bp);
   return(bp);
 }