1 /* 2 * Copyright (C) International Business Machines Corp., 2000-2004 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 12 * the GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 */ 18 19 /* 20 * Module: jfs_mount.c 21 * 22 * note: file system in transition to aggregate/fileset: 23 * 24 * file system mount is interpreted as the mount of aggregate, 25 * if not already mounted, and mount of the single/only fileset in 26 * the aggregate; 27 * 28 * a file system/aggregate is represented by an internal inode 29 * (aka mount inode) initialized with aggregate superblock; 30 * each vfs represents a fileset, and points to its "fileset inode 31 * allocation map inode" (aka fileset inode): 32 * (an aggregate itself is structured recursively as a filset: 33 * an internal vfs is constructed and points to its "fileset inode 34 * allocation map inode" (aka aggregate inode) where each inode 35 * represents a fileset inode) so that inode number is mapped to 36 * on-disk inode in uniform way at both aggregate and fileset level; 37 * 38 * each vnode/inode of a fileset is linked to its vfs (to facilitate 39 * per fileset inode operations, e.g., unmount of a fileset, etc.); 40 * each inode points to the mount inode (to facilitate access to 41 * per aggregate information, e.g., block size, etc.) as well as 42 * its file set inode. 43 * 44 * aggregate 45 * ipmnt 46 * mntvfs -> fileset ipimap+ -> aggregate ipbmap -> aggregate ipaimap; 47 * fileset vfs -> vp(1) <-> ... <-> vp(n) <->vproot; 48 */ 49 50 #include <linux/fs.h> 51 #include <linux/buffer_head.h> 52 53 #include "jfs_incore.h" 54 #include "jfs_filsys.h" 55 #include "jfs_superblock.h" 56 #include "jfs_dmap.h" 57 #include "jfs_imap.h" 58 #include "jfs_metapage.h" 59 #include "jfs_debug.h" 60 61 62 /* 63 * forward references 64 */ 65 static int chkSuper(struct super_block *); 66 static int logMOUNT(struct super_block *sb); 67 68 /* 69 * NAME: jfs_mount(sb) 70 * 71 * FUNCTION: vfs_mount() 72 * 73 * PARAMETER: sb - super block 74 * 75 * RETURN: -EBUSY - device already mounted or open for write 76 * -EBUSY - cvrdvp already mounted; 77 * -EBUSY - mount table full 78 * -ENOTDIR- cvrdvp not directory on a device mount 79 * -ENXIO - device open failure 80 */ 81 int jfs_mount(struct super_block *sb) 82 { 83 int rc = 0; /* Return code */ 84 struct jfs_sb_info *sbi = JFS_SBI(sb); 85 struct inode *ipaimap = NULL; 86 struct inode *ipaimap2 = NULL; 87 struct inode *ipimap = NULL; 88 struct inode *ipbmap = NULL; 89 90 /* 91 * read/validate superblock 92 * (initialize mount inode from the superblock) 93 */ 94 if ((rc = chkSuper(sb))) { 95 goto errout20; 96 } 97 98 ipaimap = diReadSpecial(sb, AGGREGATE_I, 0); 99 if (ipaimap == NULL) { 100 jfs_err("jfs_mount: Faild to read AGGREGATE_I"); 101 rc = -EIO; 102 goto errout20; 103 } 104 sbi->ipaimap = ipaimap; 105 106 jfs_info("jfs_mount: ipaimap:0x%p", ipaimap); 107 108 /* 109 * initialize aggregate inode allocation map 110 */ 111 if ((rc = diMount(ipaimap))) { 112 jfs_err("jfs_mount: diMount(ipaimap) failed w/rc = %d", rc); 113 goto errout21; 114 } 115 116 /* 117 * open aggregate block allocation map 118 */ 119 ipbmap = diReadSpecial(sb, BMAP_I, 0); 120 if (ipbmap == NULL) { 121 rc = -EIO; 122 goto errout22; 123 } 124 125 jfs_info("jfs_mount: ipbmap:0x%p", ipbmap); 126 127 sbi->ipbmap = ipbmap; 128 129 /* 130 * initialize aggregate block allocation map 131 */ 132 if ((rc = dbMount(ipbmap))) { 133 jfs_err("jfs_mount: dbMount failed w/rc = %d", rc); 134 goto errout22; 135 } 136 137 /* 138 * open the secondary aggregate inode allocation map 139 * 140 * This is a duplicate of the aggregate inode allocation map. 141 * 142 * hand craft a vfs in the same fashion as we did to read ipaimap. 143 * By adding INOSPEREXT (32) to the inode number, we are telling 144 * diReadSpecial that we are reading from the secondary aggregate 145 * inode table. This also creates a unique entry in the inode hash 146 * table. 147 */ 148 if ((sbi->mntflag & JFS_BAD_SAIT) == 0) { 149 ipaimap2 = diReadSpecial(sb, AGGREGATE_I, 1); 150 if (ipaimap2 == 0) { 151 jfs_err("jfs_mount: Faild to read AGGREGATE_I"); 152 rc = -EIO; 153 goto errout35; 154 } 155 sbi->ipaimap2 = ipaimap2; 156 157 jfs_info("jfs_mount: ipaimap2:0x%p", ipaimap2); 158 159 /* 160 * initialize secondary aggregate inode allocation map 161 */ 162 if ((rc = diMount(ipaimap2))) { 163 jfs_err("jfs_mount: diMount(ipaimap2) failed, rc = %d", 164 rc); 165 goto errout35; 166 } 167 } else 168 /* Secondary aggregate inode table is not valid */ 169 sbi->ipaimap2 = NULL; 170 171 /* 172 * mount (the only/single) fileset 173 */ 174 /* 175 * open fileset inode allocation map (aka fileset inode) 176 */ 177 ipimap = diReadSpecial(sb, FILESYSTEM_I, 0); 178 if (ipimap == NULL) { 179 jfs_err("jfs_mount: Failed to read FILESYSTEM_I"); 180 /* open fileset secondary inode allocation map */ 181 rc = -EIO; 182 goto errout40; 183 } 184 jfs_info("jfs_mount: ipimap:0x%p", ipimap); 185 186 /* map further access of per fileset inodes by the fileset inode */ 187 sbi->ipimap = ipimap; 188 189 /* initialize fileset inode allocation map */ 190 if ((rc = diMount(ipimap))) { 191 jfs_err("jfs_mount: diMount failed w/rc = %d", rc); 192 goto errout41; 193 } 194 195 goto out; 196 197 /* 198 * unwind on error 199 */ 200 errout41: /* close fileset inode allocation map inode */ 201 diFreeSpecial(ipimap); 202 203 errout40: /* fileset closed */ 204 205 /* close secondary aggregate inode allocation map */ 206 if (ipaimap2) { 207 diUnmount(ipaimap2, 1); 208 diFreeSpecial(ipaimap2); 209 } 210 211 errout35: 212 213 /* close aggregate block allocation map */ 214 dbUnmount(ipbmap, 1); 215 diFreeSpecial(ipbmap); 216 217 errout22: /* close aggregate inode allocation map */ 218 219 diUnmount(ipaimap, 1); 220 221 errout21: /* close aggregate inodes */ 222 diFreeSpecial(ipaimap); 223 errout20: /* aggregate closed */ 224 225 out: 226 227 if (rc) 228 jfs_err("Mount JFS Failure: %d", rc); 229 230 return rc; 231 } 232 233 /* 234 * NAME: jfs_mount_rw(sb, remount) 235 * 236 * FUNCTION: Completes read-write mount, or remounts read-only volume 237 * as read-write 238 */ 239 int jfs_mount_rw(struct super_block *sb, int remount) 240 { 241 struct jfs_sb_info *sbi = JFS_SBI(sb); 242 int rc; 243 244 /* 245 * If we are re-mounting a previously read-only volume, we want to 246 * re-read the inode and block maps, since fsck.jfs may have updated 247 * them. 248 */ 249 if (remount) { 250 if (chkSuper(sb) || (sbi->state != FM_CLEAN)) 251 return -EINVAL; 252 253 truncate_inode_pages(sbi->ipimap->i_mapping, 0); 254 truncate_inode_pages(sbi->ipbmap->i_mapping, 0); 255 diUnmount(sbi->ipimap, 1); 256 if ((rc = diMount(sbi->ipimap))) { 257 jfs_err("jfs_mount_rw: diMount failed!"); 258 return rc; 259 } 260 261 dbUnmount(sbi->ipbmap, 1); 262 if ((rc = dbMount(sbi->ipbmap))) { 263 jfs_err("jfs_mount_rw: dbMount failed!"); 264 return rc; 265 } 266 } 267 268 /* 269 * open/initialize log 270 */ 271 if ((rc = lmLogOpen(sb))) 272 return rc; 273 274 /* 275 * update file system superblock; 276 */ 277 if ((rc = updateSuper(sb, FM_MOUNT))) { 278 jfs_err("jfs_mount: updateSuper failed w/rc = %d", rc); 279 lmLogClose(sb); 280 return rc; 281 } 282 283 /* 284 * write MOUNT log record of the file system 285 */ 286 logMOUNT(sb); 287 288 /* 289 * Set page cache allocation policy 290 */ 291 mapping_set_gfp_mask(sb->s_bdev->bd_inode->i_mapping, GFP_NOFS); 292 293 return rc; 294 } 295 296 /* 297 * chkSuper() 298 * 299 * validate the superblock of the file system to be mounted and 300 * get the file system parameters. 301 * 302 * returns 303 * 0 with fragsize set if check successful 304 * error code if not successful 305 */ 306 static int chkSuper(struct super_block *sb) 307 { 308 int rc = 0; 309 struct jfs_sb_info *sbi = JFS_SBI(sb); 310 struct jfs_superblock *j_sb; 311 struct buffer_head *bh; 312 int AIM_bytesize, AIT_bytesize; 313 int expected_AIM_bytesize, expected_AIT_bytesize; 314 s64 AIM_byte_addr, AIT_byte_addr, fsckwsp_addr; 315 s64 byte_addr_diff0, byte_addr_diff1; 316 s32 bsize; 317 318 if ((rc = readSuper(sb, &bh))) 319 return rc; 320 j_sb = (struct jfs_superblock *)bh->b_data; 321 322 /* 323 * validate superblock 324 */ 325 /* validate fs signature */ 326 if (strncmp(j_sb->s_magic, JFS_MAGIC, 4) || 327 le32_to_cpu(j_sb->s_version) > JFS_VERSION) { 328 rc = -EINVAL; 329 goto out; 330 } 331 332 bsize = le32_to_cpu(j_sb->s_bsize); 333 #ifdef _JFS_4K 334 if (bsize != PSIZE) { 335 jfs_err("Currently only 4K block size supported!"); 336 rc = -EINVAL; 337 goto out; 338 } 339 #endif /* _JFS_4K */ 340 341 jfs_info("superblock: flag:0x%08x state:0x%08x size:0x%Lx", 342 le32_to_cpu(j_sb->s_flag), le32_to_cpu(j_sb->s_state), 343 (unsigned long long) le64_to_cpu(j_sb->s_size)); 344 345 /* validate the descriptors for Secondary AIM and AIT */ 346 if ((j_sb->s_flag & cpu_to_le32(JFS_BAD_SAIT)) != 347 cpu_to_le32(JFS_BAD_SAIT)) { 348 expected_AIM_bytesize = 2 * PSIZE; 349 AIM_bytesize = lengthPXD(&(j_sb->s_aim2)) * bsize; 350 expected_AIT_bytesize = 4 * PSIZE; 351 AIT_bytesize = lengthPXD(&(j_sb->s_ait2)) * bsize; 352 AIM_byte_addr = addressPXD(&(j_sb->s_aim2)) * bsize; 353 AIT_byte_addr = addressPXD(&(j_sb->s_ait2)) * bsize; 354 byte_addr_diff0 = AIT_byte_addr - AIM_byte_addr; 355 fsckwsp_addr = addressPXD(&(j_sb->s_fsckpxd)) * bsize; 356 byte_addr_diff1 = fsckwsp_addr - AIT_byte_addr; 357 if ((AIM_bytesize != expected_AIM_bytesize) || 358 (AIT_bytesize != expected_AIT_bytesize) || 359 (byte_addr_diff0 != AIM_bytesize) || 360 (byte_addr_diff1 <= AIT_bytesize)) 361 j_sb->s_flag |= cpu_to_le32(JFS_BAD_SAIT); 362 } 363 364 if ((j_sb->s_flag & cpu_to_le32(JFS_GROUPCOMMIT)) != 365 cpu_to_le32(JFS_GROUPCOMMIT)) 366 j_sb->s_flag |= cpu_to_le32(JFS_GROUPCOMMIT); 367 368 /* validate fs state */ 369 if (j_sb->s_state != cpu_to_le32(FM_CLEAN) && 370 !(sb->s_flags & MS_RDONLY)) { 371 jfs_err("jfs_mount: Mount Failure: File System Dirty."); 372 rc = -EINVAL; 373 goto out; 374 } 375 376 sbi->state = le32_to_cpu(j_sb->s_state); 377 sbi->mntflag = le32_to_cpu(j_sb->s_flag); 378 379 /* 380 * JFS always does I/O by 4K pages. Don't tell the buffer cache 381 * that we use anything else (leave s_blocksize alone). 382 */ 383 sbi->bsize = bsize; 384 sbi->l2bsize = le16_to_cpu(j_sb->s_l2bsize); 385 386 /* 387 * For now, ignore s_pbsize, l2bfactor. All I/O going through buffer 388 * cache. 389 */ 390 sbi->nbperpage = PSIZE >> sbi->l2bsize; 391 sbi->l2nbperpage = L2PSIZE - sbi->l2bsize; 392 sbi->l2niperblk = sbi->l2bsize - L2DISIZE; 393 if (sbi->mntflag & JFS_INLINELOG) 394 sbi->logpxd = j_sb->s_logpxd; 395 else { 396 sbi->logdev = new_decode_dev(le32_to_cpu(j_sb->s_logdev)); 397 memcpy(sbi->uuid, j_sb->s_uuid, sizeof(sbi->uuid)); 398 memcpy(sbi->loguuid, j_sb->s_loguuid, sizeof(sbi->uuid)); 399 } 400 sbi->fsckpxd = j_sb->s_fsckpxd; 401 sbi->ait2 = j_sb->s_ait2; 402 403 out: 404 brelse(bh); 405 return rc; 406 } 407 408 409 /* 410 * updateSuper() 411 * 412 * update synchronously superblock if it is mounted read-write. 413 */ 414 int updateSuper(struct super_block *sb, uint state) 415 { 416 struct jfs_superblock *j_sb; 417 struct jfs_sb_info *sbi = JFS_SBI(sb); 418 struct buffer_head *bh; 419 int rc; 420 421 if (sbi->flag & JFS_NOINTEGRITY) { 422 if (state == FM_DIRTY) { 423 sbi->p_state = state; 424 return 0; 425 } else if (state == FM_MOUNT) { 426 sbi->p_state = sbi->state; 427 state = FM_DIRTY; 428 } else if (state == FM_CLEAN) { 429 state = sbi->p_state; 430 } else 431 jfs_err("updateSuper: bad state"); 432 } else if (sbi->state == FM_DIRTY) 433 return 0; 434 435 if ((rc = readSuper(sb, &bh))) 436 return rc; 437 438 j_sb = (struct jfs_superblock *)bh->b_data; 439 440 j_sb->s_state = cpu_to_le32(state); 441 sbi->state = state; 442 443 if (state == FM_MOUNT) { 444 /* record log's dev_t and mount serial number */ 445 j_sb->s_logdev = cpu_to_le32(new_encode_dev(sbi->log->bdev->bd_dev)); 446 j_sb->s_logserial = cpu_to_le32(sbi->log->serial); 447 } else if (state == FM_CLEAN) { 448 /* 449 * If this volume is shared with OS/2, OS/2 will need to 450 * recalculate DASD usage, since we don't deal with it. 451 */ 452 if (j_sb->s_flag & cpu_to_le32(JFS_DASD_ENABLED)) 453 j_sb->s_flag |= cpu_to_le32(JFS_DASD_PRIME); 454 } 455 456 mark_buffer_dirty(bh); 457 sync_dirty_buffer(bh); 458 brelse(bh); 459 460 return 0; 461 } 462 463 464 /* 465 * readSuper() 466 * 467 * read superblock by raw sector address 468 */ 469 int readSuper(struct super_block *sb, struct buffer_head **bpp) 470 { 471 /* read in primary superblock */ 472 *bpp = sb_bread(sb, SUPER1_OFF >> sb->s_blocksize_bits); 473 if (*bpp) 474 return 0; 475 476 /* read in secondary/replicated superblock */ 477 *bpp = sb_bread(sb, SUPER2_OFF >> sb->s_blocksize_bits); 478 if (*bpp) 479 return 0; 480 481 return -EIO; 482 } 483 484 485 /* 486 * logMOUNT() 487 * 488 * function: write a MOUNT log record for file system. 489 * 490 * MOUNT record keeps logredo() from processing log records 491 * for this file system past this point in log. 492 * it is harmless if mount fails. 493 * 494 * note: MOUNT record is at aggregate level, not at fileset level, 495 * since log records of previous mounts of a fileset 496 * (e.g., AFTER record of extent allocation) have to be processed 497 * to update block allocation map at aggregate level. 498 */ 499 static int logMOUNT(struct super_block *sb) 500 { 501 struct jfs_log *log = JFS_SBI(sb)->log; 502 struct lrd lrd; 503 504 lrd.logtid = 0; 505 lrd.backchain = 0; 506 lrd.type = cpu_to_le16(LOG_MOUNT); 507 lrd.length = 0; 508 lrd.aggregate = cpu_to_le32(new_encode_dev(sb->s_bdev->bd_dev)); 509 lmLog(log, NULL, &lrd, NULL); 510 511 return 0; 512 } 513