From: Ben Gras Date: Wed, 23 Jun 2010 23:58:16 +0000 (+0000) Subject: mfs - statvfs call, by Buccapatnam Tirumala, Gautam. X-Git-Tag: v3.1.8~372 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/doxygen.png?a=commitdiff_plain;h=6cd2d1218e24be11e2763ed90250ddf19322622d;p=minix.git mfs - statvfs call, by Buccapatnam Tirumala, Gautam. --- diff --git a/servers/mfs/Makefile b/servers/mfs/Makefile index 133b31fa3..911891fa7 100644 --- a/servers/mfs/Makefile +++ b/servers/mfs/Makefile @@ -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 diff --git a/servers/mfs/cache.c b/servers/mfs/cache.c index 6e3d522b3..eae8f74b5 100644 --- a/servers/mfs/cache.c +++ b/servers/mfs/cache.c @@ -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; } } diff --git a/servers/mfs/proto.h b/servers/mfs/proto.h index bfb3bf8e7..0eecbe98f 100644 --- a/servers/mfs/proto.h +++ b/servers/mfs/proto.h @@ -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) ); diff --git a/servers/mfs/stadir.c b/servers/mfs/stadir.c index 520def45f..7719c59f1 100644 --- a/servers/mfs/stadir.c +++ b/servers/mfs/stadir.c @@ -1,6 +1,7 @@ #include "fs.h" #include #include +#include #include "inode.h" #include "super.h" #include @@ -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 index 000000000..0191c3f60 --- /dev/null +++ b/servers/mfs/stats.c @@ -0,0 +1,85 @@ +#include "fs.h" +#include +#include +#include +#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 */ +} diff --git a/servers/mfs/table.c b/servers/mfs/table.c index d9f99874d..d50005f20 100644 --- a/servers/mfs/table.c +++ b/servers/mfs/table.c @@ -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 */ };