Merge commit 'ccbf62d8a284cf181ac28c8e8407dd077d90dd4b' into for-next
[firefly-linux-kernel-4.4.55.git] / fs / xfs / xfs_mount.c
index 944f3d9456a8b4f6f0fe44721fe98f9f52c3bd69..3507cd0ec4004e37f65ec490e9fb4ea9e6e314f0 100644 (file)
@@ -323,8 +323,19 @@ reread:
        /*
         * Initialize the mount structure from the superblock.
         */
-       xfs_sb_from_disk(&mp->m_sb, XFS_BUF_TO_SBP(bp));
-       xfs_sb_quota_from_disk(&mp->m_sb);
+       xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(bp));
+       xfs_sb_quota_from_disk(sbp);
+
+       /*
+        * If we haven't validated the superblock, do so now before we try
+        * to check the sector size and reread the superblock appropriately.
+        */
+       if (sbp->sb_magicnum != XFS_SB_MAGIC) {
+               if (loud)
+                       xfs_warn(mp, "Invalid superblock magic number");
+               error = EINVAL;
+               goto release_buf;
+       }
 
        /*
         * We must be able to do sector-sized and sector-aligned IO.
@@ -337,11 +348,11 @@ reread:
                goto release_buf;
        }
 
-       /*
-        * Re-read the superblock so the buffer is correctly sized,
-        * and properly verified.
-        */
        if (buf_ops == NULL) {
+               /*
+                * Re-read the superblock so the buffer is correctly sized,
+                * and properly verified.
+                */
                xfs_buf_relse(bp);
                sector_size = sbp->sb_sectsize;
                buf_ops = loud ? &xfs_sb_buf_ops : &xfs_sb_quiet_buf_ops;
@@ -697,6 +708,12 @@ xfs_mountfs(
                        mp->m_update_flags |= XFS_SB_VERSIONNUM;
        }
 
+       /* always use v2 inodes by default now */
+       if (!(mp->m_sb.sb_versionnum & XFS_SB_VERSION_NLINKBIT)) {
+               mp->m_sb.sb_versionnum |= XFS_SB_VERSION_NLINKBIT;
+               mp->m_update_flags |= XFS_SB_VERSIONNUM;
+       }
+
        /*
         * Check if sb_agblocks is aligned at stripe boundary
         * If sb_agblocks is NOT aligned turn off m_dalign since
@@ -774,12 +791,11 @@ xfs_mountfs(
 
        mp->m_dmevmask = 0;     /* not persistent; set after each mount */
 
-       xfs_dir_mount(mp);
-
-       /*
-        * Initialize the attribute manager's entries.
-        */
-       mp->m_attr_magicpct = (mp->m_sb.sb_blocksize * 37) / 100;
+       error = xfs_da_mount(mp);
+       if (error) {
+               xfs_warn(mp, "Failed dir/attr init: %d", error);
+               goto out_remove_uuid;
+       }
 
        /*
         * Initialize the precomputed transaction reservations values.
@@ -794,7 +810,7 @@ xfs_mountfs(
        error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
        if (error) {
                xfs_warn(mp, "Failed per-ag init: %d", error);
-               goto out_remove_uuid;
+               goto out_free_dir;
        }
 
        if (!sbp->sb_logblocks) {
@@ -969,6 +985,8 @@ xfs_mountfs(
        xfs_wait_buftarg(mp->m_ddev_targp);
  out_free_perag:
        xfs_free_perag(mp);
+ out_free_dir:
+       xfs_da_unmount(mp);
  out_remove_uuid:
        xfs_uuid_unmount(mp);
  out:
@@ -1046,6 +1064,7 @@ xfs_unmountfs(
                                "Freespace may not be correct on next mount.");
 
        xfs_log_unmount(mp);
+       xfs_da_unmount(mp);
        xfs_uuid_unmount(mp);
 
 #if defined(DEBUG)