|
|
1.1 ! root 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) ! 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) ! 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) ! 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) ! 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.