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