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