mfs - statvfs call, by Buccapatnam Tirumala, Gautam.

This commit is contained in:
Ben Gras 2010-06-23 23:58:16 +00:00
parent 4b496e29bd
commit 6cd2d1218e
6 changed files with 127 additions and 3 deletions

View 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>

View 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;
}
}

View 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) );

View 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 *
*===========================================================================*/

85
servers/mfs/stats.c Normal file
View file

@ -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 */
}

View 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 */
};