[XFS] Fix an infinite loop issue in bulkstat when a corrupt inode is
[safe/jmp/linux-2.6] / fs / xfs / xfs_log_recover.c
index f61dcd1..add13f5 100644 (file)
@@ -1,33 +1,19 @@
 /*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation.
  *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like.  Any license provided herein, whether implied or
- * otherwise, applies only to this software file.  Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA  94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 #include "xfs.h"
 #include "xfs_fs.h"
@@ -797,8 +783,7 @@ int
 xlog_find_tail(
        xlog_t                  *log,
        xfs_daddr_t             *head_blk,
-       xfs_daddr_t             *tail_blk,
-       int                     readonly)
+       xfs_daddr_t             *tail_blk)
 {
        xlog_rec_header_t       *rhead;
        xlog_op_header_t        *op_head;
@@ -2012,79 +1997,74 @@ xfs_qm_dqcheck(
         * This is all fine; things are still consistent, and we haven't lost
         * any quota information. Just don't complain about bad dquot blks.
         */
-       if (INT_GET(ddq->d_magic, ARCH_CONVERT) != XFS_DQUOT_MAGIC) {
+       if (be16_to_cpu(ddq->d_magic) != XFS_DQUOT_MAGIC) {
                if (flags & XFS_QMOPT_DOWARN)
                        cmn_err(CE_ALERT,
                        "%s : XFS dquot ID 0x%x, magic 0x%x != 0x%x",
-                       str, id,
-                       INT_GET(ddq->d_magic, ARCH_CONVERT), XFS_DQUOT_MAGIC);
+                       str, id, be16_to_cpu(ddq->d_magic), XFS_DQUOT_MAGIC);
                errs++;
        }
-       if (INT_GET(ddq->d_version, ARCH_CONVERT) != XFS_DQUOT_VERSION) {
+       if (ddq->d_version != XFS_DQUOT_VERSION) {
                if (flags & XFS_QMOPT_DOWARN)
                        cmn_err(CE_ALERT,
                        "%s : XFS dquot ID 0x%x, version 0x%x != 0x%x",
-                       str, id,
-                       INT_GET(ddq->d_magic, ARCH_CONVERT), XFS_DQUOT_VERSION);
+                       str, id, ddq->d_version, XFS_DQUOT_VERSION);
                errs++;
        }
 
-       if (INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_USER &&
-           INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_PROJ &&
-           INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_GROUP) {
+       if (ddq->d_flags != XFS_DQ_USER &&
+           ddq->d_flags != XFS_DQ_PROJ &&
+           ddq->d_flags != XFS_DQ_GROUP) {
                if (flags & XFS_QMOPT_DOWARN)
                        cmn_err(CE_ALERT,
                        "%s : XFS dquot ID 0x%x, unknown flags 0x%x",
-                       str, id, INT_GET(ddq->d_flags, ARCH_CONVERT));
+                       str, id, ddq->d_flags);
                errs++;
        }
 
