Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / fs / xfs / xfs_log.c
index 092d5fb..32e841d 100644 (file)
@@ -1,58 +1,47 @@
 /*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-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
  */
-
-/*
- * High level interface routines for log manager
- */
-
 #include "xfs.h"
-#include "xfs_macros.h"
+#include "xfs_fs.h"
 #include "xfs_types.h"
-#include "xfs_inum.h"
-#include "xfs_ag.h"
-#include "xfs_sb.h"
+#include "xfs_bit.h"
 #include "xfs_log.h"
+#include "xfs_inum.h"
 #include "xfs_trans.h"
+#include "xfs_sb.h"
+#include "xfs_ag.h"
 #include "xfs_dir.h"
+#include "xfs_dir2.h"
 #include "xfs_dmapi.h"
 #include "xfs_mount.h"
 #include "xfs_error.h"
 #include "xfs_log_priv.h"
 #include "xfs_buf_item.h"
+#include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
+#include "xfs_ialloc_btree.h"
 #include "xfs_log_recover.h"
-#include "xfs_bit.h"
-#include "xfs_rw.h"
 #include "xfs_trans_priv.h"
+#include "xfs_dir_sf.h"
+#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
+#include "xfs_dinode.h"
+#include "xfs_inode.h"
+#include "xfs_rw.h"
 
 
 #define xlog_write_adv_cnt(ptr, len, off, bytes) \
@@ -70,7 +59,7 @@ STATIC xlog_t *  xlog_alloc_log(xfs_mount_t   *mp,
                                int             num_bblks);
 STATIC int      xlog_space_left(xlog_t *log, int cycle, int bytes);
 STATIC int      xlog_sync(xlog_t *log, xlog_in_core_t *iclog);
-STATIC void     xlog_unalloc_log(xlog_t *log);
+STATIC void     xlog_dealloc_log(xlog_t *log);
 STATIC int      xlog_write(xfs_mount_t *mp, xfs_log_iovec_t region[],
                            int nentries, xfs_log_ticket_t tic,
                            xfs_lsn_t *start_lsn,
@@ -93,8 +82,11 @@ STATIC int  xlog_state_release_iclog(xlog_t          *log,
 STATIC void xlog_state_switch_iclogs(xlog_t            *log,
                                     xlog_in_core_t *iclog,
                                     int                eventual_size);
-STATIC int  xlog_state_sync(xlog_t *log, xfs_lsn_t lsn, uint flags);
-STATIC int  xlog_state_sync_all(xlog_t *log, uint flags);
+STATIC int  xlog_state_sync(xlog_t                     *log,
+                           xfs_lsn_t                   lsn,
+                           uint                        flags,
+                           int                         *log_flushed);
+STATIC int  xlog_state_sync_all(xlog_t *log, uint flags, int *log_flushed);
 STATIC void xlog_state_want_sync(xlog_t        *log, xlog_in_core_t *iclog);
 
 /* local functions to manipulate grant head */
@@ -119,8 +111,7 @@ STATIC xlog_ticket_t        *xlog_ticket_get(xlog_t *log,
                                         uint   flags);
 STATIC void            xlog_ticket_put(xlog_t *log, xlog_ticket_t *ticket);
 
-/* local debug functions */
-#if defined(DEBUG) && !defined(XLOG_NOLOG)
+#if defined(DEBUG)
 STATIC void    xlog_verify_dest_ptr(xlog_t *log, __psint_t ptr);
 STATIC void    xlog_verify_grant_head(xlog_t *log, int equals);
 STATIC void    xlog_verify_iclog(xlog_t *log, xlog_in_core_t *iclog,
@@ -134,36 +125,21 @@ STATIC void       xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog,
 #define xlog_verify_tail_lsn(a,b,c)
 #endif
 
-int            xlog_iclogs_empty(xlog_t *log);
-
-#ifdef DEBUG
-int xlog_do_error = 0;
-int xlog_req_num  = 0;
-int xlog_error_mod = 33;
-#endif
-
-#define XLOG_FORCED_SHUTDOWN(log)      (log->l_flags & XLOG_IO_ERROR)
-
-/*
- * 0 => disable log manager
- * 1 => enable log manager
- * 2 => enable log manager and log debugging
- */
-#if defined(XLOG_NOLOG) || defined(DEBUG)
-int   xlog_debug = 1;
-xfs_buftarg_t *xlog_target;
-#endif
+STATIC int     xlog_iclogs_empty(xlog_t *log);
 
 #if defined(XFS_LOG_TRACE)
-
 void
 xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string)
 {
-       if (! log->l_grant_trace) {
-               log->l_grant_trace = ktrace_alloc(1024, KM_NOSLEEP);
-               if (! log->l_grant_trace)
+       unsigned long cnts;
+
+       if (!log->l_grant_trace) {
+               log->l_grant_trace = ktrace_alloc(2048, KM_NOSLEEP);
+               if (!log->l_grant_trace)
                        return;
        }
+       /* ticket counts are 1 byte each */
+       cnts = ((unsigned long)tic->t_ocnt) | ((unsigned long)tic->t_cnt) << 8;
 
        ktrace_enter(log->l_grant_trace,
                     (void *)tic,
@@ -178,45 +154,107 @@ xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string)
                     (void *)((unsigned long)CYCLE_LSN(log->l_tail_lsn)),
                     (void *)((unsigned long)BLOCK_LSN(log->l_tail_lsn)),
                     (void *)string,
-                    (void *)((unsigned long)13),
-                    (void *)((unsigned long)14),
-                    (void *)((unsigned long)15),
-                    (void *)((unsigned long)16));
+                    (void *)((unsigned long)tic->t_trans_type),
+                    (void *)cnts,
+                    (void *)((unsigned long)tic->t_curr_res),
+                    (void *)((unsigned long)tic->t_unit_res));
 }
 
 void
 xlog_trace_iclog(xlog_in_core_t *iclog, uint state)
 {
-       pid_t pid;
-
-       pid = current_pid();
-
        if (!iclog->ic_trace)
                iclog->ic_trace = ktrace_alloc(256, KM_SLEEP);
        ktrace_enter(iclog->ic_trace,
                     (void *)((unsigned long)state),
-                    (void *)((unsigned long)pid),
-                    (void *)0,
-                    (void *)0,
-                    (void *)0,
-                    (void *)0,
-                    (void *)0,
-                    (void *)0,
-                    (void *)0,
-                    (void *)0,
-                    (void *)0,
-                    (void *)0,
-                    (void *)0,
-                    (void *)0,
-                    (void *)0,
-                    (void *)0);
+                    (void *)((unsigned long)current_pid()),
+                    (void *)NULL, (void *)NULL, (void *)NULL, (void *)NULL,
+                    (void *)NULL, (void *)NULL, (void *)NULL, (void *)NULL,
+                    (void *)NULL, (void *)NULL, (void *)NULL, (void *)NULL,
+                    (void *)NULL, (void *)NULL);
 }
