aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_lrw.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_lrw.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c48
1 files changed, 21 insertions, 27 deletions
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 65e79b471d49..ff8d64eba9f8 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -43,8 +43,6 @@
43#include "xfs_itable.h" 43#include "xfs_itable.h"
44#include "xfs_rw.h" 44#include "xfs_rw.h"
45#include "xfs_acl.h" 45#include "xfs_acl.h"
46#include "xfs_cap.h"
47#include "xfs_mac.h"
48#include "xfs_attr.h" 46#include "xfs_attr.h"
49#include "xfs_inode_item.h" 47#include "xfs_inode_item.h"
50#include "xfs_buf_item.h" 48#include "xfs_buf_item.h"
@@ -134,13 +132,11 @@ STATIC int
134xfs_iozero( 132xfs_iozero(
135 struct inode *ip, /* inode */ 133 struct inode *ip, /* inode */
136 loff_t pos, /* offset in file */ 134 loff_t pos, /* offset in file */
137 size_t count, /* size of data to zero */ 135 size_t count) /* size of data to zero */
138 loff_t end_size) /* max file size to set */
139{ 136{
140 unsigned bytes; 137 unsigned bytes;
141 struct page *page; 138 struct page *page;
142 struct address_space *mapping; 139 struct address_space *mapping;
143 char *kaddr;
144 int status; 140 int status;
145 141
146 mapping = ip->i_mapping; 142 mapping = ip->i_mapping;
@@ -158,26 +154,21 @@ xfs_iozero(
158 if (!page) 154 if (!page)
159 break; 155 break;
160 156
161 kaddr = kmap(page);
162 status = mapping->a_ops->prepare_write(NULL, page, offset, 157 status = mapping->a_ops->prepare_write(NULL, page, offset,
163 offset + bytes); 158 offset + bytes);
164 if (status) { 159 if (status)
165 goto unlock; 160 goto unlock;
166 }
167 161
168 memset((void *) (kaddr + offset), 0, bytes); 162 memclear_highpage_flush(page, offset, bytes);
169 flush_dcache_page(page); 163
170 status = mapping->a_ops->commit_write(NULL, page, offset, 164 status = mapping->a_ops->commit_write(NULL, page, offset,
171 offset + bytes); 165 offset + bytes);
172 if (!status) { 166 if (!status) {
173 pos += bytes; 167 pos += bytes;
174 count -= bytes; 168 count -= bytes;
175 if (pos > i_size_read(ip))
176 i_size_write(ip, pos < end_size ? pos : end_size);
177 } 169 }
178 170
179unlock: 171unlock:
180 kunmap(page);
181 unlock_page(page); 172 unlock_page(page);
182 page_cache_release(page); 173 page_cache_release(page);
183 if (status) 174 if (status)
@@ -449,8 +440,8 @@ STATIC int /* error (positive) */
449xfs_zero_last_block( 440xfs_zero_last_block(
450 struct inode *ip, 441 struct inode *ip,
451 xfs_iocore_t *io, 442 xfs_iocore_t *io,
452 xfs_fsize_t isize, 443 xfs_fsize_t offset,
453 xfs_fsize_t end_size) 444 xfs_fsize_t isize)
454{ 445{
455 xfs_fileoff_t last_fsb; 446 xfs_fileoff_t last_fsb;
456 xfs_mount_t *mp = io->io_mount; 447 xfs_mount_t *mp = io->io_mount;
@@ -459,7 +450,6 @@ xfs_zero_last_block(
459 int zero_len; 450 int zero_len;
460 int error = 0; 451 int error = 0;
461 xfs_bmbt_irec_t imap; 452 xfs_bmbt_irec_t imap;
462 loff_t loff;
463 453
464 ASSERT(ismrlocked(io->io_lock, MR_UPDATE) != 0); 454 ASSERT(ismrlocked(io->io_lock, MR_UPDATE) != 0);
465 455
@@ -494,9 +484,10 @@ xfs_zero_last_block(
494 */ 484 */
495 XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL| XFS_EXTSIZE_RD); 485 XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL| XFS_EXTSIZE_RD);
496 486
497 loff = XFS_FSB_TO_B(mp, last_fsb);
498 zero_len = mp->m_sb.sb_blocksize - zero_offset; 487 zero_len = mp->m_sb.sb_blocksize - zero_offset;
499 error = xfs_iozero(ip, loff + zero_offset, zero_len, end_size); 488 if (isize + zero_len > offset)
489 zero_len = offset - isize;
490 error = xfs_iozero(ip, isize, zero_len);
500 491
501 XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); 492 XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
502 ASSERT(error >= 0); 493 ASSERT(error >= 0);
@@ -519,14 +510,15 @@ xfs_zero_eof(
519 bhv_vnode_t *vp, 510 bhv_vnode_t *vp,
520 xfs_iocore_t *io, 511 xfs_iocore_t *io,
521 xfs_off_t offset, /* starting I/O offset */ 512 xfs_off_t offset, /* starting I/O offset */
522 xfs_fsize_t isize, /* current inode size */ 513 xfs_fsize_t isize) /* current inode size */
523 xfs_fsize_t end_size) /* terminal inode size */
524{ 514{
525 struct inode *ip = vn_to_inode(vp); 515 struct inode *ip = vn_to_inode(vp);
526 xfs_fileoff_t start_zero_fsb; 516 xfs_fileoff_t start_zero_fsb;
527 xfs_fileoff_t end_zero_fsb; 517 xfs_fileoff_t end_zero_fsb;
528 xfs_fileoff_t zero_count_fsb; 518 xfs_fileoff_t zero_count_fsb;
529 xfs_fileoff_t last_fsb; 519 xfs_fileoff_t last_fsb;
520 xfs_fileoff_t zero_off;
521 xfs_fsize_t zero_len;
530 xfs_mount_t *mp = io->io_mount; 522 xfs_mount_t *mp = io->io_mount;
531 int nimaps; 523 int nimaps;
532 int error = 0; 524 int error = 0;
@@ -540,7 +532,7 @@ xfs_zero_eof(
540 * First handle zeroing the block on which isize resides. 532 * First handle zeroing the block on which isize resides.
541 * We only zero a part of that block so it is handled specially. 533 * We only zero a part of that block so it is handled specially.
542 */ 534 */
543 error = xfs_zero_last_block(ip, io, isize, end_size); 535 error = xfs_zero_last_block(ip, io, offset, isize);
544 if (error) { 536 if (error) {
545 ASSERT(ismrlocked(io->io_lock, MR_UPDATE)); 537 ASSERT(ismrlocked(io->io_lock, MR_UPDATE));
546 ASSERT(ismrlocked(io->io_iolock, MR_UPDATE)); 538 ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
@@ -601,10 +593,13 @@ xfs_zero_eof(
601 */ 593 */
602 XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); 594 XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
603 595
604 error = xfs_iozero(ip, 596 zero_off = XFS_FSB_TO_B(mp, start_zero_fsb);
605 XFS_FSB_TO_B(mp, start_zero_fsb), 597 zero_len = XFS_FSB_TO_B(mp, imap.br_blockcount);
606 XFS_FSB_TO_B(mp, imap.br_blockcount), 598
607 end_size); 599 if ((zero_off + zero_len) > offset)
600 zero_len = offset - zero_off;
601
602 error = xfs_iozero(ip, zero_off, zero_len);
608 if (error) { 603 if (error) {
609 goto out_lock; 604 goto out_lock;
610 } 605 }
@@ -783,8 +778,7 @@ start:
783 */ 778 */
784 779
785 if (pos > isize) { 780 if (pos > isize) {
786 error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, pos, 781 error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, pos, isize);
787 isize, pos + count);
788 if (error) { 782 if (error) {
789 xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock); 783 xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
790 goto out_unlock_mutex; 784 goto out_unlock_mutex;