X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fxfs%2Flinux-2.6%2Fxfs_lrw.c;h=9bec802f12061e8ba657a543ac30d7a1d5c381c5;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=903e60e594f1d58f48196df0b882e3737c632652;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 903e60e59..9bec802f1 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c @@ -244,6 +244,7 @@ xfs_read( cred_t *credp) { struct file *file = iocb->ki_filp; + struct inode *inode = file->f_mapping->host; size_t size = 0; ssize_t ret; xfs_fsize_t n; @@ -272,7 +273,7 @@ xfs_read( } /* END copy & waste from filemap.c */ - if (ioflags & IO_ISDIRECT) { + if (unlikely(ioflags & IO_ISDIRECT)) { xfs_buftarg_t *target = (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? mp->m_rtdev_targp : mp->m_ddev_targp; @@ -296,35 +297,39 @@ xfs_read( return -EIO; } + if (unlikely(ioflags & IO_ISDIRECT)) + down(&inode->i_sem); xfs_ilock(ip, XFS_IOLOCK_SHARED); if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && !(ioflags & IO_INVIS)) { vrwlock_t locktype = VRWLOCK_READ; - ret = XFS_SEND_DATA(mp, DM_EVENT_READ, + ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), *offset, size, FILP_DELAY_FLAG(file), &locktype); if (ret) { xfs_iunlock(ip, XFS_IOLOCK_SHARED); - return -ret; + goto unlock_isem; } } xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, (void *)iovp, segs, *offset, ioflags); ret = __generic_file_aio_read(iocb, iovp, segs, offset); - if (ret == -EIOCBQUEUED) + if (ret == -EIOCBQUEUED && !(ioflags & IO_ISAIO)) ret = wait_on_sync_kiocb(iocb); - - xfs_iunlock(ip, XFS_IOLOCK_SHARED); - if (ret > 0) XFS_STATS_ADD(xs_read_bytes, ret); + xfs_iunlock(ip, XFS_IOLOCK_SHARED); + if (likely(!(ioflags & IO_INVIS))) xfs_ichgtime(ip, XFS_ICHGTIME_ACC); +unlock_isem: + if (unlikely(ioflags & IO_ISDIRECT)) + up(&inode->i_sem); return ret; } @@ -671,6 +676,8 @@ xfs_write( if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; + fs_check_frozen(vp->v_vfsp, SB_FREEZE_WRITE); + if (ioflags & IO_ISDIRECT) { xfs_buftarg_t *target = (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? @@ -849,7 +856,7 @@ retry: current->backing_dev_info = NULL; - if (ret == -EIOCBQUEUED) + if (ret == -EIOCBQUEUED && !(ioflags & IO_ISAIO)) ret = wait_on_sync_kiocb(iocb); if ((ret == -ENOSPC) && @@ -955,9 +962,9 @@ retry: xfs_trans_set_sync(tp); error = xfs_trans_commit(tp, 0, NULL); xfs_iunlock(xip, XFS_ILOCK_EXCL); - if (error) - goto out_unlock_internal; } + if (error) + goto out_unlock_internal; } xfs_rwunlock(bdp, locktype);