xfs: per-filesystem stats counter implementation
[deliverable/linux.git] / fs / xfs / xfs_log.c
index 08d4fe46f0fae9a161678e1a074cb4e09abcf86f..401252360a62363bd1212a7fb9ba0011d4229cfa 100644 (file)
@@ -268,7 +268,7 @@ xlog_grant_head_wait(
                __set_current_state(TASK_UNINTERRUPTIBLE);
                spin_unlock(&head->lock);
 
-               XFS_STATS_INC(xs_sleep_logspace);
+               XFS_STATS_INC(log->l_mp, xs_sleep_logspace);
 
                trace_xfs_log_grant_sleep(log, tic);
                schedule();
@@ -379,7 +379,7 @@ xfs_log_regrant(
        if (XLOG_FORCED_SHUTDOWN(log))
                return -EIO;
 
-       XFS_STATS_INC(xs_try_logspace);
+       XFS_STATS_INC(mp, xs_try_logspace);
 
        /*
         * This is a new transaction on the ticket, so we need to change the
@@ -448,7 +448,7 @@ xfs_log_reserve(
        if (XLOG_FORCED_SHUTDOWN(log))
                return -EIO;
 
-       XFS_STATS_INC(xs_try_logspace);
+       XFS_STATS_INC(mp, xs_try_logspace);
 
        ASSERT(*ticp == NULL);
        tic = xlog_ticket_alloc(log, unit_bytes, cnt, client, permanent,
@@ -668,9 +668,9 @@ xfs_log_mount(
                        ASSERT(0);
                        goto out_free_log;
                }
+               xfs_crit(mp, "Log size out of supported range.");
                xfs_crit(mp,
-"Log size out of supported range. Continuing onwards, but if log hangs are\n"
-"experienced then please report this message in the bug report.");
+"Continuing onwards, but if log hangs are experienced then please report this message in the bug report.");
        }
 
        /*
@@ -700,6 +700,7 @@ xfs_log_mount(
                if (error) {
                        xfs_warn(mp, "log mount/recovery failed: error %d",
                                error);
+                       xlog_recover_cancel(mp->m_log);
                        goto out_destroy_ail;
                }
        }
@@ -740,18 +741,35 @@ out:
  * it.
  */
 int
-xfs_log_mount_finish(xfs_mount_t *mp)
+xfs_log_mount_finish(
+       struct xfs_mount        *mp)
 {
        int     error = 0;
 
-       if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
-               error = xlog_recover_finish(mp->m_log);
-               if (!error)
-                       xfs_log_work_queue(mp);
-       } else {
+       if (mp->m_flags & XFS_MOUNT_NORECOVERY) {
                ASSERT(mp->m_flags & XFS_MOUNT_RDONLY);
+               return 0;
        }
 
+       error = xlog_recover_finish(mp->m_log);
+       if (!error)
+               xfs_log_work_queue(mp);
+
+       return error;
+}
+
+/*
+ * The mount has failed. Cancel the recovery if it hasn't completed and destroy
+ * the log.
+ */
+int
+xfs_log_mount_cancel(
+       struct xfs_mount        *mp)
+{
+       int                     error;
+
+       error = xlog_recover_cancel(mp->m_log);
+       xfs_log_unmount(mp);
 
        return error;
 }
@@ -1142,11 +1160,13 @@ xlog_space_left(
                 * In this case we just want to return the size of the
                 * log as the amount of space left.
                 */
+               xfs_alert(log->l_mp, "xlog_space_left: head behind tail");
                xfs_alert(log->l_mp,
-                       "xlog_space_left: head behind tail\n"
-                       "  tail_cycle = %d, tail_bytes = %d\n"
-                       "  GH   cycle = %d, GH   bytes = %d",
-                       tail_cycle, tail_bytes, head_cycle, head_bytes);
+                         "  tail_cycle = %d, tail_bytes = %d",
+                         tail_cycle, tail_bytes);
+               xfs_alert(log->l_mp,
+                         "  GH   cycle = %d, GH   bytes = %d",
+                         head_cycle, head_bytes);
                ASSERT(0);
                free_bytes = log->l_logsize;
        }
@@ -1652,8 +1672,13 @@ xlog_cksum(
        if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
                union xlog_in_core2 *xhdr = (union xlog_in_core2 *)rhead;
                int             i;
+               int             xheads;
+
+               xheads = size / XLOG_HEADER_CYCLE_SIZE;
+               if (size % XLOG_HEADER_CYCLE_SIZE)
+                       xheads++;
 
-               for (i = 1; i < log->l_iclog_heads; i++) {
+               for (i = 1; i < xheads; i++) {
                        crc = crc32c(crc, &xhdr[i].hic_xheader,
                                     sizeof(struct xlog_rec_ext_header));
                }
@@ -1743,7 +1768,7 @@ xlog_sync(
        int             v2 = xfs_sb_version_haslogv2(&log->l_mp->m_sb);
        int             size;
 
-       XFS_STATS_INC(xs_log_writes);
+       XFS_STATS_INC(log->l_mp, xs_log_writes);
        ASSERT(atomic_read(&iclog->ic_refcnt) == 0);
 
        /* Add for LR header */
@@ -1780,7 +1805,7 @@ xlog_sync(
        bp = iclog->ic_bp;
        XFS_BUF_SET_ADDR(bp, BLOCK_LSN(be64_to_cpu(iclog->ic_header.h_lsn)));
 
-       XFS_STATS_ADD(xs_log_blocks, BTOBB(count));
+       XFS_STATS_ADD(log->l_mp, xs_log_blocks, BTOBB(count));
 
        /* Do we need to split this write into 2 parts? */
        if (XFS_BUF_ADDR(bp) + BTOBB(count) > log->l_logBBsize) {
@@ -2028,26 +2053,24 @@ xlog_print_tic_res(
            "SWAPEXT"
        };
 
-       xfs_warn(mp,
-               "xlog_write: reservation summary:\n"
-               "  trans type  = %s (%u)\n"
-               "  unit res    = %d bytes\n"
-               "  current res = %d bytes\n"
-               "  total reg   = %u bytes (o/flow = %u bytes)\n"
-               "  ophdrs      = %u (ophdr space = %u bytes)\n"
-               "  ophdr + reg = %u bytes\n"
-               "  num regions = %u",
-               ((ticket->t_trans_type <= 0 ||
-                 ticket->t_trans_type > XFS_TRANS_TYPE_MAX) ?
+       xfs_warn(mp, "xlog_write: reservation summary:");
+       xfs_warn(mp, "  trans type  = %s (%u)",
+                ((ticket->t_trans_type <= 0 ||
+                  ticket->t_trans_type > XFS_TRANS_TYPE_MAX) ?
                  "bad-trans-type" : trans_type_str[ticket->t_trans_type-1]),
-               ticket->t_trans_type,
-               ticket->t_unit_res,
-               ticket->t_curr_res,
-               ticket->t_res_arr_sum, ticket->t_res_o_flow,
-               ticket->t_res_num_ophdrs, ophdr_spc,
-               ticket->t_res_arr_sum +
-               ticket->t_res_o_flow + ophdr_spc,
-               ticket->t_res_num);
+                ticket->t_trans_type);
+       xfs_warn(mp, "  unit res    = %d bytes",
+                ticket->t_unit_res);
+       xfs_warn(mp, "  current res = %d bytes",
+                ticket->t_curr_res);
+       xfs_warn(mp, "  total reg   = %u bytes (o/flow = %u bytes)",
+                ticket->t_res_arr_sum, ticket->t_res_o_flow);
+       xfs_warn(mp, "  ophdrs      = %u (ophdr space = %u bytes)",
+                ticket->t_res_num_ophdrs, ophdr_spc);
+       xfs_warn(mp, "  ophdr + reg = %u bytes",
+                ticket->t_res_arr_sum + ticket->t_res_o_flow + ophdr_spc);
+       xfs_warn(mp, "  num regions = %u",
+                ticket->t_res_num);
 
        for (i = 0; i < ticket->t_res_num; i++) {
                uint r_type = ticket->t_res_arr[i].r_type;
@@ -2890,7 +2913,7 @@ restart:
 
        iclog = log->l_iclog;
        if (iclog->ic_state != XLOG_STATE_ACTIVE) {
-               XFS_STATS_INC(xs_log_noiclogs);
+               XFS_STATS_INC(log->l_mp, xs_log_noiclogs);
 
                /* Wait for log writes to have flushed */
                xlog_wait(&log->l_flush_wait, &log->l_icloglock);
@@ -3189,7 +3212,7 @@ _xfs_log_force(
        struct xlog_in_core     *iclog;
        xfs_lsn_t               lsn;
 
-       XFS_STATS_INC(xs_log_force);
+       XFS_STATS_INC(mp, xs_log_force);
 
        xlog_cil_force(log);
 
@@ -3274,7 +3297,7 @@ maybe_sleep:
                        spin_unlock(&log->l_icloglock);
                        return -EIO;
                }
-               XFS_STATS_INC(xs_log_force_sleep);
+               XFS_STATS_INC(mp, xs_log_force_sleep);
                xlog_wait(&iclog->ic_force_wait, &log->l_icloglock);
                /*
                 * No need to grab the log lock here since we're
@@ -3339,7 +3362,7 @@ _xfs_log_force_lsn(
 
        ASSERT(lsn != 0);
 
-       XFS_STATS_INC(xs_log_force);
+       XFS_STATS_INC(mp, xs_log_force);
 
        lsn = xlog_cil_force_lsn(log, lsn);
        if (lsn == NULLCOMMITLSN)
@@ -3388,7 +3411,7 @@ try_again:
                             (XLOG_STATE_WANT_SYNC | XLOG_STATE_SYNCING))) {
                                ASSERT(!(iclog->ic_state & XLOG_STATE_IOERROR));
 
-                               XFS_STATS_INC(xs_log_force_sleep);
+                               XFS_STATS_INC(mp, xs_log_force_sleep);
 
                                xlog_wait(&iclog->ic_prev->ic_write_wait,
                                                        &log->l_icloglock);
@@ -3418,7 +3441,7 @@ try_again:
                                spin_unlock(&log->l_icloglock);
                                return -EIO;
                        }
-                       XFS_STATS_INC(xs_log_force_sleep);
+                       XFS_STATS_INC(mp, xs_log_force_sleep);
                        xlog_wait(&iclog->ic_force_wait, &log->l_icloglock);
                        /*
                         * No need to grab the log lock here since we're
This page took 0.028068 seconds and 5 git commands to generate.