diff options
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 127 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_ail.c | 133 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_priv.h | 15 |
3 files changed, 124 insertions, 151 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index ee0e981aa9d1..67d5b2cddb98 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -816,75 +816,6 @@ xfs_setup_devices( | |||
816 | return 0; | 816 | return 0; |
817 | } | 817 | } |
818 | 818 | ||
819 | /* | ||
820 | * XFS AIL push thread support | ||
821 | */ | ||
822 | void | ||
823 | xfsaild_wakeup( | ||
824 | struct xfs_ail *ailp, | ||
825 | xfs_lsn_t threshold_lsn) | ||
826 | { | ||
827 | /* only ever move the target forwards */ | ||
828 | if (XFS_LSN_CMP(threshold_lsn, ailp->xa_target) > 0) { | ||
829 | ailp->xa_target = threshold_lsn; | ||
830 | wake_up_process(ailp->xa_task); | ||
831 | } | ||
832 | } | ||
833 | |||
834 | STATIC int | ||
835 | xfsaild( | ||
836 | void *data) | ||
837 | { | ||
838 | struct xfs_ail *ailp = data; | ||
839 | xfs_lsn_t last_pushed_lsn = 0; | ||
840 | long tout = 0; /* milliseconds */ | ||
841 | |||
842 | while (!kthread_should_stop()) { | ||
843 | /* | ||
844 | * for short sleeps indicating congestion, don't allow us to | ||
845 | * get woken early. Otherwise all we do is bang on the AIL lock | ||
846 | * without making progress. | ||
847 | */ | ||
848 | if (tout && tout <= 20) | ||
849 | __set_current_state(TASK_KILLABLE); | ||
850 | else | ||
851 | __set_current_state(TASK_INTERRUPTIBLE); | ||
852 | schedule_timeout(tout ? | ||
853 | msecs_to_jiffies(tout) : MAX_SCHEDULE_TIMEOUT); | ||
854 | |||
855 | /* swsusp */ | ||
856 | try_to_freeze(); | ||
857 | |||
858 | ASSERT(ailp->xa_mount->m_log); | ||
859 | if (XFS_FORCED_SHUTDOWN(ailp->xa_mount)) | ||
860 | continue; | ||
861 | |||
862 | tout = xfsaild_push(ailp, &last_pushed_lsn); | ||
863 | } | ||
864 | |||
865 | return 0; | ||
866 | } /* xfsaild */ | ||
867 | |||
868 | int | ||
869 | xfsaild_start( | ||
870 | struct xfs_ail *ailp) | ||
871 | { | ||
872 | ailp->xa_target = 0; | ||
873 | ailp->xa_task = kthread_run(xfsaild, ailp, "xfsaild/%s", | ||
874 | ailp->xa_mount->m_fsname); | ||
875 | if (IS_ERR(ailp->xa_task)) | ||
876 | return -PTR_ERR(ailp->xa_task); | ||
877 | return 0; | ||
878 | } | ||
879 | |||
880 | void | ||
881 | xfsaild_stop( | ||
882 | struct xfs_ail *ailp) | ||
883 | { | ||
884 | kthread_stop(ailp->xa_task); | ||
885 | } | ||
886 | |||
887 | |||
888 | /* Catch misguided souls that try to use this interface on XFS */ | 819 | /* Catch misguided souls that try to use this interface on XFS */ |
889 | STATIC struct inode * | 820 | STATIC struct inode * |
890 | xfs_fs_alloc_inode( | 821 | xfs_fs_alloc_inode( |
@@ -1786,6 +1717,38 @@ xfs_destroy_zones(void) | |||
1786 | } | 1717 | } |
1787 | 1718 | ||
1788 | STATIC int __init | 1719 | STATIC int __init |
1720 | xfs_init_workqueues(void) | ||
1721 | { | ||
1722 | /* | ||
1723 | * max_active is set to 8 to give enough concurency to allow | ||
1724 | * multiple work operations on each CPU to run. This allows multiple | ||
1725 | * filesystems to be running sync work concurrently, and scales with | ||
1726 | * the number of CPUs in the system. | ||
1727 | */ | ||
1728 | xfs_syncd_wq = alloc_workqueue("xfssyncd", WQ_CPU_INTENSIVE, 8); | ||
1729 | if (!xfs_syncd_wq) | ||
1730 | goto out; | ||
1731 | |||
1732 | xfs_ail_wq = alloc_workqueue("xfsail", WQ_CPU_INTENSIVE, 8); | ||
1733 | if (!xfs_ail_wq) | ||
1734 | goto out_destroy_syncd; | ||
1735 | |||
1736 | return 0; | ||
1737 | |||
1738 | out_destroy_syncd: | ||
1739 | destroy_workqueue(xfs_syncd_wq); | ||
1740 | out: | ||
1741 | return -ENOMEM; | ||
1742 | } | ||
1743 | |||
1744 | STATIC void __exit | ||
1745 | xfs_destroy_workqueues(void) | ||
1746 | { | ||
1747 | destroy_workqueue(xfs_ail_wq); | ||
1748 | destroy_workqueue(xfs_syncd_wq); | ||
1749 | } | ||
1750 | |||
1751 | STATIC int __init | ||
1789 | init_xfs_fs(void) | 1752 | init_xfs_fs(void) |
1790 | { | 1753 | { |
1791 | int error; | 1754 | int error; |
@@ -1800,10 +1763,14 @@ init_xfs_fs(void) | |||
1800 | if (error) | 1763 | if (error) |
1801 | goto out; | 1764 | goto out; |
1802 | 1765 | ||
1803 | error = xfs_mru_cache_init(); | 1766 | error = xfs_init_workqueues(); |
1804 | if (error) | 1767 | if (error) |
1805 | goto out_destroy_zones; | 1768 | goto out_destroy_zones; |
1806 | 1769 | ||
1770 | error = xfs_mru_cache_init(); | ||
1771 | if (error) | ||
1772 | goto out_destroy_wq; | ||
1773 | |||
1807 | error = xfs_filestream_init(); | 1774 | error = xfs_filestream_init(); |
1808 | if (error) | 1775 | if (error) |
1809 | goto out_mru_cache_uninit; | 1776 | goto out_mru_cache_uninit; |
@@ -1820,27 +1787,17 @@ init_xfs_fs(void) | |||
1820 | if (error) | 1787 | if (error) |
1821 | goto out_cleanup_procfs; | 1788 | goto out_cleanup_procfs; |
1822 | 1789 | ||
1823 | /* | 1790 | error = xfs_init_workqueues(); |
1824 | * max_active is set to 8 to give enough concurency to allow | 1791 | if (error) |
1825 | * multiple work operations on each CPU to run. This allows multiple | ||
1826 | * filesystems to be running sync work concurrently, and scales with | ||
1827 | * the number of CPUs in the system. | ||
1828 | */ | ||
1829 | xfs_syncd_wq = alloc_workqueue("xfssyncd", WQ_CPU_INTENSIVE, 8); | ||
1830 | if (!xfs_syncd_wq) { | ||
1831 | error = -ENOMEM; | ||
1832 | goto out_sysctl_unregister; | 1792 | goto out_sysctl_unregister; |
1833 | } | ||
1834 | 1793 | ||
1835 | vfs_initquota(); | 1794 | vfs_initquota(); |
1836 | 1795 | ||
1837 | error = register_filesystem(&xfs_fs_type); | 1796 | error = register_filesystem(&xfs_fs_type); |
1838 | if (error) | 1797 | if (error) |
1839 | goto out_destroy_xfs_syncd; | 1798 | goto out_sysctl_unregister; |
1840 | return 0; | 1799 | return 0; |
1841 | 1800 | ||
1842 | out_destroy_xfs_syncd: | ||
1843 | destroy_workqueue(xfs_syncd_wq); | ||
1844 | out_sysctl_unregister: | 1801 | out_sysctl_unregister: |
1845 | xfs_sysctl_unregister(); | 1802 | xfs_sysctl_unregister(); |
1846 | out_cleanup_procfs: | 1803 | out_cleanup_procfs: |
@@ -1851,6 +1808,8 @@ init_xfs_fs(void) | |||
1851 | xfs_filestream_uninit(); | 1808 | xfs_filestream_uninit(); |
1852 | out_mru_cache_uninit: | 1809 | out_mru_cache_uninit: |
1853 | xfs_mru_cache_uninit(); | 1810 | xfs_mru_cache_uninit(); |
1811 | out_destroy_wq: | ||
1812 | xfs_destroy_workqueues(); | ||
1854 | out_destroy_zones: | 1813 | out_destroy_zones: |
1855 | xfs_destroy_zones(); | 1814 | xfs_destroy_zones(); |
1856 | out: | 1815 | out: |
@@ -1862,12 +1821,12 @@ exit_xfs_fs(void) | |||
1862 | { | 1821 | { |
1863 | vfs_exitquota(); | 1822 | vfs_exitquota(); |
1864 | unregister_filesystem(&xfs_fs_type); | 1823 | unregister_filesystem(&xfs_fs_type); |
1865 | destroy_workqueue(xfs_syncd_wq); | ||
1866 | xfs_sysctl_unregister(); | 1824 | xfs_sysctl_unregister(); |
1867 | xfs_cleanup_procfs(); | 1825 | xfs_cleanup_procfs(); |
1868 | xfs_buf_terminate(); | 1826 | xfs_buf_terminate(); |
1869 | xfs_filestream_uninit(); | 1827 | xfs_filestream_uninit(); |
1870 | xfs_mru_cache_uninit(); | 1828 | xfs_mru_cache_uninit(); |
1829 | xfs_destroy_workqueues(); | ||
1871 | xfs_destroy_zones(); | 1830 | xfs_destroy_zones(); |
1872 | } | 1831 | } |
1873 | 1832 | ||
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 12aff9584e29..cb3aeac929bc 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include "xfs_trans_priv.h" | 28 | #include "xfs_trans_priv.h" |
29 | #include "xfs_error.h" | 29 | #include "xfs_error.h" |
30 | 30 | ||
31 | struct workqueue_struct *xfs_ail_wq; /* AIL workqueue */ | ||
32 | |||
31 | STATIC void xfs_ail_splice(struct xfs_ail *, struct list_head *, xfs_lsn_t); | 33 | STATIC void xfs_ail_splice(struct xfs_ail *, struct list_head *, xfs_lsn_t); |
32 | STATIC void xfs_ail_delete(struct xfs_ail *, xfs_log_item_t *); | 34 | STATIC void xfs_ail_delete(struct xfs_ail *, xfs_log_item_t *); |
33 | STATIC xfs_log_item_t * xfs_ail_min(struct xfs_ail *); | 35 | STATIC xfs_log_item_t * xfs_ail_min(struct xfs_ail *); |
@@ -69,36 +71,6 @@ xfs_trans_ail_tail( | |||
69 | } | 71 | } |
70 | 72 | ||
71 | /* | 73 | /* |
72 | * xfs_trans_push_ail | ||
73 | * | ||
74 | * This routine is called to move the tail of the AIL forward. It does this by | ||
75 | * trying to flush items in the AIL whose lsns are below the given | ||
76 | * threshold_lsn. | ||
77 | * | ||
78 | * the push is run asynchronously in a separate thread, so we return the tail | ||
79 | * of the log right now instead of the tail after the push. This means we will | ||
80 | * either continue right away, or we will sleep waiting on the async thread to | ||
81 | * do its work. | ||
82 | * | ||
83 | * We do this unlocked - we only need to know whether there is anything in the | ||
84 | * AIL at the time we are called. We don't need to access the contents of | ||
85 | * any of the objects, so the lock is not needed. | ||
86 | */ | ||
87 | void | ||
88 | xfs_trans_ail_push( | ||
89 | struct xfs_ail *ailp, | ||
90 | xfs_lsn_t threshold_lsn) | ||
91 | { | ||
92 | xfs_log_item_t *lip; | ||
93 | |||
94 | lip = xfs_ail_min(ailp); | ||
95 | if (lip && !XFS_FORCED_SHUTDOWN(ailp->xa_mount)) { | ||
96 | if (XFS_LSN_CMP(threshold_lsn, ailp->xa_target) > 0) | ||
97 | xfsaild_wakeup(ailp, threshold_lsn); | ||
98 | } | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * AIL traversal cursor initialisation. | 74 | * AIL traversal cursor initialisation. |
103 | * | 75 | * |
104 | * The cursor keeps track of where our current traversal is up | 76 | * The cursor keeps track of where our current traversal is up |
@@ -236,16 +208,16 @@ out: | |||
236 | } | 208 | } |
237 | 209 | ||
238 | /* | 210 | /* |
239 | * xfsaild_push does the work of pushing on the AIL. Returning a timeout of | 211 | * xfs_ail_worker does the work of pushing on the AIL. It will requeue itself |
240 | * zero indicates that the caller should sleep until woken. | 212 | * to run at a later time if there is more work to do to complete the push. |
241 | */ | 213 | */ |
242 | long | 214 | STATIC void |
243 | xfsaild_push( | 215 | xfs_ail_worker( |
244 | struct xfs_ail *ailp, | 216 | struct work_struct *work) |
245 | xfs_lsn_t *last_lsn) | ||
246 | { | 217 | { |
247 | long tout = 0; | 218 | struct xfs_ail *ailp = container_of(to_delayed_work(work), |
248 | xfs_lsn_t last_pushed_lsn = *last_lsn; | 219 | struct xfs_ail, xa_work); |
220 | long tout; | ||
249 | xfs_lsn_t target = ailp->xa_target; | 221 | xfs_lsn_t target = ailp->xa_target; |
250 | xfs_lsn_t lsn; | 222 | xfs_lsn_t lsn; |
251 | xfs_log_item_t *lip; | 223 | xfs_log_item_t *lip; |
@@ -256,15 +228,15 @@ xfsaild_push( | |||
256 | 228 | ||
257 | spin_lock(&ailp->xa_lock); | 229 | spin_lock(&ailp->xa_lock); |
258 | xfs_trans_ail_cursor_init(ailp, cur); | 230 | xfs_trans_ail_cursor_init(ailp, cur); |
259 | lip = xfs_trans_ail_cursor_first(ailp, cur, *last_lsn); | 231 | lip = xfs_trans_ail_cursor_first(ailp, cur, ailp->xa_last_pushed_lsn); |
260 | if (!lip || XFS_FORCED_SHUTDOWN(mp)) { | 232 | if (!lip || XFS_FORCED_SHUTDOWN(mp)) { |
261 | /* | 233 | /* |
262 | * AIL is empty or our push has reached the end. | 234 | * AIL is empty or our push has reached the end. |
263 | */ | 235 | */ |
264 | xfs_trans_ail_cursor_done(ailp, cur); | 236 | xfs_trans_ail_cursor_done(ailp, cur); |
265 | spin_unlock(&ailp->xa_lock); | 237 | spin_unlock(&ailp->xa_lock); |
266 | *last_lsn = 0; | 238 | ailp->xa_last_pushed_lsn = 0; |
267 | return tout; | 239 | return; |
268 | } | 240 | } |
269 | 241 | ||
270 | XFS_STATS_INC(xs_push_ail); | 242 | XFS_STATS_INC(xs_push_ail); |
@@ -301,13 +273,13 @@ xfsaild_push( | |||
301 | case XFS_ITEM_SUCCESS: | 273 | case XFS_ITEM_SUCCESS: |
302 | XFS_STATS_INC(xs_push_ail_success); | 274 | XFS_STATS_INC(xs_push_ail_success); |
303 | IOP_PUSH(lip); | 275 | IOP_PUSH(lip); |
304 | last_pushed_lsn = lsn; | 276 | ailp->xa_last_pushed_lsn = lsn; |
305 | break; | 277 | break; |
306 | 278 | ||
307 | case XFS_ITEM_PUSHBUF: | 279 | case XFS_ITEM_PUSHBUF: |
308 | XFS_STATS_INC(xs_push_ail_pushbuf); | 280 | XFS_STATS_INC(xs_push_ail_pushbuf); |
309 | IOP_PUSHBUF(lip); | 281 | IOP_PUSHBUF(lip); |
310 | last_pushed_lsn = lsn; | 282 | ailp->xa_last_pushed_lsn = lsn; |
311 | push_xfsbufd = 1; | 283 | push_xfsbufd = 1; |
312 | break; | 284 | break; |
313 | 285 | ||
@@ -319,7 +291,7 @@ xfsaild_push( | |||
319 | 291 | ||
320 | case XFS_ITEM_LOCKED: | 292 | case XFS_ITEM_LOCKED: |
321 | XFS_STATS_INC(xs_push_ail_locked); | 293 | XFS_STATS_INC(xs_push_ail_locked); |
322 | last_pushed_lsn = lsn; | 294 | ailp->xa_last_pushed_lsn = lsn; |
323 | stuck++; | 295 | stuck++; |
324 | break; | 296 | break; |
325 | 297 | ||
@@ -374,9 +346,23 @@ xfsaild_push( | |||
374 | wake_up_process(mp->m_ddev_targp->bt_task); | 346 | wake_up_process(mp->m_ddev_targp->bt_task); |
375 | } | 347 | } |
376 | 348 | ||
349 | /* assume we have more work to do in a short while */ | ||
350 | tout = 10; | ||
377 | if (!count) { | 351 | if (!count) { |
378 | /* We're past our target or empty, so idle */ | 352 | /* We're past our target or empty, so idle */ |
379 | last_pushed_lsn = 0; | 353 | ailp->xa_last_pushed_lsn = 0; |
354 | |||
355 | /* | ||
356 | * Check for an updated push target before clearing the | ||
357 | * XFS_AIL_PUSHING_BIT. If the target changed, we've got more | ||
358 | * work to do. Wait a bit longer before starting that work. | ||
359 | */ | ||
360 | smp_rmb(); | ||
361 | if (ailp->xa_target == target) { | ||
362 | clear_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags); | ||
363 | return; | ||
364 | } | ||
365 | tout = 50; | ||
380 | } else if (XFS_LSN_CMP(lsn, target) >= 0) { | 366 | } else if (XFS_LSN_CMP(lsn, target) >= 0) { |
381 | /* | 367 | /* |
382 | * We reached the target so wait a bit longer for I/O to | 368 | * We reached the target so wait a bit longer for I/O to |
@@ -384,7 +370,7 @@ xfsaild_push( | |||
384 | * start the next scan from the start of the AIL. | 370 | * start the next scan from the start of the AIL. |
385 | */ | 371 | */ |
386 | tout = 50; | 372 | tout = 50; |
387 | last_pushed_lsn = 0; | 373 | ailp->xa_last_pushed_lsn = 0; |
388 | } else if ((stuck * 100) / count > 90) { | 374 | } else if ((stuck * 100) / count > 90) { |
389 | /* | 375 | /* |
390 | * Either there is a lot of contention on the AIL or we | 376 | * Either there is a lot of contention on the AIL or we |
@@ -396,14 +382,48 @@ xfsaild_push( | |||
396 | * continuing from where we were. | 382 | * continuing from where we were. |
397 | */ | 383 | */ |
398 | tout = 20; | 384 | tout = 20; |
399 | } else { | ||
400 | /* more to do, but wait a short while before continuing */ | ||
401 | tout = 10; | ||
402 | } | 385 | } |
403 | *last_lsn = last_pushed_lsn; | 386 | |
404 | return tout; | 387 | /* There is more to do, requeue us. */ |
388 | queue_delayed_work(xfs_syncd_wq, &ailp->xa_work, | ||
389 | msecs_to_jiffies(tout)); | ||
405 | } | 390 | } |
406 | 391 | ||
392 | /* | ||
393 | * This routine is called to move the tail of the AIL forward. It does this by | ||
394 | * trying to flush items in the AIL whose lsns are below the given | ||
395 | * threshold_lsn. | ||
396 | * | ||
397 | * The push is run asynchronously in a workqueue, which means the caller needs | ||
398 | * to handle waiting on the async flush for space to become available. | ||
399 | * We don't want to interrupt any push that is in progress, hence we only queue | ||
400 | * work if we set the pushing bit approriately. | ||
401 | * | ||
402 | * We do this unlocked - we only need to know whether there is anything in the | ||
403 | * AIL at the time we are called. We don't need to access the contents of | ||
404 | * any of the objects, so the lock is not needed. | ||
405 | */ | ||
406 | void | ||
407 | xfs_trans_ail_push( | ||
408 | struct xfs_ail *ailp, | ||
409 | xfs_lsn_t threshold_lsn) | ||
410 | { | ||
411 | xfs_log_item_t *lip; | ||
412 | |||
413 | lip = xfs_ail_min(ailp); | ||
414 | if (!lip || XFS_FORCED_SHUTDOWN(ailp->xa_mount) || | ||
415 | XFS_LSN_CMP(threshold_lsn, ailp->xa_target) <= 0) | ||
416 | return; | ||
417 | |||
418 | /* | ||
419 | * Ensure that the new target is noticed in push code before it clears | ||
420 | * the XFS_AIL_PUSHING_BIT. | ||
421 | */ | ||
422 | smp_wmb(); | ||
423 | ailp->xa_target = threshold_lsn; | ||
424 | if (!test_and_set_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags)) | ||
425 | queue_delayed_work(xfs_syncd_wq, &ailp->xa_work, 0); | ||
426 | } | ||
407 | 427 | ||
408 | /* | 428 | /* |
409 | * This is to be called when an item is unlocked that may have | 429 | * This is to be called when an item is unlocked that may have |
@@ -615,7 +635,6 @@ xfs_trans_ail_init( | |||
615 | xfs_mount_t *mp) | 635 | xfs_mount_t *mp) |
616 | { | 636 | { |
617 | struct xfs_ail *ailp; | 637 | struct xfs_ail *ailp; |
618 | int error; | ||
619 | 638 | ||
620 | ailp = kmem_zalloc(sizeof(struct xfs_ail), KM_MAYFAIL); | 639 | ailp = kmem_zalloc(sizeof(struct xfs_ail), KM_MAYFAIL); |
621 | if (!ailp) | 640 | if (!ailp) |
@@ -624,15 +643,9 @@ xfs_trans_ail_init( | |||
624 | ailp->xa_mount = mp; | 643 | ailp->xa_mount = mp; |
625 | INIT_LIST_HEAD(&ailp->xa_ail); | 644 | INIT_LIST_HEAD(&ailp->xa_ail); |
626 | spin_lock_init(&ailp->xa_lock); | 645 | spin_lock_init(&ailp->xa_lock); |
627 | error = xfsaild_start(ailp); | 646 | INIT_DELAYED_WORK(&ailp->xa_work, xfs_ail_worker); |
628 | if (error) | ||
629 | goto out_free_ailp; | ||
630 | mp->m_ail = ailp; | 647 | mp->m_ail = ailp; |
631 | return 0; | 648 | return 0; |
632 | |||
633 | out_free_ailp: | ||
634 | kmem_free(ailp); | ||
635 | return error; | ||
636 | } | 649 | } |
637 | 650 | ||
638 | void | 651 | void |
@@ -641,7 +654,7 @@ xfs_trans_ail_destroy( | |||
641 | { | 654 | { |
642 | struct xfs_ail *ailp = mp->m_ail; | 655 | struct xfs_ail *ailp = mp->m_ail; |
643 | 656 | ||
644 | xfsaild_stop(ailp); | 657 | cancel_delayed_work_sync(&ailp->xa_work); |
645 | kmem_free(ailp); | 658 | kmem_free(ailp); |
646 | } | 659 | } |
647 | 660 | ||
diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h index 35162c238fa3..6ebd322bd37c 100644 --- a/fs/xfs/xfs_trans_priv.h +++ b/fs/xfs/xfs_trans_priv.h | |||
@@ -65,16 +65,22 @@ struct xfs_ail_cursor { | |||
65 | struct xfs_ail { | 65 | struct xfs_ail { |
66 | struct xfs_mount *xa_mount; | 66 | struct xfs_mount *xa_mount; |
67 | struct list_head xa_ail; | 67 | struct list_head xa_ail; |
68 | uint xa_gen; | ||
69 | struct task_struct *xa_task; | ||
70 | xfs_lsn_t xa_target; | 68 | xfs_lsn_t xa_target; |
71 | struct xfs_ail_cursor xa_cursors; | 69 | struct xfs_ail_cursor xa_cursors; |
72 | spinlock_t xa_lock; | 70 | spinlock_t xa_lock; |
71 | struct delayed_work xa_work; | ||
72 | xfs_lsn_t xa_last_pushed_lsn; | ||
73 | unsigned long xa_flags; | ||
73 | }; | 74 | }; |
74 | 75 | ||
76 | #define XFS_AIL_PUSHING_BIT 0 | ||
77 | |||
75 | /* | 78 | /* |
76 | * From xfs_trans_ail.c | 79 | * From xfs_trans_ail.c |
77 | */ | 80 | */ |
81 | |||
82 | extern struct workqueue_struct *xfs_ail_wq; /* AIL workqueue */ | ||
83 | |||
78 | void xfs_trans_ail_update_bulk(struct xfs_ail *ailp, | 84 | void xfs_trans_ail_update_bulk(struct xfs_ail *ailp, |
79 | struct xfs_log_item **log_items, int nr_items, | 85 | struct xfs_log_item **log_items, int nr_items, |
80 | xfs_lsn_t lsn) __releases(ailp->xa_lock); | 86 | xfs_lsn_t lsn) __releases(ailp->xa_lock); |
@@ -112,11 +118,6 @@ struct xfs_log_item *xfs_trans_ail_cursor_next(struct xfs_ail *ailp, | |||
112 | void xfs_trans_ail_cursor_done(struct xfs_ail *ailp, | 118 | void xfs_trans_ail_cursor_done(struct xfs_ail *ailp, |
113 | struct xfs_ail_cursor *cur); | 119 | struct xfs_ail_cursor *cur); |
114 | 120 | ||
115 | long xfsaild_push(struct xfs_ail *, xfs_lsn_t *); | ||
116 | void xfsaild_wakeup(struct xfs_ail *, xfs_lsn_t); | ||
117 | int xfsaild_start(struct xfs_ail *); | ||
118 | void xfsaild_stop(struct xfs_ail *); | ||
119 | |||
120 | #if BITS_PER_LONG != 64 | 121 | #if BITS_PER_LONG != 64 |
121 | static inline void | 122 | static inline void |
122 | xfs_trans_ail_copy_lsn( | 123 | xfs_trans_ail_copy_lsn( |