[source navigation] [diff markup] [identifier search] [freetext search] [file search]

Oldlinux Cross Reference
Linux/fs/bitmap.c

Version: [1.0] [0.99.11] [0.99] [0.98] [0.97] [0.96a] [0.95] [0.12] [0.11] [0.01]
Architecture: [i386]

  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),"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),"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)
 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)
 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)
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)
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 }
169 

[source navigation] [diff markup] [identifier search] [freetext search] [file search]

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.