diff options
| -rw-r--r-- | fs/xfs/xfs_inode.c | 21 | ||||
| -rw-r--r-- | fs/xfs/xfs_inode.h | 1 | ||||
| -rw-r--r-- | fs/xfs/xfs_sync.c | 11 |
3 files changed, 33 insertions, 0 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index c0237c602f11..755ee8164880 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
| @@ -2835,6 +2835,27 @@ corrupt_out: | |||
| 2835 | return XFS_ERROR(EFSCORRUPTED); | 2835 | return XFS_ERROR(EFSCORRUPTED); |
| 2836 | } | 2836 | } |
| 2837 | 2837 | ||
| 2838 | void | ||
| 2839 | xfs_promote_inode( | ||
| 2840 | struct xfs_inode *ip) | ||
| 2841 | { | ||
| 2842 | struct xfs_buf *bp; | ||
| 2843 | |||
| 2844 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); | ||
| 2845 | |||
| 2846 | bp = xfs_incore(ip->i_mount->m_ddev_targp, ip->i_imap.im_blkno, | ||
| 2847 | ip->i_imap.im_len, XBF_TRYLOCK); | ||
| 2848 | if (!bp) | ||
| 2849 | return; | ||
| 2850 | |||
| 2851 | if (XFS_BUF_ISDELAYWRITE(bp)) { | ||
| 2852 | xfs_buf_delwri_promote(bp); | ||
| 2853 | wake_up_process(ip->i_mount->m_ddev_targp->bt_task); | ||
| 2854 | } | ||
| 2855 | |||
| 2856 | xfs_buf_relse(bp); | ||
| 2857 | } | ||
| 2858 | |||
| 2838 | /* | 2859 | /* |
| 2839 | * Return a pointer to the extent record at file index idx. | 2860 | * Return a pointer to the extent record at file index idx. |
| 2840 | */ | 2861 | */ |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 760140d1dd66..b4cd4739f98e 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
| @@ -498,6 +498,7 @@ int xfs_iunlink(struct xfs_trans *, xfs_inode_t *); | |||
| 498 | void xfs_iext_realloc(xfs_inode_t *, int, int); | 498 | void xfs_iext_realloc(xfs_inode_t *, int, int); |
| 499 | void xfs_iunpin_wait(xfs_inode_t *); | 499 | void xfs_iunpin_wait(xfs_inode_t *); |
| 500 | int xfs_iflush(xfs_inode_t *, uint); | 500 | int xfs_iflush(xfs_inode_t *, uint); |
| 501 | void xfs_promote_inode(struct xfs_inode *); | ||
| 501 | void xfs_lock_inodes(xfs_inode_t **, int, uint); | 502 | void xfs_lock_inodes(xfs_inode_t **, int, uint); |
| 502 | void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint); | 503 | void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint); |
| 503 | 504 | ||
diff --git a/fs/xfs/xfs_sync.c b/fs/xfs/xfs_sync.c index aa3dc1a4d53d..be5c51d8f757 100644 --- a/fs/xfs/xfs_sync.c +++ b/fs/xfs/xfs_sync.c | |||
| @@ -770,6 +770,17 @@ restart: | |||
| 770 | if (!xfs_iflock_nowait(ip)) { | 770 | if (!xfs_iflock_nowait(ip)) { |
| 771 | if (!(sync_mode & SYNC_WAIT)) | 771 | if (!(sync_mode & SYNC_WAIT)) |
| 772 | goto out; | 772 | goto out; |
| 773 | |||
| 774 | /* | ||
| 775 | * If we only have a single dirty inode in a cluster there is | ||
| 776 | * a fair chance that the AIL push may have pushed it into | ||
| 777 | * the buffer, but xfsbufd won't touch it until 30 seconds | ||
| 778 | * from now, and thus we will lock up here. | ||
| 779 | * | ||
| 780 | * Promote the inode buffer to the front of the delwri list | ||
| 781 | * and wake up xfsbufd now. | ||
| 782 | */ | ||
| 783 | xfs_promote_inode(ip); | ||
| 773 | xfs_iflock(ip); | 784 | xfs_iflock(ip); |
| 774 | } | 785 | } |
| 775 | 786 | ||
