diff options
Diffstat (limited to 'fs/xfs/xfs_log.c')
-rw-r--r-- | fs/xfs/xfs_log.c | 111 |
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 */ |
71 | STATIC int xlog_grant_log_space(xlog_t *log, | 71 | STATIC int xlog_grant_log_space(xlog_t *log, |
72 | xlog_ticket_t *xtic); | 72 | xlog_ticket_t *xtic); |
73 | STATIC void xlog_grant_push_ail(xfs_mount_t *mp, | 73 | STATIC void xlog_grant_push_ail(struct log *log, |
74 | int need_bytes); | 74 | int need_bytes); |
75 | STATIC void xlog_regrant_reserve_log_space(xlog_t *log, | 75 | STATIC 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 | */ |
1187 | STATIC void | 1191 | STATIC void |
1188 | xlog_grant_push_ail(xfs_mount_t *mp, | 1192 | xlog_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); |