-
 #else
 #define        xlog_trace_loggrant(log,tic,string)
 #define        xlog_trace_iclog(iclog,state)
 #endif /* XFS_LOG_TRACE */
 
+
+static void
+xlog_ins_ticketq(struct xlog_ticket **qp, struct xlog_ticket *tic)
+{
+       if (*qp) {
+               tic->t_next         = (*qp);
+               tic->t_prev         = (*qp)->t_prev;
+               (*qp)->t_prev->t_next = tic;
+               (*qp)->t_prev       = tic;
+       } else {
+               tic->t_prev = tic->t_next = tic;
+               *qp = tic;
+       }
+
+       tic->t_flags |= XLOG_TIC_IN_Q;
+}
+
+static void
+xlog_del_ticketq(struct xlog_ticket **qp, struct xlog_ticket *tic)
+{
+       if (tic == tic->t_next) {
+               *qp = NULL;
+       } else {
+               *qp = tic->t_next;
+               tic->t_next->t_prev = tic->t_prev;
+               tic->t_prev->t_next = tic->t_next;
+       }
+
+       tic->t_next = tic->t_prev = NULL;
+       tic->t_flags &= ~XLOG_TIC_IN_Q;
+}
+
+static void
+xlog_grant_sub_space(struct log *log, int bytes)
+{
+       log->l_grant_write_bytes -= bytes;
+       if (log->l_grant_write_bytes < 0) {
+               log->l_grant_write_bytes += log->l_logsize;
+               log->l_grant_write_cycle--;
+       }
+
+       log->l_grant_reserve_bytes -= bytes;
+       if ((log)->l_grant_reserve_bytes < 0) {
+               log->l_grant_reserve_bytes += log->l_logsize;
+               log->l_grant_reserve_cycle--;
+       }
+
+}
+
+static void
+xlog_grant_add_space_write(struct log *log, int bytes)
+{
+       log->l_grant_write_bytes += bytes;
+       if (log->l_grant_write_bytes > log->l_logsize) {
+               log->l_grant_write_bytes -= log->l_logsize;
+               log->l_grant_write_cycle++;
+       }
+}
+
+static void
+xlog_grant_add_space_reserve(struct log *log, int bytes)
+{
+       log->l_grant_reserve_bytes += bytes;
+       if (log->l_grant_reserve_bytes > log->l_logsize) {
+               log->l_grant_reserve_bytes -= log->l_logsize;
+               log->l_grant_reserve_cycle++;
+       }
+}
+
+static inline void
+xlog_grant_add_space(struct log *log, int bytes)
+{
+       xlog_grant_add_space_write(log, bytes);
+       xlog_grant_add_space_reserve(log, bytes);
+}
+
+
 /*
  * NOTES:
  *
@@ -248,11 +286,6 @@ xfs_log_done(xfs_mount_t   *mp,
        xlog_ticket_t   *ticket = (xfs_log_ticket_t) xtic;
        xfs_lsn_t       lsn     = 0;
 
-#if defined(DEBUG) || defined(XLOG_NOLOG)
-       if (!xlog_debug && xlog_target == log->l_targ)
-               return 0;
-#endif
-
        if (XLOG_FORCED_SHUTDOWN(log) ||
            /*
             * If nothing was ever written, don't write out commit record.
@@ -271,12 +304,14 @@ xfs_log_done(xfs_mount_t  *mp,
        if ((ticket->t_flags & XLOG_TIC_PERM_RESERV) == 0 ||
            (flags & XFS_LOG_REL_PERM_RESERV)) {
                /*
-                * Release ticket if not permanent reservation or a specifc
+                * Release ticket if not permanent reservation or a specific
                 * request has been made to release a permanent reservation.
                 */
+               xlog_trace_loggrant(log, ticket, "xfs_log_done: (non-permanent)");
                xlog_ungrant_log_space(log, ticket);
                xlog_state_put_ticket(log, ticket);
        } else {
+               xlog_trace_loggrant(log, ticket, "xfs_log_done: (permanent)");
                xlog_regrant_reserve_log_space(log, ticket);
        }
 
