aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/linux-2.6')
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c18
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c27
2 files changed, 35 insertions, 10 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index c40f81ba9b13..34dcb43a7837 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -1390,11 +1390,19 @@ xfs_vm_direct_IO(
1390 1390
1391 iocb->private = xfs_alloc_ioend(inode, IOMAP_UNWRITTEN); 1391 iocb->private = xfs_alloc_ioend(inode, IOMAP_UNWRITTEN);
1392 1392
1393 ret = blockdev_direct_IO_own_locking(rw, iocb, inode, 1393 if (rw == WRITE) {
1394 iomap.iomap_target->bt_bdev, 1394 ret = blockdev_direct_IO_own_locking(rw, iocb, inode,
1395 iov, offset, nr_segs, 1395 iomap.iomap_target->bt_bdev,
1396 xfs_get_blocks_direct, 1396 iov, offset, nr_segs,
1397 xfs_end_io_direct); 1397 xfs_get_blocks_direct,
1398 xfs_end_io_direct);
1399 } else {
1400 ret = blockdev_direct_IO_no_locking(rw, iocb, inode,
1401 iomap.iomap_target->bt_bdev,
1402 iov, offset, nr_segs,
1403 xfs_get_blocks_direct,
1404 xfs_end_io_direct);
1405 }
1398 1406
1399 if (unlikely(ret <= 0 && iocb->private)) 1407 if (unlikely(ret <= 0 && iocb->private))
1400 xfs_destroy_ioend(iocb->private); 1408 xfs_destroy_ioend(iocb->private);
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 5d9cfd91ad08..ee788b1cb364 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -264,7 +264,9 @@ xfs_read(
264 dmflags, &locktype); 264 dmflags, &locktype);
265 if (ret) { 265 if (ret) {
266 xfs_iunlock(ip, XFS_IOLOCK_SHARED); 266 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
267 goto unlock_mutex; 267 if (unlikely(ioflags & IO_ISDIRECT))
268 mutex_unlock(&inode->i_mutex);
269 return ret;
268 } 270 }
269 } 271 }
270 272
@@ -272,6 +274,9 @@ xfs_read(
272 bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)), 274 bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
273 -1, FI_REMAPF_LOCKED); 275 -1, FI_REMAPF_LOCKED);
274 276
277 if (unlikely(ioflags & IO_ISDIRECT))
278 mutex_unlock(&inode->i_mutex);
279
275 xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, 280 xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
276 (void *)iovp, segs, *offset, ioflags); 281 (void *)iovp, segs, *offset, ioflags);
277 ret = __generic_file_aio_read(iocb, iovp, segs, offset); 282 ret = __generic_file_aio_read(iocb, iovp, segs, offset);
@@ -281,10 +286,6 @@ xfs_read(
281 XFS_STATS_ADD(xs_read_bytes, ret); 286 XFS_STATS_ADD(xs_read_bytes, ret);
282 287
283 xfs_iunlock(ip, XFS_IOLOCK_SHARED); 288 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
284
285unlock_mutex:
286 if (unlikely(ioflags & IO_ISDIRECT))
287 mutex_unlock(&inode->i_mutex);
288 return ret; 289 return ret;
289} 290}
290 291
@@ -390,6 +391,8 @@ xfs_splice_write(
390 xfs_inode_t *ip = XFS_BHVTOI(bdp); 391 xfs_inode_t *ip = XFS_BHVTOI(bdp);
391 xfs_mount_t *mp = ip->i_mount; 392 xfs_mount_t *mp = ip->i_mount;
392 ssize_t ret; 393 ssize_t ret;
394 struct inode *inode = outfilp->f_mapping->host;
395 xfs_fsize_t isize;
393 396
394 XFS_STATS_INC(xs_write_calls); 397 XFS_STATS_INC(xs_write_calls);
395 if (XFS_FORCED_SHUTDOWN(ip->i_mount)) 398 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
@@ -416,6 +419,20 @@ xfs_splice_write(
416 if (ret > 0) 419 if (ret > 0)
417 XFS_STATS_ADD(xs_write_bytes, ret); 420 XFS_STATS_ADD(xs_write_bytes, ret);
418 421
422 isize = i_size_read(inode);
423 if (unlikely(ret < 0 && ret != -EFAULT && *ppos > isize))
424 *ppos = isize;
425
426 if (*ppos > ip->i_d.di_size) {
427 xfs_ilock(ip, XFS_ILOCK_EXCL);
428 if (*ppos > ip->i_d.di_size) {
429 ip->i_d.di_size = *ppos;
430 i_size_write(inode, *ppos);
431 ip->i_update_core = 1;
432 ip->i_update_size = 1;
433 }
434 xfs_iunlock(ip, XFS_ILOCK_EXCL);
435 }
419 xfs_iunlock(ip, XFS_IOLOCK_EXCL); 436 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
420 return ret; 437 return ret;
421} 438}