root/fs/bitmap.c

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

DEFINITIONS

This source file includes following definitions.
  1. free_block
  2. new_block
  3. free_inode
  4. new_inode

   1 /*
   2  *  linux/fs/bitmap.c
   3  *
   4  *  (C) 1991  Linus Torvalds
   5  */
   6 
   7 /* bitmap.c contains the code that handles the inode and block bitmaps */
   8 #include <string.h>
   9 
  10 #include <linux/sched.h>
  11 #include <linux/kernel.h>
  12 
  13 #define clear_block(addr) \
  14 __asm__("cld\n\t" \
  15         "rep\n\t" \
  16         "stosl" \
  17         ::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")
  18 
  19 #define set_bit(nr,addr) ({\
  20 register int res __asm__("ax"); \
  21 __asm__("btsl %2,%3\n\tsetb %%al":"=a" (res):"0" (0),"r" (nr),"m" (*(addr))); \
  22 res;})
  23 
  24 #define clear_bit(nr,addr) ({\
  25 register int res __asm__("ax"); \
  26 __asm__("btrl %2,%3\n\tsetnb %%al":"=a" (res):"0" (0),"r" (nr),"m" (*(addr))); \
  27 res;})
  28 
  29 #define find_first_zero(addr) ({ \
  30 int __res; \
  31 __asm__("cld\n" \
  32         "1:\tlodsl\n\t" \
  33         "notl %%eax\n\t" \
  34         "bsfl %%eax,%%edx\n\t" \
  35         "je 2f\n\t" \
  36         "addl %%edx,%%ecx\n\t" \
  37         "jmp 3f\n" \
  38         "2:\taddl $32,%%ecx\n\t" \
  39         "cmpl $8192,%%ecx\n\t" \
  40         "jl 1b\n" \
  41         "3:" \
  42         :"=c" (__res):"c" (0),"S" (addr):"ax","dx","si"); \
  43 __res;})
  44 
  45 void free_block(int dev, int block)
     /* [previous][next][first][last][top][bottom][index][help] */
  46 {
  47         struct super_block * sb;
  48         struct buffer_head * bh;
  49 
  50         if (!(sb = get_super(dev)))
  51                 panic("trying to free block on nonexistent device");
  52         if (block < sb->s_firstdatazone || block >= sb->s_nzones)
  53                 panic("trying to free block not in datazone");
  54         bh = get_hash_table(dev,block);
  55         if (bh) {
  56                 if (bh->b_count != 1) {
  57                         printk("trying to free block (%04x:%d), count=%d\n",
  58                                 dev,block,bh->b_count);
  59                         return;
  60                 }
  61                 bh->b_dirt=0;
  62                 bh->b_uptodate=0;
  63                 brelse(bh);
  64         }
  65         block -= sb->s_firstdatazone - 1 ;
  66         if (clear_bit(block&8191,sb->s_zmap[block/8192]->b_data)) {
  67                 printk("block (%04x:%d) ",dev,block+sb->s_firstdatazone-1);
  68                 panic("free_block: bit already cleared");
  69         }
  70         sb->s_zmap[block/8192]->b_dirt = 1;
  71 }
  72 
  73 int new_block(int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  74 {
  75         struct buffer_head * bh;
  76         struct super_block * sb;
  77         int i,j;
  78 
  79         if (!(sb = get_super(dev)))
  80                 panic("trying to get new block from nonexistant device");
  81         j = 8192;
  82         for (i=0 ; i<8 ; i++)
  83                 if (bh=sb->s_zmap[i])
  84                         if ((j=find_first_zero(bh->b_data))<8192)
  85                                 break;
  86         if (i>=8 || !bh || j>=8192)
  87                 return 0;
  88         if (set_bit(j,bh->b_data))
  89                 panic("new_block: bit already set");
  90         bh->b_dirt = 1;
  91         j += i*8192 + sb->s_firstdatazone-1;
  92         if (j >= sb->s_nzones)
  93                 return 0;
  94         if (!(bh=getblk(dev,j)))
  95                 panic("new_block: cannot get block");
  96         if (bh->b_count != 1)
  97                 panic("new block: count is != 1");
  98         clear_block(bh->b_data);
  99         bh->b_uptodate = 1;
 100         bh->b_dirt = 1;
 101         brelse(bh);
 102         return j;
 103 }
 104 
 105 void free_inode(struct m_inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 106 {
 107         struct super_block * sb;
 108         struct buffer_head * bh;
 109 
 110         if (!inode)
 111                 return;
 112         if (!inode->i_dev) {
 113                 memset(inode,0,sizeof(*inode));
 114                 return;
 115         }
 116         if (inode->i_count>1) {
 117                 printk("trying to free inode with count=%d\n",inode->i_count);
 118                 panic("free_inode");
 119         }
 120         if (inode->i_nlinks)
 121                 panic("trying to free inode with links");
 122         if (!(sb = get_super(inode->i_dev)))
 123                 panic("trying to free inode on nonexistent device");
 124         if (inode->i_num < 1 || inode->i_num > sb->s_ninodes)
 125                 panic("trying to free inode 0 or nonexistant inode");
 126         if (!(bh=sb->s_imap[inode->i_num>>13]))
 127                 panic("nonexistent imap in superblock");
 128         if (clear_bit(inode->i_num&8191,bh->b_data))
 129                 panic("free_inode: bit already cleared");
 130         bh->b_dirt = 1;
 131         memset(inode,0,sizeof(*inode));
 132 }
 133 
 134 struct m_inode * new_inode(int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 135 {
 136         struct m_inode * inode;
 137         struct super_block * sb;
 138         struct buffer_head * bh;
 139         int i,j;
 140 
 141         if (!(inode=get_empty_inode()))
 142                 return NULL;
 143         if (!(sb = get_super(dev)))
 144                 panic("new_inode with unknown device");
 145         j = 8192;
 146         for (i=0 ; i<8 ; i++)
 147                 if (bh=sb->s_imap[i])
 148                         if ((j=find_first_zero(bh->b_data))<8192)
 149                                 break;
 150         if (!bh || j >= 8192 || j+i*8192 > sb->s_ninodes) {
 151                 iput(inode);
 152                 return NULL;
 153         }
 154         if (set_bit(j,bh->b_data))
 155                 panic("new_inode: bit already set");
 156         bh->b_dirt = 1;
 157         inode->i_count=1;
 158         inode->i_nlinks=1;
 159         inode->i_dev=dev;
 160         inode->i_dirt=1;
 161         inode->i_num = j + i*8192;
 162         inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 163         return inode;
 164 }

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