patch-2.4.26 linux-2.4.26/fs/xfs/xfs_log.c
Next file: linux-2.4.26/fs/xfs/xfs_log_priv.h
Previous file: linux-2.4.26/fs/xfs/xfs_iomap.c
Back to the patch index
Back to the overall index
- Lines: 260
- Date:
2004-04-14 06:05:40.000000000 -0700
- Orig file:
linux-2.4.25/fs/xfs/xfs_log.c
- Orig date:
2004-02-18 05:36:32.000000000 -0800
diff -urN linux-2.4.25/fs/xfs/xfs_log.c linux-2.4.26/fs/xfs/xfs_log.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004 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
@@ -759,8 +759,9 @@
/* Also an invalid lsn. 1 implies that we aren't passing in a valid
* tail_lsn.
*/
- if (tail_lsn != 1)
+ if (tail_lsn != 1) {
log->l_tail_lsn = tail_lsn;
+ }
if ((tic = log->l_write_headq)) {
#ifdef DEBUG
@@ -866,10 +867,11 @@
tail_lsn = xfs_trans_tail_ail(mp);
s = GRANT_LOCK(log);
- if (tail_lsn != 0)
+ if (tail_lsn != 0) {
log->l_tail_lsn = tail_lsn;
- else
+ } else {
tail_lsn = log->l_tail_lsn = log->l_last_sync_lsn;
+ }
GRANT_UNLOCK(log, s);
return tail_lsn;
@@ -921,10 +923,8 @@
* In this case we just want to return the size of the
* log as the amount of space left.
*/
-/* This assert does not take into account padding from striped log writes *
ASSERT((tail_cycle == (cycle + 1)) ||
((bytes + log->l_roundoff) >= tail_bytes));
-*/
free_bytes = log->l_logsize;
}
return free_bytes;
@@ -940,7 +940,8 @@
void
xlog_iodone(xfs_buf_t *bp)
{
- xlog_in_core_t *iclog;
+ xlog_in_core_t *iclog;
+ xlog_t *l;
int aborted;
iclog = XFS_BUF_FSPRIVATE(bp, xlog_in_core_t *);
@@ -949,18 +950,19 @@
aborted = 0;
/*
+ * Some versions of cpp barf on the recursive definition of
+ * ic_log -> hic_fields.ic_log and expand ic_log twice when
+ * it is passed through two macros. Workaround broken cpp.
+ */
+ l = iclog->ic_log;
+
+ /*
* Race to shutdown the filesystem if we see an error.
*/
- if (XFS_BUF_GETERROR(bp)) {
- /* Some versions of cpp barf on the recursive definition of
- * ic_log -> hic_fields.ic_log and expand ic_log twice when
- * it is passed through two macros. Workaround for broken cpp
- */
- struct log *l;
- xfs_ioerror_alert("xlog_iodone",
- iclog->ic_log->l_mp, bp, XFS_BUF_ADDR(bp));
+ if (XFS_TEST_ERROR((XFS_BUF_GETERROR(bp)), l->l_mp,
+ XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) {
+ xfs_ioerror_alert("xlog_iodone", l->l_mp, bp, XFS_BUF_ADDR(bp));
XFS_BUF_STALE(bp);
- l = iclog->ic_log;
xfs_force_shutdown(l->l_mp, XFS_LOG_IO_ERROR);
/*
* This flag will be propagated to the trans-committed
@@ -1183,14 +1185,6 @@
log->l_grant_reserve_cycle = 1;
log->l_grant_write_cycle = 1;
- if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) {
- if (mp->m_sb.sb_logsunit <= 1) {
- log->l_stripemask = 1;
- } else {
- log->l_stripemask = 1 <<
- xfs_highbit32(mp->m_sb.sb_logsunit >> BBSHIFT);
- }
- }
if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb)) {
log->l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT;
ASSERT(log->l_sectbb_log <= mp->m_sectbb_log);
@@ -1235,7 +1229,7 @@
kmem_zalloc(sizeof(xlog_in_core_t), KM_SLEEP);
iclog = *iclogp;
iclog->hic_data = (xlog_in_core_2_t *)
- kmem_alloc(iclogsize, KM_SLEEP);
+ kmem_zalloc(iclogsize, KM_SLEEP);
iclog->ic_prev = prev_iclog;
prev_iclog = iclog;
@@ -1401,45 +1395,35 @@
xfs_caddr_t dptr; /* pointer to byte sized element */
xfs_buf_t *bp;
int i, ops;
- uint roundup;
uint count; /* byte count of bwrite */
+ uint count_init; /* initial count before roundup */
int split = 0; /* split write into two regions */
int error;
XFS_STATS_INC(xs_log_writes);
ASSERT(iclog->ic_refcnt == 0);
+ /* Add for LR header */
+ count_init = log->l_iclog_hsize + iclog->ic_offset;
+
/* Round out the log write size */
- if (iclog->ic_offset & BBMASK) {
- /* count of 0 is already accounted for up in
- * xlog_state_sync_all(). Once in this routine,
- * operations on the iclog are single threaded.
- *
- * Difference between rounded up size and size
- */
- count = iclog->ic_offset & BBMASK;
- iclog->ic_roundoff += BBSIZE - count;
- }
- if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
- unsigned sunit = BTOBB(log->l_mp->m_sb.sb_logsunit);
- if (!sunit)
- sunit = 1;
-
- count = BTOBB(log->l_iclog_hsize + iclog->ic_offset);
- if (count & (sunit - 1)) {
- roundup = sunit - (count & (sunit - 1));
- } else {
- roundup = 0;
- }
- iclog->ic_offset += BBTOB(roundup);
+ if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) &&
+ log->l_mp->m_sb.sb_logsunit > 1) {
+ /* we have a v2 stripe unit to use */
+ count = XLOG_LSUNITTOB(log, XLOG_BTOLSUNIT(log, count_init));
+ } else {
+ count = BBTOB(BTOBB(count_init));
}
-
+ iclog->ic_roundoff = count - count_init;
log->l_roundoff += iclog->ic_roundoff;
xlog_pack_data(log, iclog); /* put cycle number in every block */
/* real byte length */
- INT_SET(iclog->ic_header.h_len, ARCH_CONVERT, iclog->ic_offset);
+ INT_SET(iclog->ic_header.h_len,
+ ARCH_CONVERT,
+ iclog->ic_offset + iclog->ic_roundoff);
+
/* put ops count in correct order */
ops = iclog->ic_header.h_num_logops;
INT_SET(iclog->ic_header.h_num_logops, ARCH_CONVERT, ops);
@@ -1449,12 +1433,6 @@
XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2);
XFS_BUF_SET_ADDR(bp, BLOCK_LSN(iclog->ic_header.h_lsn, ARCH_CONVERT));
- /* Count is already rounded up to a BBSIZE above */
- count = iclog->ic_offset + iclog->ic_roundoff;
- ASSERT((count & BBMASK) == 0);
-
- /* Add for LR header */
- count += log->l_iclog_hsize;
XFS_STATS_ADD(xs_log_blocks, BTOBB(count));
/* Do we need to split this write into 2 parts? */
@@ -2783,8 +2761,6 @@
xlog_in_core_t *iclog,
int eventual_size)
{
- uint roundup;
-
ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE);
if (!eventual_size)
eventual_size = iclog->ic_offset;
@@ -2797,14 +2773,10 @@
log->l_curr_block += BTOBB(eventual_size)+BTOBB(log->l_iclog_hsize);
/* Round up to next log-sunit */
- if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
- if (log->l_curr_block & (log->l_stripemask - 1)) {
- roundup = log->l_stripemask -
- (log->l_curr_block & (log->l_stripemask - 1));
- } else {
- roundup = 0;
- }
- log->l_curr_block += roundup;
+ if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) &&
+ log->l_mp->m_sb.sb_logsunit > 1) {
+ __uint32_t sunit_bb = BTOBB(log->l_mp->m_sb.sb_logsunit);
+ log->l_curr_block = roundup(log->l_curr_block, sunit_bb);
}
if (log->l_curr_block >= log->l_logBBsize) {
@@ -3188,6 +3160,7 @@
uint xflags)
{
xlog_ticket_t *tic;
+ uint num_headers;
SPLDECL(s);
alloc:
@@ -3211,21 +3184,30 @@
* in the log. A unit in this case is the amount of space for one
* of these log operations. Normal reservations have a cnt of 1
* and their unit amount is the total amount of space required.
- * The following line of code adds one log record header length
- * for each part of an operation which may fall on a different
- * log record.
*
- * One more XLOG_HEADER_SIZE is added to account for possible
- * round off errors when syncing a LR to disk. The bytes are
- * subtracted if the thread using this ticket is the first writer
- * to a new LR.
- *
- * We add an extra log header for the possibility that the commit
- * record is the first data written to a new log record. In this
- * case it is separate from the rest of the transaction data and
- * will be charged for the log record header.
+ * The following lines of code account for non-transaction data
+ * which occupy space in the on-disk log.
*/
- unit_bytes += log->l_iclog_hsize * (XLOG_BTOLRBB(unit_bytes) + 2);
+
+ /* for start-rec */
+ unit_bytes += sizeof(xlog_op_header_t);
+
+ /* for padding */
+ if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) &&
+ log->l_mp->m_sb.sb_logsunit > 1) {
+ /* log su roundoff */
+ unit_bytes += log->l_mp->m_sb.sb_logsunit;
+ } else {
+ /* BB roundoff */
+ unit_bytes += 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;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)