|
|
1.1 root 1: /* 1.1.1.3 ! root 2: * linux/fs/minix/bitmap.c 1.1 root 3: * 4: * (C) 1991 Linus Torvalds 5: */ 6: 7: /* bitmap.c contains the code that handles the inode and block bitmaps */ 1.1.1.2 root 8: #include <linux/string.h> 1.1 root 9: 10: #include <linux/sched.h> 11: #include <linux/minix_fs.h> 12: #include <linux/kernel.h> 13: 14: #define clear_block(addr) \ 15: __asm__("cld\n\t" \ 16: "rep\n\t" \ 17: "stosl" \ 18: ::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di") 19: 20: #define set_bit(nr,addr) ({\ 21: char res; \ 22: __asm__ __volatile__("btsl %1,%2\n\tsetb %0": \ 23: "=q" (res):"r" (nr),"m" (*(addr))); \ 24: res;}) 25: 26: #define clear_bit(nr,addr) ({\ 27: char res; \ 28: __asm__ __volatile__("btrl %1,%2\n\tsetnb %0": \ 29: "=q" (res):"r" (nr),"m" (*(addr))); \ 30: res;}) 31: 32: #define find_first_zero(addr) ({ \ 33: int __res; \ 34: __asm__("cld\n" \ 35: "1:\tlodsl\n\t" \ 36: "notl %%eax\n\t" \ 37: "bsfl %%eax,%%edx\n\t" \ 38: "jne 2f\n\t" \ 39: "addl $32,%%ecx\n\t" \ 40: "cmpl $8192,%%ecx\n\t" \ 41: "jl 1b\n\t" \ 42: "xorl %%edx,%%edx\n" \ 43: "2:\taddl %%edx,%%ecx" \ 44: :"=c" (__res):"0" (0),"S" (addr):"ax","dx","si"); \ 45: __res;}) 46: 1.1.1.3 ! root 47: static int nibblemap[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 }; ! 48: ! 49: static unsigned long count_used(struct buffer_head *map[], unsigned numblocks, ! 50: unsigned numbits) ! 51: { ! 52: unsigned i, j, end, sum = 0; ! 53: struct buffer_head *bh; ! 54: ! 55: for (i=0; (i<numblocks) && numbits; i++) { ! 56: if (!(bh=map[i])) ! 57: return(0); ! 58: if (numbits >= (8*BLOCK_SIZE)) { ! 59: end = BLOCK_SIZE; ! 60: numbits -= 8*BLOCK_SIZE; ! 61: } else { ! 62: int tmp; ! 63: end = numbits >> 3; ! 64: numbits &= 0x7; ! 65: tmp = bh->b_data[end] & ((1<<numbits)-1); ! 66: sum += nibblemap[tmp&0xf] + nibblemap[(tmp>>4)&0xf]; ! 67: numbits = 0; ! 68: } ! 69: for (j=0; j<end; j++) ! 70: sum += nibblemap[bh->b_data[j] & 0xf] ! 71: + nibblemap[(bh->b_data[j]>>4)&0xf]; ! 72: } ! 73: return(sum); ! 74: } ! 75: 1.1 root 76: int minix_free_block(int dev, int block) 77: { 78: struct super_block * sb; 79: struct buffer_head * bh; 80: unsigned int bit,zone; 81: 82: if (!(sb = get_super(dev))) 83: panic("trying to free block on nonexistent device"); 84: if (block < sb->s_firstdatazone || block >= sb->s_nzones) 85: panic("trying to free block not in datazone"); 86: bh = get_hash_table(dev,block); 87: if (bh) { 88: if (bh->b_count > 1) { 89: brelse(bh); 90: return 0; 91: } 92: bh->b_dirt=0; 93: bh->b_uptodate=0; 94: if (bh->b_count) 95: brelse(bh); 96: } 97: zone = block - sb->s_firstdatazone + 1; 98: bit = zone & 8191; 99: zone >>= 13; 100: bh = sb->s_zmap[zone]; 101: if (clear_bit(bit,bh->b_data)) 102: printk("free_block (%04x:%d): bit already cleared\n",dev,block); 103: bh->b_dirt = 1; 104: return 1; 105: } 106: 107: int minix_new_block(int dev) 108: { 109: struct buffer_head * bh; 110: struct super_block * sb; 111: int i,j; 112: 113: if (!(sb = get_super(dev))) 114: panic("trying to get new block from nonexistant device"); 115: j = 8192; 116: for (i=0 ; i<8 ; i++) 117: if (bh=sb->s_zmap[i]) 118: if ((j=find_first_zero(bh->b_data))<8192) 119: break; 120: if (i>=8 || !bh || j>=8192) 121: return 0; 122: if (set_bit(j,bh->b_data)) 123: panic("new_block: bit already set"); 124: bh->b_dirt = 1; 125: j += i*8192 + sb->s_firstdatazone-1; 126: if (j >= sb->s_nzones) 127: return 0; 128: if (!(bh=getblk(dev,j))) 129: panic("new_block: cannot get block"); 130: if (bh->b_count != 1) 131: panic("new block: count is != 1"); 132: clear_block(bh->b_data); 133: bh->b_uptodate = 1; 134: bh->b_dirt = 1; 135: brelse(bh); 136: return j; 137: } 138: 1.1.1.3 ! root 139: unsigned long minix_count_free_blocks(struct super_block *sb) ! 140: { ! 141: return (sb->s_nzones - count_used(sb->s_zmap,sb->s_zmap_blocks,sb->s_nzones)) ! 142: << sb->s_log_zone_size; ! 143: } ! 144: 1.1 root 145: void minix_free_inode(struct inode * inode) 146: { 147: struct buffer_head * bh; 148: 149: if (!inode) 150: return; 151: if (!inode->i_dev) { 152: memset(inode,0,sizeof(*inode)); 153: return; 154: } 155: if (inode->i_count>1) { 156: printk("free_inode: inode has count=%d\n",inode->i_count); 157: return; 158: } 159: if (inode->i_nlink) { 160: printk("free_inode: inode has nlink=%d\n",inode->i_nlink); 161: return; 162: } 163: if (!inode->i_sb) { 164: printk("free_inode: inode on nonexistent device\n"); 165: return; 166: } 167: if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->s_ninodes) { 168: printk("free_inode: inode 0 or nonexistent inode\n"); 169: return; 170: } 171: if (!(bh=inode->i_sb->s_imap[inode->i_ino>>13])) { 172: printk("free_inode: nonexistent imap in superblock\n"); 173: return; 174: } 175: if (clear_bit(inode->i_ino&8191,bh->b_data)) 176: printk("free_inode: bit already cleared.\n\r"); 177: bh->b_dirt = 1; 178: memset(inode,0,sizeof(*inode)); 179: } 180: 181: struct inode * minix_new_inode(int dev) 182: { 183: struct inode * inode; 184: struct buffer_head * bh; 185: int i,j; 186: 187: if (!(inode=get_empty_inode())) 188: return NULL; 189: if (!(inode->i_sb = get_super(dev))) { 190: printk("new_inode: unknown device\n"); 191: iput(inode); 192: return NULL; 193: } 194: j = 8192; 195: for (i=0 ; i<8 ; i++) 196: if (bh=inode->i_sb->s_imap[i]) 197: if ((j=find_first_zero(bh->b_data))<8192) 198: break; 199: if (!bh || j >= 8192 || j+i*8192 > inode->i_sb->s_ninodes) { 200: iput(inode); 201: return NULL; 202: } 203: if (set_bit(j,bh->b_data)) { /* shouldn't happen */ 204: printk("new_inode: bit already set"); 205: iput(inode); 206: return NULL; 207: } 208: bh->b_dirt = 1; 209: inode->i_count = 1; 210: inode->i_nlink = 1; 211: inode->i_dev = dev; 212: inode->i_uid = current->euid; 213: inode->i_gid = current->egid; 214: inode->i_dirt = 1; 215: inode->i_ino = j + i*8192; 216: inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 1.1.1.2 root 217: inode->i_op = NULL; 1.1 root 218: return inode; 219: } 1.1.1.3 ! root 220: ! 221: unsigned long minix_count_free_inodes(struct super_block *sb) ! 222: { ! 223: return sb->s_ninodes - count_used(sb->s_imap,sb->s_imap_blocks,sb->s_ninodes); ! 224: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.