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, int bufsiz)
175 {
176 struct statfs tmp;
177
178 tmp.f_type = _XIAFS_SUPER_MAGIC;
179 tmp.f_bsize = XIAFS_ZSIZE(sb);
180 tmp.f_blocks = sb->u.xiafs_sb.s_ndatazones;
181 tmp.f_bfree = xiafs_count_free_zones(sb);
182 tmp.f_bavail = tmp.f_bfree;
183 tmp.f_files = sb->u.xiafs_sb.s_ninodes;
184 tmp.f_ffree = xiafs_count_free_inodes(sb);
185 tmp.f_namelen = _XIAFS_NAME_LEN;
186 memcpy_tofs(buf, &tmp, bufsiz);
187 }
188
189 static int zone_bmap(struct buffer_head * bh, int nr)
190 {
191 int tmp;
192
193 if (!bh)
194 return 0;
195 tmp = ((u_long *) bh->b_data)[nr];
196 brelse(bh);
197 return tmp;
198 }
199
200 int xiafs_bmap(struct inode * inode,int zone)
201 {
202 int i;
203
204 if (zone < 0) {
205 printk("XIA-FS: block < 0 (%s %d)\n", WHERE_ERR);
206 return 0;
207 }
208 if (zone >= 8+(1+XIAFS_ADDRS_PER_Z(inode->i_sb))*XIAFS_ADDRS_PER_Z(inode->i_sb)) {
209 printk("XIA-FS: zone > big (%s %d)\n", WHERE_ERR);
210 return 0;
211 }
212 if (!IS_RDONLY (inode)) {
213 inode->i_atime = CURRENT_TIME;
214 inode->i_dirt = 1;
215 }
216 if (zone < 8)
217 return inode->u.xiafs_i.i_zone[zone];
218 zone -= 8;
219 if (zone < XIAFS_ADDRS_PER_Z(inode->i_sb)) {
220 i = inode->u.xiafs_i.i_ind_zone;
221 if (i)
222 i = zone_bmap(bread(inode->i_dev, i, XIAFS_ZSIZE(inode->i_sb)), zone);
223 return i;
224 }
225 zone -= XIAFS_ADDRS_PER_Z(inode->i_sb);
226 i = inode->u.xiafs_i.i_dind_zone;
227 if (i)
228 i = zone_bmap(bread(inode->i_dev, i, XIAFS_ZSIZE(inode->i_sb)),
229 zone >> XIAFS_ADDRS_PER_Z_BITS(inode->i_sb));
230 if (i)
231 i= zone_bmap(bread(inode->i_dev,i, XIAFS_ZSIZE(inode->i_sb)),
232 zone & (XIAFS_ADDRS_PER_Z(inode->i_sb)-1));
233 return i;
234 }
235
236 static u_long get_prev_addr(struct inode * inode, int zone)
237 {
238 u_long tmp;
239
240 if (zone > 0)
241 while (--zone >= 0)
242 if ((tmp=xiafs_bmap(inode, zone)))
243 return tmp;
244 random_nr=(random_nr+23)%inode->i_sb->u.xiafs_sb.s_ndatazones;
245 return random_nr + inode->i_sb->u.xiafs_sb.s_firstdatazone;
246 }
247
248 static struct buffer_head *
249 dt_getblk(struct inode * inode, u_long *lp, int create, u_long prev_addr)
250 {
251 int tmp;
252 struct buffer_head * result;
253
254 repeat:
255 if ((tmp=*lp)) {
256 result = getblk(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
257 if (tmp == *lp)
258 return result;
259 brelse(result);
260 goto repeat;
261 }
262 if (!create)
263 return NULL;
264 tmp = xiafs_new_zone(inode->i_sb, prev_addr);
265 if (!tmp)
266 return NULL;
267 result = getblk(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
268 if (*lp) {
269 xiafs_free_zone(inode->i_sb, tmp);
270 brelse(result);
271 goto repeat;
272 }
273 *lp = tmp;
274 inode->i_blocks+=2 << XIAFS_ZSHIFT(inode->i_sb);
275 return result;
276 }
277
278 static struct buffer_head *
279 indt_getblk(struct inode * inode, struct buffer_head * bh,
280 int nr, int create, u_long prev_addr)
281 {
282 int tmp;
283 u_long *lp;
284 struct buffer_head * result;
285
286 if (!bh)
287 return NULL;
288 if (!bh->b_uptodate) {
289 ll_rw_block(READ, 1, &bh);
290 wait_on_buffer(bh);
291 if (!bh->b_uptodate) {
292 brelse(bh);
293 return NULL;
294 }
295 }
296 lp = nr + (u_long *) bh->b_data;
297 repeat:
298 if ((tmp=*lp)) {
299 result = getblk(bh->b_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
300 if (tmp == *lp) {
301 brelse(bh);
302 return result;
303 }
304 brelse(result);
305 goto repeat;
306 }
307 if (!create) {
308 brelse(bh);
309 return NULL;
310 }
311 tmp = xiafs_new_zone(inode->i_sb, prev_addr);
312 if (!tmp) {
313 brelse(bh);
314 return NULL;
315 }
316 result = getblk(bh->b_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
317 if (*lp) {
318 xiafs_free_zone(inode->i_sb, tmp);
319 brelse(result);
320 goto repeat;
321 }
322 *lp = tmp;
323 inode->i_blocks+=2 << XIAFS_ZSHIFT(inode->i_sb);
324 mark_buffer_dirty(bh, 1);
325 brelse(bh);
326 return result;
327 }
328
329 struct buffer_head * xiafs_getblk(struct inode * inode, int zone, int create)
330 {
331 struct buffer_head * bh;
332 u_long prev_addr=0;
333
334 if (zone<0) {
335 printk("XIA-FS: zone < 0 (%s %d)\n", WHERE_ERR);
336 return NULL;
337 }
338 if (zone >= 8+(1+XIAFS_ADDRS_PER_Z(inode->i_sb))*XIAFS_ADDRS_PER_Z(inode->i_sb)) {
339 if (!create)
340 printk("XIA-FS: zone > big (%s %d)\n", WHERE_ERR);
341 return NULL;
342 }
343 if (create)
344 prev_addr=get_prev_addr(inode, zone);
345 if (zone < 8)
346 return dt_getblk(inode, zone+inode->u.xiafs_i.i_zone, create, prev_addr);
347 zone -= 8;
348 if (zone < XIAFS_ADDRS_PER_Z(inode->i_sb)) {
349 bh = dt_getblk(inode, &(inode->u.xiafs_i.i_ind_zone), create, prev_addr);
350 bh = indt_getblk(inode, bh, zone, create, prev_addr);
351 return bh;
352 }
353 zone -= XIAFS_ADDRS_PER_Z(inode->i_sb);
354 bh = dt_getblk(inode, &(inode->u.xiafs_i.i_dind_zone), create, prev_addr);
355 bh = indt_getblk(inode, bh, zone>>XIAFS_ADDRS_PER_Z_BITS(inode->i_sb),
356 create, prev_addr);
357 bh = indt_getblk(inode, bh, zone&(XIAFS_ADDRS_PER_Z(inode->i_sb)-1),
358 create, prev_addr);
359 return bh;
360 }
361
362 struct buffer_head * xiafs_bread(struct inode * inode, int zone, int create)
363 {
364 struct buffer_head * bh;
365
366 bh = xiafs_getblk(inode, zone, create);
367 if (!bh || bh->b_uptodate)
368 return bh;
369 ll_rw_block(READ, 1, &bh);
370 wait_on_buffer(bh);
371 if (bh->b_uptodate)
372 return bh;
373 brelse(bh);
374 return NULL;
375 }
376
377 void xiafs_read_inode(struct inode * inode)
378 {
379 struct buffer_head * bh;
380 struct xiafs_inode * raw_inode;
381 int zone;
382 ino_t ino;
383
384 ino = inode->i_ino;
385 inode->i_op = NULL;
386 inode->i_mode=0;
387 if (!ino || ino > inode->i_sb->u.xiafs_sb.s_ninodes) {
388 printk("XIA-FS: bad inode number (%s %d)\n", WHERE_ERR);
389 return;
390 }
391 zone = 1 + inode->i_sb->u.xiafs_sb.s_imap_zones +
392 inode->i_sb->u.xiafs_sb.s_zmap_zones +
393 (ino-1)/ XIAFS_INODES_PER_Z(inode->i_sb);
394 if (!(bh=bread(inode->i_dev, zone, XIAFS_ZSIZE(inode->i_sb)))) {
395 printk("XIA-FS: read i-node zone failed (%s %d)\n", WHERE_ERR);
396 return;
397 }
398 raw_inode = ((struct xiafs_inode *) bh->b_data) +
399 ((ino-1) & (XIAFS_INODES_PER_Z(inode->i_sb) - 1));
400 inode->i_mode = raw_inode->i_mode;
401 inode->i_uid = raw_inode->i_uid;
402 inode->i_gid = raw_inode->i_gid;
403 inode->i_nlink = raw_inode->i_nlinks;
404 inode->i_size = raw_inode->i_size;
405 inode->i_mtime = raw_inode->i_mtime;
406 inode->i_atime = raw_inode->i_atime;
407 inode->i_ctime = raw_inode->i_ctime;
408 inode->i_blksize = XIAFS_ZSIZE(inode->i_sb);
409 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
410 inode->i_blocks=0;
411 inode->i_rdev = raw_inode->i_zone[0];
412 } else {
413 XIAFS_GET_BLOCKS(raw_inode, inode->i_blocks);
414 for (zone = 0; zone < 8; zone++)
415 inode->u.xiafs_i.i_zone[zone] = raw_inode->i_zone[zone] & 0xffffff;
416 inode->u.xiafs_i.i_ind_zone = raw_inode->i_ind_zone & 0xffffff;
417 inode->u.xiafs_i.i_dind_zone = raw_inode->i_dind_zone & 0xffffff;
418 }
419 brelse(bh);
420 if (S_ISREG(inode->i_mode))
421 inode->i_op = &xiafs_file_inode_operations;
422 else if (S_ISDIR(inode->i_mode))
423 inode->i_op = &xiafs_dir_inode_operations;
424 else if (S_ISLNK(inode->i_mode))
425 inode->i_op = &xiafs_symlink_inode_operations;
426 else if (S_ISCHR(inode->i_mode))
427 inode->i_op = &chrdev_inode_operations;
428 else if (S_ISBLK(inode->i_mode))
429 inode->i_op = &blkdev_inode_operations;
430 else if (S_ISFIFO(inode->i_mode))
431 init_fifo(inode);
432 }
433
434 static struct buffer_head * xiafs_update_inode(struct inode * inode)
435 {
436 struct buffer_head * bh;
437 struct xiafs_inode * raw_inode;
438 int zone;
439 ino_t ino;
440
441 if (IS_RDONLY (inode)) {
442 printk("XIA-FS: write_inode on a read-only filesystem (%s %d)\n", WHERE_ERR);
443 inode->i_dirt = 0;
444 return 0;
445 }
446
447 ino = inode->i_ino;
448 if (!ino || ino > inode->i_sb->u.xiafs_sb.s_ninodes) {
449 printk("XIA-FS: bad inode number (%s %d)\n", WHERE_ERR);
450 inode->i_dirt=0;
451 return 0;
452 }
453 zone = 1 + inode->i_sb->u.xiafs_sb.s_imap_zones +
454 inode->i_sb->u.xiafs_sb.s_zmap_zones +
455 (ino-1) / XIAFS_INODES_PER_Z(inode->i_sb);
456 if (!(bh=bread(inode->i_dev, zone, XIAFS_ZSIZE(inode->i_sb)))) {
457 printk("XIA-FS: read i-node zone failed (%s %d)\n", WHERE_ERR);
458 inode->i_dirt=0;
459 return 0;
460 }
461 raw_inode = ((struct xiafs_inode *)bh->b_data) +
462 ((ino-1) & (XIAFS_INODES_PER_Z(inode->i_sb) -1));
463 raw_inode->i_mode = inode->i_mode;
464 raw_inode->i_uid = inode->i_uid;
465 raw_inode->i_gid = inode->i_gid;
466 raw_inode->i_nlinks = inode->i_nlink;
467 raw_inode->i_size = inode->i_size;
468 raw_inode->i_atime = inode->i_atime;
469 raw_inode->i_ctime = inode->i_ctime;
470 raw_inode->i_mtime = inode->i_mtime;
471 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
472 raw_inode->i_zone[0] = inode->i_rdev;
473 else {
474 XIAFS_PUT_BLOCKS(raw_inode, inode->i_blocks);
475 for (zone = 0; zone < 8; zone++)
476 raw_inode->i_zone[zone] = (raw_inode->i_zone[zone] & 0xff000000)
477 | (inode->u.xiafs_i.i_zone[zone] & 0xffffff);
478 raw_inode->i_ind_zone = (raw_inode->i_ind_zone & 0xff000000)
479 | (inode->u.xiafs_i.i_ind_zone & 0xffffff);
480 raw_inode->i_dind_zone = (raw_inode->i_dind_zone & 0xff000000)
481 | (inode->u.xiafs_i.i_dind_zone & 0xffffff);
482 }
483 inode->i_dirt=0;
484 mark_buffer_dirty(bh, 1);
485 return bh;
486 }
487
488
489 void xiafs_write_inode(struct inode * inode)
490 {
491 struct buffer_head * bh;
492 bh = xiafs_update_inode(inode);
493 brelse (bh);
494 }
495
496 int xiafs_sync_inode (struct inode *inode)
497 {
498 int err = 0;
499 struct buffer_head *bh;
500
501 bh = xiafs_update_inode(inode);
502 if (bh && bh->b_dirt)
503 {
504 ll_rw_block(WRITE, 1, &bh);
505 wait_on_buffer(bh);
506 if (bh->b_req && !bh->b_uptodate)
507 {
508 printk ("IO error syncing xiafs inode [%04X:%lu]\n",
509 inode->i_dev, inode->i_ino);
510 err = -1;
511 }
512 }
513 else if (!bh)
514 err = -1;
515 brelse (bh);
516 return err;
517 }
518
519 #ifdef MODULE
520
521
522
523 char kernel_version[] = UTS_RELEASE;
524
525 static struct file_system_type xiafs_fs_type = {
526 xiafs_read_super, "xiafs", 1, NULL
527 };
528
529 int init_module(void)
530 {
531 register_filesystem(&xiafs_fs_type);
532 return 0;
533 }
534
535 void cleanup_module(void)
536 {
537 unregister_filesystem(&xiafs_fs_type);
538 }
539
540 #endif