Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6
[pandora-kernel.git] / fs / xfs / xfs_log_recover.c
index 7b3375d..14a69ae 100644 (file)
@@ -60,9 +60,6 @@ STATIC void   xlog_recover_check_summary(xlog_t *);
  * Sector aligned buffer routines for buffer create/read/write/access
  */
 
-/* Number of basic blocks in a log sector */
-#define xlog_sectbb(log) (1 << (log)->l_sectbb_log)
-
 /*
  * Verify the given count of basic blocks is valid number of blocks
  * to specify for an operation involving the given XFS log buffer.
@@ -110,9 +107,9 @@ xlog_get_bp(
         * extend the buffer by one extra log sector to ensure
         * there's space to accomodate this possiblility.
         */
-       if (nbblks > 1 && log->l_sectbb_log)
-               nbblks += xlog_sectbb(log);
-       nbblks = round_up(nbblks, xlog_sectbb(log));
+       if (nbblks > 1 && log->l_sectBBsize > 1)
+               nbblks += log->l_sectBBsize;
+       nbblks = round_up(nbblks, log->l_sectBBsize);
 
        return xfs_buf_get_noaddr(BBTOB(nbblks), log->l_mp->m_logdev_targp);
 }
@@ -124,6 +121,10 @@ xlog_put_bp(
        xfs_buf_free(bp);
 }
 
+/*
+ * Return the address of the start of the given block number's data
+ * in a log buffer.  The buffer covers a log sector-aligned region.
+ */
 STATIC xfs_caddr_t
 xlog_align(
        xlog_t          *log,
@@ -131,14 +132,14 @@ xlog_align(
        int             nbblks,
        xfs_buf_t       *bp)
 {
+       xfs_daddr_t     offset;
        xfs_caddr_t     ptr;
 
-       if (!log->l_sectbb_log)
-               return XFS_BUF_PTR(bp);
+       offset = blk_no & ((xfs_daddr_t) log->l_sectBBsize - 1);
+       ptr = XFS_BUF_PTR(bp) + BBTOB(offset);
+
+       ASSERT(ptr + BBTOB(nbblks) <= XFS_BUF_PTR(bp) + XFS_BUF_SIZE(bp));
 
-       ptr = XFS_BUF_PTR(bp) + BBTOB((int)blk_no & log->l_sectbb_mask);
-       ASSERT(XFS_BUF_SIZE(bp) >=
-               BBTOB(nbblks + (blk_no & log->l_sectbb_mask)));
        return ptr;
 }
 
@@ -162,12 +163,11 @@ xlog_bread_noalign(
                return EFSCORRUPTED;
        }
 
-       blk_no = round_down(blk_no, xlog_sectbb(log));
-       nbblks = round_up(nbblks, xlog_sectbb(log));
+       blk_no = round_down(blk_no, log->l_sectBBsize);
+       nbblks = round_up(nbblks, log->l_sectBBsize);
 
        ASSERT(nbblks > 0);
        ASSERT(BBTOB(nbblks) <= XFS_BUF_SIZE(bp));
-       ASSERT(bp);
 
        XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no);
        XFS_BUF_READ(bp);
@@ -222,8 +222,8 @@ xlog_bwrite(
                return EFSCORRUPTED;
        }
 
-       blk_no = round_down(blk_no, xlog_sectbb(log));
-       nbblks = round_up(nbblks, xlog_sectbb(log));
+       blk_no = round_down(blk_no, log->l_sectBBsize);
+       nbblks = round_up(nbblks, log->l_sectBBsize);
 
        ASSERT(nbblks > 0);
        ASSERT(BBTOB(nbblks) <= XFS_BUF_SIZE(bp));
