diff options
author | Yingping Lu <yingping@sgi.com> | 2006-03-22 12:44:35 +1100 |
---|---|---|
committer | Nathan Scott <nathans@sgi.com> | 2006-03-22 12:44:35 +1100 |
commit | 9fa8046f50bcb88ab9183ee1f22de5adc42bf92a (patch) | |
tree | db564e5da4244025afc24e966166e59009f941b3 | |
parent | f1fdc848aab7fb95b32e058b7f06cc07912b3734 (diff) | |
download | linux-9fa8046f50bcb88ab9183ee1f22de5adc42bf92a.tar.gz linux-9fa8046f50bcb88ab9183ee1f22de5adc42bf92a.tar.bz2 linux-9fa8046f50bcb88ab9183ee1f22de5adc42bf92a.zip |
[XFS] Fixing the error caused by the conflict between DIO Write's
conversion and concurrent truncate operations. Use vn_iowait to wait for
the completion of any pending DIOs. Since the truncate requires exclusive
IOLOCK, so this blocks any further DIO operations since DIO write also
needs exclusive IOBLOCK. This serves as a barrier and prevent any
potential starvation.
SGI-PV: 947420
SGI-Modid: xfs-linux-melb:xfs-kern:208088a
Signed-off-by: Yingping Lu <yingping@sgi.com>
Signed-off-by: Nathan Scott <nathans@sgi.com>
-rw-r--r-- | fs/xfs/xfs_inode.c | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 5 |
2 files changed, 7 insertions, 1 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 2424a4777949..8d2b36879f06 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1420,6 +1420,9 @@ xfs_itruncate_start( mp = ip->i_mount; vp = XFS_ITOV(ip); + + vn_iowait(vp); /* wait for the completion of any pending DIOs */ + /* * Call VOP_TOSS_PAGES() or VOP_FLUSHINVAL_PAGES() to get rid of pages and buffers * overlapping the region being removed. We have to use diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 8b5a44fe2865..697bf22a84f3 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -615,6 +615,7 @@ xfs_setattr( code = xfs_igrow_start(ip, vap->va_size, credp); } xfs_iunlock(ip, XFS_ILOCK_EXCL); + vn_iowait(vp); /* wait for the completion of any pending DIOs */ if (!code) code = xfs_itruncate_data(ip, vap->va_size); if (code) { @@ -4310,8 +4311,10 @@ xfs_free_file_space( ASSERT(attr_flags & ATTR_NOLOCK ? attr_flags & ATTR_DMI : 1); if (attr_flags & ATTR_NOLOCK) need_iolock = 0; - if (need_iolock) + if (need_iolock) { xfs_ilock(ip, XFS_IOLOCK_EXCL); + vn_iowait(vp); /* wait for the completion of any pending DIOs */ + } rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog), (__uint8_t)NBPP); |