1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * super.c 4 * 5 * Copyright (c) 1999 Al Smith 6 * 7 * Portions derived from work (c) 1995,1996 Christian Vogelgsang. 8 */ 9 10 #include <linux/init.h> 11 #include <linux/module.h> 12 #include <linux/exportfs.h> 13 #include <linux/slab.h> 14 #include <linux/buffer_head.h> 15 #include <linux/vfs.h> 16 #include <linux/blkdev.h> 17 18 #include "efs.h" 19 #include <linux/efs_vh.h> 20 #include <linux/efs_fs_sb.h> 21 22 static int efs_statfs(struct dentry *dentry, struct kstatfs *buf); 23 static int efs_fill_super(struct super_block *s, void *d, int silent); 24 25 static struct dentry *efs_mount(struct file_system_type *fs_type, 26 int flags, const char *dev_name, void *data) 27 { 28 return mount_bdev(fs_type, flags, dev_name, data, efs_fill_super); 29 } 30 31 static void efs_kill_sb(struct super_block *s) 32 { 33 struct efs_sb_info *sbi = SUPER_INFO(s); 34 kill_block_super(s); 35 kfree(sbi); 36 } 37 38 static struct file_system_type efs_fs_type = { 39 .owner = THIS_MODULE, 40 .name = "efs", 41 .mount = efs_mount, 42 .kill_sb = efs_kill_sb, 43 .fs_flags = FS_REQUIRES_DEV, 44 }; 45 MODULE_ALIAS_FS("efs"); 46 47 static struct pt_types sgi_pt_types[] = { 48 {0x00, "SGI vh"}, 49 {0x01, "SGI trkrepl"}, 50 {0x02, "SGI secrepl"}, 51 {0x03, "SGI raw"}, 52 {0x04, "SGI bsd"}, 53 {SGI_SYSV, "SGI sysv"}, 54 {0x06, "SGI vol"}, 55 {SGI_EFS, "SGI efs"}, 56 {0x08, "SGI lv"}, 57 {0x09, "SGI rlv"}, 58 {0x0A, "SGI xfs"}, 59 {0x0B, "SGI xfslog"}, 60 {0x0C, "SGI xlv"}, 61 {0x82, "Linux swap"}, 62 {0x83, "Linux native"}, 63 {0, NULL} 64 }; 65 66 67 static struct kmem_cache * efs_inode_cachep; 68 69 static struct inode *efs_alloc_inode(struct super_block *sb) 70 { 71 struct efs_inode_info *ei; 72 ei = alloc_inode_sb(sb, efs_inode_cachep, GFP_KERNEL); 73 if (!ei) 74 return NULL; 75 return &ei->vfs_inode; 76 } 77 78 static void efs_free_inode(struct inode *inode) 79 { 80 kmem_cache_free(efs_inode_cachep, INODE_INFO(inode)); 81 } 82 83 static void init_once(void *foo) 84 { 85 struct efs_inode_info *ei = (struct efs_inode_info *) foo; 86 87 inode_init_once(&ei->vfs_inode); 88 } 89 90 static int __init init_inodecache(void) 91 { 92 efs_inode_cachep = kmem_cache_create("efs_inode_cache", 93 sizeof(struct efs_inode_info), 0, 94 SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD| 95 SLAB_ACCOUNT, init_once); 96 if (efs_inode_cachep == NULL) 97 return -ENOMEM; 98 return 0; 99 } 100 101 static void destroy_inodecache(void) 102 { 103 /* 104 * Make sure all delayed rcu free inodes are flushed before we 105 * destroy cache. 106 */ 107 rcu_barrier(); 108 kmem_cache_destroy(efs_inode_cachep); 109 } 110 111 static int efs_remount(struct super_block *sb, int *flags, char *data) 112 { 113 sync_filesystem(sb); 114 *flags |= SB_RDONLY; 115 return 0; 116 } 117 118 static const struct super_operations efs_superblock_operations = { 119 .alloc_inode = efs_alloc_inode, 120 .free_inode = efs_free_inode, 121 .statfs = efs_statfs, 122 .remount_fs = efs_remount, 123 }; 124 125 static const struct export_operations efs_export_ops = { 126 .encode_fh = generic_encode_ino32_fh, 127 .fh_to_dentry = efs_fh_to_dentry, 128 .fh_to_parent = efs_fh_to_parent, 129 .get_parent = efs_get_parent, 130 }; 131 132 static int __init init_efs_fs(void) { 133 int err; 134 pr_info(EFS_VERSION" - http://aeschi.ch.eu.org/efs/\n"); 135 err = init_inodecache(); 136 if (err) 137 goto out1; 138 err = register_filesystem(&efs_fs_type); 139 if (err) 140 goto out; 141 return 0; 142 out: 143 destroy_inodecache(); 144 out1: 145 return err; 146 } 147 148 static void __exit exit_efs_fs(void) { 149 unregister_filesystem(&efs_fs_type); 150 destroy_inodecache(); 151 } 152 153 module_init(init_efs_fs) 154 module_exit(exit_efs_fs) 155 156 static efs_block_t efs_validate_vh(struct volume_header *vh) { 157 int i; 158 __be32 cs, *ui; 159 int csum; 160 efs_block_t sblock = 0; /* shuts up gcc */ 161 struct pt_types *pt_entry; 162 int pt_type, slice = -1; 163 164 if (be32_to_cpu(vh->vh_magic) != VHMAGIC) { 165 /* 166 * assume that we're dealing with a partition and allow 167 * read_super() to try and detect a valid superblock 168 * on the next block. 169 */ 170 return 0; 171 } 172 173 ui = ((__be32 *) (vh + 1)) - 1; 174 for(csum = 0; ui >= ((__be32 *) vh);) { 175 cs = *ui--; 176 csum += be32_to_cpu(cs); 177 } 178 if (csum) { 179 pr_warn("SGI disklabel: checksum bad, label corrupted\n"); 180 return 0; 181 } 182 183 #ifdef DEBUG 184 pr_debug("bf: \"%16s\"\n", vh->vh_bootfile); 185 186 for(i = 0; i < NVDIR; i++) { 187 int j; 188 char name[VDNAMESIZE+1]; 189 190 for(j = 0; j < VDNAMESIZE; j++) { 191 name[j] = vh->vh_vd[i].vd_name[j]; 192 } 193 name[j] = (char) 0; 194 195 if (name[0]) { 196 pr_debug("vh: %8s block: 0x%08x size: 0x%08x\n", 197 name, (int) be32_to_cpu(vh->vh_vd[i].vd_lbn), 198 (int) be32_to_cpu(vh->vh_vd[i].vd_nbytes)); 199 } 200 } 201 #endif 202 203 for(i = 0; i < NPARTAB; i++) { 204 pt_type = (int) be32_to_cpu(vh->vh_pt[i].pt_type); 205 for(pt_entry = sgi_pt_types; pt_entry->pt_name; pt_entry++) { 206 if (pt_type == pt_entry->pt_type) break; 207 } 208 #ifdef DEBUG 209 if (be32_to_cpu(vh->vh_pt[i].pt_nblks)) { 210 pr_debug("pt %2d: start: %08d size: %08d type: 0x%02x (%s)\n", 211 i, (int)be32_to_cpu(vh->vh_pt[i].pt_firstlbn), 212 (int)be32_to_cpu(vh->vh_pt[i].pt_nblks), 213 pt_type, (pt_entry->pt_name) ? 214 pt_entry->pt_name : "unknown"); 215 } 216 #endif 217 if (IS_EFS(pt_type)) { 218 sblock = be32_to_cpu(vh->vh_pt[i].pt_firstlbn); 219 slice = i; 220 } 221 } 222 223 if (slice == -1) { 224 pr_notice("partition table contained no EFS partitions\n"); 225 #ifdef DEBUG 226 } else { 227 pr_info("using slice %d (type %s, offset 0x%x)\n", slice, 228 (pt_entry->pt_name) ? pt_entry->pt_name : "unknown", 229 sblock); 230 #endif 231 } 232 return sblock; 233 } 234 235 static int efs_validate_super(struct efs_sb_info *sb, struct efs_super *super) { 236 237 if (!IS_EFS_MAGIC(be32_to_cpu(super->fs_magic))) 238 return -1; 239 240 sb->fs_magic = be32_to_cpu(super->fs_magic); 241 sb->total_blocks = be32_to_cpu(super->fs_size); 242 sb->first_block = be32_to_cpu(super->fs_firstcg); 243 sb->group_size = be32_to_cpu(super->fs_cgfsize); 244 sb->data_free = be32_to_cpu(super->fs_tfree); 245 sb->inode_free = be32_to_cpu(super->fs_tinode); 246 sb->inode_blocks = be16_to_cpu(super->fs_cgisize); 247 sb->total_groups = be16_to_cpu(super->fs_ncg); 248 249 return 0; 250 } 251 252 static int efs_fill_super(struct super_block *s, void *d, int silent) 253 { 254 struct efs_sb_info *sb; 255 struct buffer_head *bh; 256 struct inode *root; 257 258 sb = kzalloc(sizeof(struct efs_sb_info), GFP_KERNEL); 259 if (!sb) 260 return -ENOMEM; 261 s->s_fs_info = sb; 262 s->s_time_min = 0; 263 s->s_time_max = U32_MAX; 264 265 s->s_magic = EFS_SUPER_MAGIC; 266 if (!sb_set_blocksize(s, EFS_BLOCKSIZE)) { 267 pr_err("device does not support %d byte blocks\n", 268 EFS_BLOCKSIZE); 269 return -EINVAL; 270 } 271 272 /* read the vh (volume header) block */ 273 bh = sb_bread(s, 0); 274 275 if (!bh) { 276 pr_err("cannot read volume header\n"); 277 return -EIO; 278 } 279 280 /* 281 * if this returns zero then we didn't find any partition table. 282 * this isn't (yet) an error - just assume for the moment that 283 * the device is valid and go on to search for a superblock. 284 */ 285 sb->fs_start = efs_validate_vh((struct volume_header *) bh->b_data); 286 brelse(bh); 287 288 if (sb->fs_start == -1) { 289 return -EINVAL; 290 } 291 292 bh = sb_bread(s, sb->fs_start + EFS_SUPER); 293 if (!bh) { 294 pr_err("cannot read superblock\n"); 295 return -EIO; 296 } 297 298 if (efs_validate_super(sb, (struct efs_super *) bh->b_data)) { 299 #ifdef DEBUG 300 pr_warn("invalid superblock at block %u\n", 301 sb->fs_start + EFS_SUPER); 302 #endif 303 brelse(bh); 304 return -EINVAL; 305 } 306 brelse(bh); 307 308 if (!sb_rdonly(s)) { 309 #ifdef DEBUG 310 pr_info("forcing read-only mode\n"); 311 #endif 312 s->s_flags |= SB_RDONLY; 313 } 314 s->s_op = &efs_superblock_operations; 315 s->s_export_op = &efs_export_ops; 316 root = efs_iget(s, EFS_ROOTINODE); 317 if (IS_ERR(root)) { 318 pr_err("get root inode failed\n"); 319 return PTR_ERR(root); 320 } 321 322 s->s_root = d_make_root(root); 323 if (!(s->s_root)) { 324 pr_err("get root dentry failed\n"); 325 return -ENOMEM; 326 } 327 328 return 0; 329 } 330 331 static int efs_statfs(struct dentry *dentry, struct kstatfs *buf) { 332 struct super_block *sb = dentry->d_sb; 333 struct efs_sb_info *sbi = SUPER_INFO(sb); 334 u64 id = huge_encode_dev(sb->s_bdev->bd_dev); 335 336 buf->f_type = EFS_SUPER_MAGIC; /* efs magic number */ 337 buf->f_bsize = EFS_BLOCKSIZE; /* blocksize */ 338 buf->f_blocks = sbi->total_groups * /* total data blocks */ 339 (sbi->group_size - sbi->inode_blocks); 340 buf->f_bfree = sbi->data_free; /* free data blocks */ 341 buf->f_bavail = sbi->data_free; /* free blocks for non-root */ 342 buf->f_files = sbi->total_groups * /* total inodes */ 343 sbi->inode_blocks * 344 (EFS_BLOCKSIZE / sizeof(struct efs_dinode)); 345 buf->f_ffree = sbi->inode_free; /* free inodes */ 346 buf->f_fsid = u64_to_fsid(id); 347 buf->f_namelen = EFS_MAXNAMELEN; /* max filename length */ 348 349 return 0; 350 } 351 352