diff options
author | David Chinner <david@fromorbit.com> | 2008-10-30 02:37:03 -0400 |
---|---|---|
committer | Lachlan McIlroy <lachlan@sgi.com> | 2008-10-30 02:37:03 -0400 |
commit | fce08f2f3bd0d08feeb4cea70e44aa3471d9bb4c (patch) | |
tree | 30bf4d33e61442b459b33c9d0bb3e5fedd3884a2 | |
parent | 493dca6178cf4a6ae2a16c602d6cb455bb7d31bd (diff) |
[XFS] move inode reclaim functions to xfs_sync.c
Background inode reclaim is run by the xfssyncd. Move the reclaim worker
functions to be close to the sync code as the are very similar in
structure and are both run from the same background thread.
SGI-PV: 988142
SGI-Modid: xfs-linux-melb:xfs-kern:32329a
Signed-off-by: David Chinner <david@fromorbit.com>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: Christoph Hellwig <hch@infradead.org>
-rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.c | 91 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.h | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 90 |
4 files changed, 94 insertions, 92 deletions
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index b2b708254ae6..79038ea55b03 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
@@ -583,3 +583,94 @@ xfs_syncd_stop( | |||
583 | kthread_stop(mp->m_sync_task); | 583 | kthread_stop(mp->m_sync_task); |
584 | } | 584 | } |
585 | 585 | ||
586 | int | ||
587 | xfs_finish_reclaim( | ||
588 | xfs_inode_t *ip, | ||
589 | int locked, | ||
590 | int sync_mode) | ||
591 | { | ||
592 | xfs_perag_t *pag = xfs_get_perag(ip->i_mount, ip->i_ino); | ||
593 | |||
594 | /* The hash lock here protects a thread in xfs_iget_core from | ||
595 | * racing with us on linking the inode back with a vnode. | ||
596 | * Once we have the XFS_IRECLAIM flag set it will not touch | ||
597 | * us. | ||
598 | */ | ||
599 | write_lock(&pag->pag_ici_lock); | ||
600 | spin_lock(&ip->i_flags_lock); | ||
601 | if (__xfs_iflags_test(ip, XFS_IRECLAIM) || | ||
602 | !__xfs_iflags_test(ip, XFS_IRECLAIMABLE)) { | ||
603 | spin_unlock(&ip->i_flags_lock); | ||
604 | write_unlock(&pag->pag_ici_lock); | ||
605 | if (locked) { | ||
606 | xfs_ifunlock(ip); | ||
607 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
608 | } | ||
609 | return 1; | ||
610 | } | ||
611 | __xfs_iflags_set(ip, XFS_IRECLAIM); | ||
612 | spin_unlock(&ip->i_flags_lock); | ||
613 | write_unlock(&pag->pag_ici_lock); | ||
614 | xfs_put_perag(ip->i_mount, pag); | ||
615 | |||
616 | /* | ||
617 | * If the inode is still dirty, then flush it out. If the inode | ||
618 | * is not in the AIL, then it will be OK to flush it delwri as | ||
619 | * long as xfs_iflush() does not keep any references to the inode. | ||
620 | * We leave that decision up to xfs_iflush() since it has the | ||
621 | * knowledge of whether it's OK to simply do a delwri flush of | ||
622 | * the inode or whether we need to wait until the inode is | ||
623 | * pulled from the AIL. | ||
624 | * We get the flush lock regardless, though, just to make sure | ||
625 | * we don't free it while it is being flushed. | ||
626 | */ | ||
627 | if (!locked) { | ||
628 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
629 | xfs_iflock(ip); | ||
630 | } | ||
631 | |||
632 | /* | ||
633 | * In the case of a forced shutdown we rely on xfs_iflush() to | ||
634 | * wait for the inode to be unpinned before returning an error. | ||
635 | */ | ||
636 | if (!is_bad_inode(VFS_I(ip)) && xfs_iflush(ip, sync_mode) == 0) { | ||
637 | /* synchronize with xfs_iflush_done */ | ||
638 | xfs_iflock(ip); | ||
639 | xfs_ifunlock(ip); | ||
640 | } | ||
641 | |||
642 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
643 | xfs_ireclaim(ip); | ||
644 | return 0; | ||
645 | } | ||
646 | |||
647 | int | ||
648 | xfs_finish_reclaim_all( | ||
649 | xfs_mount_t *mp, | ||
650 | int noblock, | ||
651 | int mode) | ||
652 | { | ||
653 | xfs_inode_t *ip, *n; | ||
654 | |||
655 | restart: | ||
656 | XFS_MOUNT_ILOCK(mp); | ||
657 | list_for_each_entry_safe(ip, n, &mp->m_del_inodes, i_reclaim) { | ||
658 | if (noblock) { | ||
659 | if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL) == 0) | ||
660 | continue; | ||
661 | if (xfs_ipincount(ip) || | ||
662 | !xfs_iflock_nowait(ip)) { | ||
663 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
664 | continue; | ||
665 | } | ||
666 | } | ||
667 | XFS_MOUNT_IUNLOCK(mp); | ||
668 | if (xfs_finish_reclaim(ip, noblock, mode)) | ||
669 | delay(1); | ||
670 | goto restart; | ||
671 | } | ||
672 | XFS_MOUNT_IUNLOCK(mp); | ||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | |||
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h index 3b49aa3bb5fc..23117a17fdef 100644 --- a/fs/xfs/linux-2.6/xfs_sync.h +++ b/fs/xfs/linux-2.6/xfs_sync.h | |||
@@ -45,4 +45,7 @@ void xfs_quiesce_attr(struct xfs_mount *mp); | |||
45 | void xfs_flush_inode(struct xfs_inode *ip); | 45 | void xfs_flush_inode(struct xfs_inode *ip); |
46 | void xfs_flush_device(struct xfs_inode *ip); | 46 | void xfs_flush_device(struct xfs_inode *ip); |
47 | 47 | ||
48 | int xfs_finish_reclaim(struct xfs_inode *ip, int locked, int sync_mode); | ||
49 | int xfs_finish_reclaim_all(struct xfs_mount *mp, int noblock, int mode); | ||
50 | |||
48 | #endif | 51 | #endif |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 345b43a90eb5..64e50ff9ad23 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -496,8 +496,6 @@ int xfs_isilocked(xfs_inode_t *, uint); | |||
496 | uint xfs_ilock_map_shared(xfs_inode_t *); | 496 | uint xfs_ilock_map_shared(xfs_inode_t *); |
497 | void xfs_iunlock_map_shared(xfs_inode_t *, uint); | 497 | void xfs_iunlock_map_shared(xfs_inode_t *, uint); |
498 | void xfs_ireclaim(xfs_inode_t *); | 498 | void xfs_ireclaim(xfs_inode_t *); |
499 | int xfs_finish_reclaim(xfs_inode_t *, int, int); | ||
500 | int xfs_finish_reclaim_all(struct xfs_mount *, int, int); | ||
501 | 499 | ||
502 | /* | 500 | /* |
503 | * xfs_inode.c prototypes. | 501 | * xfs_inode.c prototypes. |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 7fb577c9f9d8..cdcc835bc5a5 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -2849,96 +2849,6 @@ xfs_reclaim( | |||
2849 | return 0; | 2849 | return 0; |
2850 | } | 2850 | } |
2851 | 2851 | ||
2852 | int | ||
2853 | xfs_finish_reclaim( | ||
2854 | xfs_inode_t *ip, | ||
2855 | int locked, | ||
2856 | int sync_mode) | ||
2857 | { | ||
2858 | xfs_perag_t *pag = xfs_get_perag(ip->i_mount, ip->i_ino); | ||
2859 | |||
2860 | /* The hash lock here protects a thread in xfs_iget_core from | ||
2861 | * racing with us on linking the inode back with a vnode. | ||
2862 | * Once we have the XFS_IRECLAIM flag set it will not touch | ||
2863 | * us. | ||
2864 | */ | ||
2865 | write_lock(&pag->pag_ici_lock); | ||
2866 | spin_lock(&ip->i_flags_lock); | ||
2867 | if (__xfs_iflags_test(ip, XFS_IRECLAIM) || | ||
2868 | !__xfs_iflags_test(ip, XFS_IRECLAIMABLE)) { | ||
2869 | spin_unlock(&ip->i_flags_lock); | ||
2870 | write_unlock(&pag->pag_ici_lock); | ||
2871 | if (locked) { | ||
2872 | xfs_ifunlock(ip); | ||
2873 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
2874 | } | ||
2875 | return 1; | ||
2876 | } | ||
2877 | __xfs_iflags_set(ip, XFS_IRECLAIM); | ||
2878 | spin_unlock(&ip->i_flags_lock); | ||
2879 | write_unlock(&pag->pag_ici_lock); | ||
2880 | xfs_put_perag(ip->i_mount, pag); | ||
2881 | |||
2882 | /* | ||
2883 | * If the inode is still dirty, then flush it out. If the inode | ||
2884 | * is not in the AIL, then it will be OK to flush it delwri as | ||
2885 | * long as xfs_iflush() does not keep any references to the inode. | ||
2886 | * We leave that decision up to xfs_iflush() since it has the | ||
2887 | * knowledge of whether it's OK to simply do a delwri flush of | ||
2888 | * the inode or whether we need to wait until the inode is | ||
2889 | * pulled from the AIL. | ||
2890 | * We get the flush lock regardless, though, just to make sure | ||
2891 | * we don't free it while it is being flushed. | ||
2892 | */ | ||
2893 | if (!locked) { | ||
2894 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
2895 | xfs_iflock(ip); | ||
2896 | } | ||
2897 | |||
2898 | /* | ||
2899 | * In the case of a forced shutdown we rely on xfs_iflush() to | ||
2900 | * wait for the inode to be unpinned before returning an error. | ||
2901 | */ | ||
2902 | if (!is_bad_inode(VFS_I(ip)) && xfs_iflush(ip, sync_mode) == 0) { | ||
2903 | /* synchronize with xfs_iflush_done */ | ||
2904 | xfs_iflock(ip); | ||
2905 | xfs_ifunlock(ip); | ||
2906 | } | ||
2907 | |||
2908 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
2909 | xfs_ireclaim(ip); | ||
2910 | return 0; | ||
2911 | } | ||
2912 | |||
2913 | int | ||
2914 | xfs_finish_reclaim_all( | ||
2915 | xfs_mount_t *mp, | ||
2916 | int noblock, | ||
2917 | int mode) | ||
2918 | { | ||
2919 | xfs_inode_t *ip, *n; | ||
2920 | |||
2921 | restart: | ||
2922 | XFS_MOUNT_ILOCK(mp); | ||
2923 | list_for_each_entry_safe(ip, n, &mp->m_del_inodes, i_reclaim) { | ||
2924 | if (noblock) { | ||
2925 | if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL) == 0) | ||
2926 | continue; | ||
2927 | if (xfs_ipincount(ip) || | ||
2928 | !xfs_iflock_nowait(ip)) { | ||
2929 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
2930 | continue; | ||
2931 | } | ||
2932 | } | ||
2933 | XFS_MOUNT_IUNLOCK(mp); | ||
2934 | if (xfs_finish_reclaim(ip, noblock, mode)) | ||
2935 | delay(1); | ||
2936 | goto restart; | ||
2937 | } | ||
2938 | XFS_MOUNT_IUNLOCK(mp); | ||
2939 | return 0; | ||
2940 | } | ||
2941 | |||
2942 | /* | 2852 | /* |
2943 | * xfs_alloc_file_space() | 2853 | * xfs_alloc_file_space() |
2944 | * This routine allocates disk space for the given file. | 2854 | * This routine allocates disk space for the given file. |