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;
}
/* 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;
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;
}
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) ?
current->backing_dev_info = NULL;
- if (ret == -EIOCBQUEUED)
+ if (ret == -EIOCBQUEUED && !(ioflags & IO_ISAIO))
ret = wait_on_sync_kiocb(iocb);
if ((ret == -ENOSPC) &&
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);