aboutsummaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_log.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_log.c')
-rw-r--r--fs/xfs/xfs_log.c100
1 files changed, 58 insertions, 42 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 9bfb69e1e88..77c12715a7d 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -252,6 +252,29 @@ xlog_grant_add_space(struct log *log, int bytes)
xlog_grant_add_space_reserve(log, bytes);
}
+static void
+xlog_tic_reset_res(xlog_ticket_t *tic)
+{
+ tic->t_res_num = 0;
+ tic->t_res_arr_sum = 0;
+ tic->t_res_num_ophdrs = 0;
+}
+
+static void
+xlog_tic_add_region(xlog_ticket_t *tic, uint len, uint type)
+{
+ if (tic->t_res_num == XLOG_TIC_LEN_MAX) {
+ /* add to overflow and start again */
+ tic->t_res_o_flow += tic->t_res_arr_sum;
+ tic->t_res_num = 0;
+ tic->t_res_arr_sum = 0;
+ }
+
+ tic->t_res_arr[tic->t_res_num].r_len = len;
+ tic->t_res_arr[tic->t_res_num].r_type = type;
+ tic->t_res_arr_sum += len;
+ tic->t_res_num++;
+}
/*
* NOTES:
@@ -486,7 +509,7 @@ xfs_log_mount(xfs_mount_t *mp,
cmn_err(CE_NOTE,
"!Mounting filesystem \"%s\" in no-recovery mode. Filesystem will be inconsistent.",
mp->m_fsname);
- ASSERT(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY);
+ ASSERT(mp->m_flags & XFS_MOUNT_RDONLY);
}
mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks);
@@ -496,16 +519,15 @@ xfs_log_mount(xfs_mount_t *mp,
* just worked.
*/
if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
- bhv_vfs_t *vfsp = XFS_MTOVFS(mp);
- int error, readonly = (vfsp->vfs_flag & VFS_RDONLY);
+ int error, readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
if (readonly)
- vfsp->vfs_flag &= ~VFS_RDONLY;
+ mp->m_flags &= ~XFS_MOUNT_RDONLY;
error = xlog_recover(mp->m_log);
if (readonly)
- vfsp->vfs_flag |= VFS_RDONLY;
+ mp->m_flags |= XFS_MOUNT_RDONLY;
if (error) {
cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error);
xlog_dealloc_log(mp->m_log);
@@ -537,7 +559,7 @@ xfs_log_mount_finish(xfs_mount_t *mp, int mfsi_flags)
error = xlog_recover_finish(mp->m_log, mfsi_flags);
else {
error = 0;
- ASSERT(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY);
+ ASSERT(mp->m_flags & XFS_MOUNT_RDONLY);
}
return error;
@@ -597,7 +619,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
* Don't write out unmount record on read-only mounts.
* Or, if we are doing a forced umount (typically because of IO errors).
*/
- if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY)
+ if (mp->m_flags & XFS_MOUNT_RDONLY)
return 0;
xfs_log_force(mp, 0, XFS_LOG_FORCE|XFS_LOG_SYNC);
@@ -949,6 +971,19 @@ xlog_iodone(xfs_buf_t *bp)
l = iclog->ic_log;
/*
+ * If the ordered flag has been removed by a lower
+ * layer, it means the underlyin device no longer supports
+ * barrier I/O. Warn loudly and turn off barriers.
+ */
+ if ((l->l_mp->m_flags & XFS_MOUNT_BARRIER) && !XFS_BUF_ORDERED(bp)) {
+ l->l_mp->m_flags &= ~XFS_MOUNT_BARRIER;
+ xfs_fs_cmn_err(CE_WARN, l->l_mp,
+ "xlog_iodone: Barriers are no longer supported"
+ " by device. Disabling barriers\n");
+ xfs_buftrace("XLOG_IODONE BARRIERS OFF", bp);
+ }
+
+ /*
* Race to shutdown the filesystem if we see an error.
*/
if (XFS_TEST_ERROR((XFS_BUF_GETERROR(bp)), l->l_mp,
@@ -1012,10 +1047,7 @@ xlog_bdstrat_cb(struct xfs_buf *bp)
/*
* Return size of each in-core log record buffer.
*
- * Low memory machines only get 2 16KB buffers. We don't want to waste
- * memory here. However, all other machines get at least 2 32KB buffers.
- * The number is hard coded because we don't care about the minimum
- * memory size, just 32MB systems.
+ * All machines get 8 x 32KB buffers by default, unless tuned otherwise.
*
* If the filesystem blocksize is too large, we may need to choose a
* larger size since the directory code currently logs entire blocks.
@@ -1028,17 +1060,10 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp,
int size;
int xhdrs;
- 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;
- }
- } else {
+ if (mp->m_logbufs <= 0)
+ log->l_iclog_bufs = XLOG_MAX_ICLOGS;
+ else
log->l_iclog_bufs = mp->m_logbufs;
- }
/*
* Buffer size passed in from mount system call.
@@ -1069,18 +1094,9 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp,
goto done;
}
- /*
- * Special case machines that have less than 32MB of memory.
- * All machines with more memory use 32KB buffers.
- */
- if (xfs_physmem <= btoc(32*1024*1024)) {
- /* Don't change; min configuration */
- log->l_iclog_size = XLOG_RECORD_BSIZE; /* 16k */
- log->l_iclog_size_log = XLOG_RECORD_BSHIFT;
- } else {
- log->l_iclog_size = XLOG_BIG_RECORD_BSIZE; /* 32k */
- log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT;
- }
+ /* All machines use 32KB buffers by default. */
+ log->l_iclog_size = XLOG_BIG_RECORD_BSIZE;
+ log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT;
/* the default log size is 16k or 32k which is one header sector */
log->l_iclog_hsize = BBSIZE;
@@ -1771,14 +1787,14 @@ xlog_write(xfs_mount_t * mp,
len = 0;
if (ticket->t_flags & XLOG_TIC_INITED) { /* acct for start rec of xact */
len += sizeof(xlog_op_header_t);
- XLOG_TIC_ADD_OPHDR(ticket);
+ ticket->t_res_num_ophdrs++;
}
for (index = 0; index < nentries; index++) {
len += sizeof(xlog_op_header_t); /* each region gets >= 1 */
- XLOG_TIC_ADD_OPHDR(ticket);
+ ticket->t_res_num_ophdrs++;
len += reg[index].i_len;
- XLOG_TIC_ADD_REGION(ticket, reg[index].i_len, reg[index].i_type);
+ xlog_tic_add_region(ticket, reg[index].i_len, reg[index].i_type);
}
contwr = *start_lsn = 0;
@@ -1887,7 +1903,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);
+ ticket->t_res_num_ophdrs++;
}
xlog_verify_dest_ptr(log, ptr);
@@ -2385,7 +2401,7 @@ restart:
*/
if (log_offset == 0) {
ticket->t_curr_res -= log->l_iclog_hsize;
- XLOG_TIC_ADD_REGION(ticket,
+ xlog_tic_add_region(ticket,
log->l_iclog_hsize,
XLOG_REG_TYPE_LRHEADER);
INT_SET(head->h_cycle, ARCH_CONVERT, log->l_curr_cycle);
@@ -2573,7 +2589,7 @@ xlog_regrant_write_log_space(xlog_t *log,
#endif
tic->t_curr_res = tic->t_unit_res;
- XLOG_TIC_RESET_RES(tic);
+ xlog_tic_reset_res(tic);
if (tic->t_cnt > 0)
return 0;
@@ -2714,7 +2730,7 @@ xlog_regrant_reserve_log_space(xlog_t *log,
s = GRANT_LOCK(log);
xlog_grant_sub_space(log, ticket->t_curr_res);
ticket->t_curr_res = ticket->t_unit_res;
- XLOG_TIC_RESET_RES(ticket);
+ xlog_tic_reset_res(ticket);
xlog_trace_loggrant(log, ticket,
"xlog_regrant_reserve_log_space: sub current res");
xlog_verify_grant_head(log, 1);
@@ -2731,7 +2747,7 @@ xlog_regrant_reserve_log_space(xlog_t *log,
xlog_verify_grant_head(log, 0);
GRANT_UNLOCK(log, s);
ticket->t_curr_res = ticket->t_unit_res;
- XLOG_TIC_RESET_RES(ticket);
+ xlog_tic_reset_res(ticket);
} /* xlog_regrant_reserve_log_space */
@@ -3354,7 +3370,7 @@ xlog_ticket_get(xlog_t *log,
tic->t_flags |= XLOG_TIC_PERM_RESERV;
sv_init(&(tic->t_sema), SV_DEFAULT, "logtick");
- XLOG_TIC_RESET_RES(tic);
+ xlog_tic_reset_res(tic);
return tic;
} /* xlog_ticket_get */