0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/buffer_head.h>
0014 #include <linux/slab.h>
0015 #include <linux/crc32.h>
0016 #include "qnx6.h"
0017
0018 static void qnx6_mmi_copy_sb(struct qnx6_super_block *qsb,
0019 struct qnx6_mmi_super_block *sb)
0020 {
0021 qsb->sb_magic = sb->sb_magic;
0022 qsb->sb_checksum = sb->sb_checksum;
0023 qsb->sb_serial = sb->sb_serial;
0024 qsb->sb_blocksize = sb->sb_blocksize;
0025 qsb->sb_num_inodes = sb->sb_num_inodes;
0026 qsb->sb_free_inodes = sb->sb_free_inodes;
0027 qsb->sb_num_blocks = sb->sb_num_blocks;
0028 qsb->sb_free_blocks = sb->sb_free_blocks;
0029
0030
0031 memcpy(&qsb->Inode, &sb->Inode, sizeof(sb->Inode));
0032 memcpy(&qsb->Bitmap, &sb->Bitmap, sizeof(sb->Bitmap));
0033 memcpy(&qsb->Longfile, &sb->Longfile, sizeof(sb->Longfile));
0034 }
0035
0036 struct qnx6_super_block *qnx6_mmi_fill_super(struct super_block *s, int silent)
0037 {
0038 struct buffer_head *bh1, *bh2 = NULL;
0039 struct qnx6_mmi_super_block *sb1, *sb2;
0040 struct qnx6_super_block *qsb = NULL;
0041 struct qnx6_sb_info *sbi;
0042 __u64 offset;
0043
0044
0045
0046 bh1 = sb_bread(s, 0);
0047 if (!bh1) {
0048 pr_err("Unable to read first mmi superblock\n");
0049 return NULL;
0050 }
0051 sb1 = (struct qnx6_mmi_super_block *)bh1->b_data;
0052 sbi = QNX6_SB(s);
0053 if (fs32_to_cpu(sbi, sb1->sb_magic) != QNX6_SUPER_MAGIC) {
0054 if (!silent) {
0055 pr_err("wrong signature (magic) in superblock #1.\n");
0056 goto out;
0057 }
0058 }
0059
0060
0061 if (fs32_to_cpu(sbi, sb1->sb_checksum) !=
0062 crc32_be(0, (char *)(bh1->b_data + 8), 504)) {
0063 pr_err("superblock #1 checksum error\n");
0064 goto out;
0065 }
0066
0067
0068 offset = fs32_to_cpu(sbi, sb1->sb_num_blocks) + QNX6_SUPERBLOCK_AREA /
0069 fs32_to_cpu(sbi, sb1->sb_blocksize);
0070
0071
0072 if (!sb_set_blocksize(s, fs32_to_cpu(sbi, sb1->sb_blocksize))) {
0073 pr_err("unable to set blocksize\n");
0074 goto out;
0075 }
0076
0077 brelse(bh1);
0078 bh1 = sb_bread(s, 0);
0079 if (!bh1)
0080 goto out;
0081 sb1 = (struct qnx6_mmi_super_block *)bh1->b_data;
0082
0083
0084 bh2 = sb_bread(s, offset);
0085 if (!bh2) {
0086 pr_err("unable to read the second superblock\n");
0087 goto out;
0088 }
0089 sb2 = (struct qnx6_mmi_super_block *)bh2->b_data;
0090 if (fs32_to_cpu(sbi, sb2->sb_magic) != QNX6_SUPER_MAGIC) {
0091 if (!silent)
0092 pr_err("wrong signature (magic) in superblock #2.\n");
0093 goto out;
0094 }
0095
0096
0097 if (fs32_to_cpu(sbi, sb2->sb_checksum)
0098 != crc32_be(0, (char *)(bh2->b_data + 8), 504)) {
0099 pr_err("superblock #1 checksum error\n");
0100 goto out;
0101 }
0102
0103 qsb = kmalloc(sizeof(*qsb), GFP_KERNEL);
0104 if (!qsb) {
0105 pr_err("unable to allocate memory.\n");
0106 goto out;
0107 }
0108
0109 if (fs64_to_cpu(sbi, sb1->sb_serial) >
0110 fs64_to_cpu(sbi, sb2->sb_serial)) {
0111
0112 qnx6_mmi_copy_sb(qsb, sb1);
0113 #ifdef CONFIG_QNX6FS_DEBUG
0114 qnx6_superblock_debug(qsb, s);
0115 #endif
0116 memcpy(bh1->b_data, qsb, sizeof(struct qnx6_super_block));
0117
0118 sbi->sb_buf = bh1;
0119 sbi->sb = (struct qnx6_super_block *)bh1->b_data;
0120 brelse(bh2);
0121 pr_info("superblock #1 active\n");
0122 } else {
0123
0124 qnx6_mmi_copy_sb(qsb, sb2);
0125 #ifdef CONFIG_QNX6FS_DEBUG
0126 qnx6_superblock_debug(qsb, s);
0127 #endif
0128 memcpy(bh2->b_data, qsb, sizeof(struct qnx6_super_block));
0129
0130 sbi->sb_buf = bh2;
0131 sbi->sb = (struct qnx6_super_block *)bh2->b_data;
0132 brelse(bh1);
0133 pr_info("superblock #2 active\n");
0134 }
0135 kfree(qsb);
0136
0137
0138 sbi->s_blks_off = QNX6_SUPERBLOCK_AREA / s->s_blocksize;
0139
0140
0141 return sbi->sb;
0142
0143 out:
0144 if (bh1 != NULL)
0145 brelse(bh1);
0146 if (bh2 != NULL)
0147 brelse(bh2);
0148 return NULL;
0149 }