summaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorYingping Lu <yingping@sgi.com>2006-03-22 12:44:35 +1100
committerNathan Scott <nathans@sgi.com>2006-03-22 12:44:35 +1100
commit9fa8046f50bcb88ab9183ee1f22de5adc42bf92a (patch)
treedb564e5da4244025afc24e966166e59009f941b3 /fs/xfs
parentf1fdc848aab7fb95b32e058b7f06cc07912b3734 (diff)
downloadop-kernel-dev-9fa8046f50bcb88ab9183ee1f22de5adc42bf92a.zip
op-kernel-dev-9fa8046f50bcb88ab9183ee1f22de5adc42bf92a.tar.gz
[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>
Diffstat (limited to 'fs/xfs')
-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 2424a47..8d2b368 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 8b5a44f..697bf22 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);
OpenPOWER on IntegriCloud