|
|
1.1 root 1: /*
2: * linux/fs/bitmap.c
3: *
4: * (C) 1991 Linus Torvalds
5: */
6:
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/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:
47: int minix_free_block(int dev, int block)
48: {
49: struct super_block * sb;
50: struct buffer_head * bh;
51: unsigned int bit,zone;
52:
53: if (!(sb = get_super(dev)))
54: panic("trying to free block on nonexistent device");
55: if (block < sb->s_firstdatazone || block >= sb->s_nzones)
56: panic("trying to free block not in datazone");
57: bh = get_hash_table(dev,block);
58: if (bh) {
59: if (bh->b_count > 1) {
60: brelse(bh);
61: return 0;
62: }
63: bh->b_dirt=0;
64: bh->b_uptodate=0;
65: if (bh->b_count)
66: brelse(bh);
67: }
68: zone = block - sb->s_firstdatazone + 1;
69: bit = zone & 8191;
70: zone >>= 13;
71: bh = sb->s_zmap[zone];
72: if (clear_bit(bit,bh->b_data))
73: printk("free_block (%04x:%d): bit already cleared\n",dev,block);
74: bh->b_dirt = 1;
75: return 1;
76: }
77:
78: int minix_new_block(int dev)
79: {
80: struct buffer_head * bh;
81: struct super_block * sb;
82: int i,j;
83:
84: if (!(sb = get_super(dev)))
85: panic("trying to get new block from nonexistant device");
86: j = 8192;
87: for (i=0 ; i<8 ; i++)
88: if (bh=sb->s_zmap[i])
89: if ((j=find_first_zero(bh->b_data))<8192)
90: break;
91: if (i>=8 || !bh || j>=8192)
92: return 0;
93: if (set_bit(j,bh->b_data))
94: panic("new_block: bit already set");
95: bh->b_dirt = 1;
96: j += i*8192 + sb->s_firstdatazone-1;
97: if (j >= sb->s_nzones)
98: return 0;
99: if (!(bh=getblk(dev,j)))
100: panic("new_block: cannot get block");
101: if (bh->b_count != 1)
102: panic("new block: count is != 1");
103: clear_block(bh->b_data);
104: bh->b_uptodate = 1;
105: bh->b_dirt = 1;
106: brelse(bh);
107: return j;
108: }
109:
110: void minix_free_inode(struct inode * inode)
111: {
112: struct buffer_head * bh;
113:
114: if (!inode)
115: return;
116: if (!inode->i_dev) {
117: memset(inode,0,sizeof(*inode));
118: return;
119: }
120: if (inode->i_count>1) {
121: printk("free_inode: inode has count=%d\n",inode->i_count);
122: return;
123: }
124: if (inode->i_nlink) {
125: printk("free_inode: inode has nlink=%d\n",inode->i_nlink);
126: return;
127: }
128: if (!inode->i_sb) {
129: printk("free_inode: inode on nonexistent device\n");
130: return;
131: }
132: if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->s_ninodes) {
133: printk("free_inode: inode 0 or nonexistent inode\n");
134: return;
135: }
136: if (!(bh=inode->i_sb->s_imap[inode->i_ino>>13])) {
137: printk("free_inode: nonexistent imap in superblock\n");
138: return;
139: }
140: if (clear_bit(inode->i_ino&8191,bh->b_data))
141: printk("free_inode: bit already cleared.\n\r");
142: bh->b_dirt = 1;
143: memset(inode,0,sizeof(*inode));
144: }
145:
146: struct inode * minix_new_inode(int dev)
147: {
148: struct inode * inode;
149: struct buffer_head * bh;
150: int i,j;
151:
152: if (!(inode=get_empty_inode()))
153: return NULL;
154: if (!(inode->i_sb = get_super(dev))) {
155: printk("new_inode: unknown device\n");
156: iput(inode);
157: return NULL;
158: }
159: j = 8192;
160: for (i=0 ; i<8 ; i++)
161: if (bh=inode->i_sb->s_imap[i])
162: if ((j=find_first_zero(bh->b_data))<8192)
163: break;
164: if (!bh || j >= 8192 || j+i*8192 > inode->i_sb->s_ninodes) {
165: iput(inode);
166: return NULL;
167: }
168: if (set_bit(j,bh->b_data)) { /* shouldn't happen */
169: printk("new_inode: bit already set");
170: iput(inode);
171: return NULL;
172: }
173: bh->b_dirt = 1;
174: inode->i_count = 1;
175: inode->i_nlink = 1;
176: inode->i_dev = dev;
177: inode->i_uid = current->euid;
178: inode->i_gid = current->egid;
179: inode->i_dirt = 1;
180: inode->i_ino = j + i*8192;
181: inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
182: inode->i_op = &minix_inode_operations;
183: return inode;
184: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.