[XFS] Ensure file size updates have been completed before writing inode to disk.
authorLachlan McIlroy <lachlan@sgi.com>
Fri, 14 Sep 2007 05:22:50 +0000 (15:22 +1000)
committerTim Shimmin <tes@chook.melbourne.sgi.com>
Tue, 18 Sep 2007 10:12:51 +0000 (20:12 +1000)
SGI-PV: 968767
SGI-Modid: xfs-linux-melb:xfs-kern:29675a

Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Tim Shimmin <tes@sgi.com>
fs/xfs/linux-2.6/xfs_aops.c
fs/xfs/linux-2.6/xfs_super.c
fs/xfs/xfs_vnodeops.c

index d9c40fe641953a20b9b5fc8059f65b481382f9b7..5f152f60d74d83ce8878fcba2ee16780ee767513 100644 (file)
@@ -181,6 +181,7 @@ xfs_setfilesize(
                ip->i_d.di_size = isize;
                ip->i_update_core = 1;
                ip->i_update_size = 1;
+               mark_inode_dirty_sync(vn_to_inode(ioend->io_vnode));
        }
 
        xfs_iunlock(ip, XFS_ILOCK_EXCL);
index 4528f9a3f304d5e923fa09458bd6aacfd04161c2..491d1f4f202d8d5919ade355c0a212825e8c8a54 100644 (file)
@@ -415,8 +415,10 @@ xfs_fs_write_inode(
 
        if (vp) {
                vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
-               if (sync)
+               if (sync) {
+                       filemap_fdatawait(inode->i_mapping);
                        flags |= FLUSH_SYNC;
+               }
                error = bhv_vop_iflush(vp, flags);
                if (error == EAGAIN)
                        error = sync? bhv_vop_iflush(vp, flags | FLUSH_LOG) : 0;
index 1a5ad8cd97b00d3d8cd24c04961ea075cb5e1635..603459229904e0b6701b4a883b262041967e9a0a 100644 (file)
@@ -1082,6 +1082,9 @@ xfs_fsync(
        if (XFS_FORCED_SHUTDOWN(ip->i_mount))
                return XFS_ERROR(EIO);
 
+       if (flag & FSYNC_DATA)
+               filemap_fdatawait(vn_to_inode(XFS_ITOV(ip))->i_mapping);
+
        /*
         * We always need to make sure that the required inode state
         * is safe on disk.  The vnode might be clean but because
@@ -3769,12 +3772,16 @@ xfs_inode_flush(
                        sync_lsn = log->l_last_sync_lsn;
                        GRANT_UNLOCK(log, s);
 
-                       if ((XFS_LSN_CMP(iip->ili_last_lsn, sync_lsn) <= 0))
-                               return 0;
+                       if ((XFS_LSN_CMP(iip->ili_last_lsn, sync_lsn) > 0)) {
+                               if (flags & FLUSH_SYNC)
+                                       log_flags |= XFS_LOG_SYNC;
+                               error = xfs_log_force(mp, iip->ili_last_lsn, log_flags);
+                               if (error)
+                                       return error;
+                       }
 
-                       if (flags & FLUSH_SYNC)
-                               log_flags |= XFS_LOG_SYNC;
-                       return xfs_log_force(mp, iip->ili_last_lsn, log_flags);
+                       if (ip->i_update_core == 0)
+                               return 0;
                }
        }
 
@@ -3788,9 +3795,6 @@ xfs_inode_flush(
        if (flags & FLUSH_INODE) {
                int     flush_flags;
 
-               if (xfs_ipincount(ip))
-                       return EAGAIN;
-
                if (flags & FLUSH_SYNC) {
                        xfs_ilock(ip, XFS_ILOCK_SHARED);
                        xfs_iflock(ip);