1*1da177e4SLinus Torvalds /* 2*1da177e4SLinus Torvalds * super.c 3*1da177e4SLinus Torvalds * 4*1da177e4SLinus Torvalds * Copyright (C) 2001-2002 Will Dyson <will_dyson@pobox.com> 5*1da177e4SLinus Torvalds * 6*1da177e4SLinus Torvalds * Licensed under the GNU GPL. See the file COPYING for details. 7*1da177e4SLinus Torvalds * 8*1da177e4SLinus Torvalds */ 9*1da177e4SLinus Torvalds 10*1da177e4SLinus Torvalds #include <linux/fs.h> 11*1da177e4SLinus Torvalds 12*1da177e4SLinus Torvalds #include "befs.h" 13*1da177e4SLinus Torvalds #include "super.h" 14*1da177e4SLinus Torvalds #include "endian.h" 15*1da177e4SLinus Torvalds 16*1da177e4SLinus Torvalds /** 17*1da177e4SLinus Torvalds * load_befs_sb -- Read from disk and properly byteswap all the fields 18*1da177e4SLinus Torvalds * of the befs superblock 19*1da177e4SLinus Torvalds * 20*1da177e4SLinus Torvalds * 21*1da177e4SLinus Torvalds * 22*1da177e4SLinus Torvalds * 23*1da177e4SLinus Torvalds */ 24*1da177e4SLinus Torvalds int 25*1da177e4SLinus Torvalds befs_load_sb(struct super_block *sb, befs_super_block * disk_sb) 26*1da177e4SLinus Torvalds { 27*1da177e4SLinus Torvalds befs_sb_info *befs_sb = BEFS_SB(sb); 28*1da177e4SLinus Torvalds 29*1da177e4SLinus Torvalds /* Check the byte order of the filesystem */ 30*1da177e4SLinus Torvalds if (le32_to_cpu(disk_sb->fs_byte_order) == BEFS_BYTEORDER_NATIVE) 31*1da177e4SLinus Torvalds befs_sb->byte_order = BEFS_BYTESEX_LE; 32*1da177e4SLinus Torvalds else if (be32_to_cpu(disk_sb->fs_byte_order) == BEFS_BYTEORDER_NATIVE) 33*1da177e4SLinus Torvalds befs_sb->byte_order = BEFS_BYTESEX_BE; 34*1da177e4SLinus Torvalds 35*1da177e4SLinus Torvalds befs_sb->magic1 = fs32_to_cpu(sb, disk_sb->magic1); 36*1da177e4SLinus Torvalds befs_sb->magic2 = fs32_to_cpu(sb, disk_sb->magic2); 37*1da177e4SLinus Torvalds befs_sb->magic3 = fs32_to_cpu(sb, disk_sb->magic3); 38*1da177e4SLinus Torvalds befs_sb->block_size = fs32_to_cpu(sb, disk_sb->block_size); 39*1da177e4SLinus Torvalds befs_sb->block_shift = fs32_to_cpu(sb, disk_sb->block_shift); 40*1da177e4SLinus Torvalds befs_sb->num_blocks = fs64_to_cpu(sb, disk_sb->num_blocks); 41*1da177e4SLinus Torvalds befs_sb->used_blocks = fs64_to_cpu(sb, disk_sb->used_blocks); 42*1da177e4SLinus Torvalds befs_sb->inode_size = fs32_to_cpu(sb, disk_sb->inode_size); 43*1da177e4SLinus Torvalds 44*1da177e4SLinus Torvalds befs_sb->blocks_per_ag = fs32_to_cpu(sb, disk_sb->blocks_per_ag); 45*1da177e4SLinus Torvalds befs_sb->ag_shift = fs32_to_cpu(sb, disk_sb->ag_shift); 46*1da177e4SLinus Torvalds befs_sb->num_ags = fs32_to_cpu(sb, disk_sb->num_ags); 47*1da177e4SLinus Torvalds 48*1da177e4SLinus Torvalds befs_sb->log_blocks = fsrun_to_cpu(sb, disk_sb->log_blocks); 49*1da177e4SLinus Torvalds befs_sb->log_start = fs64_to_cpu(sb, disk_sb->log_start); 50*1da177e4SLinus Torvalds befs_sb->log_end = fs64_to_cpu(sb, disk_sb->log_end); 51*1da177e4SLinus Torvalds 52*1da177e4SLinus Torvalds befs_sb->root_dir = fsrun_to_cpu(sb, disk_sb->root_dir); 53*1da177e4SLinus Torvalds befs_sb->indices = fsrun_to_cpu(sb, disk_sb->indices); 54*1da177e4SLinus Torvalds befs_sb->nls = NULL; 55*1da177e4SLinus Torvalds 56*1da177e4SLinus Torvalds return BEFS_OK; 57*1da177e4SLinus Torvalds } 58*1da177e4SLinus Torvalds 59*1da177e4SLinus Torvalds int 60*1da177e4SLinus Torvalds befs_check_sb(struct super_block *sb) 61*1da177e4SLinus Torvalds { 62*1da177e4SLinus Torvalds befs_sb_info *befs_sb = BEFS_SB(sb); 63*1da177e4SLinus Torvalds 64*1da177e4SLinus Torvalds /* Check magic headers of super block */ 65*1da177e4SLinus Torvalds if ((befs_sb->magic1 != BEFS_SUPER_MAGIC1) 66*1da177e4SLinus Torvalds || (befs_sb->magic2 != BEFS_SUPER_MAGIC2) 67*1da177e4SLinus Torvalds || (befs_sb->magic3 != BEFS_SUPER_MAGIC3)) { 68*1da177e4SLinus Torvalds befs_error(sb, "invalid magic header"); 69*1da177e4SLinus Torvalds return BEFS_ERR; 70*1da177e4SLinus Torvalds } 71*1da177e4SLinus Torvalds 72*1da177e4SLinus Torvalds /* 73*1da177e4SLinus Torvalds * Check blocksize of BEFS. 74*1da177e4SLinus Torvalds * 75*1da177e4SLinus Torvalds * Blocksize of BEFS is 1024, 2048, 4096 or 8192. 76*1da177e4SLinus Torvalds */ 77*1da177e4SLinus Torvalds 78*1da177e4SLinus Torvalds if ((befs_sb->block_size != 1024) 79*1da177e4SLinus Torvalds && (befs_sb->block_size != 2048) 80*1da177e4SLinus Torvalds && (befs_sb->block_size != 4096) 81*1da177e4SLinus Torvalds && (befs_sb->block_size != 8192)) { 82*1da177e4SLinus Torvalds befs_error(sb, "invalid blocksize: %u", befs_sb->block_size); 83*1da177e4SLinus Torvalds return BEFS_ERR; 84*1da177e4SLinus Torvalds } 85*1da177e4SLinus Torvalds 86*1da177e4SLinus Torvalds if (befs_sb->block_size > PAGE_SIZE) { 87*1da177e4SLinus Torvalds befs_error(sb, "blocksize(%u) cannot be larger" 88*1da177e4SLinus Torvalds "than system pagesize(%lu)", befs_sb->block_size, 89*1da177e4SLinus Torvalds PAGE_SIZE); 90*1da177e4SLinus Torvalds return BEFS_ERR; 91*1da177e4SLinus Torvalds } 92*1da177e4SLinus Torvalds 93*1da177e4SLinus Torvalds /* 94*1da177e4SLinus Torvalds * block_shift and block_size encode the same information 95*1da177e4SLinus Torvalds * in different ways as a consistency check. 96*1da177e4SLinus Torvalds */ 97*1da177e4SLinus Torvalds 98*1da177e4SLinus Torvalds if ((1 << befs_sb->block_shift) != befs_sb->block_size) { 99*1da177e4SLinus Torvalds befs_error(sb, "block_shift disagrees with block_size. " 100*1da177e4SLinus Torvalds "Corruption likely."); 101*1da177e4SLinus Torvalds return BEFS_ERR; 102*1da177e4SLinus Torvalds } 103*1da177e4SLinus Torvalds 104*1da177e4SLinus Torvalds if (befs_sb->log_start != befs_sb->log_end) { 105*1da177e4SLinus Torvalds befs_error(sb, "Filesystem not clean! There are blocks in the " 106*1da177e4SLinus Torvalds "journal. You must boot into BeOS and mount this volume " 107*1da177e4SLinus Torvalds "to make it clean."); 108*1da177e4SLinus Torvalds return BEFS_ERR; 109*1da177e4SLinus Torvalds } 110*1da177e4SLinus Torvalds 111*1da177e4SLinus Torvalds return BEFS_OK; 112*1da177e4SLinus Torvalds } 113