]> Zhao Yanbai Git Server - minix.git/commitdiff
mfs - statvfs call, by Buccapatnam Tirumala, Gautam.
authorBen Gras <ben@minix3.org>
Wed, 23 Jun 2010 23:58:16 +0000 (23:58 +0000)
committerBen Gras <ben@minix3.org>
Wed, 23 Jun 2010 23:58:16 +0000 (23:58 +0000)
servers/mfs/Makefile
servers/mfs/cache.c
servers/mfs/proto.h
servers/mfs/stadir.c
servers/mfs/stats.c [new file with mode: 0644]
servers/mfs/table.c

index 133b31fa32c139b78d310a52ad895f846d515164..911891fa7d51bfd9ccd903bf1f346370140e84a9 100644 (file)
@@ -2,7 +2,7 @@
 PROG=  mfs
 SRCS=  cache.c device.c link.c \
        mount.c misc.c open.c protect.c read.c \
-       stadir.c table.c time.c utility.c \
+       stadir.c stats.c table.c time.c utility.c \
        write.c inode.c main.c path.c super.c
 
 DPADD+=        ${LIBSYS}
@@ -13,7 +13,7 @@ MAN=
 BINDIR?= /sbin
 INSTALLFLAGS+= -S 128k
 
-DEFAULT_NR_BUFS= 1024
+DEFAULT_NR_BUFS= 102400
 CPPFLAGS+= -DDEFAULT_NR_BUFS=${DEFAULT_NR_BUFS}
 
 .include <minix.prog.mk>
index 6e3d522b3833b38528181030f9eb6cc4674e4350..eae8f74b5316533663a15cccd186eae0dc6f327a 100644 (file)
@@ -63,8 +63,10 @@ PUBLIC struct buf *get_block(
   if(vmcache_avail < 0) {
        /* Test once for the availability of the vm yield block feature. */
        if(vm_forgetblock(VM_BLOCKID_NONE) == ENOSYS) {
+               printf("mfs: no cache\n");
                vmcache_avail = 0;
        } else {
+               printf("mfs: cache\n");
                vmcache_avail = 1;
        }
   }
index bfb3bf8e74f27f97d556f4e3d09f5cf9f7e10243..0eecbe98f6ea8c6d6dc742d67baf7ea64f24c7b0 100644 (file)
@@ -91,6 +91,7 @@ _PROTOTYPE( zone_t rd_indir, (struct buf *bp, int index)              );
 /* stadir.c */
 _PROTOTYPE( int fs_fstatfs, (void)                                     );
 _PROTOTYPE( int fs_stat, (void)                                                );
+_PROTOTYPE( int fs_statvfs, (void)                                     );
 
 /* super.c */
 _PROTOTYPE( bit_t alloc_bit, (struct super_block *sp, int map, bit_t origin));
@@ -100,6 +101,9 @@ _PROTOTYPE( unsigned int get_block_size, (dev_t dev)                                );
 _PROTOTYPE( struct super_block *get_super, (dev_t dev)                 );
 _PROTOTYPE( int read_super, (struct super_block *sp)                   );
 
+/* stats.c */
+_PROTOTYPE( bit_t count_free_bits, (struct super_block *sp, int map));
+
 /* time.c */
 _PROTOTYPE( int fs_utime, (void)                                       );
 
index 520def45f6c3e9e11acb5564050d24be1ecabd3b..7719c59f14e083fbc045e973b3b66146c8feb029 100644 (file)
@@ -1,6 +1,7 @@
 #include "fs.h"
 #include <sys/stat.h>
 #include <sys/statfs.h>
+#include <sys/statvfs.h>
 #include "inode.h"
 #include "super.h"
 #include <minix/vfsif.h>
@@ -72,6 +73,38 @@ PUBLIC int fs_fstatfs()
 }
 
 
+/*===========================================================================*
+ *                             fs_statvfs                                   *
+ *===========================================================================*/
+PUBLIC int fs_statvfs()
+{
+  struct statvfs st;
+  struct super_block *sp;
+  int r, scale;
+
+  sp = get_super(fs_dev);
+
+  scale = sp->s_log_zone_size;
+
+  st.f_bsize =  sp->s_block_size << scale;
+  st.f_frsize = sp->s_block_size;
+  st.f_blocks = sp->s_zones << scale;
+  st.f_bfree = count_free_bits(sp, ZMAP) << scale;
+  st.f_bavail = st.f_bfree;
+  st.f_files = sp->s_ninodes;
+  st.f_ffree = count_free_bits(sp, IMAP);
+  st.f_favail = st.f_ffree;
+  st.f_fsid = fs_dev;
+  st.f_flag = (sp->s_rd_only == 1 ? ST_RDONLY : 0);
+  st.f_namemax = NAME_MAX;
+
+  /* Copy the struct to user space. */
+  r = sys_safecopyto(fs_m_in.m_source, fs_m_in.REQ_GRANT, 0, (vir_bytes) &st,
+                    (phys_bytes) sizeof(st), D);
+  
+  return(r);
+}
+
 /*===========================================================================*
  *                             fs_stat                                      *
  *===========================================================================*/
