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

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