This source file includes following definitions.
- find_first_zero
- clear_buf
- que
- get__map_zone
- get_free__bit
- xiafs_free_zone
- xiafs_new_zone
- xiafs_free_inode
- xiafs_new_inode
- count_zone
- xiafs_count_free_inodes
- xiafs_count_free_zones
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #include <linux/sched.h>
15 #include <linux/locks.h>
16 #include <linux/xia_fs.h>
17 #include <linux/stat.h>
18 #include <linux/kernel.h>
19 #include <linux/string.h>
20
21 #include <asm/bitops.h>
22
23 #include "xiafs_mac.h"
24
25
26 char internal_error_message[]="XIA-FS: internal error %s %d\n";
27
28 static int find_first_zero(struct buffer_head *bh, int start_bit, int end_bit)
29 {
30
31
32
33
34
35
36 int end, i, j, tmp;
37 u_long *bmap;
38 char res;
39
40 bmap=(u_long *)bh->b_data;
41 end = end_bit >> 5;
42
43 repeat:
44 i=start_bit >> 5;
45 if ( (tmp=(~bmap[i]) & (0xffffffff << (start_bit & 31))) )
46 goto zone_found;
47 while (++i < end)
48 if (~bmap[i]) {
49 tmp=~bmap[i];
50 goto zone_found;
51 }
52 if ( !(tmp=~bmap[i] & ((1 << (end_bit & 31)) -1)) )
53 return -1;
54 zone_found:
55 for (j=0; j < 32; j++)
56 if (tmp & (1 << j))
57 break;
58 if (set_bit(j,bmap+i)) {
59 start_bit=j + (i << 5) + 1;
60 goto repeat;
61 }
62 mark_buffer_dirty(bh, 1);
63 return j + (i << 5);
64 }
65
66 static void clear_buf(struct buffer_head * bh)
67 {
68 register int i;
69 register long * lp;
70
71 lp=(long *)bh->b_data;
72 for (i= bh->b_size >> 2; i-- > 0; )
73 *lp++=0;
74 }
75
76 static void que(struct buffer_head * bmap[], int bznr[], int pos)
77 {
78 struct buffer_head * tbh;
79 int tmp;
80 int i;
81
82 tbh=bmap[pos];
83 tmp=bznr[pos];
84 for (i=pos; i > 0; i--) {
85 bmap[i]=bmap[i-1];
86 bznr[i]=bznr[i-1];
87 }
88 bmap[0]=tbh;
89 bznr[0]=tmp;
90 }
91
92 #define get_imap_zone(sb, bit_nr, not_que) \
93 get__map_zone((sb), (sb)->u.xiafs_sb.s_imap_buf, \
94 (sb)->u.xiafs_sb.s_imap_iznr, \
95 (sb)->u.xiafs_sb.s_imap_cached, 1, \
96 (sb)->u.xiafs_sb.s_imap_zones, _XIAFS_IMAP_SLOTS, \
97 bit_nr, not_que)
98
99 #define get_zmap_zone(sb, bit_nr, not_que) \
100 get__map_zone((sb), (sb)->u.xiafs_sb.s_zmap_buf, \
101 (sb)->u.xiafs_sb.s_zmap_zznr, \
102 (sb)->u.xiafs_sb.s_zmap_cached, \
103 1+(sb)->u.xiafs_sb.s_imap_zones, \
104 (sb)->u.xiafs_sb.s_zmap_zones, _XIAFS_ZMAP_SLOTS, \
105 bit_nr, not_que)
106
107 static struct buffer_head *
108 get__map_zone(struct super_block *sb, struct buffer_head * bmap_buf[],
109 int bznr[], u_char cache, int first_zone,
110 int bmap_zones, int slots, u_long bit_nr, int * not_que)
111 {
112 struct buffer_head * tmp_bh;
113 int z_nr, i;
114
115 z_nr = bit_nr >> XIAFS_BITS_PER_Z_BITS(sb);
116 if (z_nr >= bmap_zones) {
117 printk("XIA-FS: bad inode/zone number (%s %d)\n", WHERE_ERR);
118 return NULL;
119 }
120 if (!cache)
121 return bmap_buf[z_nr];
122 lock_super(sb);
123 for (i=0; i < slots; i++)
124 if (bznr[i]==z_nr)
125 break;
126 if (i < slots) {
127 if (not_que) {
128 *not_que=i;
129 return bmap_buf[i];
130 } else {
131 que(bmap_buf, bznr, i);
132 return bmap_buf[0];
133 }
134 }
135 tmp_bh=bread(sb->s_dev, z_nr+first_zone, XIAFS_ZSIZE(sb));
136 if (!tmp_bh) {
137 printk("XIA-FS: read bitmap failed (%s %d)\n", WHERE_ERR);
138 unlock_super(sb);
139 return NULL;
140 }
141 brelse(bmap_buf[slots-1]);
142 bmap_buf[slots-1]=tmp_bh;
143 bznr[slots-1]=z_nr;
144 if (not_que)
145 *not_que=slots-1;
146 else
147 que(bmap_buf, bznr, slots-1);
148 return tmp_bh;
149 }
150
151 #define xiafs_unlock_super(sb, cache) if (cache) unlock_super(sb);
152
153 #define get_free_ibit(sb, prev_bit) \
154 get_free__bit(sb, sb->u.xiafs_sb.s_imap_buf, \
155 sb->u.xiafs_sb.s_imap_iznr, \
156 sb->u.xiafs_sb.s_imap_cached, \
157 1, sb->u.xiafs_sb.s_imap_zones, \
158 _XIAFS_IMAP_SLOTS, prev_bit);
159
160 #define get_free_zbit(sb, prev_bit) \
161 get_free__bit(sb, sb->u.xiafs_sb.s_zmap_buf, \
162 sb->u.xiafs_sb.s_zmap_zznr, \
163 sb->u.xiafs_sb.s_zmap_cached, \
164 1 + sb->u.xiafs_sb.s_imap_zones, \
165 sb->u.xiafs_sb.s_zmap_zones, \
166 _XIAFS_ZMAP_SLOTS, prev_bit);
167
168 static u_long
169 get_free__bit(struct super_block *sb, struct buffer_head * bmap_buf[],
170 int bznr[], u_char cache, int first_zone, int bmap_zones,
171 int slots, u_long prev_bit)
172 {
173 struct buffer_head * bh;
174 int not_done=0;
175 u_long pos, start_bit, end_bit, total_bits;
176 int z_nr, tmp;
177
178 total_bits=bmap_zones << XIAFS_BITS_PER_Z_BITS(sb);
179 if (prev_bit >= total_bits)
180 prev_bit=0;
181 pos=prev_bit+1;
182 end_bit=XIAFS_BITS_PER_Z(sb);
183
184 do {
185 if (pos >= total_bits)
186 pos=0;
187 if (!not_done) {
188 not_done=1;
189 start_bit= pos & (end_bit-1);
190 } else
191 start_bit=0;
192 if ( pos < prev_bit && pos+end_bit >= prev_bit) {
193 not_done=0;
194 end_bit=prev_bit & (end_bit-1);
195 }
196 bh = get__map_zone(sb, bmap_buf, bznr, cache, first_zone,
197 bmap_zones, slots, pos, &z_nr);
198 if (!bh)
199 return 0;
200 tmp=find_first_zero(bh, start_bit, end_bit);
201 if (tmp >= 0)
202 break;
203 xiafs_unlock_super(sb, sb->u.xiafs_sb.s_zmap_cached);
204 pos=(pos & ~(end_bit-1))+end_bit;
205 } while (not_done);
206
207 if (tmp < 0)
208 return 0;
209 if (cache)
210 que(bmap_buf, bznr, z_nr);
211 xiafs_unlock_super(sb, cache);
212 return (pos & ~(XIAFS_BITS_PER_Z(sb)-1))+tmp;
213 }
214
215 void xiafs_free_zone(struct super_block * sb, int d_addr)
216 {
217 struct buffer_head * bh;
218 unsigned int bit, offset;
219
220 if (!sb) {
221 printk(INTERN_ERR);
222 return;
223 }
224 if (d_addr < sb->u.xiafs_sb.s_firstdatazone ||
225 d_addr >= sb->u.xiafs_sb.s_nzones) {
226 printk("XIA-FS: bad zone number (%s %d)\n", WHERE_ERR);
227 return;
228 }
229 bh = get_hash_table(sb->s_dev, d_addr, XIAFS_ZSIZE(sb));
230 if (bh)
231 bh->b_dirt=0;
232 brelse(bh);
233 bit=d_addr - sb->u.xiafs_sb.s_firstdatazone + 1;
234 bh = get_zmap_zone(sb, bit, NULL);
235 if (!bh)
236 return;
237 offset = bit & (XIAFS_BITS_PER_Z(sb) -1);
238 if (!clear_bit(offset, bh->b_data))
239 printk("XIA-FS: dev %04x"
240 " block bit %u (0x%x) already cleared (%s %d)\n",
241 sb->s_dev, bit, bit, WHERE_ERR);
242 mark_buffer_dirty(bh, 1);
243 xiafs_unlock_super(sb, sb->u.xiafs_sb.s_zmap_cached);
244 }
245
246 int xiafs_new_zone(struct super_block * sb, u_long prev_addr)
247 {
248 struct buffer_head * bh;
249 int prev_znr, tmp;
250
251 if (!sb) {
252 printk(INTERN_ERR);
253 return 0;
254 }
255 if (prev_addr < sb->u.xiafs_sb.s_firstdatazone ||
256 prev_addr >= sb->u.xiafs_sb.s_nzones) {
257 prev_addr=sb->u.xiafs_sb.s_firstdatazone;
258 }
259 prev_znr=prev_addr-sb->u.xiafs_sb.s_firstdatazone+1;
260 tmp=get_free_zbit(sb, prev_znr);
261 if (!tmp)
262 return 0;
263 tmp += sb->u.xiafs_sb.s_firstdatazone -1;
264 if (!(bh = getblk(sb->s_dev, tmp, XIAFS_ZSIZE(sb)))) {
265 printk("XIA-FS: I/O error (%s %d)\n", WHERE_ERR);
266 return 0;
267 }
268 if (bh->b_count != 1) {
269 printk(INTERN_ERR);
270 return 0;
271 }
272 clear_buf(bh);
273 bh->b_uptodate = 1;
274 mark_buffer_dirty(bh, 1);
275 brelse(bh);
276 return tmp;
277 }
278
279 void xiafs_free_inode(struct inode * inode)
280 {
281 struct buffer_head * bh;
282 struct super_block * sb;
283 unsigned long ino;
284
285 if (!inode)
286 return;
287 if (!inode->i_dev || inode->i_count!=1 || inode->i_nlink || !inode->i_sb ||
288 inode->i_ino < 3 || inode->i_ino > inode->i_sb->u.xiafs_sb.s_ninodes) {
289 printk("XIA-FS: bad inode (%s %d)\n", WHERE_ERR);
290 return;
291 }
292 sb = inode->i_sb;
293 ino = inode->i_ino;
294 bh = get_imap_zone(sb, ino, NULL);
295 if (!bh)
296 return;
297 clear_inode(inode);
298 if (!clear_bit(ino & (XIAFS_BITS_PER_Z(sb)-1), bh->b_data))
299 printk("XIA-FS: dev %04x"
300 "inode bit %ld (0x%lx) already cleared (%s %d)\n",
301 inode->i_dev, ino, ino, WHERE_ERR);
302 mark_buffer_dirty(bh, 1);
303 xiafs_unlock_super(sb, sb->u.xiafs_sb.s_imap_cached);
304 }
305
306 struct inode * xiafs_new_inode(struct inode * dir)
307 {
308 struct super_block * sb;
309 struct inode * inode;
310 ino_t tmp;
311
312 sb = dir->i_sb;
313 if (!dir || !(inode = get_empty_inode()))
314 return NULL;
315 inode->i_sb = sb;
316 inode->i_flags = inode->i_sb->s_flags;
317
318 tmp=get_free_ibit(sb, dir->i_ino);
319 if (!tmp) {
320 iput(inode);
321 return NULL;
322 }
323 inode->i_count = 1;
324 inode->i_nlink = 1;
325 inode->i_dev = sb->s_dev;
326 inode->i_uid = current->fsuid;
327 inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
328 inode->i_dirt = 1;
329 inode->i_ino = tmp;
330 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
331 inode->i_op = NULL;
332 inode->i_blocks = 0;
333 inode->i_blksize = XIAFS_ZSIZE(inode->i_sb);
334 insert_inode_hash(inode);
335 return inode;
336 }
337
338 static int nibblemap[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 };
339
340 static u_long count_zone(struct buffer_head * bh)
341 {
342 int i, tmp;
343 u_long sum;
344
345 sum=0;
346 for (i=bh->b_size; i-- > 0; ) {
347 tmp=bh->b_data[i];
348 sum += nibblemap[tmp & 0xf] + nibblemap[(tmp & 0xff) >> 4];
349 }
350 return sum;
351 }
352
353 unsigned long xiafs_count_free_inodes(struct super_block *sb)
354 {
355 struct buffer_head * bh;
356 int izones, i, not_que;
357 u_long sum;
358
359 sum=0;
360 izones=sb->u.xiafs_sb.s_imap_zones;
361 for (i=0; i < izones; i++) {
362 bh=get_imap_zone(sb, i << XIAFS_BITS_PER_Z_BITS(sb), ¬_que);
363 if (bh) {
364 sum += count_zone(bh);
365 xiafs_unlock_super(sb, sb->u.xiafs_sb.s_imap_cached);
366 }
367 }
368 i=izones << XIAFS_BITS_PER_Z_BITS(sb);
369 return i - sum;
370 }
371
372 unsigned long xiafs_count_free_zones(struct super_block *sb)
373 {
374 struct buffer_head * bh;
375 int zzones, i, not_que;
376 u_long sum;
377
378 sum=0;
379 zzones=sb->u.xiafs_sb.s_zmap_zones;
380 for (i=0; i < zzones; i++) {
381 bh=get_zmap_zone(sb, i << XIAFS_BITS_PER_Z_BITS(sb), ¬_que);
382 if (bh) {
383 sum += count_zone(bh);
384 xiafs_unlock_super(sb, sb->u.xiafs_sb.s_zmap_cached);
385 }
386 }
387 i=zzones << XIAFS_BITS_PER_Z_BITS(sb);
388 return i - sum;
389 }