1 // SPDX-License-Identifier: GPL-2.0-only
3 * linux/fs/adfs/super.c
5 * Copyright (C) 1997-1999 Russell King
7 #include <linux/module.h>
8 #include <linux/init.h>
9 #include <linux/parser.h>
10 #include <linux/mount.h>
11 #include <linux/seq_file.h>
12 #include <linux/slab.h>
13 #include <linux/statfs.h>
14 #include <linux/user_namespace.h>
17 #include "dir_fplus.h"
19 #define ADFS_SB_FLAGS SB_NOATIME
21 #define ADFS_DEFAULT_OWNER_MASK S_IRWXU
22 #define ADFS_DEFAULT_OTHER_MASK (S_IRWXG | S_IRWXO)
24 void __adfs_error(struct super_block
*sb
, const char *function
, const char *fmt
, ...)
33 printk(KERN_CRIT
"ADFS-fs error (device %s)%s%s: %pV\n",
34 sb
->s_id
, function
? ": " : "",
35 function
? function
: "", &vaf
);
40 void adfs_msg(struct super_block
*sb
, const char *pfx
, const char *fmt
, ...)
48 printk("%sADFS-fs (%s): %pV\n", pfx
, sb
->s_id
, &vaf
);
52 static int adfs_checkdiscrecord(struct adfs_discrecord
*dr
)
54 unsigned int max_idlen
;
57 /* sector size must be 256, 512 or 1024 bytes */
58 if (dr
->log2secsize
!= 8 &&
59 dr
->log2secsize
!= 9 &&
60 dr
->log2secsize
!= 10)
63 /* idlen must be at least log2secsize + 3 */
64 if (dr
->idlen
< dr
->log2secsize
+ 3)
67 /* we cannot have such a large disc that we
68 * are unable to represent sector offsets in
69 * 32 bits. This works out at 2.0 TB.
71 if (le32_to_cpu(dr
->disc_size_high
) >> dr
->log2secsize
)
75 * Maximum idlen is limited to 16 bits for new directories by
76 * the three-byte storage of an indirect disc address. For
77 * big directories, idlen must be no greater than 19 v2 [1.0]
79 max_idlen
= dr
->format_version
? 19 : 16;
80 if (dr
->idlen
> max_idlen
)
83 /* reserved bytes should be zero */
84 for (i
= 0; i
< sizeof(dr
->unused52
); i
++)
85 if (dr
->unused52
[i
] != 0)
91 static unsigned char adfs_calczonecheck(struct super_block
*sb
, unsigned char *map
)
93 unsigned int v0
, v1
, v2
, v3
;
96 v0
= v1
= v2
= v3
= 0;
97 for (i
= sb
->s_blocksize
- 4; i
; i
-= 4) {
98 v0
+= map
[i
] + (v3
>> 8);
100 v1
+= map
[i
+ 1] + (v0
>> 8);
102 v2
+= map
[i
+ 2] + (v1
>> 8);
104 v3
+= map
[i
+ 3] + (v2
>> 8);
108 v1
+= map
[1] + (v0
>> 8);
109 v2
+= map
[2] + (v1
>> 8);
110 v3
+= map
[3] + (v2
>> 8);
112 return v0
^ v1
^ v2
^ v3
;
115 static int adfs_checkmap(struct super_block
*sb
, struct adfs_discmap
*dm
)
117 unsigned char crosscheck
= 0, zonecheck
= 1;
120 for (i
= 0; i
< ADFS_SB(sb
)->s_map_size
; i
++) {
123 map
= dm
[i
].dm_bh
->b_data
;
125 if (adfs_calczonecheck(sb
, map
) != map
[0]) {
126 adfs_error(sb
, "zone %d fails zonecheck", i
);
129 crosscheck
^= map
[3];
131 if (crosscheck
!= 0xff)
132 adfs_error(sb
, "crosscheck != 0xff");
133 return crosscheck
== 0xff && zonecheck
;
136 static void adfs_put_super(struct super_block
*sb
)
139 struct adfs_sb_info
*asb
= ADFS_SB(sb
);
141 for (i
= 0; i
< asb
->s_map_size
; i
++)
142 brelse(asb
->s_map
[i
].dm_bh
);
147 static int adfs_show_options(struct seq_file
*seq
, struct dentry
*root
)
149 struct adfs_sb_info
*asb
= ADFS_SB(root
->d_sb
);
151 if (!uid_eq(asb
->s_uid
, GLOBAL_ROOT_UID
))
152 seq_printf(seq
, ",uid=%u", from_kuid_munged(&init_user_ns
, asb
->s_uid
));
153 if (!gid_eq(asb
->s_gid
, GLOBAL_ROOT_GID
))
154 seq_printf(seq
, ",gid=%u", from_kgid_munged(&init_user_ns
, asb
->s_gid
));
155 if (asb
->s_owner_mask
!= ADFS_DEFAULT_OWNER_MASK
)
156 seq_printf(seq
, ",ownmask=%o", asb
->s_owner_mask
);
157 if (asb
->s_other_mask
!= ADFS_DEFAULT_OTHER_MASK
)
158 seq_printf(seq
, ",othmask=%o", asb
->s_other_mask
);
159 if (asb
->s_ftsuffix
!= 0)
160 seq_printf(seq
, ",ftsuffix=%u", asb
->s_ftsuffix
);
165 enum {Opt_uid
, Opt_gid
, Opt_ownmask
, Opt_othmask
, Opt_ftsuffix
, Opt_err
};
167 static const match_table_t tokens
= {
170 {Opt_ownmask
, "ownmask=%o"},
171 {Opt_othmask
, "othmask=%o"},
172 {Opt_ftsuffix
, "ftsuffix=%u"},
176 static int parse_options(struct super_block
*sb
, struct adfs_sb_info
*asb
,
185 while ((p
= strsep(&options
, ",")) != NULL
) {
186 substring_t args
[MAX_OPT_ARGS
];
191 token
= match_token(p
, tokens
, args
);
194 if (match_int(args
, &option
))
196 asb
->s_uid
= make_kuid(current_user_ns(), option
);
197 if (!uid_valid(asb
->s_uid
))
201 if (match_int(args
, &option
))
203 asb
->s_gid
= make_kgid(current_user_ns(), option
);
204 if (!gid_valid(asb
->s_gid
))
208 if (match_octal(args
, &option
))
210 asb
->s_owner_mask
= option
;
213 if (match_octal(args
, &option
))
215 asb
->s_other_mask
= option
;
218 if (match_int(args
, &option
))
220 asb
->s_ftsuffix
= option
;
223 adfs_msg(sb
, KERN_ERR
,
224 "unrecognised mount option \"%s\" or missing value",
232 static int adfs_remount(struct super_block
*sb
, int *flags
, char *data
)
234 struct adfs_sb_info temp_asb
;
238 *flags
|= ADFS_SB_FLAGS
;
240 temp_asb
= *ADFS_SB(sb
);
241 ret
= parse_options(sb
, &temp_asb
, data
);
243 *ADFS_SB(sb
) = temp_asb
;
248 static int adfs_statfs(struct dentry
*dentry
, struct kstatfs
*buf
)
250 struct super_block
*sb
= dentry
->d_sb
;
251 struct adfs_sb_info
*sbi
= ADFS_SB(sb
);
252 struct adfs_discrecord
*dr
= adfs_map_discrecord(sbi
->s_map
);
253 u64 id
= huge_encode_dev(sb
->s_bdev
->bd_dev
);
255 buf
->f_type
= ADFS_SUPER_MAGIC
;
256 buf
->f_namelen
= sbi
->s_namelen
;
257 buf
->f_bsize
= sb
->s_blocksize
;
258 buf
->f_blocks
= adfs_disc_size(dr
) >> sb
->s_blocksize_bits
;
259 buf
->f_files
= sbi
->s_ids_per_zone
* sbi
->s_map_size
;
261 buf
->f_bfree
= adfs_map_free(sb
);
262 buf
->f_ffree
= (long)(buf
->f_bfree
* buf
->f_files
) / (long)buf
->f_blocks
;
263 buf
->f_fsid
.val
[0] = (u32
)id
;
264 buf
->f_fsid
.val
[1] = (u32
)(id
>> 32);
269 static struct kmem_cache
*adfs_inode_cachep
;
271 static struct inode
*adfs_alloc_inode(struct super_block
*sb
)
273 struct adfs_inode_info
*ei
;
274 ei
= kmem_cache_alloc(adfs_inode_cachep
, GFP_KERNEL
);
277 return &ei
->vfs_inode
;
280 static void adfs_free_inode(struct inode
*inode
)
282 kmem_cache_free(adfs_inode_cachep
, ADFS_I(inode
));
285 static void init_once(void *foo
)
287 struct adfs_inode_info
*ei
= (struct adfs_inode_info
*) foo
;
289 inode_init_once(&ei
->vfs_inode
);
292 static int __init
init_inodecache(void)
294 adfs_inode_cachep
= kmem_cache_create("adfs_inode_cache",
295 sizeof(struct adfs_inode_info
),
296 0, (SLAB_RECLAIM_ACCOUNT
|
297 SLAB_MEM_SPREAD
|SLAB_ACCOUNT
),
299 if (adfs_inode_cachep
== NULL
)
304 static void destroy_inodecache(void)
307 * Make sure all delayed rcu free inodes are flushed before we
311 kmem_cache_destroy(adfs_inode_cachep
);
314 static const struct super_operations adfs_sops
= {
315 .alloc_inode
= adfs_alloc_inode
,
316 .free_inode
= adfs_free_inode
,
317 .drop_inode
= generic_delete_inode
,
318 .write_inode
= adfs_write_inode
,
319 .put_super
= adfs_put_super
,
320 .statfs
= adfs_statfs
,
321 .remount_fs
= adfs_remount
,
322 .show_options
= adfs_show_options
,
325 static struct adfs_discmap
*adfs_read_map(struct super_block
*sb
, struct adfs_discrecord
*dr
)
327 struct adfs_discmap
*dm
;
328 unsigned int map_addr
, zone_size
, nzones
;
330 struct adfs_sb_info
*asb
= ADFS_SB(sb
);
332 nzones
= asb
->s_map_size
;
333 zone_size
= (8 << dr
->log2secsize
) - le16_to_cpu(dr
->zone_spare
);
334 map_addr
= (nzones
>> 1) * zone_size
-
335 ((nzones
> 1) ? ADFS_DR_SIZE_BITS
: 0);
336 map_addr
= signed_asl(map_addr
, asb
->s_map2blk
);
338 asb
->s_ids_per_zone
= zone_size
/ (asb
->s_idlen
+ 1);
340 dm
= kmalloc_array(nzones
, sizeof(*dm
), GFP_KERNEL
);
342 adfs_error(sb
, "not enough memory");
343 return ERR_PTR(-ENOMEM
);
346 for (zone
= 0; zone
< nzones
; zone
++, map_addr
++) {
347 dm
[zone
].dm_startbit
= 0;
348 dm
[zone
].dm_endbit
= zone_size
;
349 dm
[zone
].dm_startblk
= zone
* zone_size
- ADFS_DR_SIZE_BITS
;
350 dm
[zone
].dm_bh
= sb_bread(sb
, map_addr
);
352 if (!dm
[zone
].dm_bh
) {
353 adfs_error(sb
, "unable to read map");
358 /* adjust the limits for the first and last map zones */
360 dm
[0].dm_startblk
= 0;
361 dm
[0].dm_startbit
= ADFS_DR_SIZE_BITS
;
362 dm
[i
].dm_endbit
= (adfs_disc_size(dr
) >> dr
->log2bpmb
) +
363 (ADFS_DR_SIZE_BITS
- i
* zone_size
);
365 if (adfs_checkmap(sb
, dm
))
368 adfs_error(sb
, "map corrupted");
372 brelse(dm
[zone
].dm_bh
);
375 return ERR_PTR(-EIO
);
378 static int adfs_fill_super(struct super_block
*sb
, void *data
, int silent
)
380 struct adfs_discrecord
*dr
;
381 struct buffer_head
*bh
;
382 struct object_info root_obj
;
383 unsigned char *b_data
;
384 unsigned int blocksize
;
385 struct adfs_sb_info
*asb
;
389 sb
->s_flags
|= ADFS_SB_FLAGS
;
391 asb
= kzalloc(sizeof(*asb
), GFP_KERNEL
);
396 /* set default options */
397 asb
->s_uid
= GLOBAL_ROOT_UID
;
398 asb
->s_gid
= GLOBAL_ROOT_GID
;
399 asb
->s_owner_mask
= ADFS_DEFAULT_OWNER_MASK
;
400 asb
->s_other_mask
= ADFS_DEFAULT_OTHER_MASK
;
403 if (parse_options(sb
, asb
, data
))
406 sb_set_blocksize(sb
, BLOCK_SIZE
);
407 if (!(bh
= sb_bread(sb
, ADFS_DISCRECORD
/ BLOCK_SIZE
))) {
408 adfs_msg(sb
, KERN_ERR
, "error: unable to read superblock");
413 b_data
= bh
->b_data
+ (ADFS_DISCRECORD
% BLOCK_SIZE
);
415 if (adfs_checkbblk(b_data
)) {
420 dr
= (struct adfs_discrecord
*)(b_data
+ ADFS_DR_OFFSET
);
423 * Do some sanity checks on the ADFS disc record
425 if (adfs_checkdiscrecord(dr
)) {
430 blocksize
= 1 << dr
->log2secsize
;
433 if (sb_set_blocksize(sb
, blocksize
)) {
434 bh
= sb_bread(sb
, ADFS_DISCRECORD
/ sb
->s_blocksize
);
436 adfs_msg(sb
, KERN_ERR
,
437 "error: couldn't read superblock on 2nd try.");
441 b_data
= bh
->b_data
+ (ADFS_DISCRECORD
% sb
->s_blocksize
);
442 if (adfs_checkbblk(b_data
)) {
443 adfs_msg(sb
, KERN_ERR
,
444 "error: disc record mismatch, very weird!");
448 dr
= (struct adfs_discrecord
*)(b_data
+ ADFS_DR_OFFSET
);
451 adfs_msg(sb
, KERN_ERR
,
452 "error: unsupported blocksize");
458 * blocksize on this device should now be set to the ADFS log2secsize
461 sb
->s_magic
= ADFS_SUPER_MAGIC
;
462 asb
->s_idlen
= dr
->idlen
;
463 asb
->s_map_size
= dr
->nzones
| (dr
->nzones_high
<< 8);
464 asb
->s_map2blk
= dr
->log2bpmb
- dr
->log2secsize
;
465 asb
->s_log2sharesize
= dr
->log2sharesize
;
467 asb
->s_map
= adfs_read_map(sb
, dr
);
468 if (IS_ERR(asb
->s_map
)) {
469 ret
= PTR_ERR(asb
->s_map
);
476 * set up enough so that we can read an inode
478 sb
->s_op
= &adfs_sops
;
480 dr
= adfs_map_discrecord(asb
->s_map
);
482 root_obj
.parent_id
= root_obj
.indaddr
= le32_to_cpu(dr
->root
);
483 root_obj
.name_len
= 0;
484 /* Set root object date as 01 Jan 1987 00:00:00 */
485 root_obj
.loadaddr
= 0xfff0003f;
486 root_obj
.execaddr
= 0xec22c000;
487 root_obj
.size
= ADFS_NEWDIR_SIZE
;
488 root_obj
.attr
= ADFS_NDA_DIRECTORY
| ADFS_NDA_OWNER_READ
|
489 ADFS_NDA_OWNER_WRITE
| ADFS_NDA_PUBLIC_READ
;
492 * If this is a F+ disk with variable length directories,
493 * get the root_size from the disc record.
495 if (dr
->format_version
) {
496 root_obj
.size
= le32_to_cpu(dr
->root_size
);
497 asb
->s_dir
= &adfs_fplus_dir_ops
;
498 asb
->s_namelen
= ADFS_FPLUS_NAME_LEN
;
500 asb
->s_dir
= &adfs_f_dir_ops
;
501 asb
->s_namelen
= ADFS_F_NAME_LEN
;
504 * ,xyz hex filetype suffix may be added by driver
505 * to files that have valid RISC OS filetype
510 sb
->s_d_op
= &adfs_dentry_operations
;
511 root
= adfs_iget(sb
, &root_obj
);
512 sb
->s_root
= d_make_root(root
);
515 for (i
= 0; i
< asb
->s_map_size
; i
++)
516 brelse(asb
->s_map
[i
].dm_bh
);
518 adfs_error(sb
, "get root inode failed\n");
526 adfs_msg(sb
, KERN_ERR
,
527 "error: can't find an ADFS filesystem on dev %s.",
532 sb
->s_fs_info
= NULL
;
537 static struct dentry
*adfs_mount(struct file_system_type
*fs_type
,
538 int flags
, const char *dev_name
, void *data
)
540 return mount_bdev(fs_type
, flags
, dev_name
, data
, adfs_fill_super
);
543 static struct file_system_type adfs_fs_type
= {
544 .owner
= THIS_MODULE
,
547 .kill_sb
= kill_block_super
,
548 .fs_flags
= FS_REQUIRES_DEV
,
550 MODULE_ALIAS_FS("adfs");
552 static int __init
init_adfs_fs(void)
554 int err
= init_inodecache();
557 err
= register_filesystem(&adfs_fs_type
);
562 destroy_inodecache();
567 static void __exit
exit_adfs_fs(void)
569 unregister_filesystem(&adfs_fs_type
);
570 destroy_inodecache();
573 module_init(init_adfs_fs
)
574 module_exit(exit_adfs_fs
)
575 MODULE_LICENSE("GPL");