|
|
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.1.6 ! root 76: void minix_free_block(int dev, int block)
1.1 root 77: {
78: struct super_block * sb;
79: struct buffer_head * bh;
80: unsigned int bit,zone;
81:
1.1.1.6 ! root 82: if (!(sb = get_super(dev))) {
! 83: printk("trying to free block on nonexistent device\n");
! 84: return;
! 85: }
! 86: if (block < sb->u.minix_sb.s_firstdatazone ||
! 87: block >= sb->u.minix_sb.s_nzones) {
! 88: printk("trying to free block not in datazone\n");
! 89: return;
! 90: }
1.1.1.5 root 91: bh = get_hash_table(dev,block,BLOCK_SIZE);
1.1.1.6 ! root 92: if (bh)
1.1 root 93: bh->b_dirt=0;
1.1.1.6 ! root 94: brelse(bh);
1.1.1.5 root 95: zone = block - sb->u.minix_sb.s_firstdatazone + 1;
1.1 root 96: bit = zone & 8191;
97: zone >>= 13;
1.1.1.5 root 98: bh = sb->u.minix_sb.s_zmap[zone];
1.1.1.6 ! root 99: if (!bh) {
! 100: printk("minix_free_block: nonexistent bitmap buffer\n");
! 101: return;
! 102: }
1.1 root 103: if (clear_bit(bit,bh->b_data))
104: printk("free_block (%04x:%d): bit already cleared\n",dev,block);
105: bh->b_dirt = 1;
1.1.1.6 ! root 106: return;
1.1 root 107: }
108:
109: int minix_new_block(int dev)
110: {
111: struct buffer_head * bh;
112: struct super_block * sb;
113: int i,j;
114:
1.1.1.6 ! root 115: if (!(sb = get_super(dev))) {
! 116: printk("trying to get new block from nonexistant device\n");
! 117: return 0;
! 118: }
! 119: repeat:
1.1 root 120: j = 8192;
121: for (i=0 ; i<8 ; i++)
1.1.1.5 root 122: if (bh=sb->u.minix_sb.s_zmap[i])
1.1 root 123: if ((j=find_first_zero(bh->b_data))<8192)
124: break;
125: if (i>=8 || !bh || j>=8192)
126: return 0;
1.1.1.6 ! root 127: if (set_bit(j,bh->b_data)) {
! 128: printk("new_block: bit already set");
! 129: goto repeat;
! 130: }
1.1 root 131: bh->b_dirt = 1;
1.1.1.5 root 132: j += i*8192 + sb->u.minix_sb.s_firstdatazone-1;
133: if (j >= sb->u.minix_sb.s_nzones)
1.1 root 134: return 0;
1.1.1.6 ! root 135: if (!(bh=getblk(dev,j,BLOCK_SIZE))) {
! 136: printk("new_block: cannot get block");
! 137: return 0;
! 138: }
! 139: if (bh->b_count != 1) {
! 140: printk("new block: count is != 1");
! 141: return 0;
! 142: }
1.1 root 143: clear_block(bh->b_data);
144: bh->b_uptodate = 1;
145: bh->b_dirt = 1;
146: brelse(bh);
147: return j;
148: }
149:
1.1.1.3 root 150: unsigned long minix_count_free_blocks(struct super_block *sb)
151: {
1.1.1.5 root 152: 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))
153: << sb->u.minix_sb.s_log_zone_size;
1.1.1.3 root 154: }
155:
1.1 root 156: void minix_free_inode(struct inode * inode)
157: {
158: struct buffer_head * bh;
159:
160: if (!inode)
161: return;
162: if (!inode->i_dev) {
163: memset(inode,0,sizeof(*inode));
164: return;
165: }
166: if (inode->i_count>1) {
167: printk("free_inode: inode has count=%d\n",inode->i_count);
168: return;
169: }
170: if (inode->i_nlink) {
171: printk("free_inode: inode has nlink=%d\n",inode->i_nlink);
172: return;
173: }
174: if (!inode->i_sb) {
175: printk("free_inode: inode on nonexistent device\n");
176: return;
177: }
1.1.1.5 root 178: if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->u.minix_sb.s_ninodes) {
1.1 root 179: printk("free_inode: inode 0 or nonexistent inode\n");
180: return;
181: }
1.1.1.5 root 182: if (!(bh=inode->i_sb->u.minix_sb.s_imap[inode->i_ino>>13])) {
1.1 root 183: printk("free_inode: nonexistent imap in superblock\n");
184: return;
185: }
186: if (clear_bit(inode->i_ino&8191,bh->b_data))
187: printk("free_inode: bit already cleared.\n\r");
188: bh->b_dirt = 1;
189: memset(inode,0,sizeof(*inode));
190: }
191:
192: struct inode * minix_new_inode(int dev)
193: {
194: struct inode * inode;
195: struct buffer_head * bh;
196: int i,j;
197:
198: if (!(inode=get_empty_inode()))
199: return NULL;
200: if (!(inode->i_sb = get_super(dev))) {
201: printk("new_inode: unknown device\n");
202: iput(inode);
203: return NULL;
204: }
1.1.1.5 root 205: inode->i_flags = inode->i_sb->s_flags;
1.1 root 206: j = 8192;
207: for (i=0 ; i<8 ; i++)
1.1.1.5 root 208: if (bh=inode->i_sb->u.minix_sb.s_imap[i])
1.1 root 209: if ((j=find_first_zero(bh->b_data))<8192)
210: break;
1.1.1.5 root 211: if (!bh || j >= 8192 || j+i*8192 > inode->i_sb->u.minix_sb.s_ninodes) {
1.1 root 212: iput(inode);
213: return NULL;
214: }
215: if (set_bit(j,bh->b_data)) { /* shouldn't happen */
216: printk("new_inode: bit already set");
217: iput(inode);
218: return NULL;
219: }
220: bh->b_dirt = 1;
221: inode->i_count = 1;
222: inode->i_nlink = 1;
223: inode->i_dev = dev;
224: inode->i_uid = current->euid;
225: inode->i_gid = current->egid;
226: inode->i_dirt = 1;
227: inode->i_ino = j + i*8192;
228: inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
1.1.1.2 root 229: inode->i_op = NULL;
1.1.1.6 ! root 230: inode->i_blocks = inode->i_blksize = 0;
1.1 root 231: return inode;
232: }
1.1.1.3 root 233:
234: unsigned long minix_count_free_inodes(struct super_block *sb)
235: {
1.1.1.5 root 236: 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 237: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.