This source file includes following definitions.
- xiafs_put_inode
- xiafs_put_super
- xiafs_read_super
- xiafs_statfs
- zone_bmap
- xiafs_bmap
- get_prev_addr
- dt_getblk
- indt_getblk
- xiafs_getblk
- xiafs_bread
- xiafs_read_inode
- xiafs_update_inode
- xiafs_write_inode
- xiafs_sync_inode
- init_module
- cleanup_module
1
2
3
4
5
6
7
8
9
10
11
12 #ifdef MODULE
13 #include <linux/module.h>
14 #include <linux/version.h>
15 #else
16 #define MOD_INC_USE_COUNT
17 #define MOD_DEC_USE_COUNT
18 #endif
19
20 #include <linux/sched.h>
21 #include <linux/xia_fs.h>
22 #include <linux/kernel.h>
23 #include <linux/mm.h>
24 #include <linux/string.h>
25 #include <linux/stat.h>
26 #include <linux/locks.h>
27 #include <asm/system.h>
28 #include <asm/segment.h>
29
30 #include "xiafs_mac.h"
31
32 static u_long random_nr;
33
34 void xiafs_put_inode(struct inode *inode)
35 {
36 if (inode->i_nlink)
37 return;
38 inode->i_size = 0;
39 xiafs_truncate(inode);
40 xiafs_free_inode(inode);
41 }
42
43 void xiafs_put_super(struct super_block *sb)
44 {
45 int i;
46
47 lock_super(sb);
48 sb->s_dev = 0;
49 for(i = 0 ; i < _XIAFS_IMAP_SLOTS ; i++)
50 brelse(sb->u.xiafs_sb.s_imap_buf[i]);
51 for(i = 0 ; i < _XIAFS_ZMAP_SLOTS ; i++)
52 brelse(sb->u.xiafs_sb.s_zmap_buf[i]);
53 unlock_super(sb);
54 MOD_DEC_USE_COUNT;
55 }
56
57 static struct super_operations xiafs_sops = {
58 xiafs_read_inode,
59 NULL,
60 xiafs_write_inode,
61 xiafs_put_inode,
62 xiafs_put_super,
63 NULL,
64 xiafs_statfs,
65 NULL
66 };
67
68 struct super_block *xiafs_read_super(struct super_block *s, void *data,
69 int silent)
70 {
71 struct buffer_head *bh;
72 struct xiafs_super_block *sp;
73 int i, z, dev;
74
75 MOD_INC_USE_COUNT;
76 dev=s->s_dev;
77 lock_super(s);
78
79 set_blocksize(dev, BLOCK_SIZE);
80
81 if (!(bh = bread(dev, 0, BLOCK_SIZE))) {
82 s->s_dev=0;
83 unlock_super(s);
84 printk("XIA-FS: read super_block failed (%s %d)\n", WHERE_ERR);
85 MOD_DEC_USE_COUNT;
86 return NULL;
87 }
88 sp = (struct xiafs_super_block *) bh->b_data;
89 s->s_magic = sp->s_magic;
90 if (s->s_magic != _XIAFS_SUPER_MAGIC) {
91 s->s_dev = 0;
92 unlock_super(s);
93 brelse(bh);
94 if (!silent)
95 printk("VFS: Can't find a xiafs filesystem on dev 0x%04x.\n",
96 dev);
97 MOD_DEC_USE_COUNT;
98 return NULL;
99 }
100 s->s_blocksize = sp->s_zone_size;
101 s->s_blocksize_bits = 10 + sp->s_zone_shift;
102 if (s->s_blocksize != BLOCK_SIZE &&
103 (s->s_blocksize == 1024 || s->s_blocksize == 2048 ||
104 s->s_blocksize == 4096)) {
105 brelse(bh);
106 set_blocksize(dev, s->s_blocksize);
107 bh = bread (dev, 0, s->s_blocksize);
108 if(!bh) {
109 MOD_DEC_USE_COUNT;
110 return NULL;
111 }
112 sp = (struct xiafs_super_block *) (((char *)bh->b_data) + BLOCK_SIZE) ;
113 };
114 s->u.xiafs_sb.s_nzones = sp->s_nzones;
115 s->u.xiafs_sb.s_ninodes = sp->s_ninodes;
116 s->u.xiafs_sb.s_ndatazones = sp->s_ndatazones;
117 s->u.xiafs_sb.s_imap_zones = sp->s_imap_zones;
118 s->u.xiafs_sb.s_zmap_zones = sp->s_zmap_zones;
119 s->u.xiafs_sb.s_firstdatazone = sp->s_firstdatazone;
120 s->u.xiafs_sb.s_zone_shift = sp->s_zone_shift;
121 s->u.xiafs_sb.s_max_size = sp->s_max_size;
122 brelse(bh);
123 for (i=0;i < _XIAFS_IMAP_SLOTS;i++) {
124 s->u.xiafs_sb.s_imap_buf[i] = NULL;
125 s->u.xiafs_sb.s_imap_iznr[i] = -1;
126 }
127 for (i=0;i < _XIAFS_ZMAP_SLOTS;i++) {
128 s->u.xiafs_sb.s_zmap_buf[i] = NULL;
129 s->u.xiafs_sb.s_zmap_zznr[i] = -1;
130 }
131 z=1;
132 if ( s->u.xiafs_sb.s_imap_zones > _XIAFS_IMAP_SLOTS )
133 s->u.xiafs_sb.s_imap_cached=1;
134 else {
135 s->u.xiafs_sb.s_imap_cached=0;
136 for (i=0 ; i < s->u.xiafs_sb.s_imap_zones ; i++) {
137 if (!(s->u.xiafs_sb.s_imap_buf[i]=bread(dev, z++, XIAFS_ZSIZE(s))))
138 goto xiafs_read_super_fail;
139 s->u.xiafs_sb.s_imap_iznr[i]=i;
140 }
141 }
142 if ( s->u.xiafs_sb.s_zmap_zones > _XIAFS_ZMAP_SLOTS )
143 s->u.xiafs_sb.s_zmap_cached=1;
144 else {
145 s->u.xiafs_sb.s_zmap_cached=0;
146 for (i=0 ; i < s->u.xiafs_sb.s_zmap_zones ; i++) {
147 if (!(s->u.xiafs_sb.s_zmap_buf[i]=bread(dev, z++, XIAFS_ZSIZE(s))))
148 goto xiafs_read_super_fail;
149 s->u.xiafs_sb.s_zmap_zznr[i]=i;
150 }
151 }
152
153 s->s_dev = dev;
154 s->s_op = &xiafs_sops;
155 s->s_mounted = iget(s, _XIAFS_ROOT_INO);
156 if (!s->s_mounted)
157 goto xiafs_read_super_fail;
158 unlock_super(s);
159 random_nr=CURRENT_TIME;
160 return s;
161
162 xiafs_read_super_fail:
163 for(i=0; i < _XIAFS_IMAP_SLOTS; i++)
164 brelse(s->u.xiafs_sb.s_imap_buf[i]);
165 for(i=0; i < _XIAFS_ZMAP_SLOTS; i++)
166 brelse(s->u.xiafs_sb.s_zmap_buf[i]);
167 s->s_dev=0;
168 unlock_super(s);
169 printk("XIA-FS: read bitmaps failed (%s %d)\n", WHERE_ERR);
170 MOD_DEC_USE_COUNT;
171 return NULL;
172 }
173
174 void xiafs_statfs(struct super_block *sb, struct statfs *buf)
175 {
176 long tmp;
177
178 put_fs_long(_XIAFS_SUPER_MAGIC, &buf->f_type);
179 put_fs_long(XIAFS_ZSIZE(sb), &buf->f_bsize);
180 put_fs_long(sb->u.xiafs_sb.s_ndatazones, &buf->f_blocks);
181 tmp = xiafs_count_free_zones(sb);
182 put_fs_long(tmp, &buf->f_bfree);
183 put_fs_long(tmp, &buf->f_bavail);
184 put_fs_long(sb->u.xiafs_sb.s_ninodes, &buf->f_files);
185 put_fs_long(xiafs_count_free_inodes(sb), &buf->f_ffree);
186 put_fs_long(_XIAFS_NAME_LEN, &buf->f_namelen);
187
188 }
189
190 static int zone_bmap(struct buffer_head * bh, int nr)
191 {
192 int tmp;
193
194 if (!bh)
195 return 0;
196 tmp = ((u_long *) bh->b_data)[nr];
197 brelse(bh);
198 return tmp;
199 }
200
201 int xiafs_bmap(struct inode * inode,int zone)
202 {
203 int i;
204
205 if (zone < 0) {
206 printk("XIA-FS: block < 0 (%s %d)\n", WHERE_ERR);
207 return 0;
208 }
209 if (zone >= 8+(1+XIAFS_ADDRS_PER_Z(inode->i_sb))*XIAFS_ADDRS_PER_Z(inode->i_sb)) {
210 printk("XIA-FS: zone > big (%s %d)\n", WHERE_ERR);
211 return 0;
212 }
213 if (!IS_RDONLY (inode)) {
214 inode->i_atime = CURRENT_TIME;
215 inode->i_dirt = 1;
216 }
217 if (zone < 8)
218 return inode->u.xiafs_i.i_zone[zone];
219 zone -= 8;
220 if (zone < XIAFS_ADDRS_PER_Z(inode->i_sb)) {
221 i = inode->u.xiafs_i.i_ind_zone;
222 if (i)
223 i = zone_bmap(bread(inode->i_dev, i, XIAFS_ZSIZE(inode->i_sb)), zone);
224 return i;
225 }
226 zone -= XIAFS_ADDRS_PER_Z(inode->i_sb);
227 i = inode->u.xiafs_i.i_dind_zone;
228 if (i)
229 i = zone_bmap(bread(inode->i_dev, i, XIAFS_ZSIZE(inode->i_sb)),
230 zone >> XIAFS_ADDRS_PER_Z_BITS(inode->i_sb));
231 if (i)
232 i= zone_bmap(bread(inode->i_dev,i, XIAFS_ZSIZE(inode->i_sb)),
233 zone & (XIAFS_ADDRS_PER_Z(inode->i_sb)-1));
234 return i;
235 }
236
237 static u_long get_prev_addr(struct inode * inode, int zone)
238 {
239 u_long tmp;
240
241 if (zone > 0)
242 while (--zone >= 0)
243 if ((tmp=xiafs_bmap(inode, zone)))
244 return tmp;
245 random_nr=(random_nr+23)%inode->i_sb->u.xiafs_sb.s_ndatazones;
246 return random_nr + inode->i_sb->u.xiafs_sb.s_firstdatazone;
247 }
248
249 static struct buffer_head *
250 dt_getblk(struct inode * inode, u_long *lp, int create, u_long prev_addr)
251 {
252 int tmp;
253 struct buffer_head * result;
254
255 repeat:
256 if ((tmp=*lp)) {
257 result = getblk(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
258 if (tmp == *lp)
259 return result;
260 brelse(result);
261 goto repeat;
262 }
263 if (!create)
264 return NULL;
265 tmp = xiafs_new_zone(inode->i_sb, prev_addr);
266 if (!tmp)
267 return NULL;
268 result = getblk(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
269 if (*lp) {
270 xiafs_free_zone(inode->i_sb, tmp);
271 brelse(result);
272 goto repeat;
273 }
274 *lp = tmp;
275 inode->i_blocks+=2 << XIAFS_ZSHIFT(inode->i_sb);
276 return result;
277 }
278
279 static struct buffer_head *
280 indt_getblk(struct inode * inode, struct buffer_head * bh,
281 int nr, int create, u_long prev_addr)
282 {
283 int tmp;
284 u_long *lp;
285 struct buffer_head * result;
286
287 if (!bh)
288 return NULL;
289 if (!bh->b_uptodate) {
290 ll_rw_block(READ, 1, &bh);
291 wait_on_buffer(bh);
292 if (!bh->b_uptodate) {
293 brelse(bh);
294 return NULL;
295 }
296 }
297 lp = nr + (u_long *) bh->b_data;
298 repeat:
299 if ((tmp=*lp)) {
300 result = getblk(bh->b_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
301 if (tmp == *lp) {
302 brelse(bh);
303 return result;
304 }
305 brelse(result);
306 goto repeat;
307 }
308 if (!create) {
309 brelse(bh);
310 return NULL;
311 }
312 tmp = xiafs_new_zone(inode->i_sb, prev_addr);
313 if (!tmp) {
314 brelse(bh);
315 return NULL;
316 }
317 result = getblk(bh->b_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
318 if (*lp) {
319 xiafs_free_zone(inode->i_sb, tmp);
320 brelse(result);
321 goto repeat;
322 }
323 *lp = tmp;
324 inode->i_blocks+=2 << XIAFS_ZSHIFT(inode->i_sb);
325 mark_buffer_dirty(bh, 1);
326 brelse(bh);
327 return result;
328 }
329
330 struct buffer_head * xiafs_getblk(struct inode * inode, int zone, int create)
331 {
332 struct buffer_head * bh;
333 u_long prev_addr=0;
334
335 if (zone<0) {
336 printk("XIA-FS: zone < 0 (%s %d)\n", WHERE_ERR);
337 return NULL;
338 }
339 if (zone >= 8+(1+XIAFS_ADDRS_PER_Z(inode->i_sb))*XIAFS_ADDRS_PER_Z(inode->i_sb)) {
340 if (!create)
341 printk("XIA-FS: zone > big (%s %d)\n", WHERE_ERR);
342 return NULL;
343 }
344 if (create)
345 prev_addr=get_prev_addr(inode, zone);
346 if (zone < 8)
347 return dt_getblk(inode, zone+inode->u.xiafs_i.i_zone, create, prev_addr);
348 zone -= 8;
349 if (zone < XIAFS_ADDRS_PER_Z(inode->i_sb)) {
350 bh = dt_getblk(inode, &(inode->u.xiafs_i.i_ind_zone), create, prev_addr);
351 bh = indt_getblk(inode, bh, zone, create, prev_addr);
352 return bh;
353 }
354 zone -= XIAFS_ADDRS_PER_Z(inode->i_sb);
355 bh = dt_getblk(inode, &(inode->u.xiafs_i.i_dind_zone), create, prev_addr);
356 bh = indt_getblk(inode, bh, zone>>XIAFS_ADDRS_PER_Z_BITS(inode->i_sb),
357 create, prev_addr);
358 bh = indt_getblk(inode, bh, zone&(XIAFS_ADDRS_PER_Z(inode->i_sb)-1),
359 create, prev_addr);
360 return bh;
361 }
362
363 struct buffer_head * xiafs_bread(struct inode * inode, int zone, int create)
364 {
365 struct buffer_head * bh;
366
367 bh = xiafs_getblk(inode, zone, create);
368 if (!bh || bh->b_uptodate)
369 return bh;
370 ll_rw_block(READ, 1, &bh);
371 wait_on_buffer(bh);
372 if (bh->b_uptodate)
373 return bh;
374 brelse(bh);
375 return NULL;
376 }
377
378 void xiafs_read_inode(struct inode * inode)
379 {
380 struct buffer_head * bh;
381 struct xiafs_inode * raw_inode;
382 int zone;
383 ino_t ino;
384
385 ino = inode->i_ino;
386 inode->i_op = NULL;
387 inode->i_mode=0;
388 if (!ino || ino > inode->i_sb->u.xiafs_sb.s_ninodes) {
389 printk("XIA-FS: bad inode number (%s %d)\n", WHERE_ERR);
390 return;
391 }
392 zone = 1 + inode->i_sb->u.xiafs_sb.s_imap_zones +
393 inode->i_sb->u.xiafs_sb.s_zmap_zones +
394 (ino-1)/ XIAFS_INODES_PER_Z(inode->i_sb);
395 if (!(bh=bread(inode->i_dev, zone, XIAFS_ZSIZE(inode->i_sb)))) {
396 printk("XIA-FS: read i-node zone failed (%s %d)\n", WHERE_ERR);
397 return;
398 }
399 raw_inode = ((struct xiafs_inode *) bh->b_data) +
400 ((ino-1) & (XIAFS_INODES_PER_Z(inode->i_sb) - 1));
401 inode->i_mode = raw_inode->i_mode;
402 inode->i_uid = raw_inode->i_uid;
403 inode->i_gid = raw_inode->i_gid;
404 inode->i_nlink = raw_inode->i_nlinks;
405 inode->i_size = raw_inode->i_size;
406 inode->i_mtime = raw_inode->i_mtime;
407 inode->i_atime = raw_inode->i_atime;
408 inode->i_ctime = raw_inode->i_ctime;
409 inode->i_blksize = XIAFS_ZSIZE(inode->i_sb);
410 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
411 inode->i_blocks=0;
412 inode->i_rdev = raw_inode->i_zone[0];
413 } else {
414 XIAFS_GET_BLOCKS(raw_inode, inode->i_blocks);
415 for (zone = 0; zone < 8; zone++)
416 inode->u.xiafs_i.i_zone[zone] = raw_inode->i_zone[zone] & 0xffffff;
417 inode->u.xiafs_i.i_ind_zone = raw_inode->i_ind_zone & 0xffffff;
418 inode->u.xiafs_i.i_dind_zone = raw_inode->i_dind_zone & 0xffffff;
419 }
420 brelse(bh);
421 if (S_ISREG(inode->i_mode))
422 inode->i_op = &xiafs_file_inode_operations;
423 else if (S_ISDIR(inode->i_mode))
424 inode->i_op = &xiafs_dir_inode_operations;
425 else if (S_ISLNK(inode->i_mode))
426 inode->i_op = &xiafs_symlink_inode_operations;
427 else if (S_ISCHR(inode->i_mode))
428 inode->i_op = &chrdev_inode_operations;
429 else if (S_ISBLK(inode->i_mode))
430 inode->i_op = &blkdev_inode_operations;
431 else if (S_ISFIFO(inode->i_mode))
432 init_fifo(inode);
433 }
434
435 static struct buffer_head * xiafs_update_inode(struct inode * inode)
436 {
437 struct buffer_head * bh;
438 struct xiafs_inode * raw_inode;
439 int zone;
440 ino_t ino;
441
442 if (IS_RDONLY (inode)) {
443 printk("XIA-FS: write_inode on a read-only filesystem (%s %d)\n", WHERE_ERR);
444 inode->i_dirt = 0;
445 return 0;
446 }
447
448 ino = inode->i_ino;
449 if (!ino || ino > inode->i_sb->u.xiafs_sb.s_ninodes) {
450 printk("XIA-FS: bad inode number (%s %d)\n", WHERE_ERR);
451 inode->i_dirt=0;
452 return 0;
453 }
454 zone = 1 + inode->i_sb->u.xiafs_sb.s_imap_zones +
455 inode->i_sb->u.xiafs_sb.s_zmap_zones +
456 (ino-1) / XIAFS_INODES_PER_Z(inode->i_sb);
457 if (!(bh=bread(inode->i_dev, zone, XIAFS_ZSIZE(inode->i_sb)))) {
458 printk("XIA-FS: read i-node zone failed (%s %d)\n", WHERE_ERR);
459 inode->i_dirt=0;
460 return 0;
461 }
462 raw_inode = ((struct xiafs_inode *)bh->b_data) +
463 ((ino-1) & (XIAFS_INODES_PER_Z(inode->i_sb) -1));
464 raw_inode->i_mode = inode->i_mode;
465 raw_inode->i_uid = inode->i_uid;
466 raw_inode->i_gid = inode->i_gid;
467 raw_inode->i_nlinks = inode->i_nlink;
468 raw_inode->i_size = inode->i_size;
469 raw_inode->i_atime = inode->i_atime;
470 raw_inode->i_ctime = inode->i_ctime;
471 raw_inode->i_mtime = inode->i_mtime;
472 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
473 raw_inode->i_zone[0] = inode->i_rdev;
474 else {
475 XIAFS_PUT_BLOCKS(raw_inode, inode->i_blocks);
476 for (zone = 0; zone < 8; zone++)
477 raw_inode->i_zone[zone] = (raw_inode->i_zone[zone] & 0xff000000)
478 | (inode->u.xiafs_i.i_zone[zone] & 0xffffff);
479 raw_inode->i_ind_zone = (raw_inode->i_ind_zone & 0xff000000)
480 | (inode->u.xiafs_i.i_ind_zone & 0xffffff);
481 raw_inode->i_dind_zone = (raw_inode->i_dind_zone & 0xff000000)
482 | (inode->u.xiafs_i.i_dind_zone & 0xffffff);
483 }
484 inode->i_dirt=0;
485 mark_buffer_dirty(bh, 1);
486 return bh;
487 }
488
489
490 void xiafs_write_inode(struct inode * inode)
491 {
492 struct buffer_head * bh;
493 bh = xiafs_update_inode(inode);
494 brelse (bh);
495 }
496
497 int xiafs_sync_inode (struct inode *inode)
498 {
499 int err = 0;
500 struct buffer_head *bh;
501
502 bh = xiafs_update_inode(inode);
503 if (bh && bh->b_dirt)
504 {
505 ll_rw_block(WRITE, 1, &bh);
506 wait_on_buffer(bh);
507 if (bh->b_req && !bh->b_uptodate)
508 {
509 printk ("IO error syncing xiafs inode [%04X:%lu]\n",
510 inode->i_dev, inode->i_ino);
511 err = -1;
512 }
513 }
514 else if (!bh)
515 err = -1;
516 brelse (bh);
517 return err;
518 }
519
520 #ifdef MODULE
521
522
523
524 char kernel_version[] = UTS_RELEASE;
525
526 static struct file_system_type xiafs_fs_type = {
527 xiafs_read_super, "xiafs", 1, NULL
528 };
529
530 int init_module(void)
531 {
532 register_filesystem(&xiafs_fs_type);
533 return 0;
534 }
535
536 void cleanup_module(void)
537 {
538 unregister_filesystem(&xiafs_fs_type);
539 }
540
541 #endif