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/fs_parser.h>
10 #include <linux/fs_context.h>
11 #include <linux/mount.h>
12 #include <linux/seq_file.h>
13 #include <linux/slab.h>
14 #include <linux/statfs.h>
15 #include <linux/user_namespace.h>
16 #include <linux/blkdev.h>
19 #include "dir_fplus.h"
21 #define ADFS_SB_FLAGS SB_NOATIME
23 #define ADFS_DEFAULT_OWNER_MASK S_IRWXU
24 #define ADFS_DEFAULT_OTHER_MASK (S_IRWXG | S_IRWXO)
26 void __adfs_error(struct super_block
*sb
, const char *function
, const char *fmt
, ...)
35 printk(KERN_CRIT
"ADFS-fs error (device %s)%s%s: %pV\n",
36 sb
->s_id
, function
? ": " : "",
37 function
? function
: "", &vaf
);
42 void adfs_msg(struct super_block
*sb
, const char *pfx
, const char *fmt
, ...)
50 printk("%sADFS-fs (%s): %pV\n", pfx
, sb
->s_id
, &vaf
);
54 static int adfs_checkdiscrecord(struct adfs_discrecord
*dr
)
56 unsigned int max_idlen
;
59 /* sector size must be 256, 512 or 1024 bytes */
60 if (dr
->log2secsize
!= 8 &&
61 dr
->log2secsize
!= 9 &&
62 dr
->log2secsize
!= 10)
65 /* idlen must be at least log2secsize + 3 */
66 if (dr
->idlen
< dr
->log2secsize
+ 3)
69 /* we cannot have such a large disc that we
70 * are unable to represent sector offsets in
71 * 32 bits. This works out at 2.0 TB.
73 if (le32_to_cpu(dr
->disc_size_high
) >> dr
->log2secsize
)
77 * Maximum idlen is limited to 16 bits for new directories by
78 * the three-byte storage of an indirect disc address. For
79 * big directories, idlen must be no greater than 19 v2 [1.0]
81 max_idlen
= dr
->format_version
? 19 : 16;
82 if (dr
->idlen
> max_idlen
)
85 /* reserved bytes should be zero */
86 for (i
= 0; i
< sizeof(dr
->unused52
); i
++)
87 if (dr
->unused52
[i
] != 0)
93 static void adfs_put_super(struct super_block
*sb
)
95 struct adfs_sb_info
*asb
= ADFS_SB(sb
);
101 static int adfs_show_options(struct seq_file
*seq
, struct dentry
*root
)
103 struct adfs_sb_info
*asb
= ADFS_SB(root
->d_sb
);
105 if (!uid_eq(asb
->s_uid
, GLOBAL_ROOT_UID
))
106 seq_printf(seq
, ",uid=%u", from_kuid_munged(&init_user_ns
, asb
->s_uid
));
107 if (!gid_eq(asb
->s_gid
, GLOBAL_ROOT_GID
))
108 seq_printf(seq
, ",gid=%u", from_kgid_munged(&init_user_ns
, asb
->s_gid
));
109 if (asb
->s_owner_mask
!= ADFS_DEFAULT_OWNER_MASK
)
110 seq_printf(seq
, ",ownmask=%o", asb
->s_owner_mask
);
111 if (asb
->s_other_mask
!= ADFS_DEFAULT_OTHER_MASK
)
112 seq_printf(seq
, ",othmask=%o", asb
->s_other_mask
);
113 if (asb
->s_ftsuffix
!= 0)
114 seq_printf(seq
, ",ftsuffix=%u", asb
->s_ftsuffix
);
119 enum {Opt_uid
, Opt_gid
, Opt_ownmask
, Opt_othmask
, Opt_ftsuffix
};
121 static const struct fs_parameter_spec adfs_param_spec
[] = {
122 fsparam_uid ("uid", Opt_uid
),
123 fsparam_gid ("gid", Opt_gid
),
124 fsparam_u32oct ("ownmask", Opt_ownmask
),
125 fsparam_u32oct ("othmask", Opt_othmask
),
126 fsparam_u32 ("ftsuffix", Opt_ftsuffix
),
130 static int adfs_parse_param(struct fs_context
*fc
, struct fs_parameter
*param
)
132 struct adfs_sb_info
*asb
= fc
->s_fs_info
;
133 struct fs_parse_result result
;
136 opt
= fs_parse(fc
, adfs_param_spec
, param
, &result
);
142 asb
->s_uid
= result
.uid
;
145 asb
->s_gid
= result
.gid
;
148 asb
->s_owner_mask
= result
.uint_32
;
151 asb
->s_other_mask
= result
.uint_32
;
154 asb
->s_ftsuffix
= result
.uint_32
;
162 static int adfs_reconfigure(struct fs_context
*fc
)
164 struct adfs_sb_info
*new_asb
= fc
->s_fs_info
;
165 struct adfs_sb_info
*asb
= ADFS_SB(fc
->root
->d_sb
);
167 sync_filesystem(fc
->root
->d_sb
);
168 fc
->sb_flags
|= ADFS_SB_FLAGS
;
170 /* Structure copy newly parsed options */
176 static int adfs_statfs(struct dentry
*dentry
, struct kstatfs
*buf
)
178 struct super_block
*sb
= dentry
->d_sb
;
179 struct adfs_sb_info
*sbi
= ADFS_SB(sb
);
180 u64 id
= huge_encode_dev(sb
->s_bdev
->bd_dev
);
182 adfs_map_statfs(sb
, buf
);
184 buf
->f_type
= ADFS_SUPER_MAGIC
;
185 buf
->f_namelen
= sbi
->s_namelen
;
186 buf
->f_bsize
= sb
->s_blocksize
;
187 buf
->f_ffree
= (long)(buf
->f_bfree
* buf
->f_files
) / (long)buf
->f_blocks
;
188 buf
->f_fsid
= u64_to_fsid(id
);
193 static struct kmem_cache
*adfs_inode_cachep
;
195 static struct inode
*adfs_alloc_inode(struct super_block
*sb
)
197 struct adfs_inode_info
*ei
;
198 ei
= alloc_inode_sb(sb
, adfs_inode_cachep
, GFP_KERNEL
);
201 return &ei
->vfs_inode
;
204 static void adfs_free_inode(struct inode
*inode
)
206 kmem_cache_free(adfs_inode_cachep
, ADFS_I(inode
));
209 static int adfs_drop_inode(struct inode
*inode
)
211 /* always drop inodes if we are read-only */
212 return !IS_ENABLED(CONFIG_ADFS_FS_RW
) || IS_RDONLY(inode
);
215 static void init_once(void *foo
)
217 struct adfs_inode_info
*ei
= (struct adfs_inode_info
*) foo
;
219 inode_init_once(&ei
->vfs_inode
);
222 static int __init
init_inodecache(void)
224 adfs_inode_cachep
= kmem_cache_create("adfs_inode_cache",
225 sizeof(struct adfs_inode_info
),
226 0, (SLAB_RECLAIM_ACCOUNT
|
229 if (adfs_inode_cachep
== NULL
)
234 static void destroy_inodecache(void)
237 * Make sure all delayed rcu free inodes are flushed before we
241 kmem_cache_destroy(adfs_inode_cachep
);
244 static const struct super_operations adfs_sops
= {
245 .alloc_inode
= adfs_alloc_inode
,
246 .free_inode
= adfs_free_inode
,
247 .drop_inode
= adfs_drop_inode
,
248 .write_inode
= adfs_write_inode
,
249 .put_super
= adfs_put_super
,
250 .statfs
= adfs_statfs
,
251 .show_options
= adfs_show_options
,
254 static int adfs_probe(struct super_block
*sb
, unsigned int offset
, int silent
,
255 int (*validate
)(struct super_block
*sb
,
256 struct buffer_head
*bh
,
257 struct adfs_discrecord
**bhp
))
259 struct adfs_sb_info
*asb
= ADFS_SB(sb
);
260 struct adfs_discrecord
*dr
;
261 struct buffer_head
*bh
;
262 unsigned int blocksize
= BLOCK_SIZE
;
265 for (try = 0; try < 2; try++) {
266 /* try to set the requested block size */
267 if (sb
->s_blocksize
!= blocksize
&&
268 !sb_set_blocksize(sb
, blocksize
)) {
270 adfs_msg(sb
, KERN_ERR
,
271 "error: unsupported blocksize");
275 /* read the buffer */
276 bh
= sb_bread(sb
, offset
>> sb
->s_blocksize_bits
);
278 adfs_msg(sb
, KERN_ERR
,
279 "error: unable to read block %u, try %d",
280 offset
>> sb
->s_blocksize_bits
, try);
285 ret
= validate(sb
, bh
, &dr
);
291 /* does the block size match the filesystem block size? */
292 blocksize
= 1 << dr
->log2secsize
;
293 if (sb
->s_blocksize
== blocksize
) {
294 asb
->s_map
= adfs_read_map(sb
, dr
);
296 return PTR_ERR_OR_ZERO(asb
->s_map
);
305 static int adfs_validate_bblk(struct super_block
*sb
, struct buffer_head
*bh
,
306 struct adfs_discrecord
**drp
)
308 struct adfs_discrecord
*dr
;
309 unsigned char *b_data
;
311 b_data
= bh
->b_data
+ (ADFS_DISCRECORD
% sb
->s_blocksize
);
312 if (adfs_checkbblk(b_data
))
315 /* Do some sanity checks on the ADFS disc record */
316 dr
= (struct adfs_discrecord
*)(b_data
+ ADFS_DR_OFFSET
);
317 if (adfs_checkdiscrecord(dr
))
324 static int adfs_validate_dr0(struct super_block
*sb
, struct buffer_head
*bh
,
325 struct adfs_discrecord
**drp
)
327 struct adfs_discrecord
*dr
;
329 /* Do some sanity checks on the ADFS disc record */
330 dr
= (struct adfs_discrecord
*)(bh
->b_data
+ 4);
331 if (adfs_checkdiscrecord(dr
) || dr
->nzones_high
|| dr
->nzones
!= 1)
338 static int adfs_fill_super(struct super_block
*sb
, struct fs_context
*fc
)
340 struct adfs_discrecord
*dr
;
341 struct object_info root_obj
;
342 struct adfs_sb_info
*asb
= sb
->s_fs_info
;
345 int silent
= fc
->sb_flags
& SB_SILENT
;
347 sb
->s_flags
|= ADFS_SB_FLAGS
;
350 sb
->s_magic
= ADFS_SUPER_MAGIC
;
351 sb
->s_time_gran
= 10000000;
353 /* Try to probe the filesystem boot block */
354 ret
= adfs_probe(sb
, ADFS_DISCRECORD
, 1, adfs_validate_bblk
);
356 ret
= adfs_probe(sb
, 0, silent
, adfs_validate_dr0
);
357 if (ret
== -EILSEQ
) {
359 adfs_msg(sb
, KERN_ERR
,
360 "error: can't find an ADFS filesystem on dev %s.",
367 /* set up enough so that we can read an inode */
368 sb
->s_op
= &adfs_sops
;
370 dr
= adfs_map_discrecord(asb
->s_map
);
372 root_obj
.parent_id
= root_obj
.indaddr
= le32_to_cpu(dr
->root
);
373 root_obj
.name_len
= 0;
374 /* Set root object date as 01 Jan 1987 00:00:00 */
375 root_obj
.loadaddr
= 0xfff0003f;
376 root_obj
.execaddr
= 0xec22c000;
377 root_obj
.size
= ADFS_NEWDIR_SIZE
;
378 root_obj
.attr
= ADFS_NDA_DIRECTORY
| ADFS_NDA_OWNER_READ
|
379 ADFS_NDA_OWNER_WRITE
| ADFS_NDA_PUBLIC_READ
;
382 * If this is a F+ disk with variable length directories,
383 * get the root_size from the disc record.
385 if (dr
->format_version
) {
386 root_obj
.size
= le32_to_cpu(dr
->root_size
);
387 asb
->s_dir
= &adfs_fplus_dir_ops
;
388 asb
->s_namelen
= ADFS_FPLUS_NAME_LEN
;
390 asb
->s_dir
= &adfs_f_dir_ops
;
391 asb
->s_namelen
= ADFS_F_NAME_LEN
;
394 * ,xyz hex filetype suffix may be added by driver
395 * to files that have valid RISC OS filetype
400 sb
->s_d_op
= &adfs_dentry_operations
;
401 root
= adfs_iget(sb
, &root_obj
);
402 sb
->s_root
= d_make_root(root
);
405 adfs_error(sb
, "get root inode failed\n");
412 sb
->s_fs_info
= NULL
;
417 static int adfs_get_tree(struct fs_context
*fc
)
419 return get_tree_bdev(fc
, adfs_fill_super
);
422 static void adfs_free_fc(struct fs_context
*fc
)
424 struct adfs_context
*asb
= fc
->s_fs_info
;
429 static const struct fs_context_operations adfs_context_ops
= {
430 .parse_param
= adfs_parse_param
,
431 .get_tree
= adfs_get_tree
,
432 .reconfigure
= adfs_reconfigure
,
433 .free
= adfs_free_fc
,
436 static int adfs_init_fs_context(struct fs_context
*fc
)
438 struct adfs_sb_info
*asb
;
440 asb
= kzalloc(sizeof(struct adfs_sb_info
), GFP_KERNEL
);
444 if (fc
->purpose
== FS_CONTEXT_FOR_RECONFIGURE
) {
445 struct super_block
*sb
= fc
->root
->d_sb
;
446 struct adfs_sb_info
*old_asb
= ADFS_SB(sb
);
448 /* structure copy existing options before parsing */
451 /* set default options */
452 asb
->s_uid
= GLOBAL_ROOT_UID
;
453 asb
->s_gid
= GLOBAL_ROOT_GID
;
454 asb
->s_owner_mask
= ADFS_DEFAULT_OWNER_MASK
;
455 asb
->s_other_mask
= ADFS_DEFAULT_OTHER_MASK
;
459 fc
->ops
= &adfs_context_ops
;
465 static struct file_system_type adfs_fs_type
= {
466 .owner
= THIS_MODULE
,
468 .kill_sb
= kill_block_super
,
469 .fs_flags
= FS_REQUIRES_DEV
,
470 .init_fs_context
= adfs_init_fs_context
,
471 .parameters
= adfs_param_spec
,
473 MODULE_ALIAS_FS("adfs");
475 static int __init
init_adfs_fs(void)
477 int err
= init_inodecache();
480 err
= register_filesystem(&adfs_fs_type
);
485 destroy_inodecache();
490 static void __exit
exit_adfs_fs(void)
492 unregister_filesystem(&adfs_fs_type
);
493 destroy_inodecache();
496 module_init(init_adfs_fs
)
497 module_exit(exit_adfs_fs
)
498 MODULE_DESCRIPTION("Acorn Disc Filing System");
499 MODULE_LICENSE("GPL");