10 #include <linux/module.h>
16 #include <linux/slab.h>
23 #define ADFS_DEFAULT_OWNER_MASK S_IRWXU
24 #define ADFS_DEFAULT_OTHER_MASK (S_IRWXG | S_IRWXO)
32 vsnprintf(error_buf,
sizeof(error_buf), fmt, args);
36 sb->
s_id,
function ?
": " :
"",
37 function ?
function :
"", error_buf);
66 for (i = 0; i <
sizeof(dr->
unused52); i++)
73 static unsigned char adfs_calczonecheck(
struct super_block *
sb,
unsigned char *
map)
78 v0 = v1 = v2 = v3 = 0;
80 v0 += map[
i] + (v3 >> 8);
82 v1 += map[i + 1] + (v0 >> 8);
84 v2 += map[i + 2] + (v1 >> 8);
86 v3 += map[i + 3] + (v2 >> 8);
90 v1 += map[1] + (v0 >> 8);
91 v2 += map[2] + (v1 >> 8);
92 v3 += map[3] + (v2 >> 8);
94 return v0 ^ v1 ^ v2 ^
v3;
99 unsigned char crosscheck = 0, zonecheck = 1;
102 for (i = 0; i < ADFS_SB(sb)->s_map_size; i++) {
105 map = dm[
i].
dm_bh->b_data;
107 if (adfs_calczonecheck(sb, map) != map[0]) {
111 crosscheck ^= map[3];
113 if (crosscheck != 0xff)
115 return crosscheck == 0xff && zonecheck;
124 brelse(asb->
s_map[i].dm_bh);
130 static int adfs_show_options(
struct seq_file *seq,
struct dentry *root)
180 if (!uid_valid(asb->
s_uid))
187 if (!gid_valid(asb->
s_gid))
206 printk(
"ADFS-fs: unrecognised mount option \"%s\" "
207 "or missing value\n", p);
217 return parse_options(sb, data);
224 u64 id = huge_encode_dev(sb->
s_bdev->bd_dev);
257 static void adfs_destroy_inode(
struct inode *inode)
262 static void init_once(
void *
foo)
269 static int init_inodecache(
void)
276 if (adfs_inode_cachep ==
NULL)
281 static void destroy_inodecache(
void)
292 .alloc_inode = adfs_alloc_inode,
293 .destroy_inode = adfs_destroy_inode,
295 .put_super = adfs_put_super,
296 .statfs = adfs_statfs,
297 .remount_fs = adfs_remount,
298 .show_options = adfs_show_options,
304 unsigned int map_addr, zone_size, nzones;
310 map_addr = (nzones >> 1) * zone_size -
312 map_addr = signed_asl(map_addr, asb->
s_map2blk);
322 for (zone = 0; zone < nzones; zone++, map_addr++) {
326 dm[zone].
dm_bh = sb_bread(sb, map_addr);
328 if (!dm[zone].dm_bh) {
340 (ADFS_DR_SIZE_BITS - i * zone_size);
342 if (adfs_checkmap(sb, dm))
349 brelse(dm[zone].dm_bh);
355 static inline unsigned long adfs_discsize(
struct adfs_discrecord *dr,
int block_bits)
357 unsigned long discsize;
365 static int adfs_fill_super(
struct super_block *sb,
void *
data,
int silent)
368 struct buffer_head *bh;
370 unsigned char *b_data;
388 if (parse_options(sb, data))
399 if (adfs_checkbblk(b_data)) {
401 printk(
"VFS: Can't find an adfs filesystem on dev "
411 if (adfs_checkdiscrecord(dr)) {
413 printk(
"VPS: Can't find an adfs filesystem on dev "
427 if (adfs_checkbblk(b_data)) {
428 adfs_error(sb,
"disc record mismatch, very weird!");
451 asb->
s_map = adfs_read_map(sb, dr);
460 sb->
s_op = &adfs_sops;
465 root_obj.name_len = 0;
467 root_obj.loadaddr = 0xfff0003f;
468 root_obj.execaddr = 0xec22c000;
472 root_obj.filetype = -1;
499 brelse(asb->
s_map[i].dm_bh);
515 int flags,
const char *dev_name,
void *data)
517 return mount_bdev(fs_type, flags, dev_name, data, adfs_fill_super);
528 static int __init init_adfs_fs(
void)
530 int err = init_inodecache();
538 destroy_inodecache();
543 static void __exit exit_adfs_fs(
void)
546 destroy_inodecache();