0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include <linux/fs.h>
0038 #include <linux/buffer_head.h>
0039 #include <linux/blkdev.h>
0040 #include <linux/log2.h>
0041
0042 #include "jfs_incore.h"
0043 #include "jfs_filsys.h"
0044 #include "jfs_superblock.h"
0045 #include "jfs_dmap.h"
0046 #include "jfs_imap.h"
0047 #include "jfs_metapage.h"
0048 #include "jfs_debug.h"
0049
0050
0051
0052
0053
0054 static int chkSuper(struct super_block *);
0055 static int logMOUNT(struct super_block *sb);
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 int jfs_mount(struct super_block *sb)
0071 {
0072 int rc = 0;
0073 struct jfs_sb_info *sbi = JFS_SBI(sb);
0074 struct inode *ipaimap = NULL;
0075 struct inode *ipaimap2 = NULL;
0076 struct inode *ipimap = NULL;
0077 struct inode *ipbmap = NULL;
0078
0079
0080
0081
0082
0083 if ((rc = chkSuper(sb))) {
0084 goto out;
0085 }
0086
0087 ipaimap = diReadSpecial(sb, AGGREGATE_I, 0);
0088 if (ipaimap == NULL) {
0089 jfs_err("jfs_mount: Failed to read AGGREGATE_I");
0090 rc = -EIO;
0091 goto out;
0092 }
0093 sbi->ipaimap = ipaimap;
0094
0095 jfs_info("jfs_mount: ipaimap:0x%p", ipaimap);
0096
0097
0098
0099
0100 if ((rc = diMount(ipaimap))) {
0101 jfs_err("jfs_mount: diMount(ipaimap) failed w/rc = %d", rc);
0102 goto err_ipaimap;
0103 }
0104
0105
0106
0107
0108 ipbmap = diReadSpecial(sb, BMAP_I, 0);
0109 if (ipbmap == NULL) {
0110 rc = -EIO;
0111 goto err_umount_ipaimap;
0112 }
0113
0114 jfs_info("jfs_mount: ipbmap:0x%p", ipbmap);
0115
0116 sbi->ipbmap = ipbmap;
0117
0118
0119
0120
0121 if ((rc = dbMount(ipbmap))) {
0122 jfs_err("jfs_mount: dbMount failed w/rc = %d", rc);
0123 goto err_ipbmap;
0124 }
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137 if ((sbi->mntflag & JFS_BAD_SAIT) == 0) {
0138 ipaimap2 = diReadSpecial(sb, AGGREGATE_I, 1);
0139 if (!ipaimap2) {
0140 jfs_err("jfs_mount: Failed to read AGGREGATE_I");
0141 rc = -EIO;
0142 goto err_umount_ipbmap;
0143 }
0144 sbi->ipaimap2 = ipaimap2;
0145
0146 jfs_info("jfs_mount: ipaimap2:0x%p", ipaimap2);
0147
0148
0149
0150
0151 if ((rc = diMount(ipaimap2))) {
0152 jfs_err("jfs_mount: diMount(ipaimap2) failed, rc = %d",
0153 rc);
0154 goto err_ipaimap2;
0155 }
0156 } else
0157
0158 sbi->ipaimap2 = NULL;
0159
0160
0161
0162
0163
0164
0165
0166 ipimap = diReadSpecial(sb, FILESYSTEM_I, 0);
0167 if (ipimap == NULL) {
0168 jfs_err("jfs_mount: Failed to read FILESYSTEM_I");
0169
0170 rc = -EIO;
0171 goto err_umount_ipaimap2;
0172 }
0173 jfs_info("jfs_mount: ipimap:0x%p", ipimap);
0174
0175
0176 sbi->ipimap = ipimap;
0177
0178
0179 if ((rc = diMount(ipimap))) {
0180 jfs_err("jfs_mount: diMount failed w/rc = %d", rc);
0181 goto err_ipimap;
0182 }
0183
0184 return rc;
0185
0186
0187
0188
0189 err_ipimap:
0190
0191 diFreeSpecial(ipimap);
0192 err_umount_ipaimap2:
0193
0194 if (ipaimap2)
0195 diUnmount(ipaimap2, 1);
0196 err_ipaimap2:
0197
0198 if (ipaimap2)
0199 diFreeSpecial(ipaimap2);
0200 err_umount_ipbmap:
0201 dbUnmount(ipbmap, 1);
0202 err_ipbmap:
0203 diFreeSpecial(ipbmap);
0204 err_umount_ipaimap:
0205 diUnmount(ipaimap, 1);
0206 err_ipaimap:
0207 diFreeSpecial(ipaimap);
0208 out:
0209 if (rc)
0210 jfs_err("Mount JFS Failure: %d", rc);
0211
0212 return rc;
0213 }
0214
0215
0216
0217
0218
0219
0220
0221 int jfs_mount_rw(struct super_block *sb, int remount)
0222 {
0223 struct jfs_sb_info *sbi = JFS_SBI(sb);
0224 int rc;
0225
0226
0227
0228
0229
0230
0231 if (remount) {
0232 if (chkSuper(sb) || (sbi->state != FM_CLEAN))
0233 return -EINVAL;
0234
0235 truncate_inode_pages(sbi->ipimap->i_mapping, 0);
0236 truncate_inode_pages(sbi->ipbmap->i_mapping, 0);
0237 diUnmount(sbi->ipimap, 1);
0238 if ((rc = diMount(sbi->ipimap))) {
0239 jfs_err("jfs_mount_rw: diMount failed!");
0240 return rc;
0241 }
0242
0243 dbUnmount(sbi->ipbmap, 1);
0244 if ((rc = dbMount(sbi->ipbmap))) {
0245 jfs_err("jfs_mount_rw: dbMount failed!");
0246 return rc;
0247 }
0248 }
0249
0250
0251
0252
0253 if ((rc = lmLogOpen(sb)))
0254 return rc;
0255
0256
0257
0258
0259 if ((rc = updateSuper(sb, FM_MOUNT))) {
0260 jfs_err("jfs_mount: updateSuper failed w/rc = %d", rc);
0261 lmLogClose(sb);
0262 return rc;
0263 }
0264
0265
0266
0267
0268 logMOUNT(sb);
0269
0270 return rc;
0271 }
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283 static int chkSuper(struct super_block *sb)
0284 {
0285 int rc = 0;
0286 struct jfs_sb_info *sbi = JFS_SBI(sb);
0287 struct jfs_superblock *j_sb;
0288 struct buffer_head *bh;
0289 int AIM_bytesize, AIT_bytesize;
0290 int expected_AIM_bytesize, expected_AIT_bytesize;
0291 s64 AIM_byte_addr, AIT_byte_addr, fsckwsp_addr;
0292 s64 byte_addr_diff0, byte_addr_diff1;
0293 s32 bsize;
0294
0295 if ((rc = readSuper(sb, &bh)))
0296 return rc;
0297 j_sb = (struct jfs_superblock *)bh->b_data;
0298
0299
0300
0301
0302
0303 if (strncmp(j_sb->s_magic, JFS_MAGIC, 4) ||
0304 le32_to_cpu(j_sb->s_version) > JFS_VERSION) {
0305 rc = -EINVAL;
0306 goto out;
0307 }
0308
0309 bsize = le32_to_cpu(j_sb->s_bsize);
0310 if (bsize != PSIZE) {
0311 jfs_err("Only 4K block size supported!");
0312 rc = -EINVAL;
0313 goto out;
0314 }
0315
0316 jfs_info("superblock: flag:0x%08x state:0x%08x size:0x%Lx",
0317 le32_to_cpu(j_sb->s_flag), le32_to_cpu(j_sb->s_state),
0318 (unsigned long long) le64_to_cpu(j_sb->s_size));
0319
0320
0321 if ((j_sb->s_flag & cpu_to_le32(JFS_BAD_SAIT)) !=
0322 cpu_to_le32(JFS_BAD_SAIT)) {
0323 expected_AIM_bytesize = 2 * PSIZE;
0324 AIM_bytesize = lengthPXD(&(j_sb->s_aim2)) * bsize;
0325 expected_AIT_bytesize = 4 * PSIZE;
0326 AIT_bytesize = lengthPXD(&(j_sb->s_ait2)) * bsize;
0327 AIM_byte_addr = addressPXD(&(j_sb->s_aim2)) * bsize;
0328 AIT_byte_addr = addressPXD(&(j_sb->s_ait2)) * bsize;
0329 byte_addr_diff0 = AIT_byte_addr - AIM_byte_addr;
0330 fsckwsp_addr = addressPXD(&(j_sb->s_fsckpxd)) * bsize;
0331 byte_addr_diff1 = fsckwsp_addr - AIT_byte_addr;
0332 if ((AIM_bytesize != expected_AIM_bytesize) ||
0333 (AIT_bytesize != expected_AIT_bytesize) ||
0334 (byte_addr_diff0 != AIM_bytesize) ||
0335 (byte_addr_diff1 <= AIT_bytesize))
0336 j_sb->s_flag |= cpu_to_le32(JFS_BAD_SAIT);
0337 }
0338
0339 if ((j_sb->s_flag & cpu_to_le32(JFS_GROUPCOMMIT)) !=
0340 cpu_to_le32(JFS_GROUPCOMMIT))
0341 j_sb->s_flag |= cpu_to_le32(JFS_GROUPCOMMIT);
0342
0343
0344 if (j_sb->s_state != cpu_to_le32(FM_CLEAN) &&
0345 !sb_rdonly(sb)) {
0346 jfs_err("jfs_mount: Mount Failure: File System Dirty.");
0347 rc = -EINVAL;
0348 goto out;
0349 }
0350
0351 sbi->state = le32_to_cpu(j_sb->s_state);
0352 sbi->mntflag = le32_to_cpu(j_sb->s_flag);
0353
0354
0355
0356
0357
0358 sbi->bsize = bsize;
0359 sbi->l2bsize = le16_to_cpu(j_sb->s_l2bsize);
0360
0361
0362 if (sbi->l2bsize != ilog2((u32)bsize) ||
0363 j_sb->pad != 0 ||
0364 le32_to_cpu(j_sb->s_state) > FM_STATE_MAX) {
0365 rc = -EINVAL;
0366 jfs_err("jfs_mount: Mount Failure: superblock is corrupt!");
0367 goto out;
0368 }
0369
0370
0371
0372
0373
0374 sbi->nbperpage = PSIZE >> sbi->l2bsize;
0375 sbi->l2nbperpage = L2PSIZE - sbi->l2bsize;
0376 sbi->l2niperblk = sbi->l2bsize - L2DISIZE;
0377 if (sbi->mntflag & JFS_INLINELOG)
0378 sbi->logpxd = j_sb->s_logpxd;
0379 else {
0380 sbi->logdev = new_decode_dev(le32_to_cpu(j_sb->s_logdev));
0381 uuid_copy(&sbi->uuid, &j_sb->s_uuid);
0382 uuid_copy(&sbi->loguuid, &j_sb->s_loguuid);
0383 }
0384 sbi->fsckpxd = j_sb->s_fsckpxd;
0385 sbi->ait2 = j_sb->s_ait2;
0386
0387 out:
0388 brelse(bh);
0389 return rc;
0390 }
0391
0392
0393
0394
0395
0396
0397
0398 int updateSuper(struct super_block *sb, uint state)
0399 {
0400 struct jfs_superblock *j_sb;
0401 struct jfs_sb_info *sbi = JFS_SBI(sb);
0402 struct buffer_head *bh;
0403 int rc;
0404
0405 if (sbi->flag & JFS_NOINTEGRITY) {
0406 if (state == FM_DIRTY) {
0407 sbi->p_state = state;
0408 return 0;
0409 } else if (state == FM_MOUNT) {
0410 sbi->p_state = sbi->state;
0411 state = FM_DIRTY;
0412 } else if (state == FM_CLEAN) {
0413 state = sbi->p_state;
0414 } else
0415 jfs_err("updateSuper: bad state");
0416 } else if (sbi->state == FM_DIRTY)
0417 return 0;
0418
0419 if ((rc = readSuper(sb, &bh)))
0420 return rc;
0421
0422 j_sb = (struct jfs_superblock *)bh->b_data;
0423
0424 j_sb->s_state = cpu_to_le32(state);
0425 sbi->state = state;
0426
0427 if (state == FM_MOUNT) {
0428
0429 j_sb->s_logdev = cpu_to_le32(new_encode_dev(sbi->log->bdev->bd_dev));
0430 j_sb->s_logserial = cpu_to_le32(sbi->log->serial);
0431 } else if (state == FM_CLEAN) {
0432
0433
0434
0435
0436 if (j_sb->s_flag & cpu_to_le32(JFS_DASD_ENABLED))
0437 j_sb->s_flag |= cpu_to_le32(JFS_DASD_PRIME);
0438 }
0439
0440 mark_buffer_dirty(bh);
0441 sync_dirty_buffer(bh);
0442 brelse(bh);
0443
0444 return 0;
0445 }
0446
0447
0448
0449
0450
0451
0452
0453 int readSuper(struct super_block *sb, struct buffer_head **bpp)
0454 {
0455
0456 *bpp = sb_bread(sb, SUPER1_OFF >> sb->s_blocksize_bits);
0457 if (*bpp)
0458 return 0;
0459
0460
0461 *bpp = sb_bread(sb, SUPER2_OFF >> sb->s_blocksize_bits);
0462 if (*bpp)
0463 return 0;
0464
0465 return -EIO;
0466 }
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483 static int logMOUNT(struct super_block *sb)
0484 {
0485 struct jfs_log *log = JFS_SBI(sb)->log;
0486 struct lrd lrd;
0487
0488 lrd.logtid = 0;
0489 lrd.backchain = 0;
0490 lrd.type = cpu_to_le16(LOG_MOUNT);
0491 lrd.length = 0;
0492 lrd.aggregate = cpu_to_le32(new_encode_dev(sb->s_bdev->bd_dev));
0493 lmLog(log, NULL, &lrd, NULL);
0494
0495 return 0;
0496 }