|
|
1.1 root 1: /* 1.1.1.3 root 2: * linux/fs/minix/bitmap.c 1.1 root 3: * 1.1.1.5 ! root 4: * Copyright (C) 1991, 1992 Linus Torvalds 1.1 root 5: */ 6: 7: /* bitmap.c contains the code that handles the inode and block bitmaps */ 8: 9: #include <linux/sched.h> 10: #include <linux/minix_fs.h> 11: #include <linux/kernel.h> 1.1.1.5 ! root 12: #include <linux/string.h> 1.1 root 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"); 1.1.1.5 ! root 84: if (block < sb->u.minix_sb.s_firstdatazone || block >= sb->u.minix_sb.s_nzones) 1.1 root 85: panic("trying to free block not in datazone"); 1.1.1.5 ! root 86: bh = get_hash_table(dev,block,BLOCK_SIZE); 1.1 root 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: } 1.1.1.5 ! root 97: zone = block - sb->u.minix_sb.s_firstdatazone + 1; 1.1 root 98: bit = zone & 8191; 99: zone >>= 13; 1.1.1.5 ! root 100: bh = sb->u.minix_sb.s_zmap[zone]; 1.1 root 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++) 1.1.1.5 ! root 117: if (bh=sb->u.minix_sb.s_zmap[i]) 1.1 root 118: if ((j=find_first_zero(bh->b_data))<8192) 119: break; 120: if (i>=8 || !bh || j>=8192) 121: return 0; 1.1.1.5 ! root 122: if (set_bit(j,bh->b_data)) 1.1 root 123: panic("new_block: bit already set"); 124: bh->b_dirt = 1; 1.1.1.5 ! root 125: j += i*8192 + sb->u.minix_sb.s_firstdatazone-1; ! 126: if (j >= sb->u.minix_sb.s_nzones) 1.1 root 127: return 0; 1.1.1.5 ! root 128: if (!(bh=getblk(dev,j,BLOCK_SIZE))) 1.1 root 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: { 1.1.1.5 ! root 141: return (sb->u.minix_sb.s_nzones - count_used(sb->u.minix_sb.s_zmap,sb->u.minix_sb.s_zmap_blocks,sb->u.minix_sb.s_nzones)) ! 142: << sb->u.minix_sb.s_log_zone_size; 1.1.1.3 root 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: } 1.1.1.5 ! root 167: if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->u.minix_sb.s_ninodes) { 1.1 root 168: printk("free_inode: inode 0 or nonexistent inode\n"); 169: return; 170: } 1.1.1.5 ! root 171: if (!(bh=inode->i_sb->u.minix_sb.s_imap[inode->i_ino>>13])) { 1.1 root 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: } 1.1.1.5 ! root 194: inode->i_flags = inode->i_sb->s_flags; 1.1 root 195: j = 8192; 196: for (i=0 ; i<8 ; i++) 1.1.1.5 ! root 197: if (bh=inode->i_sb->u.minix_sb.s_imap[i]) 1.1 root 198: if ((j=find_first_zero(bh->b_data))<8192) 199: break; 1.1.1.5 ! root 200: if (!bh || j >= 8192 || j+i*8192 > inode->i_sb->u.minix_sb.s_ninodes) { 1.1 root 201: iput(inode); 202: return NULL; 203: } 204: if (set_bit(j,bh->b_data)) { /* shouldn't happen */ 205: printk("new_inode: bit already set"); 206: iput(inode); 207: return NULL; 208: } 209: bh->b_dirt = 1; 210: inode->i_count = 1; 211: inode->i_nlink = 1; 212: inode->i_dev = dev; 213: inode->i_uid = current->euid; 214: inode->i_gid = current->egid; 215: inode->i_dirt = 1; 216: inode->i_ino = j + i*8192; 217: inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 1.1.1.2 root 218: inode->i_op = NULL; 1.1 root 219: return inode; 220: } 1.1.1.3 root 221: 222: unsigned long minix_count_free_inodes(struct super_block *sb) 223: { 1.1.1.5 ! root 224: return sb->u.minix_sb.s_ninodes - count_used(sb->u.minix_sb.s_imap,sb->u.minix_sb.s_imap_blocks,sb->u.minix_sb.s_ninodes); 1.1.1.3 root 225: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.