aboutsummaryrefslogtreecommitdiffstats
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.c111
1 files changed, 54 insertions, 57 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index cc0504e0bb3b..1e2020d5a8b6 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -70,7 +70,7 @@ STATIC void xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog);
70/* local functions to manipulate grant head */ 70/* local functions to manipulate grant head */
71STATIC int xlog_grant_log_space(xlog_t *log, 71STATIC int xlog_grant_log_space(xlog_t *log,
72 xlog_ticket_t *xtic); 72 xlog_ticket_t *xtic);
73STATIC void xlog_grant_push_ail(xfs_mount_t *mp, 73STATIC void xlog_grant_push_ail(struct log *log,
74 int need_bytes); 74 int need_bytes);
75STATIC void xlog_regrant_reserve_log_space(xlog_t *log, 75STATIC void xlog_regrant_reserve_log_space(xlog_t *log,
76 xlog_ticket_t *ticket); 76 xlog_ticket_t *ticket);
@@ -318,7 +318,9 @@ xfs_log_reserve(
318 318
319 trace_xfs_log_reserve(log, internal_ticket); 319 trace_xfs_log_reserve(log, internal_ticket);
320 320
321 xlog_grant_push_ail(mp, internal_ticket->t_unit_res); 321 spin_lock(&log->l_grant_lock);
322 xlog_grant_push_ail(log, internal_ticket->t_unit_res);
323 spin_unlock(&log->l_grant_lock);
322 retval = xlog_regrant_write_log_space(log, internal_ticket); 324 retval = xlog_regrant_write_log_space(log, internal_ticket);
323 } else { 325 } else {
324 /* may sleep if need to allocate more tickets */ 326 /* may sleep if need to allocate more tickets */
@@ -332,9 +334,11 @@ xfs_log_reserve(
332 334
333 trace_xfs_log_reserve(log, internal_ticket); 335 trace_xfs_log_reserve(log, internal_ticket);
334 336
335 xlog_grant_push_ail(mp, 337 spin_lock(&log->l_grant_lock);
338 xlog_grant_push_ail(log,
336 (internal_ticket->t_unit_res * 339 (internal_ticket->t_unit_res *
337 internal_ticket->t_cnt)); 340 internal_ticket->t_cnt));
341 spin_unlock(&log->l_grant_lock);
338 retval = xlog_grant_log_space(log, internal_ticket); 342 retval = xlog_grant_log_space(log, internal_ticket);
339 } 343 }
340 344
@@ -1185,59 +1189,58 @@ xlog_commit_record(
1185 * water mark. In this manner, we would be creating a low water mark. 1189 * water mark. In this manner, we would be creating a low water mark.
1186 */ 1190 */
1187STATIC void 1191STATIC void
1188xlog_grant_push_ail(xfs_mount_t *mp, 1192xlog_grant_push_ail(
1189 int need_bytes) 1193 struct log *log,
1194 int need_bytes)
1190{ 1195{
1191 xlog_t *log = mp->m_log; /* pointer to the log */ 1196 xfs_lsn_t threshold_lsn = 0;
1192 xfs_lsn_t tail_lsn; /* lsn of the log tail */ 1197 xfs_lsn_t tail_lsn;
1193 xfs_lsn_t threshold_lsn = 0; /* lsn we'd like to be at */ 1198 int free_blocks;
1194 int free_blocks; /* free blocks left to write to */ 1199 int free_bytes;
1195 int free_bytes; /* free bytes left to write to */ 1200 int threshold_block;
1196 int threshold_block; /* block in lsn we'd like to be at */ 1201 int threshold_cycle;
1197 int threshold_cycle; /* lsn cycle we'd like to be at */ 1202 int free_threshold;
1198 int free_threshold; 1203
1199 1204 ASSERT(BTOBB(need_bytes) < log->l_logBBsize);
1200 ASSERT(BTOBB(need_bytes) < log->l_logBBsize); 1205
1201 1206 tail_lsn = log->l_tail_lsn;
1202 spin_lock(&log->l_grant_lock); 1207 free_bytes = xlog_space_left(log, &log->l_grant_reserve_head);
1203 free_bytes = xlog_space_left(log, &log->l_grant_reserve_head); 1208 free_blocks = BTOBBT(free_bytes);
1204 tail_lsn = log->l_tail_lsn; 1209
1205 free_blocks = BTOBBT(free_bytes); 1210 /*
1206 1211 * Set the threshold for the minimum number of free blocks in the
1207 /* 1212 * log to the maximum of what the caller needs, one quarter of the
1208 * Set the threshold for the minimum number of free blocks in the 1213 * log, and 256 blocks.
1209 * log to the maximum of what the caller needs, one quarter of the 1214 */
1210 * log, and 256 blocks. 1215 free_threshold = BTOBB(need_bytes);
1211 */ 1216 free_threshold = MAX(free_threshold, (log->l_logBBsize >> 2));
1212 free_threshold = BTOBB(need_bytes); 1217 free_threshold = MAX(free_threshold, 256);
1213 free_threshold = MAX(free_threshold, (log->l_logBBsize >> 2)); 1218 if (free_blocks >= free_threshold)
1214 free_threshold = MAX(free_threshold, 256); 1219 return;
1215 if (free_blocks < free_threshold) { 1220
1216 threshold_block = BLOCK_LSN(tail_lsn) + free_threshold; 1221 threshold_block = BLOCK_LSN(tail_lsn) + free_threshold;
1217 threshold_cycle = CYCLE_LSN(tail_lsn); 1222 threshold_cycle = CYCLE_LSN(tail_lsn);
1218 if (threshold_block >= log->l_logBBsize) { 1223 if (threshold_block >= log->l_logBBsize) {
1219 threshold_block -= log->l_logBBsize; 1224 threshold_block -= log->l_logBBsize;
1220 threshold_cycle += 1; 1225 threshold_cycle += 1;
1221 } 1226 }
1222 threshold_lsn = xlog_assign_lsn(threshold_cycle, threshold_block); 1227 threshold_lsn = xlog_assign_lsn(threshold_cycle,
1223 1228 threshold_block);
1224 /* Don't pass in an lsn greater than the lsn of the last 1229 /*
1230 * Don't pass in an lsn greater than the lsn of the last
1225 * log record known to be on disk. 1231 * log record known to be on disk.
1226 */ 1232 */
1227 if (XFS_LSN_CMP(threshold_lsn, log->l_last_sync_lsn) > 0) 1233 if (XFS_LSN_CMP(threshold_lsn, log->l_last_sync_lsn) > 0)
1228 threshold_lsn = log->l_last_sync_lsn; 1234 threshold_lsn = log->l_last_sync_lsn;
1229 } 1235
1230 spin_unlock(&log->l_grant_lock); 1236 /*
1231 1237 * Get the transaction layer to kick the dirty buffers out to
1232 /* 1238 * disk asynchronously. No point in trying to do this if
1233 * Get the transaction layer to kick the dirty buffers out to 1239 * the filesystem is shutting down.
1234 * disk asynchronously. No point in trying to do this if 1240 */
1235 * the filesystem is shutting down. 1241 if (!XLOG_FORCED_SHUTDOWN(log))
1236 */ 1242 xfs_trans_ail_push(log->l_ailp, threshold_lsn);
1237 if (threshold_lsn && 1243}
1238 !XLOG_FORCED_SHUTDOWN(log))
1239 xfs_trans_ail_push(log->l_ailp, threshold_lsn);
1240} /* xlog_grant_push_ail */
1241 1244
1242/* 1245/*
1243 * The bdstrat callback function for log bufs. This gives us a central 1246 * The bdstrat callback function for log bufs. This gives us a central
@@ -2543,9 +2546,7 @@ redo:
2543 2546
2544 trace_xfs_log_grant_sleep2(log, tic); 2547 trace_xfs_log_grant_sleep2(log, tic);
2545 2548
2546 spin_unlock(&log->l_grant_lock); 2549 xlog_grant_push_ail(log, need_bytes);
2547 xlog_grant_push_ail(log->l_mp, need_bytes);
2548 spin_lock(&log->l_grant_lock);
2549 2550
2550 XFS_STATS_INC(xs_sleep_logspace); 2551 XFS_STATS_INC(xs_sleep_logspace);
2551 xlog_wait(&tic->t_wait, &log->l_grant_lock); 2552 xlog_wait(&tic->t_wait, &log->l_grant_lock);
@@ -2641,9 +2642,7 @@ xlog_regrant_write_log_space(xlog_t *log,
2641 2642
2642 trace_xfs_log_regrant_write_sleep1(log, tic); 2643 trace_xfs_log_regrant_write_sleep1(log, tic);
2643 2644
2644 spin_unlock(&log->l_grant_lock); 2645 xlog_grant_push_ail(log, need_bytes);
2645 xlog_grant_push_ail(log->l_mp, need_bytes);
2646 spin_lock(&log->l_grant_lock);
2647 2646
2648 XFS_STATS_INC(xs_sleep_logspace); 2647 XFS_STATS_INC(xs_sleep_logspace);
2649 xlog_wait(&tic->t_wait, &log->l_grant_lock); 2648 xlog_wait(&tic->t_wait, &log->l_grant_lock);
@@ -2666,9 +2665,7 @@ redo:
2666 if (free_bytes < need_bytes) { 2665 if (free_bytes < need_bytes) {
2667 if (list_empty(&tic->t_queue)) 2666 if (list_empty(&tic->t_queue))
2668 list_add_tail(&tic->t_queue, &log->l_writeq); 2667 list_add_tail(&tic->t_queue, &log->l_writeq);
2669 spin_unlock(&log->l_grant_lock); 2668 xlog_grant_push_ail(log, need_bytes);
2670 xlog_grant_push_ail(log->l_mp, need_bytes);
2671 spin_lock(&log->l_grant_lock);
2672 2669
2673 XFS_STATS_INC(xs_sleep_logspace); 2670 XFS_STATS_INC(xs_sleep_logspace);
2674 trace_xfs_log_regrant_write_sleep2(log, tic); 2671 trace_xfs_log_regrant_write_sleep2(log, tic);