Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=71dfd5a396d11512aa6c8ed0d35b268bc084bb9b
Commit:     71dfd5a396d11512aa6c8ed0d35b268bc084bb9b
Parent:     3a02ee1828915d6540b415a160344775e2a4f918
Author:     Lachlan McIlroy <[EMAIL PROTECTED]>
AuthorDate: Tue May 8 13:50:12 2007 +1000
Committer:  Tim Shimmin <[EMAIL PROTECTED]>
CommitDate: Tue May 8 13:50:12 2007 +1000

    [XFS] Fix race in xfs_write() b/w dmapi callout and direct I/O checks.
    
    In xfs_write() the iolock is dropped and reacquired in XFS_SEND_DATA()
    which means that the file could change from not-cached to cached and we
    need to redo the direct I/O checks. We should also redo the direct I/O
    checks when the file size changes regardless if O_APPEND is set or not.
    
    SGI-PV: 963483
    SGI-Modid: xfs-linux-melb:xfs-kern:28440a
    
    Signed-off-by: Lachlan McIlroy <[EMAIL PROTECTED]>
    Signed-off-by: David Chinner <[EMAIL PROTECTED]>
    Signed-off-by: Tim Shimmin <[EMAIL PROTECTED]>
---
 fs/xfs/linux-2.6/xfs_lrw.c |   53 +++++++++++++++++++++----------------------
 1 files changed, 26 insertions(+), 27 deletions(-)

diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 82ab792..b2a1beb 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -724,34 +724,8 @@ start:
                goto out_unlock_mutex;
        }
 
-       if (ioflags & IO_ISDIRECT) {
-               xfs_buftarg_t   *target =
-                       (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
-                               mp->m_rtdev_targp : mp->m_ddev_targp;
-
-               if ((pos & target->bt_smask) || (count & target->bt_smask)) {
-                       xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
-                       return XFS_ERROR(-EINVAL);
-               }
-
-               if (!need_i_mutex && (VN_CACHED(vp) || pos > xip->i_size)) {
-                       xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
-                       iolock = XFS_IOLOCK_EXCL;
-                       locktype = VRWLOCK_WRITE;
-                       need_i_mutex = 1;
-                       mutex_lock(&inode->i_mutex);
-                       xfs_ilock(xip, XFS_ILOCK_EXCL|iolock);
-                       goto start;
-               }
-       }
-
-       new_size = pos + count;
-       if (new_size > xip->i_size)
-               io->io_new_size = new_size;
-
        if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) &&
            !(ioflags & IO_INVIS) && !eventsent)) {
-               loff_t          savedsize = pos;
                int             dmflags = FILP_DELAY_FLAG(file);
 
                if (need_i_mutex)
@@ -774,10 +748,35 @@ start:
                 * event prevents another call to XFS_SEND_DATA, which is
                 * what allows the size to change in the first place.
                 */
-               if ((file->f_flags & O_APPEND) && savedsize != xip->i_size)
+               if ((file->f_flags & O_APPEND) && pos != xip->i_size)
                        goto start;
        }
 
+       if (ioflags & IO_ISDIRECT) {
+               xfs_buftarg_t   *target =
+                       (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
+                               mp->m_rtdev_targp : mp->m_ddev_targp;
+
+               if ((pos & target->bt_smask) || (count & target->bt_smask)) {
+                       xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
+                       return XFS_ERROR(-EINVAL);
+               }
+
+               if (!need_i_mutex && (VN_CACHED(vp) || pos > xip->i_size)) {
+                       xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
+                       iolock = XFS_IOLOCK_EXCL;
+                       locktype = VRWLOCK_WRITE;
+                       need_i_mutex = 1;
+                       mutex_lock(&inode->i_mutex);
+                       xfs_ilock(xip, XFS_ILOCK_EXCL|iolock);
+                       goto start;
+               }
+       }
+
+       new_size = pos + count;
+       if (new_size > xip->i_size)
+               io->io_new_size = new_size;
+
        if (likely(!(ioflags & IO_INVIS))) {
                file_update_time(file);
                xfs_ichgtime_fast(xip, inode,
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to