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 #include <linux/sched.h>
  10 #include <linux/minix_fs.h>
  11 #include <linux/kernel.h>
  12 #include <linux/string.h>
  13 
  14 #define clear_block(addr) \
  15 __asm__("cld\n\t" \
  16         "rep\n\t" \
  17         "stosl" \
  18         ::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")
  19 
  20 #define set_bit(nr,addr) ({\
  21 char res; \
  22 __asm__ __volatile__("btsl %1,%2\n\tsetb %0": \
  23 "=q" (res):"r" (nr),"m" (*(addr))); \
  24 res;})
  25 
  26 #define clear_bit(nr,addr) ({\
  27 char res; \
  28 __asm__ __volatile__("btrl %1,%2\n\tsetnb %0": \
  29 "=q" (res):"r" (nr),"m" (*(addr))); \
  30 res;})
  31 
  32 #define find_first_zero(addr) ({ \
  33 int __res; \
  34 __asm__("cld\n" \
  35         "1:\tlodsl\n\t" \
  36         "notl %%eax\n\t" \
  37         "bsfl %%eax,%%edx\n\t" \
  38         "jne 2f\n\t" \
  39         "addl $32,%%ecx\n\t" \
  40         "cmpl $8192,%%ecx\n\t" \
  41         "jl 1b\n\t" \
  42         "xorl %%edx,%%edx\n" \
  43         "2:\taddl %%edx,%%ecx" \
  44         :"=c" (__res):"0" (0),"S" (addr):"ax","dx","si"); \
  45 __res;})
  46 
  47 static int nibblemap[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 };
  48 
  49 static unsigned long count_used(struct buffer_head *map[], unsigned numblocks,
     /* [previous][next][first][last][top][bottom][index][help] */
  50         unsigned numbits)
  51 {
  52         unsigned i, j, end, sum = 0;
  53         struct buffer_head *bh;
  54   
  55         for (i=0; (i<numblocks) && numbits; i++) {
  56                 if (!(bh=map[i])) 
  57                         return(0);
  58                 if (numbits >= (8*BLOCK_SIZE)) { 
  59                         end = BLOCK_SIZE;
  60                         numbits -= 8*BLOCK_SIZE;
  61                 } else {
  62                         int tmp;
  63                         end = numbits >> 3;
  64                         numbits &= 0x7;
  65                         tmp = bh->b_data[end] & ((1<<numbits)-1);
  66                         sum += nibblemap[tmp&0xf] + nibblemap[(tmp>>4)&0xf];
  67                         numbits = 0;
  68                 }  
  69                 for (j=0; j<end; j++)
  70                         sum += nibblemap[bh->b_data[j] & 0xf] 
  71                                 + nibblemap[(bh->b_data[j]>>4)&0xf];
  72         }
  73         return(sum);
  74 }
  75 
  76 int minix_free_block(int dev, int block)
     /* [previous][next][first][last][top][bottom][index][help] */
  77 {
  78         struct super_block * sb;
  79         struct buffer_head * bh;
  80         unsigned int bit,zone;
  81 
  82         if (!(sb = get_super(dev)))
  83                 panic("trying to free block on nonexistent device");
  84         if (block < sb->u.minix_sb.s_firstdatazone || block >= sb->u.minix_sb.s_nzones)
  85                 panic("trying to free block not in datazone");
  86         bh = get_hash_table(dev,block,BLOCK_SIZE);
  87         if (bh) {
  88                 if (bh->b_count > 1) {
  89                         brelse(bh);
  90                         return 0;
  91                 }
  92                 bh->b_dirt=0;
  93                 bh->b_uptodate=0;
  94                 if (bh->b_count)
  95                         brelse(bh);
  96         }
  97         zone = block - sb->u.minix_sb.s_firstdatazone + 1;
  98         bit = zone & 8191;
  99         zone >>= 13;
 100         bh = sb->u.minix_sb.s_zmap[zone];
 101         if (clear_bit(bit,bh->b_data))
 102                 printk("free_block (%04x:%d): bit already cleared\n",dev,block);
 103         bh->b_dirt = 1;
 104         return 1;
 105 }
 106 
 107 int minix_new_block(int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 108 {
 109         struct buffer_head * bh;
 110         struct super_block * sb;
 111         int i,j;
 112 
 113         if (!(sb = get_super(dev)))
 114                 panic("trying to get new block from nonexistant device");
 115         j = 8192;
 116         for (i=0 ; i<8 ; i++)
 117                 if (bh=sb->u.minix_sb.s_zmap[i])
 118                         if ((j=find_first_zero(bh->b_data))<8192)
 119                                 break;
 120         if (i>=8 || !bh || j>=8192)
 121                 return 0;
 122         if (set_bit(j,bh->b_data)) 
 123                 panic("new_block: bit already set");
 124         bh->b_dirt = 1;
 125         j += i*8192 + sb->u.minix_sb.s_firstdatazone-1;
 126         if (j >= sb->u.minix_sb.s_nzones)
 127                 return 0;
 128         if (!(bh=getblk(dev,j,BLOCK_SIZE)))
 129                 panic("new_block: cannot get block");
 130         if (bh->b_count != 1)
 131                 panic("new block: count is != 1");
 132         clear_block(bh->b_data);
 133         bh->b_uptodate = 1;
 134         bh->b_dirt = 1;
 135         brelse(bh);
 136         return j;
 137 }
 138 
 139 unsigned long minix_count_free_blocks(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
 140 {
 141         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))
 142                  << sb->u.minix_sb.s_log_zone_size;
 143 }
 144 
 145 void minix_free_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 146 {
 147         struct buffer_head * bh;
 148 
 149         if (!inode)
 150                 return;
 151         if (!inode->i_dev) {
 152                 memset(inode,0,sizeof(*inode));
 153                 return;
 154         }
 155         if (inode->i_count>1) {
 156                 printk("free_inode: inode has count=%d\n",inode->i_count);
 157                 return;
 158         }
 159         if (inode->i_nlink) {
 160                 printk("free_inode: inode has nlink=%d\n",inode->i_nlink);
 161                 return;
 162         }
 163         if (!inode->i_sb) {
 164                 printk("free_inode: inode on nonexistent device\n");
 165                 return;
 166         }
 167         if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->u.minix_sb.s_ninodes) {
 168                 printk("free_inode: inode 0 or nonexistent inode\n");
 169                 return;
 170         }
 171         if (!(bh=inode->i_sb->u.minix_sb.s_imap[inode->i_ino>>13])) {
 172                 printk("free_inode: nonexistent imap in superblock\n");
 173                 return;
 174         }
 175         if (clear_bit(inode->i_ino&8191,bh->b_data))
 176                 printk("free_inode: bit already cleared.\n\r");
 177         bh->b_dirt = 1;
 178         memset(inode,0,sizeof(*inode));
 179 }
 180 
 181 struct inode * minix_new_inode(int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 182 {
 183         struct inode * inode;
 184         struct buffer_head * bh;
 185         int i,j;
 186 
 187         if (!(inode=get_empty_inode()))
 188                 return NULL;
 189         if (!(inode->i_sb = get_super(dev))) {
 190                 printk("new_inode: unknown device\n");
 191                 iput(inode);
 192                 return NULL;
 193         }
 194         inode->i_flags = inode->i_sb->s_flags;
 195         j = 8192;
 196         for (i=0 ; i<8 ; i++)
 197                 if (bh=inode->i_sb->u.minix_sb.s_imap[i])
 198                         if ((j=find_first_zero(bh->b_data))<8192)
 199                                 break;
 200         if (!bh || j >= 8192 || j+i*8192 > inode->i_sb->u.minix_sb.s_ninodes) {
 201                 iput(inode);
 202                 return NULL;
 203         }
 204         if (set_bit(j,bh->b_data)) {    /* shouldn't happen */
 205                 printk("new_inode: bit already set");
 206                 iput(inode);
 207                 return NULL;
 208         }
 209         bh->b_dirt = 1;
 210         inode->i_count = 1;
 211         inode->i_nlink = 1;
 212         inode->i_dev = dev;
 213         inode->i_uid = current->euid;
 214         inode->i_gid = current->egid;
 215         inode->i_dirt = 1;
 216         inode->i_ino = j + i*8192;
 217         inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 218         inode->i_op = NULL;
 219         return inode;
 220 }
 221 
 222 unsigned long minix_count_free_inodes(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
 223 {
 224         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);
 225 }

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