2 * linux/fs/affs/inode.c
4 * (c) 1996 Hans-Joachim Widmaier - Rewritten
6 * (C) 1993 Ray Burr - Modified for Amiga FFS filesystem.
8 * (C) 1992 Eric Youngdale Modified for ISO 9660 filesystem.
10 * (C) 1991 Linus Torvalds - minix filesystem
14 #include <linux/module.h>
15 #include <linux/errno.h>
17 #include <linux/malloc.h>
18 #include <linux/stat.h>
19 #include <linux/sched.h>
20 #include <linux/affs_fs.h>
21 #include <linux/kernel.h>
23 #include <linux/string.h>
24 #include <linux/locks.h>
25 #include <linux/genhd.h>
26 #include <linux/amigaffs.h>
27 #include <linux/major.h>
28 #include <linux/blkdev.h>
29 #include <linux/init.h>
30 #include <asm/system.h>
31 #include <asm/uaccess.h>
33 extern int *blk_size
[];
34 extern struct timezone sys_tz
;
36 #define MIN(a,b) (((a)<(b))?(a):(b))
38 static int affs_statfs(struct super_block
*sb
, struct statfs
*buf
, int bufsiz
);
39 static int affs_remount (struct super_block
*sb
, int *flags
, char *data
);
42 affs_put_super(struct super_block
*sb
)
46 pr_debug("AFFS: put_super()\n");
48 for (i
= 0; i
< sb
->u
.affs_sb
.s_bm_count
; i
++)
49 affs_brelse(sb
->u
.affs_sb
.s_bitmap
[i
].bm_bh
);
50 if (!(sb
->s_flags
& MS_RDONLY
)) {
51 ROOT_END_S(sb
->u
.affs_sb
.s_root_bh
->b_data
,sb
)->bm_flag
= be32_to_cpu(1);
52 secs_to_datestamp(CURRENT_TIME
,
53 &ROOT_END_S(sb
->u
.affs_sb
.s_root_bh
->b_data
,sb
)->disk_altered
);
54 affs_fix_checksum(sb
->s_blocksize
,sb
->u
.affs_sb
.s_root_bh
->b_data
,5);
55 mark_buffer_dirty(sb
->u
.affs_sb
.s_root_bh
,1);
58 if (sb
->u
.affs_sb
.s_prefix
)
59 kfree(sb
->u
.affs_sb
.s_prefix
);
60 kfree(sb
->u
.affs_sb
.s_bitmap
);
61 affs_brelse(sb
->u
.affs_sb
.s_root_bh
);
64 * Restore the previous value of this device's blksize_size[][]
66 set_blocksize(sb
->s_dev
, sb
->u
.affs_sb
.s_blksize
);
73 affs_write_super(struct super_block
*sb
)
77 if (!(sb
->s_flags
& MS_RDONLY
)) {
79 for (i
= 0, clean
= 1; i
< sb
->u
.affs_sb
.s_bm_count
; i
++) {
80 if (sb
->u
.affs_sb
.s_bitmap
[i
].bm_bh
) {
81 if (buffer_dirty(sb
->u
.affs_sb
.s_bitmap
[i
].bm_bh
)) {
88 ROOT_END_S(sb
->u
.affs_sb
.s_root_bh
->b_data
,sb
)->bm_flag
= be32_to_cpu(clean
);
89 secs_to_datestamp(CURRENT_TIME
,
90 &ROOT_END_S(sb
->u
.affs_sb
.s_root_bh
->b_data
,sb
)->disk_altered
);
91 affs_fix_checksum(sb
->s_blocksize
,sb
->u
.affs_sb
.s_root_bh
->b_data
,5);
92 mark_buffer_dirty(sb
->u
.affs_sb
.s_root_bh
,1);
93 sb
->s_dirt
= !clean
; /* redo until bitmap synced */
97 pr_debug("AFFS: write_super() at %lu, clean=%d\n", CURRENT_TIME
, clean
);
100 static struct super_operations affs_sops
= {
113 parse_options(char *options
, uid_t
*uid
, gid_t
*gid
, int *mode
, int *reserved
, s32
*root
,
114 int *blocksize
, char **prefix
, char *volume
, unsigned long *mount_opts
)
116 char *this_char
, *value
, *optn
;
119 /* Fill in defaults */
131 for (this_char
= strtok(options
,","); this_char
; this_char
= strtok(NULL
,",")) {
133 if ((value
= strchr(this_char
,'=')) != NULL
)
135 if ((optn
= "protect") && !strcmp(this_char
, optn
)) {
138 *mount_opts
|= SF_IMMUTABLE
;
139 } else if ((optn
= "verbose") && !strcmp(this_char
, optn
)) {
142 *mount_opts
|= SF_VERBOSE
;
143 } else if ((optn
= "mufs") && !strcmp(this_char
, optn
)) {
146 *mount_opts
|= SF_MUFS
;
147 } else if ((f
= !strcmp(this_char
,"setuid")) || !strcmp(this_char
,"setgid")) {
150 printk("AFFS: Argument for set[ug]id option missing\n");
153 (f
? *uid
: *gid
) = simple_strtoul(value
,&value
,0);
155 printk("AFFS: Bad set[ug]id argument\n");
158 *mount_opts
|= f
? SF_SETUID
: SF_SETGID
;
161 } else if (!strcmp(this_char
,"prefix")) {
163 if (!value
|| !*value
)
165 if (*prefix
) { /* Free any previous prefix */
169 *prefix
= kmalloc(strlen(value
) + 1,GFP_KERNEL
);
172 strcpy(*prefix
,value
);
173 *mount_opts
|= SF_PREFIX
;
174 } else if (!strcmp(this_char
,"volume")) {
176 if (!value
|| !*value
)
178 if (strlen(value
) > 30)
180 strncpy(volume
,value
,30);
181 } else if (!strcmp(this_char
,"mode")) {
183 if (!value
|| !*value
)
185 *mode
= simple_strtoul(value
,&value
,8) & 0777;
188 *mount_opts
|= SF_SETMODE
;
189 } else if (!strcmp(this_char
,"reserved")) {
191 if (!value
|| !*value
)
193 *reserved
= simple_strtoul(value
,&value
,0);
196 } else if (!strcmp(this_char
,"root")) {
198 if (!value
|| !*value
)
200 *root
= simple_strtoul(value
,&value
,0);
203 } else if (!strcmp(this_char
,"bs")) {
205 if (!value
|| !*value
)
207 *blocksize
= simple_strtoul(value
,&value
,0);
210 if (*blocksize
!= 512 && *blocksize
!= 1024 && *blocksize
!= 2048
211 && *blocksize
!= 4096) {
212 printk ("AFFS: Invalid blocksize (512, 1024, 2048, 4096 allowed)\n");
215 } else if (!strcmp (this_char
, "grpquota")
216 || !strcmp (this_char
, "noquota")
217 || !strcmp (this_char
, "quota")
218 || !strcmp (this_char
, "usrquota"))
219 /* Silently ignore the quota options */
222 printk("AFFS: Unrecognized mount option %s\n", this_char
);
229 printk("AFFS: The %s option requires an argument\n", optn
);
232 printk("AFFS: Option %s does not take an argument\n", optn
);
236 /* This function definitely needs to be split up. Some fine day I'll
237 * hopefully have the guts to do so. Until then: sorry for the mess.
240 static struct super_block
*
241 affs_read_super(struct super_block
*s
, void *data
, int silent
)
243 struct buffer_head
*bh
= NULL
;
244 struct buffer_head
*bb
;
245 struct inode
*root_inode
;
246 kdev_t dev
= s
->s_dev
;
248 int blocks
, size
, blocksize
;
261 unsigned long mount_flags
;
262 unsigned long offset
;
264 pr_debug("AFFS: read_super(%s)\n",data
? (const char *)data
: "no options");
268 s
->s_magic
= AFFS_SUPER_MAGIC
;
269 s
->s_op
= &affs_sops
;
270 s
->u
.affs_sb
.s_bitmap
= NULL
;
271 s
->u
.affs_sb
.s_root_bh
= NULL
;
272 s
->u
.affs_sb
.s_prefix
= NULL
;
273 s
->u
.affs_sb
.s_hashsize
= 0;
275 if (!parse_options(data
,&uid
,&gid
,&i
,&reserved
,&root_block
,
276 &blocksize
,&s
->u
.affs_sb
.s_prefix
,
277 s
->u
.affs_sb
.s_volume
, &mount_flags
))
279 /* N.B. after this point s_prefix must be released */
281 s
->u
.affs_sb
.s_flags
= mount_flags
;
282 s
->u
.affs_sb
.s_mode
= i
;
283 s
->u
.affs_sb
.s_uid
= uid
;
284 s
->u
.affs_sb
.s_gid
= gid
;
285 s
->u
.affs_sb
.s_reserved
= reserved
;
287 /* Get the size of the device in 512-byte blocks.
288 * If we later see that the partition uses bigger
289 * blocks, we will have to change it.
292 blocks
= blk_size
[MAJOR(dev
)][MINOR(dev
)];
295 s
->u
.affs_sb
.s_blksize
= blksize_size
[MAJOR(dev
)][MINOR(dev
)];
296 if (!s
->u
.affs_sb
.s_blksize
)
297 s
->u
.affs_sb
.s_blksize
= BLOCK_SIZE
;
298 size
= (s
->u
.affs_sb
.s_blksize
/ 512) * blocks
;
299 pr_debug("AFFS: initial blksize=%d, blocks=%d\n",
300 s
->u
.affs_sb
.s_blksize
, blocks
);
302 /* Try to find root block. Its location depends on the block size. */
308 size
= size
/ (blocksize
/ 512);
310 for (blocksize
= i
, key
= 0; blocksize
<= j
; blocksize
<<= 1, size
>>= 1) {
311 s
->u
.affs_sb
.s_root_block
= root_block
;
313 s
->u
.affs_sb
.s_root_block
= (reserved
+ size
- 1) / 2;
314 pr_debug("AFFS: setting blocksize to %d\n", blocksize
);
315 set_blocksize(dev
, blocksize
);
317 /* The root block location that was calculated above is not
318 * correct if the partition size is an odd number of 512-
319 * byte blocks, which will be rounded down to a number of
320 * 1024-byte blocks, and if there were an even number of
321 * reserved blocks. Ideally, all partition checkers should
322 * report the real number of blocks of the real blocksize,
323 * but since this just cannot be done, we have to try to
324 * find the root block anyways. In the above case, it is one
325 * block behind the calculated one. So we check this one, too.
327 for (num_bm
= 0; num_bm
< 2; num_bm
++) {
328 pr_debug("AFFS: Dev %s, trying root=%u, bs=%d, "
329 "size=%d, reserved=%d\n",
331 s
->u
.affs_sb
.s_root_block
+ num_bm
,
332 blocksize
, size
, reserved
);
333 bh
= affs_bread(dev
, s
->u
.affs_sb
.s_root_block
+ num_bm
,
337 if (!affs_checksum_block(blocksize
,bh
->b_data
,&ptype
,&stype
) &&
338 ptype
== T_SHORT
&& stype
== ST_ROOT
) {
339 s
->s_blocksize
= blocksize
;
340 s
->u
.affs_sb
.s_hashsize
= blocksize
/ 4 - 56;
341 s
->u
.affs_sb
.s_root_block
+= num_bm
;
349 goto out_no_valid_block
;
351 /* N.B. after this point bh must be released */
353 root_block
= s
->u
.affs_sb
.s_root_block
;
355 s
->u
.affs_sb
.s_partition_size
= size
;
356 s
->s_blocksize_bits
= blocksize
== 512 ? 9 :
357 blocksize
== 1024 ? 10 :
358 blocksize
== 2048 ? 11 : 12;
360 /* Find out which kind of FS we have */
361 bb
= affs_bread(dev
,0,s
->s_blocksize
);
363 goto out_no_root_block
;
364 chksum
= be32_to_cpu(*(u32
*)bb
->b_data
);
367 /* Dircache filesystems are compatible with non-dircache ones
368 * when reading. As long as they aren't supported, writing is
371 if ((chksum
== FS_DCFFS
|| chksum
== MUFS_DCFFS
|| chksum
== FS_DCOFS
372 || chksum
== MUFS_DCOFS
) && !(s
->s_flags
& MS_RDONLY
)) {
373 printk(KERN_NOTICE
"AFFS: Dircache FS - mounting %s read only\n",
375 s
->s_flags
|= MS_RDONLY
;
376 s
->u
.affs_sb
.s_flags
|= SF_READONLY
;
381 s
->u
.affs_sb
.s_flags
|= SF_MUFS
;
384 s
->u
.affs_sb
.s_flags
|= SF_INTL
;
388 s
->u
.affs_sb
.s_flags
|= SF_MUFS
;
394 s
->u
.affs_sb
.s_flags
|= SF_MUFS
;
397 s
->u
.affs_sb
.s_flags
|= SF_OFS
;
398 s
->s_flags
|= MS_NOEXEC
;
402 s
->u
.affs_sb
.s_flags
|= SF_MUFS
;
405 s
->u
.affs_sb
.s_flags
|= SF_INTL
| SF_OFS
;
406 s
->s_flags
|= MS_NOEXEC
;
412 if (mount_flags
& SF_VERBOSE
) {
413 chksum
= cpu_to_be32(chksum
);
414 printk(KERN_NOTICE
"AFFS: Mounting volume \"%*s\": Type=%.3s\\%c, Blocksize=%d\n",
415 GET_END_PTR(struct root_end
,bh
->b_data
,blocksize
)->disk_name
[0],
416 &GET_END_PTR(struct root_end
,bh
->b_data
,blocksize
)->disk_name
[1],
417 (char *)&chksum
,((char *)&chksum
)[3] + '0',blocksize
);
420 s
->s_flags
|= MS_NODEV
| MS_NOSUID
;
422 /* Keep super block in cache */
423 bb
= affs_bread(dev
,root_block
,s
->s_blocksize
);
425 goto out_no_root_block
;
426 s
->u
.affs_sb
.s_root_bh
= bb
;
427 /* N.B. after this point s_root_bh must be released */
429 /* Allocate space for bitmaps, zones and others */
431 size
= s
->u
.affs_sb
.s_partition_size
- reserved
;
432 num_bm
= (size
+ s
->s_blocksize
* 8 - 32 - 1) / (s
->s_blocksize
* 8 - 32);
433 az_no
= (size
+ AFFS_ZONE_SIZE
- 1) / (AFFS_ZONE_SIZE
- 32);
434 ptype
= num_bm
* sizeof(struct affs_bm_info
) +
435 az_no
* sizeof(struct affs_alloc_zone
) +
436 MAX_ZONES
* sizeof(struct affs_zone
);
437 pr_debug("AFFS: num_bm=%d, az_no=%d, sum=%d\n",num_bm
,az_no
,ptype
);
438 if (!(s
->u
.affs_sb
.s_bitmap
= kmalloc(ptype
, GFP_KERNEL
)))
440 memset(s
->u
.affs_sb
.s_bitmap
,0,ptype
);
441 /* N.B. after the point s_bitmap must be released */
443 s
->u
.affs_sb
.s_zones
= (struct affs_zone
*)&s
->u
.affs_sb
.s_bitmap
[num_bm
];
444 s
->u
.affs_sb
.s_alloc
= (struct affs_alloc_zone
*)&s
->u
.affs_sb
.s_zones
[MAX_ZONES
];
445 s
->u
.affs_sb
.s_num_az
= az_no
;
449 if (ROOT_END_S(bh
->b_data
,s
)->bm_flag
== 0) {
450 if (!(s
->s_flags
& MS_RDONLY
)) {
451 printk(KERN_NOTICE
"AFFS: Bitmap invalid - mounting %s read only\n",
453 s
->s_flags
|= MS_RDONLY
;
460 /* The following section is ugly, I know. Especially because of the
461 * reuse of some variables that are not named properly.
465 ptype
= s
->s_blocksize
/ 4 - 49;
467 offset
= s
->u
.affs_sb
.s_reserved
;
470 bm
= (u32
*)bh
->b_data
;
471 for (i
= ptype
; i
< stype
&& bm
[i
]; i
++, mapidx
++) {
472 if (mapidx
>= num_bm
) {
473 printk(KERN_ERR
"AFFS: Extraneous bitmap pointer - "
474 "mounting %s read only.\n",kdevname(dev
));
475 s
->s_flags
|= MS_RDONLY
;
476 s
->u
.affs_sb
.s_flags
|= SF_READONLY
;
479 bb
= affs_bread(dev
,be32_to_cpu(bm
[i
]),s
->s_blocksize
);
482 if (affs_checksum_block(s
->s_blocksize
,bb
->b_data
,NULL
,NULL
) &&
483 !(s
->s_flags
& MS_RDONLY
)) {
484 printk(KERN_WARNING
"AFFS: Bitmap (%d,key=%u) invalid - "
485 "mounting %s read only.\n",mapidx
,be32_to_cpu(bm
[i
]),
487 s
->s_flags
|= MS_RDONLY
;
488 s
->u
.affs_sb
.s_flags
|= SF_READONLY
;
490 /* Mark unused bits in the last word as allocated */
491 if (size
<= s
->s_blocksize
* 8 - 32) { /* last bitmap */
492 ptype
= size
/ 32 + 1; /* word number */
493 key
= size
& 0x1F; /* used bits */
494 if (key
&& !(s
->s_flags
& MS_RDONLY
)) {
495 chksum
= cpu_to_be32(0x7FFFFFFF >> (31 - key
));
496 ((u32
*)bb
->b_data
)[ptype
] &= chksum
;
497 affs_fix_checksum(s
->s_blocksize
,bb
->b_data
,0);
498 mark_buffer_dirty(bb
,1);
501 ptype
= (size
+ 31) & ~0x1F;
503 s
->u
.affs_sb
.s_flags
|= SF_BM_VALID
;
505 ptype
= s
->s_blocksize
* 8 - 32;
508 s
->u
.affs_sb
.s_bitmap
[mapidx
].bm_firstblk
= offset
;
509 s
->u
.affs_sb
.s_bitmap
[mapidx
].bm_bh
= NULL
;
510 s
->u
.affs_sb
.s_bitmap
[mapidx
].bm_key
= be32_to_cpu(bm
[i
]);
511 s
->u
.affs_sb
.s_bitmap
[mapidx
].bm_count
= 0;
514 for (j
= 0; ptype
> 0; j
++, az_no
++, ptype
-= key
) {
515 key
= MIN(ptype
,AFFS_ZONE_SIZE
); /* size in bits */
516 s
->u
.affs_sb
.s_alloc
[az_no
].az_size
= key
/ 32;
517 s
->u
.affs_sb
.s_alloc
[az_no
].az_free
=
518 affs_count_free_bits(key
/ 8,bb
->b_data
+
519 j
* (AFFS_ZONE_SIZE
/ 8) + 4);
523 key
= be32_to_cpu(bm
[stype
]); /* Next block of bitmap pointers */
525 stype
= s
->s_blocksize
/ 4 - 1;
529 bh
= affs_bread(dev
,key
,s
->s_blocksize
);
538 s
->u
.affs_sb
.s_bm_count
= num_bm
;
540 /* set up enough so that it can read an inode */
543 root_inode
= iget(s
,root_block
);
546 s
->s_root
= d_alloc_root(root_inode
, NULL
);
549 s
->s_root
->d_op
= &affs_dentry_operations
;
552 /* Record date of last change if the bitmap was truncated and
553 * create data zones if the volume is writable.
556 if (!(s
->s_flags
& MS_RDONLY
)) {
558 secs_to_datestamp(CURRENT_TIME
,&ROOT_END(
559 s
->u
.affs_sb
.s_root_bh
->b_data
,root_inode
)->disk_altered
);
560 affs_fix_checksum(s
->s_blocksize
,s
->u
.affs_sb
.s_root_bh
->b_data
,5);
561 mark_buffer_dirty(s
->u
.affs_sb
.s_root_bh
,1);
566 pr_debug("AFFS: s_flags=%lX\n",s
->s_flags
);
570 printk(KERN_ERR
"AFFS: Error parsing options\n");
573 printk(KERN_ERR
"AFFS: Could not determine device size\n");
574 goto out_free_prefix
;
577 printk(KERN_ERR
"AFFS: No valid root block on device %s\n",
581 printk(KERN_ERR
"AFFS: Unknown filesystem on device %s: %08X\n",
582 kdevname(dev
), chksum
);
585 printk(KERN_ERR
"AFFS: Cannot read root block\n");
588 printk(KERN_ERR
"AFFS: Bitmap allocation failed\n");
589 goto out_free_root_block
;
591 printk(KERN_ERR
"AFFS: Cannot read bitmap\n");
592 goto out_free_bitmap
;
594 printk(KERN_ERR
"AFFS: Cannot read bitmap extension\n");
595 goto out_free_bitmap
;
597 printk(KERN_ERR
"AFFS: Got only %d bitmap blocks, expected %d\n",
599 goto out_free_bitmap
;
601 printk(KERN_ERR
"AFFS: Get root inode failed\n");
604 * Begin the cascaded cleanup ...
608 kfree(s
->u
.affs_sb
.s_bitmap
);
610 affs_brelse(s
->u
.affs_sb
.s_root_bh
);
614 set_blocksize(dev
, s
->u
.affs_sb
.s_blksize
);
616 if (s
->u
.affs_sb
.s_prefix
)
617 kfree(s
->u
.affs_sb
.s_prefix
);
626 affs_remount(struct super_block
*sb
, int *flags
, char *data
)
634 unsigned long mount_flags
;
635 unsigned long read_only
= sb
->u
.affs_sb
.s_flags
& SF_READONLY
;
637 pr_debug("AFFS: remount(flags=0x%x,opts=\"%s\")\n",*flags
,data
);
639 if (!parse_options(data
,&uid
,&gid
,&mode
,&reserved
,&root_block
,
640 &blocksize
,&sb
->u
.affs_sb
.s_prefix
,sb
->u
.affs_sb
.s_volume
,&mount_flags
))
642 sb
->u
.affs_sb
.s_flags
= mount_flags
| read_only
;
643 sb
->u
.affs_sb
.s_mode
= mode
;
644 sb
->u
.affs_sb
.s_uid
= uid
;
645 sb
->u
.affs_sb
.s_gid
= gid
;
647 if ((*flags
& MS_RDONLY
) == (sb
->s_flags
& MS_RDONLY
))
649 if (*flags
& MS_RDONLY
) {
652 affs_write_super(sb
);
653 sb
->s_flags
|= MS_RDONLY
;
654 } else if (!(sb
->u
.affs_sb
.s_flags
& SF_READONLY
)) {
655 sb
->s_flags
&= ~MS_RDONLY
;
658 affs_warning(sb
,"remount","Cannot remount fs read/write because of errors");
665 affs_statfs(struct super_block
*sb
, struct statfs
*buf
, int bufsiz
)
670 pr_debug("AFFS: statfs() partsize=%d, reserved=%d\n",sb
->u
.affs_sb
.s_partition_size
,
671 sb
->u
.affs_sb
.s_reserved
);
673 free
= affs_count_free_blocks(sb
);
674 tmp
.f_type
= AFFS_SUPER_MAGIC
;
675 tmp
.f_bsize
= sb
->s_blocksize
;
676 tmp
.f_blocks
= sb
->u
.affs_sb
.s_partition_size
- sb
->u
.affs_sb
.s_reserved
;
681 return copy_to_user(buf
,&tmp
,bufsiz
) ? -EFAULT
: 0;
684 static struct file_system_type affs_fs_type
= {
691 __initfunc(int init_affs_fs(void))
693 return register_filesystem(&affs_fs_type
);
702 return register_filesystem(&affs_fs_type
);
708 unregister_filesystem(&affs_fs_type
);