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

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