@@ -306,33 +341,28 @@ xfs_log_done(xfs_mount_t  *mp,
  * semaphore.
  */
 int
-xfs_log_force(xfs_mount_t *mp,
-             xfs_lsn_t   lsn,
-             uint        flags)
+_xfs_log_force(
+       xfs_mount_t     *mp,
+       xfs_lsn_t       lsn,
+       uint            flags,
+       int             *log_flushed)
 {
-       int     rval;
-       xlog_t *log = mp->m_log;
+       xlog_t          *log = mp->m_log;
+       int             dummy;
 
-#if defined(DEBUG) || defined(XLOG_NOLOG)
-       if (!xlog_debug && xlog_target == log->l_targ)
-               return 0;
-#endif
+       if (!log_flushed)
+               log_flushed = &dummy;
 
        ASSERT(flags & XFS_LOG_FORCE);
 
        XFS_STATS_INC(xs_log_force);
 
-       if ((log->l_flags & XLOG_IO_ERROR) == 0) {
-               if (lsn == 0)
-                       rval = xlog_state_sync_all(log, flags);
-               else
-                       rval = xlog_state_sync(log, lsn, flags);
-       } else {
-               rval = XFS_ERROR(EIO);
-       }
-
-       return rval;
-
+       if (log->l_flags & XLOG_IO_ERROR)
+               return XFS_ERROR(EIO);
+       if (lsn == 0)
+               return xlog_state_sync_all(log, flags, log_flushed);
+       else
+               return xlog_state_sync(log, lsn, flags, log_flushed);
 }      /* xfs_log_force */
 
 /*
@@ -350,10 +380,6 @@ xfs_log_notify(xfs_mount_t   *mp,          /* mount of partition */
        xlog_in_core_t    *iclog = (xlog_in_core_t *)iclog_hndl;
        int     abortflg, spl;
 
-#if defined(DEBUG) || defined(XLOG_NOLOG)
-       if (!xlog_debug && xlog_target == log->l_targ)
-               return 0;
-#endif
        cb->cb_next = NULL;
        spl = LOG_LOCK(log);
        abortflg = (iclog->ic_state & XLOG_STATE_IOERROR);
@@ -377,7 +403,7 @@ xfs_log_release_iclog(xfs_mount_t *mp,
 
        if (xlog_state_release_iclog(log, iclog)) {
                xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
-               return(EIO);
+               return EIO;
        }
 
        return 0;
@@ -399,17 +425,13 @@ xfs_log_reserve(xfs_mount_t        *mp,
                int              cnt,
                xfs_log_ticket_t *ticket,
                __uint8_t        client,
-               uint             flags)
+               uint             flags,
+               uint             t_type)
 {
        xlog_t          *log = mp->m_log;
        xlog_ticket_t   *internal_ticket;
-       int             retval;
+       int             retval = 0;
 
-#if defined(DEBUG) || defined(XLOG_NOLOG)
-       if (!xlog_debug && xlog_target == log->l_targ)
-               return 0;
-#endif
-       retval = 0;
        ASSERT(client == XFS_TRANSACTION || client == XFS_LOG);
        ASSERT((flags & XFS_LOG_NOSLEEP) == 0);
 
@@ -421,13 +443,19 @@ xfs_log_reserve(xfs_mount_t        *mp,
        if (*ticket != NULL) {
                ASSERT(flags & XFS_LOG_PERM_RESERV);
                internal_ticket = (xlog_ticket_t *)*ticket;
+               xlog_trace_loggrant(log, internal_ticket, "xfs_log_reserve: existing ticket (permanent trans)");
                xlog_grant_push_ail(mp, internal_ticket->t_unit_res);
                retval = xlog_regrant_write_log_space(log, internal_ticket);
        } else {
                /* may sleep if need to allocate more tickets */
                internal_ticket = xlog_ticket_get(log, unit_bytes, cnt,
                                                  client, flags);
+               internal_ticket->t_trans_type = t_type;
                *ticket = internal_ticket;
+               xlog_trace_loggrant(log, internal_ticket, 
+                       (internal_ticket->t_flags & XLOG_TIC_PERM_RESERV) ?
+                       "xfs_log_reserve: create new ticket (permanent trans)" :
+                       "xfs_log_reserve: create new ticket");
                xlog_grant_push_ail(mp,
                                    (internal_ticket->t_unit_res *
                                     internal_ticket->t_cnt));
@@ -465,12 +493,6 @@ xfs_log_mount(xfs_mount_t  *mp,
 
        mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks);
 
-#if defined(DEBUG) || defined(XLOG_NOLOG)
-       if (!xlog_debug) {
-               cmn_err(CE_NOTE, "log dev: %s", XFS_BUFTARG_NAME(log_target));
-               return 0;
-       }
-#endif
        /*
         * skip log recovery on a norecovery mount.  pretend it all
         * just worked.
@@ -483,13 +505,13 @@ xfs_log_mount(xfs_mount_t *mp,
                if (readonly)
                        vfsp->vfs_flag &= ~VFS_RDONLY;
 
-               error = xlog_recover(mp->m_log, readonly);
+               error = xlog_recover(mp->m_log);
 
                if (readonly)
                        vfsp->vfs_flag |= VFS_RDONLY;
                if (error) {
                        cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error);
-                       xlog_unalloc_log(mp->m_log);
+                       xlog_dealloc_log(mp->m_log);
                        return error;
                }
        }
@@ -534,7 +556,7 @@ xfs_log_unmount(xfs_mount_t *mp)
 
        error = xfs_log_unmount_write(mp);
        xfs_log_unmount_dealloc(mp);
-       return (error);
+       return error;
 }
 
 /*
@@ -574,11 +596,6 @@ xfs_log_unmount_write(xfs_mount_t *mp)
            __uint32_t pad2; /* may as well make it 64 bits */
        } magic = { XLOG_UNMOUNT_TYPE, 0, 0 };
 
-#if defined(DEBUG) || defined(XLOG_NOLOG)
-       if (!xlog_debug && xlog_target == log->l_targ)
-               return 0;
-#endif
-
        /*
         * Don't write out unmount record on read-only mounts.
         * Or, if we are doing a forced umount (typically because of IO errors).
@@ -601,8 +618,9 @@ xfs_log_unmount_write(xfs_mount_t *mp)
        if (! (XLOG_FORCED_SHUTDOWN(log))) {
                reg[0].i_addr = (void*)&magic;
                reg[0].i_len  = sizeof(magic);
+               XLOG_VEC_SET_TYPE(&reg[0], XLOG_REG_TYPE_UNMOUNT);
 
-               error = xfs_log_reserve(mp, 600, 1, &tic, XFS_LOG, 0);
+               error = xfs_log_reserve(mp, 600, 1, &tic, XFS_LOG, 0, 0);
                if (!error) {
                        /* remove inited flag */
                        ((xlog_ticket_t *)tic)->t_flags = 0;
@@ -649,7 +667,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
                 *
                 * Go through the motions of sync'ing and releasing
                 * the iclog, even though no I/O will actually happen,
-                * we need to wait for other log I/O's that may already
+                * we need to wait for other log I/Os that may already
                 * be in progress.  Do this as a separate section of
                 * code so we'll know if we ever get stuck here that
                 * we're in this odd situation of trying to unmount
@@ -686,7 +704,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
 void
 xfs_log_unmount_dealloc(xfs_mount_t *mp)
 {
-       xlog_unalloc_log(mp->m_log);
+       xlog_dealloc_log(mp->m_log);
 }
 
 /*
@@ -704,19 +722,13 @@ xfs_log_write(xfs_mount_t *       mp,
        int     error;
        xlog_t *log = mp->m_log;
 
-#if defined(DEBUG) || defined(XLOG_NOLOG)
-       if (!xlog_debug && xlog_target == log->l_targ) {
-               *start_lsn = 0;
-               return 0;
-       }
-#endif
        if (XLOG_FORCED_SHUTDOWN(log))
                return XFS_ERROR(EIO);
 
        if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0))) {
                xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
        }
-       return (error);
+       return error;
 }      /* xfs_log_write */
 
 
@@ -729,11 +741,6 @@ xfs_log_move_tail(xfs_mount_t      *mp,
        int             need_bytes, free_bytes, cycle, bytes;
        SPLDECL(s);
 
-#if defined(DEBUG) || defined(XLOG_NOLOG)
-       if (!xlog_debug && xlog_target == log->l_targ)
-               return;
-#endif
-       /* XXXsup tmp */
        if (XLOG_FORCED_SHUTDOWN(log))
                return;
        ASSERT(!XFS_FORCED_SHUTDOWN(mp));
@@ -829,7 +836,7 @@ xfs_log_need_covered(xfs_mount_t *mp)
                needed = 1;
        }
        LOG_UNLOCK(log, s);
-       return(needed);
+       return needed;
 }
 
 /******************************************************************************
@@ -996,7 +1003,7 @@ xlog_bdstrat_cb(struct xfs_buf *bp)
        XFS_BUF_ERROR(bp, EIO);
        XFS_BUF_STALE(bp);
        xfs_biodone(bp);
-       return (XFS_ERROR(EIO));
+       return XFS_ERROR(EIO);
 
 
 }
@@ -1020,51 +1027,22 @@ xlog_get_iclog_buffer_size(xfs_mount_t  *mp,
        int size;
        int xhdrs;
 
-#if defined(DEBUG) || defined(XLOG_NOLOG)
-       /*
-        * When logbufs == 0, someone has disabled the log from the FSTAB
-        * file.  This is not a documented feature.  We need to set xlog_debug
-        * to zero (this deactivates the log) and set xlog_target to the
-        * appropriate device.  Only one filesystem may be affected as such
-        * since this is just a performance hack to test what we might be able
-        * to get if the log were not present.
-        */
-       if (mp->m_logbufs == 0) {
-               xlog_debug = 0;
-               xlog_target = log->l_targ;
-               log->l_iclog_bufs = XLOG_MIN_ICLOGS;
-       } else
-#endif
-       {
-               /*
-                * This is the normal path.  If m_logbufs == -1, then the
-                * admin has chosen to use the system defaults for logbuffers.
-                */
-               if (mp->m_logbufs == -1) { 
-                       if (xfs_physmem <= btoc(128*1024*1024)) { 
-                               log->l_iclog_bufs = XLOG_MIN_ICLOGS; 
-                       } else if (xfs_physmem <= btoc(400*1024*1024)) { 
-                               log->l_iclog_bufs = XLOG_MED_ICLOGS; 
-                       } else {
-                               /* 256K with 32K bufs */
-                               log->l_iclog_bufs = XLOG_MAX_ICLOGS;
-                       }
-               } else
-                       log->l_iclog_bufs = mp->m_logbufs;
-
-#if defined(DEBUG) || defined(XLOG_NOLOG)
-               /* We are reactivating a filesystem after it was inactive */
-               if (log->l_targ == xlog_target) {
-                       xlog_target = NULL;
-                       xlog_debug = 1;
+       if (mp->m_logbufs <= 0) {
+               if (xfs_physmem <= btoc(128*1024*1024)) {
+                       log->l_iclog_bufs = XLOG_MIN_ICLOGS;
+               } else if (xfs_physmem <= btoc(400*1024*1024)) {
+                       log->l_iclog_bufs = XLOG_MED_ICLOGS;
+               } else {        /* 256K with 32K bufs */
+                       log->l_iclog_bufs = XLOG_MAX_ICLOGS;
                }
-#endif
+       } else {
+               log->l_iclog_bufs = mp->m_logbufs;
        }
 
        /*
         * Buffer size passed in from mount system call.
         */
-       if (mp->m_logbsize != -1) {
+       if (mp->m_logbsize > 0) {
                size = log->l_iclog_size = mp->m_logbsize;
                log->l_iclog_size_log = 0;
                while (size != 1) {
@@ -1087,7 +1065,7 @@ xlog_get_iclog_buffer_size(xfs_mount_t    *mp,
                        log->l_iclog_hsize = BBSIZE;
                        log->l_iclog_heads = 1;
                }
-               return;
+               goto done;
        }
 
        /*
@@ -1114,7 +1092,7 @@ xlog_get_iclog_buffer_size(xfs_mount_t    *mp,
        if (mp->m_sb.sb_blocksize >= 16*1024) {
                log->l_iclog_size = XLOG_BIG_RECORD_BSIZE;
                log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT;
-               if (mp->m_logbufs == -1) {
+               if (mp->m_logbufs <= 0) {
                        switch (mp->m_sb.sb_blocksize) {
                            case 16*1024:                       /* 16 KB */
                                log->l_iclog_bufs = 3;
@@ -1131,6 +1109,12 @@ xlog_get_iclog_buffer_size(xfs_mount_t   *mp,
                        }
                }
        }
+
+done:  /* are we being asked to make the sizes selected above visible? */
+       if (mp->m_logbufs == 0)
+               mp->m_logbufs = log->l_iclog_bufs;
+       if (mp->m_logbsize == 0)
+               mp->m_logbsize = log->l_iclog_size;
 }      /* xlog_get_iclog_buffer_size */
 
 
@@ -1272,13 +1256,14 @@ xlog_commit_record(xfs_mount_t  *mp,
 
        reg[0].i_addr = NULL;
        reg[0].i_len = 0;
+       XLOG_VEC_SET_TYPE(&reg[0], XLOG_REG_TYPE_COMMIT);
 
        ASSERT_ALWAYS(iclog);
        if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp,
                               iclog, XLOG_COMMIT_TRANS))) {
                xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
        }
-       return (error);
+       return error;
 }      /* xlog_commit_record */
 
 
