diff options
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_lrw.c')
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_lrw.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 5d9cfd91ad08..55992b40353c 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
| @@ -264,13 +264,18 @@ 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 | ||
| 271 | if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp))) | 273 | if (unlikely(ioflags & IO_ISDIRECT)) { |
| 272 | bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)), | 274 | if (VN_CACHED(vp)) |
| 273 | -1, FI_REMAPF_LOCKED); | 275 | bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)), |
| 276 | -1, FI_REMAPF_LOCKED); | ||
| 277 | mutex_unlock(&inode->i_mutex); | ||
| 278 | } | ||
| 274 | 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); |
| @@ -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 | |||
| 285 | unlock_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 | } |