diff --git a/servers/mfs/stats.c b/servers/mfs/stats.c
new file mode 100644 (file)
index 0000000..0191c3f
--- /dev/null
@@ -0,0 +1,85 @@
+#include "fs.h"
+#include <string.h>
+#include <minix/com.h>
+#include <minix/u64.h>
+#include "buf.h"
+#include "inode.h"
+#include "super.h"
+#include "const.h"
+
+/*===========================================================================*
+ *                             count_free_bits                              *
+ *===========================================================================*/
+PUBLIC bit_t count_free_bits(sp, map)
+struct super_block *sp;                /* the filesystem to allocate from */
+int map;                       /* IMAP (inode map) or ZMAP (zone map) */
+{
+/* Allocate a bit from a bit map and return its bit number. */
+  block_t start_block;         /* first bit block */
+  block_t block;
+  bit_t map_bits;              /* how many bits are there in the bit map? */
+  short bit_blocks;            /* how many blocks are there in the bit map? */
+  bit_t origin;                        /* number of bit to start searching at */
+  unsigned word, bcount;
+  struct buf *bp;
+  bitchunk_t *wptr, *wlim, k;
+  bit_t i, b;
+  bit_t free_bits;
+
+  if (map == IMAP) {
+    start_block = START_BLOCK;
+    map_bits = (bit_t) (sp->s_ninodes + 1);
+    bit_blocks = sp->s_imap_blocks;
+    origin = sp->s_isearch;
+  } else {
+    start_block = START_BLOCK + sp->s_imap_blocks;
+    map_bits = (bit_t) (sp->s_zones - (sp->s_firstdatazone - 1));
+    bit_blocks = sp->s_zmap_blocks;
+    origin = sp->s_zsearch;
+  }
+
+  /* Figure out where to start the bit search (depends on 'origin'). */
+  if (origin >= map_bits) origin = 0;    /* for robustness */
+  free_bits = 0;
+
+  /* Locate the starting place. */
+  block = (block_t) (origin / FS_BITS_PER_BLOCK(sp->s_block_size));
+  word = (origin % FS_BITS_PER_BLOCK(sp->s_block_size)) / FS_BITCHUNK_BITS;
+
+  /* Iterate over all blocks plus one, because we start in the middle. */
+  bcount = bit_blocks;
+  do {
+    bp = get_block(sp->s_dev, start_block + block, NORMAL);
+    wlim = &bp->b_bitmap[FS_BITMAP_CHUNKS(sp->s_block_size)];
+
+    /* Iterate over the words in block. */
+    for (wptr = &bp->b_bitmap[word]; wptr < wlim; wptr++) {
+
+        /* Does this word contain a free bit? */
+      if (*wptr == (bitchunk_t) ~0) continue;
+
+      /* Find and allocate the free bit. */
+      k = (bitchunk_t) conv2(sp->s_native, (int) *wptr);
+
+      for (i = 0; i < 8*sizeof(k); ++i) {
+        /* Bit number from the start of the bit map. */
+        b = ((bit_t) block * FS_BITS_PER_BLOCK(sp->s_block_size))
+            + (wptr - &bp->b_bitmap[0]) * FS_BITCHUNK_BITS
+            + i;
+
+        /* Don't count bits beyond the end of the map. */
+        if (b >= map_bits) {
+          break;
+        } 
+        if ((k & (1 << i)) == 0) {
+          free_bits++;
+        }
+      }
+
+      if (b >= map_bits) break;
+    }
+    ++block;
+    word = 0;
+  } while (--bcount > 0);
+  return free_bits;        /* no bit could be allocated */
+}
index d9f99874dbee8dbf3de7fa7944f2a122d83fd59b..d50005f204bf05f98482b0440989f13cde8c5921 100644 (file)
@@ -44,6 +44,6 @@ PUBLIC _PROTOTYPE (int (*fs_call_vec[]), (void) ) = {
         no_sys,                    /* 29  */           /* Was: fs_newnode */
         fs_rdlink,         /* 30  */
         fs_getdents,       /* 31  */
-        no_sys,    /* 32 */
+        fs_statvfs,    /* 32 */
 };