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.c49
1 files changed, 25 insertions, 24 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index ad3d26ddfe31..91b00a5686cd 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -226,20 +226,24 @@ xlog_grant_sub_space(struct log *log, int bytes)
226static void 226static void
227xlog_grant_add_space_write(struct log *log, int bytes) 227xlog_grant_add_space_write(struct log *log, int bytes)
228{ 228{
229 log->l_grant_write_bytes += bytes; 229 int tmp = log->l_logsize - log->l_grant_write_bytes;
230 if (log->l_grant_write_bytes > log->l_logsize) { 230 if (tmp > bytes)
231 log->l_grant_write_bytes -= log->l_logsize; 231 log->l_grant_write_bytes += bytes;
232 else {
232 log->l_grant_write_cycle++; 233 log->l_grant_write_cycle++;
234 log->l_grant_write_bytes = bytes - tmp;
233 } 235 }
234} 236}
235 237
236static void 238static void
237xlog_grant_add_space_reserve(struct log *log, int bytes) 239xlog_grant_add_space_reserve(struct log *log, int bytes)
238{ 240{
239 log->l_grant_reserve_bytes += bytes; 241 int tmp = log->l_logsize - log->l_grant_reserve_bytes;
240 if (log->l_grant_reserve_bytes > log->l_logsize) { 242 if (tmp > bytes)
241 log->l_grant_reserve_bytes -= log->l_logsize; 243 log->l_grant_reserve_bytes += bytes;
244 else {
242 log->l_grant_reserve_cycle++; 245 log->l_grant_reserve_cycle++;
246 log->l_grant_reserve_bytes = bytes - tmp;
243 } 247 }
244} 248}
245 249
@@ -1228,7 +1232,7 @@ xlog_alloc_log(xfs_mount_t *mp,
1228 1232
1229 spin_lock_init(&log->l_icloglock); 1233 spin_lock_init(&log->l_icloglock);
1230 spin_lock_init(&log->l_grant_lock); 1234 spin_lock_init(&log->l_grant_lock);
1231 initnsema(&log->l_flushsema, 0, "ic-flush"); 1235 sv_init(&log->l_flush_wait, 0, "flush_wait");
1232 1236
1233 /* log record size must be multiple of BBSIZE; see xlog_rec_header_t */ 1237 /* log record size must be multiple of BBSIZE; see xlog_rec_header_t */
1234 ASSERT((XFS_BUF_SIZE(bp) & BBMASK) == 0); 1238 ASSERT((XFS_BUF_SIZE(bp) & BBMASK) == 0);
@@ -1570,10 +1574,9 @@ xlog_dealloc_log(xlog_t *log)
1570 } 1574 }
1571#endif 1575#endif
1572 next_iclog = iclog->ic_next; 1576 next_iclog = iclog->ic_next;
1573 kmem_free(iclog, sizeof(xlog_in_core_t)); 1577 kmem_free(iclog);
1574 iclog = next_iclog; 1578 iclog = next_iclog;
1575 } 1579 }
1576 freesema(&log->l_flushsema);
1577 spinlock_destroy(&log->l_icloglock); 1580 spinlock_destroy(&log->l_icloglock);
1578 spinlock_destroy(&log->l_grant_lock); 1581 spinlock_destroy(&log->l_grant_lock);
1579 1582
@@ -1587,7 +1590,7 @@ xlog_dealloc_log(xlog_t *log)
1587 } 1590 }
1588#endif 1591#endif
1589 log->l_mp->m_log = NULL; 1592 log->l_mp->m_log = NULL;
1590 kmem_free(log, sizeof(xlog_t)); 1593 kmem_free(log);
1591} /* xlog_dealloc_log */ 1594} /* xlog_dealloc_log */
1592 1595
1593/* 1596/*
@@ -2097,6 +2100,7 @@ xlog_state_do_callback(
2097 int funcdidcallbacks; /* flag: function did callbacks */ 2100 int funcdidcallbacks; /* flag: function did callbacks */
2098 int repeats; /* for issuing console warnings if 2101 int repeats; /* for issuing console warnings if
2099 * looping too many times */ 2102 * looping too many times */
2103 int wake = 0;
2100 2104
2101 spin_lock(&log->l_icloglock); 2105 spin_lock(&log->l_icloglock);
2102 first_iclog = iclog = log->l_iclog; 2106 first_iclog = iclog = log->l_iclog;
@@ -2278,15 +2282,13 @@ xlog_state_do_callback(
2278 } 2282 }
2279#endif 2283#endif
2280 2284
2281 flushcnt = 0; 2285 if (log->l_iclog->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_IOERROR))
2282 if (log->l_iclog->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_IOERROR)) { 2286 wake = 1;
2283 flushcnt = log->l_flushcnt;
2284 log->l_flushcnt = 0;
2285 }
2286 spin_unlock(&log->l_icloglock); 2287 spin_unlock(&log->l_icloglock);
2287 while (flushcnt--) 2288
2288 vsema(&log->l_flushsema); 2289 if (wake)
2289} /* xlog_state_do_callback */ 2290 sv_broadcast(&log->l_flush_wait);
2291}
2290 2292
2291 2293
2292/* 2294/*
@@ -2384,16 +2386,15 @@ restart:
2384 } 2386 }
2385 2387
2386 iclog = log->l_iclog; 2388 iclog = log->l_iclog;
2387 if (! (iclog->ic_state == XLOG_STATE_ACTIVE)) { 2389 if (iclog->ic_state != XLOG_STATE_ACTIVE) {
2388 log->l_flushcnt++;
2389 spin_unlock(&log->l_icloglock);
2390 xlog_trace_iclog(iclog, XLOG_TRACE_SLEEP_FLUSH); 2390 xlog_trace_iclog(iclog, XLOG_TRACE_SLEEP_FLUSH);
2391 XFS_STATS_INC(xs_log_noiclogs); 2391 XFS_STATS_INC(xs_log_noiclogs);
2392 /* Ensure that log writes happen */ 2392
2393 psema(&log->l_flushsema, PINOD); 2393 /* Wait for log writes to have flushed */
2394 sv_wait(&log->l_flush_wait, 0, &log->l_icloglock, 0);
2394 goto restart; 2395 goto restart;
2395 } 2396 }
2396 ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE); 2397
2397 head = &iclog->ic_header; 2398 head = &iclog->ic_header;
2398 2399
2399 atomic_inc(&iclog->ic_refcnt); /* prevents sync */ 2400 atomic_inc(&iclog->ic_refcnt); /* prevents sync */