summaryrefslogtreecommitdiffstats
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 65e79b4..ff8d64e 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -43,8 +43,6 @@
#include "xfs_itable.h"
#include "xfs_rw.h"
#include "xfs_acl.h"
-#include "xfs_cap.h"
-#include "xfs_mac.h"
#include "xfs_attr.h"
#include "xfs_inode_item.h"
#include "xfs_buf_item.h"
@@ -134,13 +132,11 @@ STATIC int
xfs_iozero(
struct inode *ip, /* inode */
loff_t pos, /* offset in file */
- size_t count, /* size of data to zero */
- loff_t end_size) /* max file size to set */
+ size_t count) /* size of data to zero */
{
unsigned bytes;
struct page *page;
struct address_space *mapping;
- char *kaddr;
int status;
mapping = ip->i_mapping;
@@ -158,26 +154,21 @@ xfs_iozero(
if (!page)
break;
- kaddr = kmap(page);
status = mapping->a_ops->prepare_write(NULL, page, offset,
offset + bytes);
- if (status) {
+ if (status)
goto unlock;
- }
- memset((void *) (kaddr + offset), 0, bytes);
- flush_dcache_page(page);
+ memclear_highpage_flush(page, offset, bytes);
+
status = mapping->a_ops->commit_write(NULL, page, offset,
offset + bytes);
if (!status) {
pos += bytes;
count -= bytes;
- if (pos > i_size_read(ip))
- i_size_write(ip, pos < end_size ? pos : end_size);
}
unlock:
- kunmap(page);
unlock_page(page);
page_cache_release(page);
if (status)
@@ -449,8 +440,8 @@ STATIC int /* error (positive) */
xfs_zero_last_block(
struct inode *ip,
xfs_iocore_t *io,
- xfs_fsize_t isize,
- xfs_fsize_t end_size)
+ xfs_fsize_t offset,
+ xfs_fsize_t isize)
{
xfs_fileoff_t last_fsb;
xfs_mount_t *mp = io->io_mount;
@@ -459,7 +450,6 @@ xfs_zero_last_block(
int zero_len;
int error = 0;
xfs_bmbt_irec_t imap;
- loff_t loff;
ASSERT(ismrlocked(io->io_lock, MR_UPDATE) != 0);
@@ -494,9 +484,10 @@ xfs_zero_last_block(
*/
XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL| XFS_EXTSIZE_RD);
- loff = XFS_FSB_TO_B(mp, last_fsb);
zero_len = mp->m_sb.sb_blocksize - zero_offset;
- error = xfs_iozero(ip, loff + zero_offset, zero_len, end_size);
+ if (isize + zero_len > offset)
+ zero_len = offset - isize;
+ error = xfs_iozero(ip, isize, zero_len);
XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
ASSERT(error >= 0);
@@ -519,14 +510,15 @@ xfs_zero_eof(
bhv_vnode_t *vp,
xfs_iocore_t *io,
xfs_off_t offset, /* starting I/O offset */
- xfs_fsize_t isize, /* current inode size */
- xfs_fsize_t end_size) /* terminal inode size */
+ xfs_fsize_t isize) /* current inode size */
{
struct inode *ip = vn_to_inode(vp);
xfs_fileoff_t start_zero_fsb;
xfs_fileoff_t end_zero_fsb;
xfs_fileoff_t zero_count_fsb;
xfs_fileoff_t last_fsb;
+ xfs_fileoff_t zero_off;
+ xfs_fsize_t zero_len;
xfs_mount_t *mp = io->io_mount;
int nimaps;
int error = 0;
@@ -540,7 +532,7 @@ xfs_zero_eof(
* First handle zeroing the block on which isize resides.
* We only zero a part of that block so it is handled specially.
*/
- error = xfs_zero_last_block(ip, io, isize, end_size);
+ error = xfs_zero_last_block(ip, io, offset, isize);
if (error) {
ASSERT(ismrlocked(io->io_lock, MR_UPDATE));
ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
@@ -601,10 +593,13 @@ xfs_zero_eof(
*/
XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
- error = xfs_iozero(ip,
- XFS_FSB_TO_B(mp, start_zero_fsb),
- XFS_FSB_TO_B(mp, imap.br_blockcount),
- end_size);
+ zero_off = XFS_FSB_TO_B(mp, start_zero_fsb);
+ zero_len = XFS_FSB_TO_B(mp, imap.br_blockcount);
+
+ if ((zero_off + zero_len) > offset)
+ zero_len = offset - zero_off;
+
+ error = xfs_iozero(ip, zero_off, zero_len);
if (error) {
goto out_lock;
}
@@ -783,8 +778,7 @@ start:
*/
if (pos > isize) {
- error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, pos,
- isize, pos + count);
+ error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, pos, isize);
if (error) {
xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
goto out_unlock_mutex;
OpenPOWER on IntegriCloud