Fork me on GitHub

root/fs/minix/bitmaps.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. count_bits
  2. minix_change_bit
  3. minix_balloc
  4. minix_bfree
  5. minix_count_free_inodes
  6. minix_count_free_blocks
  7. minix_find_first_zero

   1 /*
   2  * fiwix/fs/minix/bitmaps.c
   3  *
   4  * Copyright 2018, Jordi Sanfeliu. All rights reserved.
   5  * Distributed under the terms of the Fiwix License.
   6  */
   7 
   8 #include <fiwix/types.h>
   9 #include <fiwix/fs.h>
  10 #include <fiwix/filesystems.h>
  11 #include <fiwix/fs_minix.h>
  12 #include <fiwix/buffer.h>
  13 #include <fiwix/errno.h>
  14 #include <fiwix/stdio.h>
  15 #include <fiwix/string.h>
  16 
  17 #define COUNT           1
  18 #define FIRST_ZERO      2
  19 
  20 static int count_bits(struct superblock *sb, __blk_t offset, int num, int blocks, int mode)
  21 {
  22         unsigned char c;
  23         int blksize;
  24         int n, n2, last, bits, count, mapb;
  25         struct buffer *buf;
  26 
  27         count = mapb = 0;
  28         blksize = sb->s_blocksize;
  29 
  30         while(offset < blocks) {
  31                 if(!(buf = bread(sb->dev, offset, blksize))) {
  32                         return -EIO;
  33                 }
  34                 last = (num / 8) > blksize ? blksize : (num / 8);
  35                 for(n = 0; n < last; n++) {
  36                         c = (unsigned char)buf->data[n];
  37                         bits = n < last ? 8 : num & 8;
  38                         for(n2 = 0; n2 < bits; n2++) {
  39                                 if(c & (1 << n2)) {
  40                                         if(mode == COUNT) {
  41                                                 count++;
  42                                         }
  43                                 } else {
  44                                         if(mode == FIRST_ZERO) {
  45                                                 brelse(buf);
  46                                                 return n2 + ((n * 8) + (mapb * blksize * 8));
  47                                         }
  48                                 }
  49                         }
  50                 }
  51                 offset++;
  52                 mapb++;
  53                 num -= (blksize * 8);
  54                 brelse(buf);
  55         }
  56         return count;
  57 }
  58 
  59 int minix_change_bit(int mode, struct superblock *sb, int map, int item)
  60 {
  61         int byte, bit, mask;
  62         struct buffer *buf;
  63 
  64         map += item / (sb->s_blocksize * 8);
  65         byte = (item % (sb->s_blocksize * 8)) / 8;
  66         bit = (item % (sb->s_blocksize * 8)) % 8;
  67         mask = 1 << bit;
  68 
  69         if(!(buf = bread(sb->dev, map, sb->s_blocksize))) {
  70                 return -EIO;
  71         }
  72 
  73         if(mode == CLEAR_BIT) {
  74                 if(!(buf->data[byte] & mask)) {
  75                         brelse(buf);
  76                         return 1;
  77                 }
  78                 buf->data[byte] &= ~mask;
  79         }
  80         if(mode == SET_BIT) {
  81                 if((buf->data[byte] & mask)) {
  82                         brelse(buf);
  83                         return 1;
  84                 }
  85                 buf->data[byte] |= mask;
  86         }
  87 
  88         bwrite(buf);
  89         return 0;
  90 }
  91 
  92 int minix_balloc(struct superblock *sb)
  93 {
  94         int map, block, errno;
  95 
  96         superblock_lock(sb);
  97 
  98         map = 1 + SUPERBLOCK + sb->u.minix.sb.s_imap_blocks;
  99 
 100         if(!(block = minix_find_first_zero(sb, map, sb->u.minix.nzones, map + sb->u.minix.sb.s_zmap_blocks))) {
 101                 superblock_unlock(sb);
 102                 return -ENOSPC;
 103         }
 104 
 105         errno = minix_change_bit(SET_BIT, sb, map, block);
 106         block += sb->u.minix.sb.s_firstdatazone - 1;
 107 
 108         if(errno) {
 109                 if(errno < 0) {
 110                         printk("WARNING: %s(): unable to set block %d.\n", __FUNCTION__, block);
 111                         superblock_unlock(sb);
 112                         return errno;
 113                 } else {
 114                         printk("WARNING: %s(): block %d is already marked as used!\n", __FUNCTION__, block);
 115                 }
 116         }
 117 
 118         superblock_unlock(sb);
 119         return block;
 120 }
 121 
 122 void minix_bfree(struct superblock *sb, int block)
 123 {
 124         int map, errno;
 125 
 126         if(block < sb->u.minix.sb.s_firstdatazone || block > sb->u.minix.nzones) {
 127                 printk("WARNING: %s(): block %d is not in datazone.\n", __FUNCTION__, block);
 128                 return;
 129         }
 130 
 131         superblock_lock(sb);
 132 
 133         map = 1 + SUPERBLOCK + sb->u.minix.sb.s_imap_blocks;
 134         block -= sb->u.minix.sb.s_firstdatazone - 1;
 135         errno = minix_change_bit(CLEAR_BIT, sb, map, block);
 136 
 137         if(errno) {
 138                 if(errno < 0) {
 139                         printk("WARNING: %s(): unable to free block %d.\n", __FUNCTION__, block);
 140                 } else {
 141                         printk("WARNING: %s(): block %d is already marked as free!\n", __FUNCTION__, block);
 142                 }
 143         }
 144 
 145         superblock_unlock(sb);
 146         return;
 147 }
 148 
 149 int minix_count_free_inodes(struct superblock *sb)
 150 {
 151         __blk_t offset;
 152 
 153         offset = 1 + SUPERBLOCK;
 154         return count_bits(sb, offset, sb->u.minix.sb.s_ninodes, offset + sb->u.minix.sb.s_imap_blocks, COUNT);
 155 }
 156 
 157 int minix_count_free_blocks(struct superblock *sb)
 158 {
 159         __blk_t offset;
 160 
 161         offset = 1 + SUPERBLOCK + sb->u.minix.sb.s_imap_blocks;
 162         return count_bits(sb, offset, sb->u.minix.nzones, offset + sb->u.minix.sb.s_zmap_blocks, COUNT);
 163 }
 164 
 165 int minix_find_first_zero(struct superblock *sb, __blk_t offset, int num, int blocks)
 166 {
 167         return count_bits(sb, offset, num, blocks, FIRST_ZERO);
 168 }

/* [previous][next][first][last][top][bottom][index][help] */