xfs: prevent lockdep false positive in xfs_iget_cache_miss
[safe/jmp/linux-2.6] / fs / xfs / xfs_mount.c
index 177976d..3530025 100644 (file)
@@ -45,7 +45,6 @@
 #include "xfs_fsops.h"
 #include "xfs_utils.h"
 
-STATIC int     xfs_mount_log_sb(xfs_mount_t *, __int64_t);
 STATIC int     xfs_uuid_mount(xfs_mount_t *);
 STATIC void    xfs_unmountfs_wait(xfs_mount_t *);
 
@@ -575,8 +574,7 @@ xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
        mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
        mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1;
        mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
-       mp->m_litino = sbp->sb_inodesize -
-               ((uint)sizeof(xfs_dinode_core_t) + (uint)sizeof(xfs_agino_t));
+       mp->m_litino = sbp->sb_inodesize - sizeof(struct xfs_dinode);
        mp->m_blockmask = sbp->sb_blocksize - 1;
        mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
        mp->m_blockwmask = mp->m_blockwsize - 1;
@@ -683,7 +681,7 @@ xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount)
  * Update alignment values based on mount options and sb values
  */
 STATIC int
-xfs_update_alignment(xfs_mount_t *mp, __uint64_t *update_flags)
+xfs_update_alignment(xfs_mount_t *mp)
 {
        xfs_sb_t        *sbp = &(mp->m_sb);
 
@@ -737,11 +735,11 @@ xfs_update_alignment(xfs_mount_t *mp, __uint64_t *update_flags)
                if (xfs_sb_version_hasdalign(sbp)) {
                        if (sbp->sb_unit != mp->m_dalign) {
                                sbp->sb_unit = mp->m_dalign;
-                               *update_flags |= XFS_SB_UNIT;
+                               mp->m_update_flags |= XFS_SB_UNIT;
                        }
                        if (sbp->sb_width != mp->m_swidth) {
                                sbp->sb_width = mp->m_swidth;
-                               *update_flags |= XFS_SB_WIDTH;
+                               mp->m_update_flags |= XFS_SB_WIDTH;
                        }
                }
        } else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN &&
@@ -906,7 +904,6 @@ xfs_mountfs(
        xfs_sb_t        *sbp = &(mp->m_sb);
        xfs_inode_t     *rip;
        __uint64_t      resblks;
-       __int64_t       update_flags = 0LL;
        uint            quotamount, quotaflags;
        int             uuid_mounted = 0;
        int             error = 0;
@@ -934,7 +931,7 @@ xfs_mountfs(
                        "XFS: correcting sb_features alignment problem");
                sbp->sb_features2 |= sbp->sb_bad_features2;
                sbp->sb_bad_features2 = sbp->sb_features2;
-               update_flags |= XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2;
+               mp->m_update_flags |= XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2;
 
                /*
                 * Re-check for ATTR2 in case it was found in bad_features2
@@ -948,11 +945,11 @@ xfs_mountfs(
        if (xfs_sb_version_hasattr2(&mp->m_sb) &&
           (mp->m_flags & XFS_MOUNT_NOATTR2)) {
                xfs_sb_version_removeattr2(&mp->m_sb);
-               update_flags |= XFS_SB_FEATURES2;
+               mp->m_update_flags |= XFS_SB_FEATURES2;
 
                /* update sb_versionnum for the clearing of the morebits */
                if (!sbp->sb_features2)
-                       update_flags |= XFS_SB_VERSIONNUM;
+                       mp->m_update_flags |= XFS_SB_VERSIONNUM;
        }
 
        /*
@@ -961,7 +958,7 @@ xfs_mountfs(
         * allocator alignment is within an ag, therefore ag has
         * to be aligned at stripe boundary.
         */
-       error = xfs_update_alignment(mp, &update_flags);
+       error = xfs_update_alignment(mp);
        if (error)
                goto error1;
 
@@ -1138,10 +1135,12 @@ xfs_mountfs(
        }
 
        /*
-        * If fs is not mounted readonly, then update the superblock changes.
+        * If this is a read-only mount defer the superblock updates until
+        * the next remount into writeable mode.  Otherwise we would never
+        * perform the update e.g. for the root filesystem.
         */
-       if (update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) {
-               error = xfs_mount_log_sb(mp, update_flags);
+       if (mp->m_update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) {
+               error = xfs_mount_log_sb(mp, mp->m_update_flags);
                if (error) {
                        cmn_err(CE_WARN, "XFS: failed to write sb changes");
                        goto error4;
@@ -1221,6 +1220,16 @@ xfs_unmountfs(
        __uint64_t              resblks;
        int                     error;
 
+       /*
+        * Release dquot that rootinode, rbmino and rsumino might be holding,
+        * and release the quota inodes.
+        */
+       XFS_QM_UNMOUNT(mp);
+
+       if (mp->m_rbmip)
+               IRELE(mp->m_rbmip);
+       if (mp->m_rsumip)
+               IRELE(mp->m_rsumip);
        IRELE(mp->m_rootip);
 
        /*
@@ -1353,24 +1362,6 @@ xfs_log_sbcount(
        return error;
 }
 
-STATIC void
-xfs_mark_shared_ro(
-       xfs_mount_t     *mp,
-       xfs_buf_t       *bp)
-{
-       xfs_dsb_t       *sb = XFS_BUF_TO_SBP(bp);
-       __uint16_t      version;
-
-       if (!(sb->sb_flags & XFS_SBF_READONLY))
-               sb->sb_flags |= XFS_SBF_READONLY;
-
-       version = be16_to_cpu(sb->sb_versionnum);
-       if ((version & XFS_SB_VERSION_NUMBITS) != XFS_SB_VERSION_4 ||
-           !(version & XFS_SB_VERSION_SHAREDBIT))
-               version |= XFS_SB_VERSION_SHAREDBIT;
-       sb->sb_versionnum = cpu_to_be16(version);
-}
-
 int
 xfs_unmountfs_writesb(xfs_mount_t *mp)
 {
@@ -1386,12 +1377,6 @@ xfs_unmountfs_writesb(xfs_mount_t *mp)
 
                sbp = xfs_getsb(mp, 0);
 
-               /*
-                * mark shared-readonly if desired
-                */
-               if (mp->m_mk_sharedro)
-                       xfs_mark_shared_ro(mp, sbp);
-
                XFS_BUF_UNDONE(sbp);
                XFS_BUF_UNREAD(sbp);
                XFS_BUF_UNDELAYWRITE(sbp);
@@ -1403,8 +1388,6 @@ xfs_unmountfs_writesb(xfs_mount_t *mp)
                if (error)
                        xfs_ioerror_alert("xfs_unmountfs_writesb",
                                          mp, sbp, XFS_BUF_ADDR(sbp));
-               if (error && mp->m_mk_sharedro)
-                       xfs_fs_cmn_err(CE_ALERT, mp, "Superblock write error detected while unmounting.  Filesystem may not be marked shared readonly");
                xfs_buf_relse(sbp);
        }
        return error;
@@ -1837,7 +1820,7 @@ xfs_uuid_mount(
  * be altered by the mount options, as well as any potential sb_features2
  * fixup. Only the first superblock is updated.
  */
-STATIC int
+int
 xfs_mount_log_sb(
        xfs_mount_t     *mp,
        __int64_t       fields)