root/fs/minix/bitmap.c

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

DEFINITIONS

This source file includes following definitions.
  1. count_free
  2. minix_free_block
  3. minix_new_block
  4. minix_count_free_blocks
  5. V1_minix_clear_inode
  6. V2_minix_clear_inode
  7. minix_clear_inode
  8. minix_free_inode
  9. minix_new_inode
  10. 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 #include <linux/sched.h>
  10 #include <linux/minix_fs.h>
  11 #include <linux/stat.h>
  12 #include <linux/kernel.h>
  13 #include <linux/string.h>
  14 
  15 #include <asm/bitops.h>
  16 
  17 static int nibblemap[] = { 4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0 };
  18 
  19 static unsigned long count_free(struct buffer_head *map[], unsigned numblocks)
     /* [previous][next][first][last][top][bottom][index][help] */
  20 {
  21         unsigned i, j, sum = 0;
  22         struct buffer_head *bh;
  23   
  24         for (i=0; i<numblocks; i++) {
  25                 if (!(bh=map[i])) 
  26                         return(0);
  27                 for (j=0; j<BLOCK_SIZE; j++)
  28                         sum += nibblemap[bh->b_data[j] & 0xf] 
  29                                 + nibblemap[(bh->b_data[j]>>4)&0xf];
  30         }
  31         return(sum);
  32 }
  33 
  34 void minix_free_block(struct super_block * sb, int block)
     /* [previous][next][first][last][top][bottom][index][help] */
  35 {
  36         struct buffer_head * bh;
  37         unsigned int bit,zone;
  38 
  39         if (!sb) {
  40                 printk("trying to free block on nonexistent device\n");
  41                 return;
  42         }
  43         if (block < sb->u.minix_sb.s_firstdatazone ||
  44             block >= sb->u.minix_sb.s_nzones) {
  45                 printk("trying to free block not in datazone\n");
  46                 return;
  47         }
  48         bh = get_hash_table(sb->s_dev,block,BLOCK_SIZE);
  49         if (bh)
  50                 clear_bit(BH_Dirty, &bh->b_state);
  51         brelse(bh);
  52         zone = block - sb->u.minix_sb.s_firstdatazone + 1;
  53         bit = zone & 8191;
  54         zone >>= 13;
  55         bh = sb->u.minix_sb.s_zmap[zone];
  56         if (!bh) {
  57                 printk("minix_free_block: nonexistent bitmap buffer\n");
  58                 return;
  59         }
  60         if (!clear_bit(bit,bh->b_data))
  61                 printk("free_block (%s:%d): bit already cleared\n",
  62                        kdevname(sb->s_dev), block);
  63         mark_buffer_dirty(bh, 1);
  64         return;
  65 }
  66 
  67 int minix_new_block(struct super_block * sb)
     /* [previous][next][first][last][top][bottom][index][help] */
  68 {
  69         struct buffer_head * bh;
  70         int i,j;
  71 
  72         if (!sb) {
  73                 printk("trying to get new block from nonexistent device\n");
  74                 return 0;
  75         }
  76 repeat:
  77         j = 8192;
  78         for (i=0 ; i<64 ; i++)
  79                 if ((bh=sb->u.minix_sb.s_zmap[i]) != NULL)
  80                         if ((j=find_first_zero_bit(bh->b_data, 8192)) < 8192)
  81                                 break;
  82         if (i>=64 || !bh || j>=8192)
  83                 return 0;
  84         if (set_bit(j,bh->b_data)) {
  85                 printk("new_block: bit already set");
  86                 goto repeat;
  87         }
  88         mark_buffer_dirty(bh, 1);
  89         j += i*8192 + sb->u.minix_sb.s_firstdatazone-1;
  90         if (j < sb->u.minix_sb.s_firstdatazone ||
  91             j >= sb->u.minix_sb.s_nzones)
  92                 return 0;
  93         if (!(bh = getblk(sb->s_dev,j,BLOCK_SIZE))) {
  94                 printk("new_block: cannot get block");
  95                 return 0;
  96         }
  97         memset(bh->b_data, 0, BLOCK_SIZE);
  98         mark_buffer_uptodate(bh, 1);
  99         mark_buffer_dirty(bh, 1);
 100         brelse(bh);
 101         return j;
 102 }
 103 
 104 unsigned long minix_count_free_blocks(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
 105 {
 106         return (count_free(sb->u.minix_sb.s_zmap,sb->u.minix_sb.s_zmap_blocks)
 107                  << sb->u.minix_sb.s_log_zone_size);
 108 }
 109 
 110 static struct buffer_head *V1_minix_clear_inode(struct inode *inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 111 {
 112         struct buffer_head *bh;
 113         struct minix_inode *raw_inode;
 114         int ino, block;
 115 
 116         ino = inode->i_ino;
 117         if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
 118                 printk("Bad inode number on dev %s: %d is out of range\n",
 119                        kdevname(inode->i_dev), ino);
 120                 return 0;
 121         }
 122         block = (2 + inode->i_sb->u.minix_sb.s_imap_blocks +
 123                  inode->i_sb->u.minix_sb.s_zmap_blocks +
 124                  (ino - 1) / MINIX_INODES_PER_BLOCK);
 125         bh = bread(inode->i_dev, block, BLOCK_SIZE);
 126         if (!bh) {
 127                 printk("unable to read i-node block\n");
 128                 return 0;
 129         }
 130         raw_inode = ((struct minix_inode *)bh->b_data +
 131                      (ino - 1) % MINIX_INODES_PER_BLOCK);
 132         raw_inode->i_nlinks = 0;
 133         raw_inode->i_mode = 0;
 134         mark_buffer_dirty(bh, 1);
 135         return bh;
 136 }
 137 
 138 static struct buffer_head *V2_minix_clear_inode(struct inode *inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 139 {
 140         struct buffer_head *bh;
 141         struct minix2_inode *raw_inode;
 142         int ino, block;
 143 
 144         ino = inode->i_ino;
 145         if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
 146                 printk("Bad inode number on dev %s: %d is out of range\n",
 147                        kdevname(inode->i_dev), ino);
 148                 return 0;
 149         }
 150         block = (2 + inode->i_sb->u.minix_sb.s_imap_blocks +
 151                  inode->i_sb->u.minix_sb.s_zmap_blocks +
 152                  (ino - 1) / MINIX2_INODES_PER_BLOCK);
 153         bh = bread(inode->i_dev, block, BLOCK_SIZE);
 154         if (!bh) {
 155                 printk("unable to read i-node block\n");
 156                 return 0;
 157         }
 158         raw_inode = ((struct minix2_inode *) bh->b_data +
 159                      (ino - 1) % MINIX2_INODES_PER_BLOCK);
 160         raw_inode->i_nlinks = 0;
 161         raw_inode->i_mode = 0;
 162         mark_buffer_dirty(bh, 1);
 163         return bh;
 164 }
 165 
 166 /* Clear the link count and mode of a deleted inode on disk. */
 167 
 168 static void minix_clear_inode(struct inode *inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 169 {
 170         struct buffer_head *bh;
 171         if (INODE_VERSION(inode) == MINIX_V1)
 172                 bh = V1_minix_clear_inode(inode);
 173         else
 174                 bh = V2_minix_clear_inode(inode);
 175         brelse (bh);
 176 }
 177 
 178 void minix_free_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 179 {
 180         struct buffer_head * bh;
 181         unsigned long ino;
 182 
 183         if (!inode)
 184                 return;
 185         if (!inode->i_dev) {
 186                 printk("free_inode: inode has no device\n");
 187                 return;
 188         }
 189         if (inode->i_count != 1) {
 190                 printk("free_inode: inode has count=%d\n",inode->i_count);
 191                 return;
 192         }
 193         if (inode->i_nlink) {
 194                 printk("free_inode: inode has nlink=%d\n",inode->i_nlink);
 195                 return;
 196         }
 197         if (!inode->i_sb) {
 198                 printk("free_inode: inode on nonexistent device\n");
 199                 return;
 200         }
 201         if (inode->i_ino < 1 || inode->i_ino >= inode->i_sb->u.minix_sb.s_ninodes) {
 202                 printk("free_inode: inode 0 or nonexistent inode\n");
 203                 return;
 204         }
 205         ino = inode->i_ino;
 206         if (!(bh=inode->i_sb->u.minix_sb.s_imap[ino >> 13])) {
 207                 printk("free_inode: nonexistent imap in superblock\n");
 208                 return;
 209         }
 210         minix_clear_inode(inode);
 211         clear_inode(inode);
 212         if (!clear_bit(ino & 8191, bh->b_data))
 213                 printk("free_inode: bit %lu already cleared.\n",ino);
 214         mark_buffer_dirty(bh, 1);
 215 }
 216 
 217 struct inode * minix_new_inode(const struct inode * dir)
     /* [previous][next][first][last][top][bottom][index][help] */
 218 {
 219         struct super_block * sb;
 220         struct inode * inode;
 221         struct buffer_head * bh;
 222         int i,j;
 223 
 224         if (!dir || !(inode = get_empty_inode()))
 225                 return NULL;
 226         sb = dir->i_sb;
 227         inode->i_sb = sb;
 228         inode->i_flags = inode->i_sb->s_flags;
 229         j = 8192;
 230         for (i=0 ; i<8 ; i++)
 231                 if ((bh = inode->i_sb->u.minix_sb.s_imap[i]) != NULL)
 232                         if ((j=find_first_zero_bit(bh->b_data, 8192)) < 8192)
 233                                 break;
 234         if (!bh || j >= 8192) {
 235                 iput(inode);
 236                 return NULL;
 237         }
 238         if (set_bit(j,bh->b_data)) {    /* shouldn't happen */
 239                 printk("new_inode: bit already set");
 240                 iput(inode);
 241                 return NULL;
 242         }
 243         mark_buffer_dirty(bh, 1);
 244         j += i*8192;
 245         if (!j || j >= inode->i_sb->u.minix_sb.s_ninodes) {
 246                 iput(inode);
 247                 return NULL;
 248         }
 249         inode->i_count = 1;
 250         inode->i_nlink = 1;
 251         inode->i_dev = sb->s_dev;
 252         inode->i_uid = current->fsuid;
 253         inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
 254         inode->i_dirt = 1;
 255         inode->i_ino = j;
 256         inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 257         inode->i_op = NULL;
 258         inode->i_blocks = inode->i_blksize = 0;
 259         insert_inode_hash(inode);
 260         return inode;
 261 }
 262 
 263 unsigned long minix_count_free_inodes(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
 264 {
 265         return count_free(sb->u.minix_sb.s_imap,sb->u.minix_sb.s_imap_blocks);
 266 }

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