/* 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));
_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) );
#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>
}
+/*===========================================================================*
+ * 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 *
*===========================================================================*/
--- /dev/null
+#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 */
+}