@@ -380,14 +380,12 @@ xlog_find_cycle_start(
 }
 
 /*
- * Check that the range of blocks does not contain the cycle number
- * given.  The scan needs to occur from front to back and the ptr into the
- * region must be updated since a later routine will need to perform another
- * test.  If the region is completely good, we end up returning the same
- * last block number.
- *
- * Set blkno to -1 if we encounter no errors.  This is an invalid block number
- * since we don't ever expect logs to get this large.
+ * Check that a range of blocks does not contain stop_on_cycle_no.
+ * Fill in *new_blk with the block offset where such a block is
+ * found, or with -1 (an invalid block number) if there is no such
+ * block in the range.  The scan needs to occur from front to back
+ * and the pointer into the region must be updated since a later
+ * routine will need to perform another test.
  */
 STATIC int
 xlog_find_verify_cycle(
@@ -413,7 +411,7 @@ xlog_find_verify_cycle(
        bufblks = 1 << ffs(nbblks);
        while (!(bp = xlog_get_bp(log, bufblks))) {
                bufblks >>= 1;
-               if (bufblks < xlog_sectbb(log))
+               if (bufblks < log->l_sectBBsize)
                        return ENOMEM;
        }
 
@@ -661,7 +659,7 @@ xlog_find_head(
                 * In this case we want to find the first block with cycle
                 * number matching last_half_cycle.  We expect the log to be
                 * some variation on
-                *        x + 1 ... | x ...
+                *        x + 1 ... | x ... | x
                 * The first block with cycle number x (last_half_cycle) will
                 * be where the new head belongs.  First we do a binary search
                 * for the first occurrence of last_half_cycle.  The binary
@@ -671,11 +669,13 @@ xlog_find_head(
                 * the log, then we look for occurrences of last_half_cycle - 1
                 * at the end of the log.  The cases we're looking for look
                 * like
-                *        x + 1 ... | x | x + 1 | x ...
-                *                               ^ binary search stopped here
+                *                               v binary search stopped here
+                *        x + 1 ... | x | x + 1 | x ... | x
+                *                   ^ but we want to locate this spot
                 * or
-                *        x + 1 ... | x ... | x - 1 | x
                 *        <---------> less than scan distance
+                *        x + 1 ... | x ... | x - 1 | x
+                *                           ^ we want to locate this spot
                 */
                stop_on_cycle = last_half_cycle;
                if ((error = xlog_find_cycle_start(log, bp, first_blk,
@@ -731,9 +731,9 @@ xlog_find_head(
                 * certainly not the head of the log.  By searching for
                 * last_half_cycle-1 we accomplish that.
                 */
-               start_blk = log_bbnum - num_scan_bblks + head_blk;
                ASSERT(head_blk <= INT_MAX &&
-                       (xfs_daddr_t) num_scan_bblks - head_blk >= 0);
+                       (xfs_daddr_t) num_scan_bblks >= head_blk);
+               start_blk = log_bbnum - (num_scan_bblks - head_blk);
                if ((error = xlog_find_verify_cycle(log, start_blk,
                                        num_scan_bblks - (int)head_blk,
                                        (stop_on_cycle - 1), &new_blk)))
@@ -780,7 +780,7 @@ validate_head:
                if ((error = xlog_find_verify_log_record(log, start_blk,
                                                        &head_blk, 0)) == -1) {
                        /* We hit the beginning of the log during our search */
-                       start_blk = log_bbnum - num_scan_bblks + head_blk;
+                       start_blk = log_bbnum - (num_scan_bblks - head_blk);
                        new_blk = log_bbnum;
                        ASSERT(start_blk <= INT_MAX &&
                                (xfs_daddr_t) log_bbnum-start_blk >= 0);
@@ -1182,7 +1182,7 @@ xlog_write_log_records(
        xfs_caddr_t     offset;
        xfs_buf_t       *bp;
        int             balign, ealign;
-       int             sectbb = xlog_sectbb(log);
+       int             sectbb = log->l_sectBBsize;
        int             end_block = start_block + blocks;
        int             bufblks;
        int             error = 0;
@@ -1197,7 +1197,7 @@ xlog_write_log_records(
        bufblks = 1 << ffs(blocks);
        while (!(bp = xlog_get_bp(log, bufblks))) {
                bufblks >>= 1;
-               if (bufblks < xlog_sectbb(log))
+               if (bufblks < sectbb)
                        return ENOMEM;
        }
 
@@ -1576,7 +1576,7 @@ xlog_recover_reorder_trans(
 
                switch (ITEM_TYPE(item)) {
                case XFS_LI_BUF:
-                       if (!(buf_f->blf_flags & XFS_BLI_CANCEL)) {
+                       if (!(buf_f->blf_flags & XFS_BLF_CANCEL)) {
                                trace_xfs_log_recover_item_reorder_head(log,
                                                        trans, item, pass);
                                list_move(&item->ri_list, &trans->r_itemq);
@@ -1638,7 +1638,7 @@ xlog_recover_do_buffer_pass1(
        /*
         * If this isn't a cancel buffer item, then just return.
         */
-       if (!(flags & XFS_BLI_CANCEL)) {
+       if (!(flags & XFS_BLF_CANCEL)) {
                trace_xfs_log_recover_buf_not_cancel(log, buf_f);
                return;
        }
@@ -1696,7 +1696,7 @@ xlog_recover_do_buffer_pass1(
  * Check to see whether the buffer being recovered has a corresponding
  * entry in the buffer cancel record table.  If it does then return 1
  * so that it will be cancelled, otherwise return 0.  If the buffer is
- * actually a buffer cancel item (XFS_BLI_CANCEL is set), then decrement
+ * actually a buffer cancel item (XFS_BLF_CANCEL is set), then decrement
  * the refcount on the entry in the table and remove it from the table
  * if this is the last reference.
  *
@@ -1721,7 +1721,7 @@ xlog_check_buffer_cancelled(
                 * There is nothing in the table built in pass one,
                 * so this buffer must not be cancelled.
                 */
-               ASSERT(!(flags & XFS_BLI_CANCEL));
+               ASSERT(!(flags & XFS_BLF_CANCEL));
                return 0;
        }
 
@@ -1733,7 +1733,7 @@ xlog_check_buffer_cancelled(
                 * There is no corresponding entry in the table built
                 * in pass one, so this buffer has not been cancelled.
                 */
-               ASSERT(!(flags & XFS_BLI_CANCEL));
+               ASSERT(!(flags & XFS_BLF_CANCEL));
                return 0;
        }
 
@@ -1752,7 +1752,7 @@ xlog_check_buffer_cancelled(
                         * one in the table and remove it if this is the
                         * last reference.
                         */
-                       if (flags & XFS_BLI_CANCEL) {
+                       if (flags & XFS_BLF_CANCEL) {
                                bcp->bc_refcount--;
                                if (bcp->bc_refcount == 0) {
                                        if (prevp == NULL) {
@@ -1772,7 +1772,7 @@ xlog_check_buffer_cancelled(
         * We didn't find a corresponding entry in the table, so
         * return 0 so that the buffer is NOT cancelled.
         */
-       ASSERT(!(flags & XFS_BLI_CANCEL));
+       ASSERT(!(flags & XFS_BLF_CANCEL));
        return 0;
 }
 
@@ -1874,8 +1874,8 @@ xlog_recover_do_inode_buffer(
                        nbits = xfs_contig_bits(data_map, map_size,
                                                         bit);
                        ASSERT(nbits > 0);
-                       reg_buf_offset = bit << XFS_BLI_SHIFT;
-                       reg_buf_bytes = nbits << XFS_BLI_SHIFT;
+                       reg_buf_offset = bit << XFS_BLF_SHIFT;
+                       reg_buf_bytes = nbits << XFS_BLF_SHIFT;
                        item_index++;
                }
 
@@ -1889,7 +1889,7 @@ xlog_recover_do_inode_buffer(
                }
 
                ASSERT(item->ri_buf[item_index].i_addr != NULL);
-               ASSERT((item->ri_buf[item_index].i_len % XFS_BLI_CHUNK) == 0);
+               ASSERT((item->ri_buf[item_index].i_len % XFS_BLF_CHUNK) == 0);
                ASSERT((reg_buf_offset + reg_buf_bytes) <= XFS_BUF_COUNT(bp));
 
                /*
@@ -1955,9 +1955,9 @@ xlog_recover_do_reg_buffer(
                nbits = xfs_contig_bits(data_map, map_size, bit);
                ASSERT(nbits > 0);
                ASSERT(item->ri_buf[i].i_addr != NULL);
-               ASSERT(item->ri_buf[i].i_len % XFS_BLI_CHUNK == 0);
+               ASSERT(item->ri_buf[i].i_len % XFS_BLF_CHUNK == 0);
                ASSERT(XFS_BUF_COUNT(bp) >=
-                      ((uint)bit << XFS_BLI_SHIFT)+(nbits<<XFS_BLI_SHIFT));
+                      ((uint)bit << XFS_BLF_SHIFT)+(nbits<<XFS_BLF_SHIFT));
 
                /*
                 * Do a sanity check if this is a dquot buffer. Just checking
@@ -1966,7 +1966,7 @@ xlog_recover_do_reg_buffer(
                 */
                error = 0;
                if (buf_f->blf_flags &
-                  (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
+                  (XFS_BLF_UDQUOT_BUF|XFS_BLF_PDQUOT_BUF|XFS_BLF_GDQUOT_BUF)) {
                        if (item->ri_buf[i].i_addr == NULL) {
                                cmn_err(CE_ALERT,
                                        "XFS: NULL dquot in %s.", __func__);
@@ -1987,9 +1987,9 @@ xlog_recover_do_reg_buffer(
                }
 
                memcpy(xfs_buf_offset(bp,
-                       (uint)bit << XFS_BLI_SHIFT),    /* dest */
+                       (uint)bit << XFS_BLF_SHIFT),    /* dest */
                        item->ri_buf[i].i_addr,         /* source */
-                       nbits<<XFS_BLI_SHIFT);          /* length */
+                       nbits<<XFS_BLF_SHIFT);          /* length */
  next:
                i++;
                bit += nbits;
@@ -2148,11 +2148,11 @@ xlog_recover_do_dquot_buffer(
        }
 
        type = 0;
-       if (buf_f->blf_flags & XFS_BLI_UDQUOT_BUF)
+       if (buf_f->blf_flags & XFS_BLF_UDQUOT_BUF)
                type |= XFS_DQ_USER;
-       if (buf_f->blf_flags & XFS_BLI_PDQUOT_BUF)
+       if (buf_f->blf_flags & XFS_BLF_PDQUOT_BUF)
                type |= XFS_DQ_PROJ;
-       if (buf_f->blf_flags & XFS_BLI_GDQUOT_BUF)
+       if (buf_f->blf_flags & XFS_BLF_GDQUOT_BUF)
                type |= XFS_DQ_GROUP;
        /*
         * This type of quotas was turned off, so ignore this buffer
@@ -2173,7 +2173,7 @@ xlog_recover_do_dquot_buffer(
  * here which overlaps that may be stale.
  *
  * When meta-data buffers are freed at run time we log a buffer item
- * with the XFS_BLI_CANCEL bit set to indicate that previous copies
+ * with the XFS_BLF_CANCEL bit set to indicate that previous copies
  * of the buffer in the log should not be replayed at recovery time.
  * This is so that if the blocks covered by the buffer are reused for
  * file data before we crash we don't end up replaying old, freed
@@ -2207,7 +2207,7 @@ xlog_recover_do_buffer_trans(
        if (pass == XLOG_RECOVER_PASS1) {
                /*
                 * In this pass we're only looking for buf items
-                * with the XFS_BLI_CANCEL bit set.
+                * with the XFS_BLF_CANCEL bit set.
                 */
                xlog_recover_do_buffer_pass1(log, buf_f);
                return 0;
@@ -2244,7 +2244,7 @@ xlog_recover_do_buffer_trans(
 
        mp = log->l_mp;
        buf_flags = XBF_LOCK;
-       if (!(flags & XFS_BLI_INODE_BUF))
+       if (!(flags & XFS_BLF_INODE_BUF))
                buf_flags |= XBF_MAPPED;
 
        bp = xfs_buf_read(mp->m_ddev_targp, blkno, len, buf_flags);
@@ -2257,10 +2257,10 @@ xlog_recover_do_buffer_trans(
        }
 
        error = 0;
-       if (flags & XFS_BLI_INODE_BUF) {
+       if (flags & XFS_BLF_INODE_BUF) {
                error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f);
        } else if (flags &
-                 (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
+                 (XFS_BLF_UDQUOT_BUF|XFS_BLF_PDQUOT_BUF|XFS_BLF_GDQUOT_BUF)) {
                xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
        } else {
                xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
@@ -3395,42 +3395,6 @@ xlog_pack_data(
        }
 }
 
-#if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
-STATIC void
-xlog_unpack_data_checksum(
-       xlog_rec_header_t       *rhead,
-       xfs_caddr_t             dp,
-       xlog_t                  *log)
-{
-       __be32                  *up = (__be32 *)dp;
-       uint                    chksum = 0;
-       int                     i;
-
-       /* divide length by 4 to get # words */
-       for (i=0; i < be32_to_cpu(rhead->h_len) >> 2; i++) {
-               chksum ^= be32_to_cpu(*up);
-               up++;
-       }
-       if (chksum != be32_to_cpu(rhead->h_chksum)) {
-           if (rhead->h_chksum ||
-               ((log->l_flags & XLOG_CHKSUM_MISMATCH) == 0)) {
-                   cmn_err(CE_DEBUG,
-                       "XFS: LogR chksum mismatch: was (0x%x) is (0x%x)\n",
-                           be32_to_cpu(rhead->h_chksum), chksum);
-                   cmn_err(CE_DEBUG,
-"XFS: Disregard message if filesystem was created with non-DEBUG kernel");
-                   if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
-                           cmn_err(CE_DEBUG,
-                               "XFS: LogR this is a LogV2 filesystem\n");
-                   }
-                   log->l_flags |= XLOG_CHKSUM_MISMATCH;
-           }
-       }
-}
-#else
-#define xlog_unpack_data_checksum(rhead, dp, log)
-#endif
-
 STATIC void
 xlog_unpack_data(
        xlog_rec_header_t       *rhead,
@@ -3454,8 +3418,6 @@ xlog_unpack_data(
                        dp += BBSIZE;
                }
        }
-
-       xlog_unpack_data_checksum(rhead, dp, log);
 }
 
 STATIC int
@@ -3554,7 +3516,7 @@ xlog_do_recovery_pass(
                        hblks = 1;
                }
        } else {
-               ASSERT(log->l_sectbb_log == 0);
+               ASSERT(log->l_sectBBsize == 1);
                hblks = 1;
                hbp = xlog_get_bp(log, 1);
                h_size = XLOG_BIG_RECORD_BSIZE;
@@ -4010,10 +3972,6 @@ xlog_recover_check_summary(
        xfs_agf_t       *agfp;
        xfs_buf_t       *agfbp;
        xfs_buf_t       *agibp;
-       xfs_buf_t       *sbbp;
-#ifdef XFS_LOUD_RECOVERY
-       xfs_sb_t        *sbp;
-#endif
        xfs_agnumber_t  agno;
        __uint64_t      freeblks;
        __uint64_t      itotal;
@@ -4048,30 +4006,5 @@ xlog_recover_check_summary(
                        xfs_buf_relse(agibp);
                }
        }
-
-       sbbp = xfs_getsb(mp, 0);
-#ifdef XFS_LOUD_RECOVERY
-       sbp = &mp->m_sb;
-       xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(sbbp));
-       cmn_err(CE_NOTE,
-               "xlog_recover_check_summary: sb_icount %Lu itotal %Lu",
-               sbp->sb_icount, itotal);
-       cmn_err(CE_NOTE,
-               "xlog_recover_check_summary: sb_ifree %Lu itotal %Lu",
-               sbp->sb_ifree, ifree);
-       cmn_err(CE_NOTE,
-               "xlog_recover_check_summary: sb_fdblocks %Lu freeblks %Lu",
-               sbp->sb_fdblocks, freeblks);
-#if 0
-       /*
-        * This is turned off until I account for the allocation
-        * btree blocks which live in free space.
-        */
-       ASSERT(sbp->sb_icount == itotal);
-       ASSERT(sbp->sb_ifree == ifree);
-       ASSERT(sbp->sb_fdblocks == freeblks);
-#endif
-#endif
-       xfs_buf_relse(sbbp);
 }
 #endif /* DEBUG */