diff options
-rw-r--r-- | fs/xfs/xfs_log.c | 61 | ||||
-rw-r--r-- | fs/xfs/xfs_log.h | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_log_priv.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_super.c | 16 | ||||
-rw-r--r-- | fs/xfs/xfs_sync.c | 39 | ||||
-rw-r--r-- | fs/xfs/xfs_sync.h | 2 |
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 | ||
38 | kmem_zone_t *xfs_log_ticket_zone; | 39 | kmem_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 | */ |
689 | int | 692 | int |
690 | xfs_log_mount_finish(xfs_mount_t *mp) | 693 | xfs_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) | |||
858 | void | 863 | void |
859 | xfs_log_unmount(xfs_mount_t *mp) | 864 | xfs_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 | ||
1169 | void | ||
1170 | xfs_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 | */ | ||
1182 | void | ||
1183 | xfs_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); |
182 | bool xfs_log_item_in_current_chkpt(struct xfs_log_item *lip); | 182 | bool xfs_log_item_in_current_chkpt(struct xfs_log_item *lip); |
183 | 183 | ||
184 | void xfs_log_work_queue(struct xfs_mount *mp); | ||
185 | void 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 | ||
379 | void | ||
380 | xfs_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 | */ | ||
391 | void | ||
392 | xfs_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 | ||
27 | extern struct workqueue_struct *xfs_syncd_wq; /* sync workqueue */ | 27 | extern struct workqueue_struct *xfs_syncd_wq; /* sync workqueue */ |
28 | 28 | ||
29 | void xfs_syncd_queue_sync(struct xfs_mount *mp); | ||
30 | void xfs_sync_worker(struct work_struct *work); | ||
31 | void xfs_flush_worker(struct work_struct *work); | 29 | void xfs_flush_worker(struct work_struct *work); |
32 | void xfs_reclaim_worker(struct work_struct *work); | 30 | void xfs_reclaim_worker(struct work_struct *work); |
33 | 31 | ||