@@ -1412,8 +1397,7 @@ xlog_sync(xlog_t          *log,
 
        /* move grant heads by roundoff in sync */
        s = GRANT_LOCK(log);
-       XLOG_GRANT_ADD_SPACE(log, roundoff, 'w');
-       XLOG_GRANT_ADD_SPACE(log, roundoff, 'r');
+       xlog_grant_add_space(log, roundoff);
        GRANT_UNLOCK(log, s);
 
        /* put cycle number in every block */
@@ -1452,14 +1436,13 @@ xlog_sync(xlog_t                *log,
        XFS_BUF_BUSY(bp);
        XFS_BUF_ASYNC(bp);
        /*
-        * Do a disk write cache flush for the log block.
-        * This is a bit of a sledgehammer, it would be better
-        * to use a tag barrier here that just prevents reordering.
+        * Do an ordered write for the log block.
+        *
         * It may not be needed to flush the first split block in the log wrap
         * case, but do it anyways to be safe -AK
         */
-       if (!(log->l_mp->m_flags & XFS_MOUNT_NOLOGFLUSH))
-               XFS_BUF_FLUSH(bp);
+       if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
+               XFS_BUF_ORDERED(bp);
 
        ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
        ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize);
@@ -1477,7 +1460,7 @@ xlog_sync(xlog_t          *log,
        if ((error = XFS_bwrite(bp))) {
                xfs_ioerror_alert("xlog_sync", log->l_mp, bp,
                                  XFS_BUF_ADDR(bp));
-               return (error);
+               return error;
        }
        if (split) {
                bp              = iclog->ic_log->l_xbuf;
@@ -1490,8 +1473,8 @@ xlog_sync(xlog_t          *log,
                XFS_BUF_SET_FSPRIVATE(bp, iclog);
                XFS_BUF_BUSY(bp);
                XFS_BUF_ASYNC(bp);
-               if (!(log->l_mp->m_flags & XFS_MOUNT_NOLOGFLUSH))
-                       XFS_BUF_FLUSH(bp);
+               if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
+                       XFS_BUF_ORDERED(bp);
                dptr = XFS_BUF_PTR(bp);
                /*
                 * Bump the cycle numbers at the start of each block
@@ -1509,24 +1492,24 @@ xlog_sync(xlog_t                *log,
                ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
                ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize);
 
-               /* account for internal log which does't start at block #0 */
+               /* account for internal log which doesn't start at block #0 */
                XFS_BUF_SET_ADDR(bp, XFS_BUF_ADDR(bp) + log->l_logBBstart);
                XFS_BUF_WRITE(bp);
                if ((error = XFS_bwrite(bp))) {
                        xfs_ioerror_alert("xlog_sync (split)", log->l_mp,
                                          bp, XFS_BUF_ADDR(bp));
-                       return (error);
+                       return error;
                }
        }
-       return (0);
+       return 0;
 }      /* xlog_sync */
 
 
 /*
- * Unallocate a log structure
+ * Deallocate a log structure
  */
 void
-xlog_unalloc_log(xlog_t *log)
+xlog_dealloc_log(xlog_t *log)
 {
        xlog_in_core_t  *iclog, *next_iclog;
        xlog_ticket_t   *tic, *next_tic;
@@ -1556,7 +1539,7 @@ xlog_unalloc_log(xlog_t *log)
        if ((log->l_ticket_cnt != log->l_ticket_tcnt)  &&
            !XLOG_FORCED_SHUTDOWN(log)) {
                xfs_fs_cmn_err(CE_WARN, log->l_mp,
-                       "xlog_unalloc_log: (cnt: %d, total: %d)",
+                       "xlog_dealloc_log: (cnt: %d, total: %d)",
                        log->l_ticket_cnt, log->l_ticket_tcnt);
                /* ASSERT(log->l_ticket_cnt == log->l_ticket_tcnt); */
 
@@ -1579,7 +1562,7 @@ xlog_unalloc_log(xlog_t *log)
 #endif
        log->l_mp->m_log = NULL;
        kmem_free(log, sizeof(xlog_t));
-}      /* xlog_unalloc_log */
+}      /* xlog_dealloc_log */
 
 /*
  * Update counters atomically now that memcpy is done.
@@ -1604,6 +1587,113 @@ xlog_state_finish_copy(xlog_t           *log,
 
 
 
+/*
+ * print out info relating to regions written which consume
+ * the reservation
+ */
+STATIC void
+xlog_print_tic_res(xfs_mount_t *mp, xlog_ticket_t *ticket)
+{
+       uint i;
+       uint ophdr_spc = ticket->t_res_num_ophdrs * (uint)sizeof(xlog_op_header_t);
+
+       /* match with XLOG_REG_TYPE_* in xfs_log.h */
+       static char *res_type_str[XLOG_REG_TYPE_MAX] = {
+           "bformat",
+           "bchunk",
+           "efi_format",
+           "efd_format",
+           "iformat",
+           "icore",
+           "iext",
+           "ibroot",
+           "ilocal",
+           "iattr_ext",
+           "iattr_broot",
+           "iattr_local",
+           "qformat",
+           "dquot",
+           "quotaoff",
+           "LR header",
+           "unmount",
+           "commit",
+           "trans header"
+       };
+       static char *trans_type_str[XFS_TRANS_TYPE_MAX] = {
+           "SETATTR_NOT_SIZE",
+           "SETATTR_SIZE",
+           "INACTIVE",
+           "CREATE",
+           "CREATE_TRUNC",
+           "TRUNCATE_FILE",
+           "REMOVE",
+           "LINK",
+           "RENAME",
+           "MKDIR",
+           "RMDIR",
+           "SYMLINK",
+           "SET_DMATTRS",
+           "GROWFS",
+           "STRAT_WRITE",
+           "DIOSTRAT",
+           "WRITE_SYNC",
+           "WRITEID",
+           "ADDAFORK",
+           "ATTRINVAL",
+           "ATRUNCATE",
+           "ATTR_SET",
+           "ATTR_RM",
+           "ATTR_FLAG",
+           "CLEAR_AGI_BUCKET",
+           "QM_SBCHANGE",
+           "DUMMY1",
+           "DUMMY2",
+           "QM_QUOTAOFF",
+           "QM_DQALLOC",
+           "QM_SETQLIM",
+           "QM_DQCLUSTER",
+           "QM_QINOCREATE",
+           "QM_QUOTAOFF_END",
+           "SB_UNIT",
+           "FSYNC_TS",
+           "GROWFSRT_ALLOC",
+           "GROWFSRT_ZERO",
+           "GROWFSRT_FREE",
+           "SWAPEXT"
+       };
+
+       xfs_fs_cmn_err(CE_WARN, mp,
+                       "xfs_log_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\n",
+                       ((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);
+
+       for (i = 0; i < ticket->t_res_num; i++) {
+               uint r_type = ticket->t_res_arr[i].r_type; 
+               cmn_err(CE_WARN,
+                           "region[%u]: %s - %u bytes\n",
+                           i, 
+                           ((r_type <= 0 || r_type > XLOG_REG_TYPE_MAX) ?
+                           "bad-rtype" : res_type_str[r_type-1]),
+                           ticket->t_res_arr[i].r_len);
+       }
+}
+
 /*
  * Write some region out to in-core log
  *
@@ -1677,16 +1767,21 @@ xlog_write(xfs_mount_t *        mp,
      * xlog_op_header_t and may need to be double word aligned.
      */
     len = 0;
-    if (ticket->t_flags & XLOG_TIC_INITED)     /* acct for start rec of xact */
+    if (ticket->t_flags & XLOG_TIC_INITED) {    /* acct for start rec of xact */
        len += sizeof(xlog_op_header_t);
+       XLOG_TIC_ADD_OPHDR(ticket);
+    }
 
     for (index = 0; index < nentries; index++) {
        len += sizeof(xlog_op_header_t);            /* each region gets >= 1 */
+       XLOG_TIC_ADD_OPHDR(ticket);
        len += reg[index].i_len;
+       XLOG_TIC_ADD_REGION(ticket, reg[index].i_len, reg[index].i_type);
     }
     contwr = *start_lsn = 0;
 
     if (ticket->t_curr_res < len) {
+       xlog_print_tic_res(mp, ticket);
 #ifdef DEBUG
        xlog_panic(
                "xfs_log_write: reservation ran out. Need to up reservation");
@@ -1703,7 +1798,7 @@ xlog_write(xfs_mount_t *  mp,
     for (index = 0; index < nentries; ) {
        if ((error = xlog_state_get_iclog_space(log, len, &iclog, ticket,
                                               &contwr, &log_offset)))
-               return (error);
+               return error;
 
        ASSERT(log_offset <= iclog->ic_size - 1);
        ptr = (__psint_t) ((char *)iclog->ic_datap+log_offset);
@@ -1790,6 +1885,7 @@ xlog_write(xfs_mount_t *  mp,
                len += sizeof(xlog_op_header_t); /* from splitting of region */
                /* account for new log op header */
                ticket->t_curr_res -= sizeof(xlog_op_header_t);
+               XLOG_TIC_ADD_OPHDR(ticket);
            }
            xlog_verify_dest_ptr(log, ptr);
 
@@ -1807,7 +1903,7 @@ xlog_write(xfs_mount_t *  mp,
                    xlog_state_finish_copy(log, iclog, record_cnt, data_cnt);
                    record_cnt = data_cnt = 0;
                    if ((error = xlog_state_release_iclog(log, iclog)))
-                           return (error);
+                           return error;
                    break;                      /* don't increment index */
            } else {                            /* copied entire region */
                index++;
@@ -1821,7 +1917,7 @@ xlog_write(xfs_mount_t *  mp,
                        ASSERT(flags & XLOG_COMMIT_TRANS);
                        *commit_iclog = iclog;
                    } else if ((error = xlog_state_release_iclog(log, iclog)))
-                          return (error);
+                          return error;
                    if (index == nentries)
                            return 0;           /* we are done */
                    else
@@ -1838,7 +1934,7 @@ xlog_write(xfs_mount_t *  mp,
        *commit_iclog = iclog;
        return 0;
     }
-    return (xlog_state_release_iclog(log, iclog));
+    return xlog_state_release_iclog(log, iclog);
 }      /* xlog_write */
 
 
@@ -1857,7 +1953,7 @@ xlog_write(xfs_mount_t *  mp,
  *
  * State Change: DIRTY -> ACTIVE
  */
-void
+STATIC void
 xlog_state_clean_log(xlog_t *log)
 {
        xlog_in_core_t  *iclog;
@@ -1954,7 +2050,7 @@ xlog_get_lowest_lsn(
            }
            lsn_log = lsn_log->ic_next;
        } while (lsn_log != log->l_iclog);
-       return(lowest_lsn);
+       return lowest_lsn;
 }
 
 
@@ -2282,6 +2378,9 @@ restart:
         */
        if (log_offset == 0) {
                ticket->t_curr_res -= log->l_iclog_hsize;
+               XLOG_TIC_ADD_REGION(ticket,
+                                   log->l_iclog_hsize,
+                                   XLOG_REG_TYPE_LRHEADER);
                INT_SET(head->h_cycle, ARCH_CONVERT, log->l_curr_cycle);
                ASSIGN_LSN(head->h_lsn, log);
                ASSERT(log->l_curr_block >= 0);
@@ -2303,7 +2402,7 @@ restart:
                if (iclog->ic_refcnt == 1) {
                        LOG_UNLOCK(log, s);
                        if ((error = xlog_state_release_iclog(log, iclog)))
-                               return (error);
+                               return error;
                } else {
                        iclog->ic_refcnt--;
                        LOG_UNLOCK(log, s);
@@ -2362,7 +2461,7 @@ xlog_grant_log_space(xlog_t          *log,
 
        /* something is already sleeping; insert new transaction at end */
        if (log->l_reserve_headq) {
-               XLOG_INS_TICKETQ(log->l_reserve_headq, tic);
+               xlog_ins_ticketq(&log->l_reserve_headq, tic);
                xlog_trace_loggrant(log, tic,
                                    "xlog_grant_log_space: sleep 1");
                /*
@@ -2395,7 +2494,7 @@ redo:
                                     log->l_grant_reserve_bytes);
        if (free_bytes < need_bytes) {
                if ((tic->t_flags & XLOG_TIC_IN_Q) == 0)
-                       XLOG_INS_TICKETQ(log->l_reserve_headq, tic);
+                       xlog_ins_ticketq(&log->l_reserve_headq, tic);
                xlog_trace_loggrant(log, tic,
                                    "xlog_grant_log_space: sleep 2");
                XFS_STATS_INC(xs_sleep_logspace);
@@ -2412,11 +2511,10 @@ redo:
                s = GRANT_LOCK(log);
                goto redo;
        } else if (tic->t_flags & XLOG_TIC_IN_Q)
-               XLOG_DEL_TICKETQ(log->l_reserve_headq, tic);
+               xlog_del_ticketq(&log->l_reserve_headq, tic);
 
        /* we've got enough space */
-       XLOG_GRANT_ADD_SPACE(log, need_bytes, 'w');
-       XLOG_GRANT_ADD_SPACE(log, need_bytes, 'r');
+       xlog_grant_add_space(log, need_bytes);
 #ifdef DEBUG
        tail_lsn = log->l_tail_lsn;
        /*
@@ -2437,7 +2535,7 @@ redo:
 
  error_return:
        if (tic->t_flags & XLOG_TIC_IN_Q)
-               XLOG_DEL_TICKETQ(log->l_reserve_headq, tic);
+               xlog_del_ticketq(&log->l_reserve_headq, tic);
        xlog_trace_loggrant(log, tic, "xlog_grant_log_space: err_ret");
        /*
         * If we are failing, make sure the ticket doesn't have any
@@ -2468,9 +2566,10 @@ xlog_regrant_write_log_space(xlog_t         *log,
 #endif
 
        tic->t_curr_res = tic->t_unit_res;
+       XLOG_TIC_RESET_RES(tic);
 
        if (tic->t_cnt > 0)
-               return (0);
+               return 0;
 
 #ifdef DEBUG
        if (log->l_flags & XLOG_ACTIVE_RECOVERY)
@@ -2505,7 +2604,7 @@ xlog_regrant_write_log_space(xlog_t          *log,
 
                if (ntic != log->l_write_headq) {
                        if ((tic->t_flags & XLOG_TIC_IN_Q) == 0)
-                               XLOG_INS_TICKETQ(log->l_write_headq, tic);
+                               xlog_ins_ticketq(&log->l_write_headq, tic);
 
                        xlog_trace_loggrant(log, tic,
                                    "xlog_regrant_write_log_space: sleep 1");
@@ -2537,7 +2636,7 @@ redo:
                                     log->l_grant_write_bytes);
        if (free_bytes < need_bytes) {
                if ((tic->t_flags & XLOG_TIC_IN_Q) == 0)
-                       XLOG_INS_TICKETQ(log->l_write_headq, tic);
+                       xlog_ins_ticketq(&log->l_write_headq, tic);
                XFS_STATS_INC(xs_sleep_logspace);
                sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s);
 
@@ -2553,9 +2652,10 @@ redo:
                s = GRANT_LOCK(log);
                goto redo;
        } else if (tic->t_flags & XLOG_TIC_IN_Q)
-               XLOG_DEL_TICKETQ(log->l_write_headq, tic);
+               xlog_del_ticketq(&log->l_write_headq, tic);
 
-       XLOG_GRANT_ADD_SPACE(log, need_bytes, 'w'); /* we've got enough space */
+       /* we've got enough space */
+       xlog_grant_add_space_write(log, need_bytes);
 #ifdef DEBUG
        tail_lsn = log->l_tail_lsn;
        if (CYCLE_LSN(tail_lsn) != log->l_grant_write_cycle) {
@@ -2567,12 +2667,12 @@ redo:
        xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: exit");
        xlog_verify_grant_head(log, 1);
        GRANT_UNLOCK(log, s);
-       return (0);
+       return 0;
 
 
  error_return:
        if (tic->t_flags & XLOG_TIC_IN_Q)
-               XLOG_DEL_TICKETQ(log->l_reserve_headq, tic);
+               xlog_del_ticketq(&log->l_reserve_headq, tic);
        xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: err_ret");
        /*
         * If we are failing, make sure the ticket doesn't have any
@@ -2605,9 +2705,9 @@ xlog_regrant_reserve_log_space(xlog_t          *log,
                ticket->t_cnt--;
 
        s = GRANT_LOCK(log);
-       XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'w');
-       XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'r');
+       xlog_grant_sub_space(log, ticket->t_curr_res);
        ticket->t_curr_res = ticket->t_unit_res;
+       XLOG_TIC_RESET_RES(ticket);
        xlog_trace_loggrant(log, ticket,
                            "xlog_regrant_reserve_log_space: sub current res");
        xlog_verify_grant_head(log, 1);
@@ -2618,12 +2718,13 @@ xlog_regrant_reserve_log_space(xlog_t        *log,
                return;
        }
 
-       XLOG_GRANT_ADD_SPACE(log, ticket->t_unit_res, 'r');
+       xlog_grant_add_space_reserve(log, ticket->t_unit_res);
        xlog_trace_loggrant(log, ticket,
                            "xlog_regrant_reserve_log_space: exit");
        xlog_verify_grant_head(log, 0);
        GRANT_UNLOCK(log, s);
        ticket->t_curr_res = ticket->t_unit_res;
+       XLOG_TIC_RESET_RES(ticket);
 }      /* xlog_regrant_reserve_log_space */
 
 
@@ -2653,8 +2754,7 @@ xlog_ungrant_log_space(xlog_t          *log,
        s = GRANT_LOCK(log);
        xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: enter");
 
-       XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'w');
-       XLOG_GRANT_SUB_SPACE(log, ticket->t_curr_res, 'r');
+       xlog_grant_sub_space(log, ticket->t_curr_res);
 
        xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: sub current");
 
@@ -2663,8 +2763,7 @@ xlog_ungrant_log_space(xlog_t          *log,
         */
        if (ticket->t_cnt > 0) {
                ASSERT(ticket->t_flags & XLOG_TIC_PERM_RESERV);
-               XLOG_GRANT_SUB_SPACE(log, ticket->t_unit_res*ticket->t_cnt,'w');
-               XLOG_GRANT_SUB_SPACE(log, ticket->t_unit_res*ticket->t_cnt,'r');
+               xlog_grant_sub_space(log, ticket->t_unit_res*ticket->t_cnt);
        }
 
        xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: exit");
@@ -2730,7 +2829,7 @@ xlog_state_release_iclog(xlog_t           *log,
 
        /*
         * We let the log lock go, so it's possible that we hit a log I/O
-        * error or someother SHUTDOWN condition that marks the iclog
+        * error or some other SHUTDOWN condition that marks the iclog
         * as XLOG_STATE_IOERROR before the bwrite. However, we know that
         * this iclog has consistent data, so we ignore IOERROR
         * flags after this point.
@@ -2738,7 +2837,7 @@ xlog_state_release_iclog(xlog_t           *log,
        if (sync) {
                return xlog_sync(log, iclog);
        }
-       return (0);
+       return 0;
 
 }      /* xlog_state_release_iclog */
 
@@ -2813,7 +2912,7 @@ xlog_state_switch_iclogs(xlog_t           *log,
  *             not in the active nor dirty state.
  */
 STATIC int
-xlog_state_sync_all(xlog_t *log, uint flags)
+xlog_state_sync_all(xlog_t *log, uint flags, int *log_flushed)
 {
        xlog_in_core_t  *iclog;
        xfs_lsn_t       lsn;
@@ -2862,6 +2961,7 @@ xlog_state_sync_all(xlog_t *log, uint flags)
 
                                if (xlog_state_release_iclog(log, iclog))
                                        return XFS_ERROR(EIO);
+                               *log_flushed = 1;
                                s = LOG_LOCK(log);
                                if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) == lsn &&
                                    iclog->ic_state != XLOG_STATE_DIRTY)
@@ -2905,6 +3005,7 @@ maybe_sleep:
                 */
                if (iclog->ic_state & XLOG_STATE_IOERROR)
                        return XFS_ERROR(EIO);
+               *log_flushed = 1;
 
        } else {
 
@@ -2930,7 +3031,8 @@ no_sleep:
 int
 xlog_state_sync(xlog_t   *log,
                xfs_lsn_t lsn,
-               uint      flags)
+               uint      flags,
+               int       *log_flushed)
 {
     xlog_in_core_t     *iclog;
     int                        already_slept = 0;
@@ -2982,6 +3084,7 @@ try_again:
                        XFS_STATS_INC(xs_log_force_sleep);
                        sv_wait(&iclog->ic_prev->ic_writesema, PSWP,
                                &log->l_icloglock, s);
+                       *log_flushed = 1;
                        already_slept = 1;
                        goto try_again;
                } else {
@@ -2990,6 +3093,7 @@ try_again:
                        LOG_UNLOCK(log, s);
                        if (xlog_state_release_iclog(log, iclog))
                                return XFS_ERROR(EIO);
+                       *log_flushed = 1;
                        s = LOG_LOCK(log);
                }
        }
@@ -3014,6 +3118,7 @@ try_again:
                 */
                if (iclog->ic_state & XLOG_STATE_IOERROR)
                        return XFS_ERROR(EIO);
+               *log_flushed = 1;
        } else {                /* just return */
                LOG_UNLOCK(log, s);
        }
@@ -3022,7 +3127,7 @@ try_again:
     } while (iclog != log->l_iclog);
 
     LOG_UNLOCK(log, s);
-    return (0);
+    return 0;
 }      /* xlog_state_sync */
 
 
@@ -3179,29 +3284,57 @@ xlog_ticket_get(xlog_t          *log,
         * and their unit amount is the total amount of space required.
         *
         * The following lines of code account for non-transaction data
-        * which occupy space in the on-disk log. 
+        * which occupy space in the on-disk log.
+        *
+        * Normal form of a transaction is:
+        * <oph><trans-hdr><start-oph><reg1-oph><reg1><reg2-oph>...<commit-oph>
+        * and then there are LR hdrs, split-recs and roundoff at end of syncs.
+        *
+        * We need to account for all the leadup data and trailer data
+        * around the transaction data.
+        * And then we need to account for the worst case in terms of using
+        * more space.
+        * The worst case will happen if:
+        * - the placement of the transaction happens to be such that the
+        *   roundoff is at its maximum
+        * - the transaction data is synced before the commit record is synced
+        *   i.e. <transaction-data><roundoff> | <commit-rec><roundoff>
+        *   Therefore the commit record is in its own Log Record.
+        *   This can happen as the commit record is called with its
+        *   own region to xlog_write().
+        *   This then means that in the worst case, roundoff can happen for
+        *   the commit-rec as well.
+        *   The commit-rec is smaller than padding in this scenario and so it is
+        *   not added separately.
         */
 
+       /* for trans header */
+       unit_bytes += sizeof(xlog_op_header_t);
+       unit_bytes += sizeof(xfs_trans_header_t);
+
        /* for start-rec */
-       unit_bytes += sizeof(xlog_op_header_t); 
+       unit_bytes += sizeof(xlog_op_header_t);
 
-       /* for padding */
+       /* for LR headers */
+       num_headers = ((unit_bytes + log->l_iclog_size-1) >> log->l_iclog_size_log);
+       unit_bytes += log->l_iclog_hsize * num_headers;
+
+       /* for commit-rec LR header - note: padding will subsume the ophdr */
+       unit_bytes += log->l_iclog_hsize;
+
+       /* for split-recs - ophdrs added when data split over LRs */
+       unit_bytes += sizeof(xlog_op_header_t) * num_headers;
+
+       /* for roundoff padding for transaction data and one for commit record */
        if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) &&
-               log->l_mp->m_sb.sb_logsunit > 1) {
+           log->l_mp->m_sb.sb_logsunit > 1) {
                /* log su roundoff */
-               unit_bytes += log->l_mp->m_sb.sb_logsunit;  
+               unit_bytes += 2*log->l_mp->m_sb.sb_logsunit;
        } else {
                /* BB roundoff */
-               unit_bytes += BBSIZE;
+               unit_bytes += 2*BBSIZE;
         }
 
-       /* for commit-rec */
-       unit_bytes += sizeof(xlog_op_header_t);
-       /* for LR headers */
-       num_headers = ((unit_bytes + log->l_iclog_size-1) >> log->l_iclog_size_log);
-       unit_bytes += log->l_iclog_hsize * num_headers;
-
        tic->t_unit_res         = unit_bytes;
        tic->t_curr_res         = unit_bytes;
        tic->t_cnt              = cnt;
@@ -3209,10 +3342,13 @@ xlog_ticket_get(xlog_t          *log,
        tic->t_tid              = (xlog_tid_t)((__psint_t)tic & 0xffffffff);
        tic->t_clientid         = client;
        tic->t_flags            = XLOG_TIC_INITED;
+       tic->t_trans_type       = 0;
        if (xflags & XFS_LOG_PERM_RESERV)
                tic->t_flags |= XLOG_TIC_PERM_RESERV;
        sv_init(&(tic->t_sema), SV_DEFAULT, "logtick");
 
+       XLOG_TIC_RESET_RES(tic);
+
        return tic;
 }      /* xlog_ticket_get */
 
@@ -3223,7 +3359,7 @@ xlog_ticket_get(xlog_t            *log,
  *
  ******************************************************************************
  */
-#if defined(DEBUG) && !defined(XLOG_NOLOG)
+#if defined(DEBUG)
 /*
  * Make sure that the destination ptr is within the valid data region of
  * one of the iclogs.  This uses backup pointers stored in a different
@@ -3364,7 +3500,9 @@ xlog_verify_iclog(xlog_t   *log,
                        }
                }
                if (clientid != XFS_TRANSACTION && clientid != XFS_LOG)
-                       cmn_err(CE_WARN, "xlog_verify_iclog: invalid clientid %d op 0x%p offset 0x%x", clientid, ophead, field_offset);
+                       cmn_err(CE_WARN, "xlog_verify_iclog: "
+                               "invalid clientid %d op 0x%p offset 0x%lx",
+                               clientid, ophead, (unsigned long)field_offset);
 
                /* check length */
                field_offset = (__psint_t)
@@ -3385,7 +3523,7 @@ xlog_verify_iclog(xlog_t   *log,
                ptr += sizeof(xlog_op_header_t) + op_len;
        }
 }      /* xlog_verify_iclog */
-#endif /* DEBUG && !XLOG_NOLOG */
+#endif
 
 /*
  * Mark all iclogs IOERROR. LOG_LOCK is held by the caller.
@@ -3407,12 +3545,12 @@ xlog_state_ioerror(
                        ic->ic_state = XLOG_STATE_IOERROR;
                        ic = ic->ic_next;
                } while (ic != iclog);
-               return (0);
+               return 0;
        }
        /*
         * Return non-zero, if state transition has already happened.
         */
-       return (1);
+       return 1;
 }
 
 /*
@@ -3435,6 +3573,7 @@ xfs_log_force_umount(
        xlog_ticket_t   *tic;
        xlog_t          *log;
        int             retval;
+       int             dummy;
        SPLDECL(s);
        SPLDECL(s2);
 
@@ -3448,7 +3587,7 @@ xfs_log_force_umount(
            log->l_flags & XLOG_ACTIVE_RECOVERY) {
                mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN;
                XFS_BUF_DONE(mp->m_sb_bp);
-               return (0);
+               return 0;
        }
 
        /*
@@ -3457,7 +3596,7 @@ xfs_log_force_umount(
         */
        if (logerror && log->l_iclog->ic_state & XLOG_STATE_IOERROR) {
                ASSERT(XLOG_FORCED_SHUTDOWN(log));
-               return (1);
+               return 1;
        }
        retval = 0;
        /*
@@ -3513,7 +3652,7 @@ xfs_log_force_umount(
                 * Force the incore logs to disk before shutting the
                 * log down completely.
                 */
-               xlog_state_sync_all(log, XFS_LOG_FORCE|XFS_LOG_SYNC);
+               xlog_state_sync_all(log, XFS_LOG_FORCE|XFS_LOG_SYNC, &dummy);
                s2 = LOG_LOCK(log);
                retval = xlog_state_ioerror(log);
                LOG_UNLOCK(log, s2);
@@ -3539,10 +3678,10 @@ xfs_log_force_umount(
        }
 #endif
        /* return non-zero if log IOERROR transition had already happened */
-       return (retval);
+       return retval;
 }
 
-int
+STATIC int
 xlog_iclogs_empty(xlog_t *log)
 {
        xlog_in_core_t  *iclog;
@@ -3553,8 +3692,8 @@ xlog_iclogs_empty(xlog_t *log)
                 * any language.
                 */
                if (iclog->ic_header.h_num_logops)
-                       return(0);
+                       return 0;
                iclog = iclog->ic_next;
        } while (iclog != log->l_iclog);
-       return(1);
+       return 1;
 }