^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/fs/adfs/super.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 1997-1999 Russell King
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/parser.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/statfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/user_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "adfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "dir_f.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "dir_fplus.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define ADFS_SB_FLAGS SB_NOATIME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define ADFS_DEFAULT_OWNER_MASK S_IRWXU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define ADFS_DEFAULT_OTHER_MASK (S_IRWXG | S_IRWXO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) void __adfs_error(struct super_block *sb, const char *function, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct va_format vaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) vaf.fmt = fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) vaf.va = &args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) printk(KERN_CRIT "ADFS-fs error (device %s)%s%s: %pV\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) sb->s_id, function ? ": " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) function ? function : "", &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) void adfs_msg(struct super_block *sb, const char *pfx, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct va_format vaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) vaf.fmt = fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) vaf.va = &args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) printk("%sADFS-fs (%s): %pV\n", pfx, sb->s_id, &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static int adfs_checkdiscrecord(struct adfs_discrecord *dr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) unsigned int max_idlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* sector size must be 256, 512 or 1024 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (dr->log2secsize != 8 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) dr->log2secsize != 9 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) dr->log2secsize != 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* idlen must be at least log2secsize + 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (dr->idlen < dr->log2secsize + 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* we cannot have such a large disc that we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * are unable to represent sector offsets in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * 32 bits. This works out at 2.0 TB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (le32_to_cpu(dr->disc_size_high) >> dr->log2secsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * Maximum idlen is limited to 16 bits for new directories by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * the three-byte storage of an indirect disc address. For
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * big directories, idlen must be no greater than 19 v2 [1.0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) max_idlen = dr->format_version ? 19 : 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (dr->idlen > max_idlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* reserved bytes should be zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) for (i = 0; i < sizeof(dr->unused52); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (dr->unused52[i] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static void adfs_put_super(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct adfs_sb_info *asb = ADFS_SB(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) adfs_free_map(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) kfree_rcu(asb, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static int adfs_show_options(struct seq_file *seq, struct dentry *root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct adfs_sb_info *asb = ADFS_SB(root->d_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (!uid_eq(asb->s_uid, GLOBAL_ROOT_UID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) seq_printf(seq, ",uid=%u", from_kuid_munged(&init_user_ns, asb->s_uid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (!gid_eq(asb->s_gid, GLOBAL_ROOT_GID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) seq_printf(seq, ",gid=%u", from_kgid_munged(&init_user_ns, asb->s_gid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (asb->s_owner_mask != ADFS_DEFAULT_OWNER_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) seq_printf(seq, ",ownmask=%o", asb->s_owner_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (asb->s_other_mask != ADFS_DEFAULT_OTHER_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) seq_printf(seq, ",othmask=%o", asb->s_other_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (asb->s_ftsuffix != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) seq_printf(seq, ",ftsuffix=%u", asb->s_ftsuffix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) enum {Opt_uid, Opt_gid, Opt_ownmask, Opt_othmask, Opt_ftsuffix, Opt_err};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static const match_table_t tokens = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {Opt_uid, "uid=%u"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {Opt_gid, "gid=%u"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {Opt_ownmask, "ownmask=%o"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {Opt_othmask, "othmask=%o"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {Opt_ftsuffix, "ftsuffix=%u"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {Opt_err, NULL}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static int parse_options(struct super_block *sb, struct adfs_sb_info *asb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (!options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) while ((p = strsep(&options, ",")) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) substring_t args[MAX_OPT_ARGS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) int token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (!*p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) token = match_token(p, tokens, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) switch (token) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) case Opt_uid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (match_int(args, &option))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) asb->s_uid = make_kuid(current_user_ns(), option);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (!uid_valid(asb->s_uid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) case Opt_gid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (match_int(args, &option))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) asb->s_gid = make_kgid(current_user_ns(), option);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (!gid_valid(asb->s_gid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) case Opt_ownmask:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (match_octal(args, &option))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) asb->s_owner_mask = option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) case Opt_othmask:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (match_octal(args, &option))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) asb->s_other_mask = option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) case Opt_ftsuffix:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (match_int(args, &option))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) asb->s_ftsuffix = option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) adfs_msg(sb, KERN_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) "unrecognised mount option \"%s\" or missing value",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static int adfs_remount(struct super_block *sb, int *flags, char *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct adfs_sb_info temp_asb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) sync_filesystem(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) *flags |= ADFS_SB_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) temp_asb = *ADFS_SB(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) ret = parse_options(sb, &temp_asb, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) *ADFS_SB(sb) = temp_asb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static int adfs_statfs(struct dentry *dentry, struct kstatfs *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct super_block *sb = dentry->d_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct adfs_sb_info *sbi = ADFS_SB(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) adfs_map_statfs(sb, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) buf->f_type = ADFS_SUPER_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) buf->f_namelen = sbi->s_namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) buf->f_bsize = sb->s_blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) buf->f_ffree = (long)(buf->f_bfree * buf->f_files) / (long)buf->f_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) buf->f_fsid = u64_to_fsid(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static struct kmem_cache *adfs_inode_cachep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static struct inode *adfs_alloc_inode(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct adfs_inode_info *ei;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ei = kmem_cache_alloc(adfs_inode_cachep, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (!ei)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return &ei->vfs_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static void adfs_free_inode(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) kmem_cache_free(adfs_inode_cachep, ADFS_I(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static int adfs_drop_inode(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /* always drop inodes if we are read-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return !IS_ENABLED(CONFIG_ADFS_FS_RW) || IS_RDONLY(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static void init_once(void *foo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct adfs_inode_info *ei = (struct adfs_inode_info *) foo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) inode_init_once(&ei->vfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static int __init init_inodecache(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) adfs_inode_cachep = kmem_cache_create("adfs_inode_cache",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) sizeof(struct adfs_inode_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 0, (SLAB_RECLAIM_ACCOUNT|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) SLAB_MEM_SPREAD|SLAB_ACCOUNT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) init_once);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (adfs_inode_cachep == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static void destroy_inodecache(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * Make sure all delayed rcu free inodes are flushed before we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * destroy cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) rcu_barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) kmem_cache_destroy(adfs_inode_cachep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static const struct super_operations adfs_sops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) .alloc_inode = adfs_alloc_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) .free_inode = adfs_free_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) .drop_inode = adfs_drop_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) .write_inode = adfs_write_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) .put_super = adfs_put_super,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) .statfs = adfs_statfs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) .remount_fs = adfs_remount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) .show_options = adfs_show_options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static int adfs_probe(struct super_block *sb, unsigned int offset, int silent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int (*validate)(struct super_block *sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct buffer_head *bh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct adfs_discrecord **bhp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct adfs_sb_info *asb = ADFS_SB(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct adfs_discrecord *dr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) unsigned int blocksize = BLOCK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) int ret, try;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) for (try = 0; try < 2; try++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* try to set the requested block size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (sb->s_blocksize != blocksize &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) !sb_set_blocksize(sb, blocksize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (!silent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) adfs_msg(sb, KERN_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) "error: unsupported blocksize");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /* read the buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) bh = sb_bread(sb, offset >> sb->s_blocksize_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (!bh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) adfs_msg(sb, KERN_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) "error: unable to read block %u, try %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) offset >> sb->s_blocksize_bits, try);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /* validate it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) ret = validate(sb, bh, &dr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* does the block size match the filesystem block size? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) blocksize = 1 << dr->log2secsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (sb->s_blocksize == blocksize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) asb->s_map = adfs_read_map(sb, dr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return PTR_ERR_OR_ZERO(asb->s_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static int adfs_validate_bblk(struct super_block *sb, struct buffer_head *bh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct adfs_discrecord **drp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct adfs_discrecord *dr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) unsigned char *b_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) b_data = bh->b_data + (ADFS_DISCRECORD % sb->s_blocksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (adfs_checkbblk(b_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) /* Do some sanity checks on the ADFS disc record */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) dr = (struct adfs_discrecord *)(b_data + ADFS_DR_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (adfs_checkdiscrecord(dr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) *drp = dr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static int adfs_validate_dr0(struct super_block *sb, struct buffer_head *bh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) struct adfs_discrecord **drp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct adfs_discrecord *dr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* Do some sanity checks on the ADFS disc record */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) dr = (struct adfs_discrecord *)(bh->b_data + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (adfs_checkdiscrecord(dr) || dr->nzones_high || dr->nzones != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) *drp = dr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static int adfs_fill_super(struct super_block *sb, void *data, int silent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct adfs_discrecord *dr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct object_info root_obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct adfs_sb_info *asb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct inode *root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) sb->s_flags |= ADFS_SB_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) asb = kzalloc(sizeof(*asb), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (!asb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) sb->s_fs_info = asb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) sb->s_magic = ADFS_SUPER_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) sb->s_time_gran = 10000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /* set default options */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) asb->s_uid = GLOBAL_ROOT_UID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) asb->s_gid = GLOBAL_ROOT_GID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) asb->s_owner_mask = ADFS_DEFAULT_OWNER_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) asb->s_other_mask = ADFS_DEFAULT_OTHER_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) asb->s_ftsuffix = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (parse_options(sb, asb, data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /* Try to probe the filesystem boot block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) ret = adfs_probe(sb, ADFS_DISCRECORD, 1, adfs_validate_bblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (ret == -EILSEQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) ret = adfs_probe(sb, 0, silent, adfs_validate_dr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (ret == -EILSEQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (!silent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) adfs_msg(sb, KERN_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) "error: can't find an ADFS filesystem on dev %s.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) sb->s_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /* set up enough so that we can read an inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) sb->s_op = &adfs_sops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) dr = adfs_map_discrecord(asb->s_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) root_obj.parent_id = root_obj.indaddr = le32_to_cpu(dr->root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) root_obj.name_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /* Set root object date as 01 Jan 1987 00:00:00 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) root_obj.loadaddr = 0xfff0003f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) root_obj.execaddr = 0xec22c000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) root_obj.size = ADFS_NEWDIR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) root_obj.attr = ADFS_NDA_DIRECTORY | ADFS_NDA_OWNER_READ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ADFS_NDA_OWNER_WRITE | ADFS_NDA_PUBLIC_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * If this is a F+ disk with variable length directories,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * get the root_size from the disc record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (dr->format_version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) root_obj.size = le32_to_cpu(dr->root_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) asb->s_dir = &adfs_fplus_dir_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) asb->s_namelen = ADFS_FPLUS_NAME_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) asb->s_dir = &adfs_f_dir_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) asb->s_namelen = ADFS_F_NAME_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * ,xyz hex filetype suffix may be added by driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * to files that have valid RISC OS filetype
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (asb->s_ftsuffix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) asb->s_namelen += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) sb->s_d_op = &adfs_dentry_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) root = adfs_iget(sb, &root_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) sb->s_root = d_make_root(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (!sb->s_root) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) adfs_free_map(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) adfs_error(sb, "get root inode failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) sb->s_fs_info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) kfree(asb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static struct dentry *adfs_mount(struct file_system_type *fs_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) int flags, const char *dev_name, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return mount_bdev(fs_type, flags, dev_name, data, adfs_fill_super);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static struct file_system_type adfs_fs_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) .name = "adfs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) .mount = adfs_mount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) .kill_sb = kill_block_super,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) .fs_flags = FS_REQUIRES_DEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) MODULE_ALIAS_FS("adfs");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static int __init init_adfs_fs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) int err = init_inodecache();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) err = register_filesystem(&adfs_fs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) destroy_inodecache();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) static void __exit exit_adfs_fs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) unregister_filesystem(&adfs_fs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) destroy_inodecache();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) module_init(init_adfs_fs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) module_exit(exit_adfs_fs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY);