18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * super.c 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (C) 2001-2002 Will Dyson <will_dyson@pobox.com> 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Licensed under the GNU GPL. See the file COPYING for details. 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/fs.h> 118c2ecf20Sopenharmony_ci#include <asm/page.h> /* for PAGE_SIZE */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include "befs.h" 148c2ecf20Sopenharmony_ci#include "super.h" 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci/* 178c2ecf20Sopenharmony_ci * befs_load_sb -- Read from disk and properly byteswap all the fields 188c2ecf20Sopenharmony_ci * of the befs superblock 198c2ecf20Sopenharmony_ci */ 208c2ecf20Sopenharmony_ciint 218c2ecf20Sopenharmony_cibefs_load_sb(struct super_block *sb, befs_super_block *disk_sb) 228c2ecf20Sopenharmony_ci{ 238c2ecf20Sopenharmony_ci struct befs_sb_info *befs_sb = BEFS_SB(sb); 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci /* Check the byte order of the filesystem */ 268c2ecf20Sopenharmony_ci if (disk_sb->fs_byte_order == BEFS_BYTEORDER_NATIVE_LE) 278c2ecf20Sopenharmony_ci befs_sb->byte_order = BEFS_BYTESEX_LE; 288c2ecf20Sopenharmony_ci else if (disk_sb->fs_byte_order == BEFS_BYTEORDER_NATIVE_BE) 298c2ecf20Sopenharmony_ci befs_sb->byte_order = BEFS_BYTESEX_BE; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci befs_sb->magic1 = fs32_to_cpu(sb, disk_sb->magic1); 328c2ecf20Sopenharmony_ci befs_sb->magic2 = fs32_to_cpu(sb, disk_sb->magic2); 338c2ecf20Sopenharmony_ci befs_sb->magic3 = fs32_to_cpu(sb, disk_sb->magic3); 348c2ecf20Sopenharmony_ci befs_sb->block_size = fs32_to_cpu(sb, disk_sb->block_size); 358c2ecf20Sopenharmony_ci befs_sb->block_shift = fs32_to_cpu(sb, disk_sb->block_shift); 368c2ecf20Sopenharmony_ci befs_sb->num_blocks = fs64_to_cpu(sb, disk_sb->num_blocks); 378c2ecf20Sopenharmony_ci befs_sb->used_blocks = fs64_to_cpu(sb, disk_sb->used_blocks); 388c2ecf20Sopenharmony_ci befs_sb->inode_size = fs32_to_cpu(sb, disk_sb->inode_size); 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci befs_sb->blocks_per_ag = fs32_to_cpu(sb, disk_sb->blocks_per_ag); 418c2ecf20Sopenharmony_ci befs_sb->ag_shift = fs32_to_cpu(sb, disk_sb->ag_shift); 428c2ecf20Sopenharmony_ci befs_sb->num_ags = fs32_to_cpu(sb, disk_sb->num_ags); 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci befs_sb->flags = fs32_to_cpu(sb, disk_sb->flags); 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci befs_sb->log_blocks = fsrun_to_cpu(sb, disk_sb->log_blocks); 478c2ecf20Sopenharmony_ci befs_sb->log_start = fs64_to_cpu(sb, disk_sb->log_start); 488c2ecf20Sopenharmony_ci befs_sb->log_end = fs64_to_cpu(sb, disk_sb->log_end); 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci befs_sb->root_dir = fsrun_to_cpu(sb, disk_sb->root_dir); 518c2ecf20Sopenharmony_ci befs_sb->indices = fsrun_to_cpu(sb, disk_sb->indices); 528c2ecf20Sopenharmony_ci befs_sb->nls = NULL; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci return BEFS_OK; 558c2ecf20Sopenharmony_ci} 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ciint 588c2ecf20Sopenharmony_cibefs_check_sb(struct super_block *sb) 598c2ecf20Sopenharmony_ci{ 608c2ecf20Sopenharmony_ci struct befs_sb_info *befs_sb = BEFS_SB(sb); 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci /* Check magic headers of super block */ 638c2ecf20Sopenharmony_ci if ((befs_sb->magic1 != BEFS_SUPER_MAGIC1) 648c2ecf20Sopenharmony_ci || (befs_sb->magic2 != BEFS_SUPER_MAGIC2) 658c2ecf20Sopenharmony_ci || (befs_sb->magic3 != BEFS_SUPER_MAGIC3)) { 668c2ecf20Sopenharmony_ci befs_error(sb, "invalid magic header"); 678c2ecf20Sopenharmony_ci return BEFS_ERR; 688c2ecf20Sopenharmony_ci } 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci /* 718c2ecf20Sopenharmony_ci * Check blocksize of BEFS. 728c2ecf20Sopenharmony_ci * 738c2ecf20Sopenharmony_ci * Blocksize of BEFS is 1024, 2048, 4096 or 8192. 748c2ecf20Sopenharmony_ci */ 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci if ((befs_sb->block_size != 1024) 778c2ecf20Sopenharmony_ci && (befs_sb->block_size != 2048) 788c2ecf20Sopenharmony_ci && (befs_sb->block_size != 4096) 798c2ecf20Sopenharmony_ci && (befs_sb->block_size != 8192)) { 808c2ecf20Sopenharmony_ci befs_error(sb, "invalid blocksize: %u", befs_sb->block_size); 818c2ecf20Sopenharmony_ci return BEFS_ERR; 828c2ecf20Sopenharmony_ci } 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci if (befs_sb->block_size > PAGE_SIZE) { 858c2ecf20Sopenharmony_ci befs_error(sb, "blocksize(%u) cannot be larger " 868c2ecf20Sopenharmony_ci "than system pagesize(%lu)", befs_sb->block_size, 878c2ecf20Sopenharmony_ci PAGE_SIZE); 888c2ecf20Sopenharmony_ci return BEFS_ERR; 898c2ecf20Sopenharmony_ci } 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci /* 928c2ecf20Sopenharmony_ci * block_shift and block_size encode the same information 938c2ecf20Sopenharmony_ci * in different ways as a consistency check. 948c2ecf20Sopenharmony_ci */ 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci if ((1 << befs_sb->block_shift) != befs_sb->block_size) { 978c2ecf20Sopenharmony_ci befs_error(sb, "block_shift disagrees with block_size. " 988c2ecf20Sopenharmony_ci "Corruption likely."); 998c2ecf20Sopenharmony_ci return BEFS_ERR; 1008c2ecf20Sopenharmony_ci } 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci /* ag_shift also encodes the same information as blocks_per_ag in a 1048c2ecf20Sopenharmony_ci * different way, non-fatal consistency check 1058c2ecf20Sopenharmony_ci */ 1068c2ecf20Sopenharmony_ci if ((1 << befs_sb->ag_shift) != befs_sb->blocks_per_ag) 1078c2ecf20Sopenharmony_ci befs_error(sb, "ag_shift disagrees with blocks_per_ag."); 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci if (befs_sb->log_start != befs_sb->log_end || 1108c2ecf20Sopenharmony_ci befs_sb->flags == BEFS_DIRTY) { 1118c2ecf20Sopenharmony_ci befs_error(sb, "Filesystem not clean! There are blocks in the " 1128c2ecf20Sopenharmony_ci "journal. You must boot into BeOS and mount this " 1138c2ecf20Sopenharmony_ci "volume to make it clean."); 1148c2ecf20Sopenharmony_ci return BEFS_ERR; 1158c2ecf20Sopenharmony_ci } 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci return BEFS_OK; 1188c2ecf20Sopenharmony_ci} 119