-       if (id != -1 && id != INT_GET(ddq->d_id, ARCH_CONVERT)) {
+       if (id != -1 && id != be32_to_cpu(ddq->d_id)) {
                if (flags & XFS_QMOPT_DOWARN)
                        cmn_err(CE_ALERT,
                        "%s : ondisk-dquot 0x%p, ID mismatch: "
                        "0x%x expected, found id 0x%x",
-                       str, ddq, id, INT_GET(ddq->d_id, ARCH_CONVERT));
+                       str, ddq, id, be32_to_cpu(ddq->d_id));
                errs++;
        }
 
        if (!errs && ddq->d_id) {
-               if (INT_GET(ddq->d_blk_softlimit, ARCH_CONVERT) &&
-                   INT_GET(ddq->d_bcount, ARCH_CONVERT) >=
-                               INT_GET(ddq->d_blk_softlimit, ARCH_CONVERT)) {
+               if (ddq->d_blk_softlimit &&
+                   be64_to_cpu(ddq->d_bcount) >=
+                               be64_to_cpu(ddq->d_blk_softlimit)) {
                        if (!ddq->d_btimer) {
                                if (flags & XFS_QMOPT_DOWARN)
                                        cmn_err(CE_ALERT,
                                        "%s : Dquot ID 0x%x (0x%p) "
                                        "BLK TIMER NOT STARTED",
-                                       str, (int)
-                                       INT_GET(ddq->d_id, ARCH_CONVERT), ddq);
+                                       str, (int)be32_to_cpu(ddq->d_id), ddq);
                                errs++;
                        }
                }
-               if (INT_GET(ddq->d_ino_softlimit, ARCH_CONVERT) &&
-                   INT_GET(ddq->d_icount, ARCH_CONVERT) >=
-                               INT_GET(ddq->d_ino_softlimit, ARCH_CONVERT)) {
+               if (ddq->d_ino_softlimit &&
+                   be64_to_cpu(ddq->d_icount) >=
+                               be64_to_cpu(ddq->d_ino_softlimit)) {
                        if (!ddq->d_itimer) {
                                if (flags & XFS_QMOPT_DOWARN)
                                        cmn_err(CE_ALERT,
                                        "%s : Dquot ID 0x%x (0x%p) "
                                        "INODE TIMER NOT STARTED",
-                                       str, (int)
-                                       INT_GET(ddq->d_id, ARCH_CONVERT), ddq);
+                                       str, (int)be32_to_cpu(ddq->d_id), ddq);
                                errs++;
                        }
                }
-               if (INT_GET(ddq->d_rtb_softlimit, ARCH_CONVERT) &&
-                   INT_GET(ddq->d_rtbcount, ARCH_CONVERT) >=
-                               INT_GET(ddq->d_rtb_softlimit, ARCH_CONVERT)) {
+               if (ddq->d_rtb_softlimit &&
+                   be64_to_cpu(ddq->d_rtbcount) >=
+                               be64_to_cpu(ddq->d_rtb_softlimit)) {
                        if (!ddq->d_rtbtimer) {
                                if (flags & XFS_QMOPT_DOWARN)
                                        cmn_err(CE_ALERT,
                                        "%s : Dquot ID 0x%x (0x%p) "
                                        "RTBLK TIMER NOT STARTED",
-                                       str, (int)
-                                       INT_GET(ddq->d_id, ARCH_CONVERT), ddq);
+                                       str, (int)be32_to_cpu(ddq->d_id), ddq);
                                errs++;
                        }
                }
@@ -2102,10 +2082,11 @@ xfs_qm_dqcheck(
        ASSERT(id != -1);
        ASSERT(flags & XFS_QMOPT_DQREPAIR);
        memset(d, 0, sizeof(xfs_dqblk_t));
-       INT_SET(d->dd_diskdq.d_magic, ARCH_CONVERT, XFS_DQUOT_MAGIC);
-       INT_SET(d->dd_diskdq.d_version, ARCH_CONVERT, XFS_DQUOT_VERSION);
-       INT_SET(d->dd_diskdq.d_id, ARCH_CONVERT, id);
-       INT_SET(d->dd_diskdq.d_flags, ARCH_CONVERT, type);
+
+       d->dd_diskdq.d_magic = cpu_to_be16(XFS_DQUOT_MAGIC);
+       d->dd_diskdq.d_version = XFS_DQUOT_VERSION;
+       d->dd_diskdq.d_flags = type;
+       d->dd_diskdq.d_id = cpu_to_be32(id);
 
        return errs;
 }
@@ -2581,10 +2562,12 @@ xlog_recover_do_quotaoff_trans(
 
        /*
         * The logitem format's flag tells us if this was user quotaoff,
-        * group quotaoff or both.
+        * group/project quotaoff or both.
         */
        if (qoff_f->qf_flags & XFS_UQUOTA_ACCT)
                log->l_quotaoffs_flag |= XFS_DQ_USER;
+       if (qoff_f->qf_flags & XFS_PQUOTA_ACCT)
+               log->l_quotaoffs_flag |= XFS_DQ_PROJ;
        if (qoff_f->qf_flags & XFS_GQUOTA_ACCT)
                log->l_quotaoffs_flag |= XFS_DQ_GROUP;
 
@@ -3178,13 +3161,12 @@ xlog_recover_clear_agi_bucket(
        }
 
        agi = XFS_BUF_TO_AGI(agibp);
-       if (INT_GET(agi->agi_magicnum, ARCH_CONVERT) != XFS_AGI_MAGIC) {
+       if (be32_to_cpu(agi->agi_magicnum) != XFS_AGI_MAGIC) {
                xfs_trans_cancel(tp, XFS_TRANS_ABORT);
                return;
        }
-       ASSERT(INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC);
 
-       INT_SET(agi->agi_unlinked[bucket], ARCH_CONVERT, NULLAGINO);
+       agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
        offset = offsetof(xfs_agi_t, agi_unlinked) +
                 (sizeof(xfs_agino_t) * bucket);
        xfs_trans_log_buf(tp, agibp, offset,
@@ -3243,12 +3225,11 @@ xlog_recover_process_iunlinks(
                                XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)));
                }
                agi = XFS_BUF_TO_AGI(agibp);
-               ASSERT(XFS_AGI_MAGIC ==
-                       INT_GET(agi->agi_magicnum, ARCH_CONVERT));
+               ASSERT(XFS_AGI_MAGIC == be32_to_cpu(agi->agi_magicnum));
 
                for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++) {
 
-                       agino = INT_GET(agi->agi_unlinked[bucket], ARCH_CONVERT);
+                       agino = be32_to_cpu(agi->agi_unlinked[bucket]);
                        while (agino != NULLAGINO) {
 
                                /*
@@ -3268,7 +3249,7 @@ xlog_recover_process_iunlinks(
                                         * next inode in the bucket.
                                         */
                                        error = xfs_itobp(mp, NULL, ip, &dip,
-                                                       &ibp, 0);
+                                                       &ibp, 0, 0);
                                        ASSERT(error || (dip != NULL));
                                }
 
