root/fs/minix/bitmap.c

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

DEFINITIONS

This source file includes following definitions.
  1. count_used
  2. minix_free_block
  3. minix_new_block
  4. minix_count_free_blocks
  5. minix_free_inode
  6. minix_new_inode
  7. minix_count_free_inodes

   1 /*
   2  *  linux/fs/minix/bitmap.c
   3  *
   4  *  Copyright (C) 1991, 1992  Linus Torvalds
   5  */
   6 
   7 /* bitmap.c contains the code that handles the inode and block bitmaps */
   8 
   9 #ifdef MODULE
  10 #include <linux/module.h>
  11 #endif
  12 
  13 #include <linux/sched.h>
  14 #include <linux/minix_fs.h>
  15 #include <linux/stat.h>
  16 #include <linux/kernel.h>
  17 #include <linux/string.h>
  18 
  19 #include <asm/bitops.h>
  20 
  21 static int nibblemap[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 };
  22 
  23 static unsigned long count_used(struct buffer_head *map[], unsigned numblocks,
     /* [previous][next][first][last][top][bottom][index][help] */
  24         unsigned numbits)
  25 {
  26         unsigned i, j, end, sum = 0;
  27         struct buffer_head *bh;
  28   
  29         for (i=0; (i<numblocks) && numbits; i++) {
  30                 if (!(bh=map[i])) 
  31                         return(0);
  32                 if (numbits >= (8*BLOCK_SIZE)) { 
  33                         end = BLOCK_SIZE;
  34                         numbits -= 8*BLOCK_SIZE;
  35                 } else {
  36                         int tmp;
  37                         end = numbits >> 3;
  38                         numbits &= 0x7;
  39                         tmp = bh->b_data[end] & ((1<<numbits)-1);
  40                         sum += nibblemap[tmp&0xf] + nibblemap[(tmp>>4)&0xf];
  41                         numbits = 0;
  42                 }  
  43                 for (j=0; j<end; j++)
  44                         sum += nibblemap[bh->b_data[j] & 0xf] 
  45                                 + nibblemap[(bh->b_data[j]>>4)&0xf];
  46         }
  47         return(sum);
  48 }
  49 
  50 void minix_free_block(struct super_block * sb, int block)
     /* [previous][next][first][last][top][bottom][index][help] */
  51 {
  52         struct buffer_head * bh;
  53         unsigned int bit,zone;
  54 
  55         if (!sb) {
  56                 printk("trying to free block on nonexistent device\n");
  57                 return;
  58         }
  59         if (block < sb->u.minix_sb.s_firstdatazone ||
  60             block >= sb->u.minix_sb.s_nzones) {
  61                 printk("trying to free block not in datazone\n");
  62                 return;
  63         }
  64         bh = get_hash_table(sb->s_dev,block,BLOCK_SIZE);
  65         if (bh)
  66                 bh->b_dirt=0;
  67         brelse(bh);
  68         zone = block - sb->u.minix_sb.s_firstdatazone + 1;
  69         bit = zone & 8191;
  70         zone >>= 13;
  71         bh = sb->u.minix_sb.s_zmap[zone];
  72         if (!bh) {
  73                 printk("minix_free_block: nonexistent bitmap buffer\n");
  74                 return;
  75         }
  76         if (!clear_bit(bit,bh->b_data))
  77                 printk("free_block (%s:%d): bit already cleared\n",
  78                        kdevname(sb->s_dev), block);
  79         mark_buffer_dirty(bh, 1);
  80         return;
  81 }
  82 
  83 int minix_new_block(struct super_block * sb)
     /* [previous][next][first][last][top][bottom][index][help] */
  84 {
  85         struct buffer_head * bh;
  86         int i,j;
  87 
  88         if (!sb) {
  89                 printk("trying to get new block from nonexistent device\n");
  90                 return 0;
  91         }
  92 repeat:
  93         j = 8192;
  94         for (i=0 ; i<8 ; i++)
  95                 if ((bh=sb->u.minix_sb.s_zmap[i]) != NULL)
  96                         if ((j=find_first_zero_bit(bh->b_data, 8192)) < 8192)
  97                                 break;
  98         if (i>=8 || !bh || j>=8192)
  99                 return 0;
 100         if (set_bit(j,bh->b_data)) {
 101                 printk("new_block: bit already set");
 102                 goto repeat;
 103         }
 104         mark_buffer_dirty(bh, 1);
 105         j += i*8192 + sb->u.minix_sb.s_firstdatazone-1;
 106         if (j < sb->u.minix_sb.s_firstdatazone ||
 107             j >= sb->u.minix_sb.s_nzones)
 108                 return 0;
 109         if (!(bh = getblk(sb->s_dev,j,BLOCK_SIZE))) {
 110                 printk("new_block: cannot get block");
 111                 return 0;
 112         }
 113         memset(bh->b_data, 0, BLOCK_SIZE);
 114         bh->b_uptodate = 1;
 115         mark_buffer_dirty(bh, 1);
 116         brelse(bh);
 117         return j;
 118 }
 119 
 120 unsigned long minix_count_free_blocks(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
 121 {
 122         return (sb->u.minix_sb.s_nzones - count_used(sb->u.minix_sb.s_zmap,sb->u.minix_sb.s_zmap_blocks,sb->u.minix_sb.s_nzones))
 123                  << sb->u.minix_sb.s_log_zone_size;
 124 }
 125 
 126 void minix_free_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 127 {
 128         struct buffer_head * bh;
 129         unsigned long ino;
 130 
 131         if (!inode)
 132                 return;
 133         if (!inode->i_dev) {
 134                 printk("free_inode: inode has no device\n");
 135                 return;
 136         }
 137         if (inode->i_count != 1) {
 138                 printk("free_inode: inode has count=%d\n",inode->i_count);
 139                 return;
 140         }
 141         if (inode->i_nlink) {
 142                 printk("free_inode: inode has nlink=%d\n",inode->i_nlink);
 143                 return;
 144         }
 145         if (!inode->i_sb) {
 146                 printk("free_inode: inode on nonexistent device\n");
 147                 return;
 148         }
 149         if (inode->i_ino < 1 || inode->i_ino >= inode->i_sb->u.minix_sb.s_ninodes) {
 150                 printk("free_inode: inode 0 or nonexistent inode\n");
 151                 return;
 152         }
 153         ino = inode->i_ino;
 154         if (!(bh=inode->i_sb->u.minix_sb.s_imap[ino >> 13])) {
 155                 printk("free_inode: nonexistent imap in superblock\n");
 156                 return;
 157         }
 158         clear_inode(inode);
 159         if (!clear_bit(ino & 8191, bh->b_data))
 160                 printk("free_inode: bit %lu already cleared.\n",ino);
 161         mark_buffer_dirty(bh, 1);
 162 }
 163 
 164 struct inode * minix_new_inode(const struct inode * dir)
     /* [previous][next][first][last][top][bottom][index][help] */
 165 {
 166         struct super_block * sb;
 167         struct inode * inode;
 168         struct buffer_head * bh;
 169         int i,j;
 170 
 171         if (!dir || !(inode = get_empty_inode()))
 172                 return NULL;
 173         sb = dir->i_sb;
 174         inode->i_sb = sb;
 175         inode->i_flags = inode->i_sb->s_flags;
 176         j = 8192;
 177         for (i=0 ; i<8 ; i++)
 178                 if ((bh = inode->i_sb->u.minix_sb.s_imap[i]) != NULL)
 179                         if ((j=find_first_zero_bit(bh->b_data, 8192)) < 8192)
 180                                 break;
 181         if (!bh || j >= 8192) {
 182                 iput(inode);
 183                 return NULL;
 184         }
 185         if (set_bit(j,bh->b_data)) {    /* shouldn't happen */
 186                 printk("new_inode: bit already set");
 187                 iput(inode);
 188                 return NULL;
 189         }
 190         mark_buffer_dirty(bh, 1);
 191         j += i*8192;
 192         if (!j || j >= inode->i_sb->u.minix_sb.s_ninodes) {
 193                 iput(inode);
 194                 return NULL;
 195         }
 196         inode->i_count = 1;
 197         inode->i_nlink = 1;
 198         inode->i_dev = sb->s_dev;
 199         inode->i_uid = current->fsuid;
 200         inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
 201         inode->i_dirt = 1;
 202         inode->i_ino = j;
 203         inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 204         inode->i_op = NULL;
 205         inode->i_blocks = inode->i_blksize = 0;
 206         insert_inode_hash(inode);
 207         return inode;
 208 }
 209 
 210 unsigned long minix_count_free_inodes(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
 211 {
 212         return sb->u.minix_sb.s_ninodes - count_used(sb->u.minix_sb.s_imap,sb->u.minix_sb.s_imap_blocks,sb->u.minix_sb.s_ninodes);
 213 }

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