aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_log.c61
-rw-r--r--fs/xfs/xfs_log.h3
-rw-r--r--fs/xfs/xfs_log_priv.h1
-rw-r--r--fs/xfs/xfs_mount.h1
-rw-r--r--fs/xfs/xfs_super.c16
-rw-r--r--fs/xfs/xfs_sync.c39
-rw-r--r--fs/xfs/xfs_sync.h2
7 files changed, 62 insertions, 61 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 7f4f9370d0e7..efea12bfbd6b 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -34,6 +34,7 @@
34#include "xfs_dinode.h" 34#include "xfs_dinode.h"
35#include "xfs_inode.h" 35#include "xfs_inode.h"
36#include "xfs_trace.h" 36#include "xfs_trace.h"
37#include "xfs_fsops.h"
37 38
38kmem_zone_t *xfs_log_ticket_zone; 39kmem_zone_t *xfs_log_ticket_zone;
39 40
@@ -679,25 +680,29 @@ out:
679} 680}
680 681
681/* 682/*
682 * Finish the recovery of the file system. This is separate from 683 * Finish the recovery of the file system. This is separate from the
683 * the xfs_log_mount() call, because it depends on the code in 684 * xfs_log_mount() call, because it depends on the code in xfs_mountfs() to read
684 * xfs_mountfs() to read in the root and real-time bitmap inodes 685 * in the root and real-time bitmap inodes between calling xfs_log_mount() and
685 * between calling xfs_log_mount() and here. 686 * here.
686 * 687 *
687 * mp - ubiquitous xfs mount point structure 688 * If we finish recovery successfully, start the background log work. If we are
689 * not doing recovery, then we have a RO filesystem and we don't need to start
690 * it.
688 */ 691 */
689int 692int
690xfs_log_mount_finish(xfs_mount_t *mp) 693xfs_log_mount_finish(xfs_mount_t *mp)
691{ 694{
692 int error; 695 int error = 0;
693 696
694 if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) 697 if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
695 error = xlog_recover_finish(mp->m_log); 698 error = xlog_recover_finish(mp->m_log);
696 else { 699 if (!error)
697 error = 0; 700 xfs_log_work_queue(mp);
701 } else {
698 ASSERT(mp->m_flags & XFS_MOUNT_RDONLY); 702 ASSERT(mp->m_flags & XFS_MOUNT_RDONLY);
699 } 703 }
700 704
705
701 return error; 706 return error;
702} 707}
703 708
@@ -858,7 +863,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
858void 863void
859xfs_log_unmount(xfs_mount_t *mp) 864xfs_log_unmount(xfs_mount_t *mp)
860{ 865{
861 cancel_delayed_work_sync(&mp->m_sync_work); 866 cancel_delayed_work_sync(&mp->m_log->l_work);
862 xfs_trans_ail_destroy(mp); 867 xfs_trans_ail_destroy(mp);
863 xlog_dealloc_log(mp->m_log); 868 xlog_dealloc_log(mp->m_log);
864} 869}
@@ -1161,6 +1166,40 @@ done:
1161} /* xlog_get_iclog_buffer_size */ 1166} /* xlog_get_iclog_buffer_size */
1162 1167
1163 1168
1169void
1170xfs_log_work_queue(
1171 struct xfs_mount *mp)
1172{
1173 queue_delayed_work(xfs_syncd_wq, &mp->m_log->l_work,
1174 msecs_to_jiffies(xfs_syncd_centisecs * 10));
1175}
1176
1177/*
1178 * Every sync period we need to unpin all items in the AIL and push them to
1179 * disk. If there is nothing dirty, then we might need to cover the log to
1180 * indicate that the filesystem is idle.
1181 */
1182void
1183xfs_log_worker(
1184 struct work_struct *work)
1185{
1186 struct xlog *log = container_of(to_delayed_work(work),
1187 struct xlog, l_work);
1188 struct xfs_mount *mp = log->l_mp;
1189
1190 /* dgc: errors ignored - not fatal and nowhere to report them */
1191 if (xfs_log_need_covered(mp))
1192 xfs_fs_log_dummy(mp);
1193 else
1194 xfs_log_force(mp, 0);
1195
1196 /* start pushing all the metadata that is currently dirty */
1197 xfs_ail_push_all(mp->m_ail);
1198
1199 /* queue us up again */
1200 xfs_log_work_queue(mp);
1201}
1202
1164/* 1203/*
1165 * This routine initializes some of the log structure for a given mount point. 1204 * This routine initializes some of the log structure for a given mount point.
1166 * Its primary purpose is to fill in enough, so recovery can occur. However, 1205 * Its primary purpose is to fill in enough, so recovery can occur. However,
@@ -1195,6 +1234,7 @@ xlog_alloc_log(
1195 log->l_logBBsize = num_bblks; 1234 log->l_logBBsize = num_bblks;
1196 log->l_covered_state = XLOG_STATE_COVER_IDLE; 1235 log->l_covered_state = XLOG_STATE_COVER_IDLE;
1197 log->l_flags |= XLOG_ACTIVE_RECOVERY; 1236 log->l_flags |= XLOG_ACTIVE_RECOVERY;
1237 INIT_DELAYED_WORK(&log->l_work, xfs_log_worker);
1198 1238
1199 log->l_prev_block = -1; 1239 log->l_prev_block = -1;
1200 /* log->l_tail_lsn = 0x100000000LL; cycle = 1; current block = 0 */ 1240 /* log->l_tail_lsn = 0x100000000LL; cycle = 1; current block = 0 */
@@ -3700,3 +3740,4 @@ xlog_iclogs_empty(
3700 } while (iclog != log->l_iclog); 3740 } while (iclog != log->l_iclog);
3701 return 1; 3741 return 1;
3702} 3742}
3743
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h
index 748d312850e2..26ed7de352d7 100644
--- a/fs/xfs/xfs_log.h
+++ b/fs/xfs/xfs_log.h
@@ -181,5 +181,8 @@ int xfs_log_commit_cil(struct xfs_mount *mp, struct xfs_trans *tp,
181 xfs_lsn_t *commit_lsn, int flags); 181 xfs_lsn_t *commit_lsn, int flags);
182bool xfs_log_item_in_current_chkpt(struct xfs_log_item *lip); 182bool xfs_log_item_in_current_chkpt(struct xfs_log_item *lip);
183 183
184void xfs_log_work_queue(struct xfs_mount *mp);
185void xfs_log_worker(struct work_struct *work);
186
184#endif 187#endif
185#endif /* __XFS_LOG_H__ */ 188#endif /* __XFS_LOG_H__ */
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index 18a801d76a42..9a4e0e5ec322 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -495,6 +495,7 @@ struct xlog {
495 struct xfs_buf *l_xbuf; /* extra buffer for log 495 struct xfs_buf *l_xbuf; /* extra buffer for log
496 * wrapping */ 496 * wrapping */
497 struct xfs_buftarg *l_targ; /* buftarg of log */ 497 struct xfs_buftarg *l_targ; /* buftarg of log */
498 struct delayed_work l_work; /* background flush work */
498 uint l_flags; 499 uint l_flags;
499 uint l_quotaoffs_flag; /* XFS_DQ_*, for QUOTAOFFs */ 500 uint l_quotaoffs_flag; /* XFS_DQ_*, for QUOTAOFFs */
500 struct list_head *l_buf_cancel_table; 501 struct list_head *l_buf_cancel_table;
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index deee09e534dc..26e46aeaa3f1 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -197,7 +197,6 @@ typedef struct xfs_mount {
197 struct mutex m_icsb_mutex; /* balancer sync lock */ 197 struct mutex m_icsb_mutex; /* balancer sync lock */
198#endif 198#endif
199 struct xfs_mru_cache *m_filestream; /* per-mount filestream data */ 199 struct xfs_mru_cache *m_filestream; /* per-mount filestream data */
200 struct delayed_work m_sync_work; /* background sync work */
201 struct delayed_work m_reclaim_work; /* background inode reclaim */ 200 struct delayed_work m_reclaim_work; /* background inode reclaim */
202 struct work_struct m_flush_work; /* background inode flush */ 201 struct work_struct m_flush_work; /* background inode flush */
203 __int64_t m_update_flags; /* sb flags we need to update 202 __int64_t m_update_flags; /* sb flags we need to update
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 20fa955d80d1..37c39a155a58 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1005,7 +1005,6 @@ xfs_fs_put_super(
1005{ 1005{
1006 struct xfs_mount *mp = XFS_M(sb); 1006 struct xfs_mount *mp = XFS_M(sb);
1007 1007
1008 cancel_delayed_work_sync(&mp->m_sync_work);
1009 cancel_work_sync(&mp->m_flush_work); 1008 cancel_work_sync(&mp->m_flush_work);
1010 1009
1011 xfs_filestream_unmount(mp); 1010 xfs_filestream_unmount(mp);
@@ -1040,10 +1039,10 @@ xfs_fs_sync_fs(
1040 if (laptop_mode) { 1039 if (laptop_mode) {
1041 /* 1040 /*
1042 * The disk must be active because we're syncing. 1041 * The disk must be active because we're syncing.
1043 * We schedule xfssyncd now (now that the disk is 1042 * We schedule log work now (now that the disk is
1044 * active) instead of later (when it might not be). 1043 * active) instead of later (when it might not be).
1045 */ 1044 */
1046 flush_delayed_work(&mp->m_sync_work); 1045 flush_delayed_work(&mp->m_log->l_work);
1047 } 1046 }
1048 1047
1049 return 0; 1048 return 0;
@@ -1200,7 +1199,7 @@ xfs_fs_remount(
1200 * value if it is non-zero, otherwise go with the default. 1199 * value if it is non-zero, otherwise go with the default.
1201 */ 1200 */
1202 xfs_restore_resvblks(mp); 1201 xfs_restore_resvblks(mp);
1203 xfs_syncd_queue_sync(mp); 1202 xfs_log_work_queue(mp);
1204 } 1203 }
1205 1204
1206 /* rw -> ro */ 1205 /* rw -> ro */
@@ -1246,7 +1245,7 @@ xfs_fs_unfreeze(
1246 struct xfs_mount *mp = XFS_M(sb); 1245 struct xfs_mount *mp = XFS_M(sb);
1247 1246
1248 xfs_restore_resvblks(mp); 1247 xfs_restore_resvblks(mp);
1249 xfs_syncd_queue_sync(mp); 1248 xfs_log_work_queue(mp);
1250 return 0; 1249 return 0;
1251} 1250}
1252 1251
@@ -1326,7 +1325,6 @@ xfs_fs_fill_super(
1326 mutex_init(&mp->m_growlock); 1325 mutex_init(&mp->m_growlock);
1327 atomic_set(&mp->m_active_trans, 0); 1326 atomic_set(&mp->m_active_trans, 0);
1328 INIT_WORK(&mp->m_flush_work, xfs_flush_worker); 1327 INIT_WORK(&mp->m_flush_work, xfs_flush_worker);
1329 INIT_DELAYED_WORK(&mp->m_sync_work, xfs_sync_worker);
1330 INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker); 1328 INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker);
1331 1329
1332 mp->m_super = sb; 1330 mp->m_super = sb;
@@ -1410,12 +1408,6 @@ xfs_fs_fill_super(
1410 goto out_unmount; 1408 goto out_unmount;
1411 } 1409 }
1412 1410
1413 /*
1414 * The filesystem is successfully mounted, so we can start background
1415 * sync work now.
1416 */
1417 xfs_syncd_queue_sync(mp);
1418
1419 return 0; 1411 return 0;
1420 1412
1421 out_filestream_unmount: 1413 out_filestream_unmount:
diff --git a/fs/xfs/xfs_sync.c b/fs/xfs/xfs_sync.c
index e898d1807044..2174555aebb2 100644
--- a/fs/xfs/xfs_sync.c
+++ b/fs/xfs/xfs_sync.c
@@ -19,6 +19,7 @@
19#include "xfs_fs.h" 19#include "xfs_fs.h"
20#include "xfs_types.h" 20#include "xfs_types.h"
21#include "xfs_log.h" 21#include "xfs_log.h"
22#include "xfs_log_priv.h"
22#include "xfs_inum.h" 23#include "xfs_inum.h"
23#include "xfs_trans.h" 24#include "xfs_trans.h"
24#include "xfs_trans_priv.h" 25#include "xfs_trans_priv.h"
@@ -344,8 +345,8 @@ xfs_quiesce_attr(
344 /* flush all pending changes from the AIL */ 345 /* flush all pending changes from the AIL */
345 xfs_ail_push_all_sync(mp->m_ail); 346 xfs_ail_push_all_sync(mp->m_ail);
346 347
347 /* stop background sync work */ 348 /* stop background log work */
348 cancel_delayed_work_sync(&mp->m_sync_work); 349 cancel_delayed_work_sync(&mp->m_log->l_work);
349 350
350 /* 351 /*
351 * Just warn here till VFS can correctly support 352 * Just warn here till VFS can correctly support
@@ -376,40 +377,6 @@ xfs_quiesce_attr(
376 xfs_buf_unlock(mp->m_sb_bp); 377 xfs_buf_unlock(mp->m_sb_bp);
377} 378}
378 379
379void
380xfs_syncd_queue_sync(
381 struct xfs_mount *mp)
382{
383 queue_delayed_work(xfs_syncd_wq, &mp->m_sync_work,
384 msecs_to_jiffies(xfs_syncd_centisecs * 10));
385}
386
387/*
388 * Every sync period we need to push dirty metadata and try to cover the log
389 * to indicate the filesystem is idle and not frozen.
390 */
391void
392xfs_sync_worker(
393 struct work_struct *work)
394{
395 struct xfs_mount *mp = container_of(to_delayed_work(work),
396 struct xfs_mount, m_sync_work);
397 int error;
398
399 /* dgc: errors ignored here */
400 if (mp->m_super->s_writers.frozen == SB_UNFROZEN &&
401 xfs_log_need_covered(mp))
402 error = xfs_fs_log_dummy(mp);
403 else
404 xfs_log_force(mp, 0);
405
406 /* start pushing all the metadata that is currently dirty */
407 xfs_ail_push_all(mp->m_ail);
408
409 /* queue us up again */
410 xfs_syncd_queue_sync(mp);
411}
412
413/* 380/*
414 * Queue a new inode reclaim pass if there are reclaimable inodes and there 381 * Queue a new inode reclaim pass if there are reclaimable inodes and there
415 * isn't a reclaim pass already in progress. By default it runs every 5s based 382 * isn't a reclaim pass already in progress. By default it runs every 5s based
diff --git a/fs/xfs/xfs_sync.h b/fs/xfs/xfs_sync.h
index 3f59e5bed66b..8d58fab72a10 100644
--- a/fs/xfs/xfs_sync.h
+++ b/fs/xfs/xfs_sync.h
@@ -26,8 +26,6 @@ struct xfs_perag;
26 26
27extern struct workqueue_struct *xfs_syncd_wq; /* sync workqueue */ 27extern struct workqueue_struct *xfs_syncd_wq; /* sync workqueue */
28 28
29void xfs_syncd_queue_sync(struct xfs_mount *mp);
30void xfs_sync_worker(struct work_struct *work);
31void xfs_flush_worker(struct work_struct *work); 29void xfs_flush_worker(struct work_struct *work);
32void xfs_reclaim_worker(struct work_struct *work); 30void xfs_reclaim_worker(struct work_struct *work);
33 31