|
|
1.1.1.2 ! root 1: /* ! 2: * linux/fs/bitmap.c ! 3: * ! 4: * (C) 1991 Linus Torvalds ! 5: */ ! 6: 1.1 root 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) 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) 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) 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) 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.