aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYingping Lu <yingping@sgi.com>2006-03-21 20:44:35 -0500
committerNathan Scott <nathans@sgi.com>2006-03-21 20:44:35 -0500
commit9fa8046f50bcb88ab9183ee1f22de5adc42bf92a (patch)
treedb564e5da4244025afc24e966166e59009f941b3
parentf1fdc848aab7fb95b32e058b7f06cc07912b3734 (diff)
[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.c3
-rw-r--r--fs/xfs/xfs_vnodeops.c5
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(
1420 1420
1421 mp = ip->i_mount; 1421 mp = ip->i_mount;
1422 vp = XFS_ITOV(ip); 1422 vp = XFS_ITOV(ip);
1423
1424 vn_iowait(vp); /* wait for the completion of any pending DIOs */
1425
1423 /* 1426 /*
1424 * Call VOP_TOSS_PAGES() or VOP_FLUSHINVAL_PAGES() to get rid of pages and buffers 1427 * Call VOP_TOSS_PAGES() or VOP_FLUSHINVAL_PAGES() to get rid of pages and buffers
1425 * overlapping the region being removed. We have to use 1428 * 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(
615 code = xfs_igrow_start(ip, vap->va_size, credp); 615 code = xfs_igrow_start(ip, vap->va_size, credp);
616 } 616 }
617 xfs_iunlock(ip, XFS_ILOCK_EXCL); 617 xfs_iunlock(ip, XFS_ILOCK_EXCL);
618 vn_iowait(vp); /* wait for the completion of any pending DIOs */
618 if (!code) 619 if (!code)
619 code = xfs_itruncate_data(ip, vap->va_size); 620 code = xfs_itruncate_data(ip, vap->va_size);
620 if (code) { 621 if (code) {
@@ -4310,8 +4311,10 @@ xfs_free_file_space(
4310 ASSERT(attr_flags & ATTR_NOLOCK ? attr_flags & ATTR_DMI : 1); 4311 ASSERT(attr_flags & ATTR_NOLOCK ? attr_flags & ATTR_DMI : 1);
4311 if (attr_flags & ATTR_NOLOCK) 4312 if (attr_flags & ATTR_NOLOCK)
4312 need_iolock = 0; 4313 need_iolock = 0;
4313 if (need_iolock) 4314 if (need_iolock) {
4314 xfs_ilock(ip, XFS_IOLOCK_EXCL); 4315 xfs_ilock(ip, XFS_IOLOCK_EXCL);
4316 vn_iowait(vp); /* wait for the completion of any pending DIOs */
4317 }
4315 4318
4316 rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog), 4319 rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog),
4317 (__uint8_t)NBPP); 4320 (__uint8_t)NBPP);