@@ -3336,8 +3317,8 @@ xlog_recover_process_iunlinks(
                                                        XFS_AGI_DADDR(mp)));
                                }
                                agi = XFS_BUF_TO_AGI(agibp);
-                               ASSERT(XFS_AGI_MAGIC == INT_GET(
-                                       agi->agi_magicnum, ARCH_CONVERT));
+                               ASSERT(XFS_AGI_MAGIC == be32_to_cpu(
+                                       agi->agi_magicnum));
                        }
                }
 
@@ -3910,14 +3891,13 @@ xlog_do_recover(
  */
 int
 xlog_recover(
-       xlog_t          *log,
-       int             readonly)
+       xlog_t          *log)
 {
        xfs_daddr_t     head_blk, tail_blk;
        int             error;
 
        /* find the tail of the log */
-       if ((error = xlog_find_tail(log, &head_blk, &tail_blk, readonly)))
+       if ((error = xlog_find_tail(log, &head_blk, &tail_blk)))
                return error;
 
        if (tail_blk != head_blk) {
@@ -4040,14 +4020,12 @@ xlog_recover_check_summary(
                                                mp, agfbp, agfdaddr);
                }
                agfp = XFS_BUF_TO_AGF(agfbp);
-               ASSERT(XFS_AGF_MAGIC ==
-                       INT_GET(agfp->agf_magicnum, ARCH_CONVERT));
-               ASSERT(XFS_AGF_GOOD_VERSION(
-                       INT_GET(agfp->agf_versionnum, ARCH_CONVERT)));
-               ASSERT(INT_GET(agfp->agf_seqno, ARCH_CONVERT) == agno);
-
-               freeblks += INT_GET(agfp->agf_freeblks, ARCH_CONVERT) +
-                           INT_GET(agfp->agf_flcount, ARCH_CONVERT);
+               ASSERT(XFS_AGF_MAGIC == be32_to_cpu(agfp->agf_magicnum));
+               ASSERT(XFS_AGF_GOOD_VERSION(be32_to_cpu(agfp->agf_versionnum)));
+               ASSERT(be32_to_cpu(agfp->agf_seqno) == agno);
+
+               freeblks += be32_to_cpu(agfp->agf_freeblks) +
+                           be32_to_cpu(agfp->agf_flcount);
                xfs_buf_relse(agfbp);
 
                agidaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp));
@@ -4058,14 +4036,12 @@ xlog_recover_check_summary(
                                          mp, agibp, agidaddr);
                }
                agip = XFS_BUF_TO_AGI(agibp);
-               ASSERT(XFS_AGI_MAGIC ==
-                       INT_GET(agip->agi_magicnum, ARCH_CONVERT));
-               ASSERT(XFS_AGI_GOOD_VERSION(
-                       INT_GET(agip->agi_versionnum, ARCH_CONVERT)));
-               ASSERT(INT_GET(agip->agi_seqno, ARCH_CONVERT) == agno);
-
-               itotal += INT_GET(agip->agi_count, ARCH_CONVERT);
-               ifree += INT_GET(agip->agi_freecount, ARCH_CONVERT);
+               ASSERT(XFS_AGI_MAGIC == be32_to_cpu(agip->agi_magicnum));
+               ASSERT(XFS_AGI_GOOD_VERSION(be32_to_cpu(agip->agi_versionnum)));
+               ASSERT(be32_to_cpu(agip->agi_seqno) == agno);
+
+               itotal += be32_to_cpu(agip->agi_count);
+               ifree += be32_to_cpu(agip->agi_freecount);
                xfs_buf_relse(agibp);
        }