aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_file.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2011-12-18 15:00:11 -0500
committerBen Myers <bpm@sgi.com>2012-01-17 16:08:53 -0500
commitce7ae151ddada3dbf67301464343c154903166b3 (patch)
treedb56a153e7ae07aa5103d001a7d7252dc0891c7e /fs/xfs/xfs_file.c
parentf392e6319a4e9a028b0c8b48f000bb01d660ad53 (diff)
xfs: remove the i_size field in struct xfs_inode
There is no fundamental need to keep an in-memory inode size copy in the XFS inode. We already have the on-disk value in the dinode, and the separate in-memory copy that we need for regular files only in the XFS inode. Remove the xfs_inode i_size field and change the XFS_ISIZE macro to use the VFS inode i_size field for regular files. Switch code that was directly accessing the i_size field in the xfs_inode to XFS_ISIZE, or in cases where we are limited to regular files direct access of the VFS inode i_size field. This also allows dropping some fairly complicated code in the write path which dealt with keeping the xfs_inode i_size uptodate with the VFS i_size that is getting updated inside ->write_end. Note that we do not bother resetting the VFS i_size when truncating a file that gets freed to zero as there is no point in doing so because the VFS inode is no longer in use at this point. Just relax the assert in xfs_ifree to only check the on-disk size instead. Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_file.c')
-rw-r--r--fs/xfs/xfs_file.c45
1 files changed, 11 insertions, 34 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index f675f3d9d7b3..86d5dc260464 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -327,7 +327,7 @@ xfs_file_aio_read(
327 mp->m_rtdev_targp : mp->m_ddev_targp; 327 mp->m_rtdev_targp : mp->m_ddev_targp;
328 if ((iocb->ki_pos & target->bt_smask) || 328 if ((iocb->ki_pos & target->bt_smask) ||
329 (size & target->bt_smask)) { 329 (size & target->bt_smask)) {
330 if (iocb->ki_pos == ip->i_size) 330 if (iocb->ki_pos == i_size_read(inode))
331 return 0; 331 return 0;
332 return -XFS_ERROR(EINVAL); 332 return -XFS_ERROR(EINVAL);
333 } 333 }
@@ -412,30 +412,6 @@ xfs_file_splice_read(
412 return ret; 412 return ret;
413} 413}
414 414
415STATIC void
416xfs_aio_write_isize_update(
417 struct inode *inode,
418 loff_t *ppos,
419 ssize_t bytes_written)
420{
421 struct xfs_inode *ip = XFS_I(inode);
422 xfs_fsize_t isize = i_size_read(inode);
423
424 if (bytes_written > 0)
425 XFS_STATS_ADD(xs_write_bytes, bytes_written);
426
427 if (unlikely(bytes_written < 0 && bytes_written != -EFAULT &&
428 *ppos > isize))
429 *ppos = isize;
430
431 if (*ppos > ip->i_size) {
432 xfs_rw_ilock(ip, XFS_ILOCK_EXCL);
433 if (*ppos > ip->i_size)
434 ip->i_size = *ppos;
435 xfs_rw_iunlock(ip, XFS_ILOCK_EXCL);
436 }
437}
438
439/* 415/*
440 * If this was a direct or synchronous I/O that failed (such as ENOSPC) then 416 * If this was a direct or synchronous I/O that failed (such as ENOSPC) then
441 * part of the I/O may have been written to disk before the error occurred. In 417 * part of the I/O may have been written to disk before the error occurred. In
@@ -451,8 +427,8 @@ xfs_aio_write_newsize_update(
451 xfs_rw_ilock(ip, XFS_ILOCK_EXCL); 427 xfs_rw_ilock(ip, XFS_ILOCK_EXCL);
452 if (new_size == ip->i_new_size) 428 if (new_size == ip->i_new_size)
453 ip->i_new_size = 0; 429 ip->i_new_size = 0;
454 if (ip->i_d.di_size > ip->i_size) 430 if (ip->i_d.di_size > i_size_read(VFS_I(ip)))
455 ip->i_d.di_size = ip->i_size; 431 ip->i_d.di_size = i_size_read(VFS_I(ip));
456 xfs_rw_iunlock(ip, XFS_ILOCK_EXCL); 432 xfs_rw_iunlock(ip, XFS_ILOCK_EXCL);
457 } 433 }
458} 434}
@@ -492,15 +468,16 @@ xfs_file_splice_write(
492 new_size = *ppos + count; 468 new_size = *ppos + count;
493 469
494 xfs_ilock(ip, XFS_ILOCK_EXCL); 470 xfs_ilock(ip, XFS_ILOCK_EXCL);
495 if (new_size > ip->i_size) 471 if (new_size > i_size_read(inode))
496 ip->i_new_size = new_size; 472 ip->i_new_size = new_size;
497 xfs_iunlock(ip, XFS_ILOCK_EXCL); 473 xfs_iunlock(ip, XFS_ILOCK_EXCL);
498 474
499 trace_xfs_file_splice_write(ip, count, *ppos, ioflags); 475 trace_xfs_file_splice_write(ip, count, *ppos, ioflags);
500 476
501 ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags); 477 ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags);
478 if (ret > 0)
479 XFS_STATS_ADD(xs_write_bytes, ret);
502 480
503 xfs_aio_write_isize_update(inode, ppos, ret);
504 xfs_aio_write_newsize_update(ip, new_size); 481 xfs_aio_write_newsize_update(ip, new_size);
505 xfs_iunlock(ip, XFS_IOLOCK_EXCL); 482 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
506 return ret; 483 return ret;
@@ -728,14 +705,14 @@ restart:
728 * values are still valid. 705 * values are still valid.
729 */ 706 */
730 if ((ip->i_new_size && *pos > ip->i_new_size) || 707 if ((ip->i_new_size && *pos > ip->i_new_size) ||
731 (!ip->i_new_size && *pos > ip->i_size)) { 708 (!ip->i_new_size && *pos > i_size_read(inode))) {
732 if (*iolock == XFS_IOLOCK_SHARED) { 709 if (*iolock == XFS_IOLOCK_SHARED) {
733 xfs_rw_iunlock(ip, XFS_ILOCK_EXCL | *iolock); 710 xfs_rw_iunlock(ip, XFS_ILOCK_EXCL | *iolock);
734 *iolock = XFS_IOLOCK_EXCL; 711 *iolock = XFS_IOLOCK_EXCL;
735 xfs_rw_ilock(ip, XFS_ILOCK_EXCL | *iolock); 712 xfs_rw_ilock(ip, XFS_ILOCK_EXCL | *iolock);
736 goto restart; 713 goto restart;
737 } 714 }
738 error = -xfs_zero_eof(ip, *pos, ip->i_size); 715 error = -xfs_zero_eof(ip, *pos, i_size_read(inode));
739 } 716 }
740 717
741 /* 718 /*
@@ -744,7 +721,7 @@ restart:
744 * ip->i_new_size if this IO ends beyond any other in-flight writes. 721 * ip->i_new_size if this IO ends beyond any other in-flight writes.
745 */ 722 */
746 new_size = *pos + *count; 723 new_size = *pos + *count;
747 if (new_size > ip->i_size) { 724 if (new_size > i_size_read(inode)) {
748 if (new_size > ip->i_new_size) 725 if (new_size > ip->i_new_size)
749 ip->i_new_size = new_size; 726 ip->i_new_size = new_size;
750 *new_sizep = new_size; 727 *new_sizep = new_size;
@@ -957,11 +934,11 @@ xfs_file_aio_write(
957 ret = xfs_file_buffered_aio_write(iocb, iovp, nr_segs, pos, 934 ret = xfs_file_buffered_aio_write(iocb, iovp, nr_segs, pos,
958 ocount, &new_size, &iolock); 935 ocount, &new_size, &iolock);
959 936
960 xfs_aio_write_isize_update(inode, &iocb->ki_pos, ret);
961
962 if (ret <= 0) 937 if (ret <= 0)
963 goto out_unlock; 938 goto out_unlock;
964 939
940 XFS_STATS_ADD(xs_write_bytes, ret);
941
965 /* Handle various SYNC-type writes */ 942 /* Handle various SYNC-type writes */
966 if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { 943 if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) {
967 loff_t end = pos + ret - 1; 944 loff_t end = pos + ret - 1;