xref: /minix/minix/fs/mfs/stats.c (revision 83133719)
1 #include "fs.h"
2 #include <string.h>
3 #include <minix/com.h>
4 #include <assert.h>
5 #include <minix/u64.h>
6 #include "buf.h"
7 #include "inode.h"
8 #include "super.h"
9 #include "const.h"
10 
11 /*===========================================================================*
12  *				count_free_bits				     *
13  *===========================================================================*/
14 bit_t count_free_bits(sp, map)
15 struct super_block *sp;		/* the filesystem to allocate from */
16 int map;			/* IMAP (inode map) or ZMAP (zone map) */
17 {
18 /* Allocate a bit from a bit map and return its bit number. */
19   block_t start_block;		/* first bit block */
20   block_t block;
21   bit_t map_bits;		/* how many bits are there in the bit map? */
22   short bit_blocks;		/* how many blocks are there in the bit map? */
23   bit_t origin;			/* number of bit to start searching at */
24   unsigned word, bcount;
25   struct buf *bp;
26   bitchunk_t *wptr, *wlim, k;
27   bit_t i, b;
28   bit_t free_bits;
29 
30   assert(sp != NULL);
31 
32   if (map == IMAP) {
33     start_block = START_BLOCK;
34     map_bits = (bit_t) (sp->s_ninodes + 1);
35     bit_blocks = sp->s_imap_blocks;
36     origin = sp->s_isearch;
37   } else {
38     start_block = START_BLOCK + sp->s_imap_blocks;
39     map_bits = (bit_t) (sp->s_zones - (sp->s_firstdatazone - 1));
40     bit_blocks = sp->s_zmap_blocks;
41     origin = sp->s_zsearch;
42   }
43 
44   /* Figure out where to start the bit search (depends on 'origin'). */
45   if (origin >= map_bits) origin = 0;    /* for robustness */
46   free_bits = 0;
47 
48   /* Locate the starting place. */
49   block = (block_t) (origin / FS_BITS_PER_BLOCK(sp->s_block_size));
50   word = (origin % FS_BITS_PER_BLOCK(sp->s_block_size)) / FS_BITCHUNK_BITS;
51 
52   /* Iterate over all blocks plus one, because we start in the middle. */
53   bcount = bit_blocks;
54   do {
55     bp = get_block(sp->s_dev, start_block + block, NORMAL);
56     assert(bp);
57     wlim = &b_bitmap(bp)[FS_BITMAP_CHUNKS(sp->s_block_size)];
58 
59     /* Iterate over the words in block. */
60     for (wptr = &b_bitmap(bp)[word]; wptr < wlim; wptr++) {
61 
62       /* Does this word contain a free bit? */
63       if (*wptr == (bitchunk_t) ~0) continue;
64 
65       k = (bitchunk_t) conv4(sp->s_native, (int) *wptr);
66 
67       for (i = 0; i < 8*sizeof(k); ++i) {
68         /* Bit number from the start of the bit map. */
69         b = ((bit_t) block * FS_BITS_PER_BLOCK(sp->s_block_size))
70             + (wptr - &b_bitmap(bp)[0]) * FS_BITCHUNK_BITS
71             + i;
72 
73         /* Don't count bits beyond the end of the map. */
74         if (b >= map_bits) {
75           break;
76         }
77         if ((k & (1 << i)) == 0) {
78           free_bits++;
79         }
80       }
81 
82       if (b >= map_bits) break;
83     }
84     put_block(bp, MAP_BLOCK);
85     ++block;
86     word = 0;
87   } while (--bcount > 0);
88   return free_bits;        /* no bit could be allocated */
89 }
90 
91 
92 /*===========================================================================*
93  *				blockstats				     *
94  *===========================================================================*/
95 void fs_blockstats(u64_t *blocks, u64_t *free, u64_t *used)
96 {
97   struct super_block *sp;
98 
99   sp = get_super(fs_dev);
100 
101   assert(sp);
102   assert(!sp->s_log_zone_size);
103 
104   *blocks = sp->s_zones;
105   *used = get_used_blocks(sp);
106   *free = *blocks - *used;
107 
108   return;
109 }
110