root/fs/jfs/jfs_mount.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. jfs_mount
  2. jfs_mount_rw
  3. chkSuper
  4. updateSuper
  5. readSuper
  6. logMOUNT

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

/* [<][>][^][v][top][bottom][index][help] */