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