From 681601613759accffd8e8ddbc6f942eba7ecbfe5 Mon Sep 17 00:00:00 2001 From: Lachlan McIlroy Date: Sat, 10 Feb 2007 18:36:47 +1100 Subject: [XFS] Fix callers of xfs_iozero() to zero the correct range. The problem is the two callers of xfs_iozero() are rounding out the range to be zeroed to the end of a fsb and in some cases this extends past the new eof. The call to commit_write() in xfs_iozero() will cause the Linux inode's file size to be set too high. SGI-PV: 960788 SGI-Modid: xfs-linux-melb:xfs-kern:28013a Signed-off-by: Lachlan McIlroy Signed-off-by: David Chinner Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_lrw.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'fs/xfs/linux-2.6/xfs_lrw.c') diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 65e79b471d4..50ba4794f19 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c @@ -134,8 +134,7 @@ 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; @@ -172,8 +171,6 @@ xfs_iozero( if (!status) { pos += bytes; count -= bytes; - if (pos > i_size_read(ip)) - i_size_write(ip, pos < end_size ? pos : end_size); } unlock: @@ -449,8 +446,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 +456,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 +490,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 +516,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 +538,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 +599,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 +784,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; -- cgit v1.2.3 From 7bc5306d74922d9b14f507e1164d8dd852a98ad3 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Sat, 10 Feb 2007 18:37:28 +1100 Subject: [XFS] Remove unused header files for MAC and CAP checking functionality. xfs_mac.h and xfs_cap.h provide definitions and macros that aren't used anywhere in XFS at all. They are left-overs from "to be implement at some point in the future" functionality that Irix XFS has. If this functionality ever goes into Linux, it will be provided at a different layer, most likely through the security hooks in the kernel so we will never need this functionality in XFS. Patch provided by Eric Sandeen (sandeen@sandeen.net). SGI-PV: 960895 SGI-Modid: xfs-linux-melb:xfs-kern:28036a Signed-off-by: Eric Sandeen Signed-off-by: David Chinner Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_lrw.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'fs/xfs/linux-2.6/xfs_lrw.c') diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 50ba4794f19..0b5c9b6774c 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" -- cgit v1.2.3 From e7ff6aed8761b2c86cd9ab7083e512de2b8cfa48 Mon Sep 17 00:00:00 2001 From: David Chinner Date: Sat, 10 Feb 2007 18:37:46 +1100 Subject: [XFS] Don't use kmap in xfs_iozero. kmap() is inefficient and does not scale well. kmap_atomic() is a better choice. Use the generic wrapper function instead of open coding the kmap-memset-dcache flush-kunmap stuff. SGI-PV: 960904 SGI-Modid: xfs-linux-melb:xfs-kern:28041a Signed-off-by: David Chinner Signed-off-by: Christoph Hellwig Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_lrw.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'fs/xfs/linux-2.6/xfs_lrw.c') diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 0b5c9b6774c..ff8d64eba9f 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c @@ -137,7 +137,6 @@ xfs_iozero( unsigned bytes; struct page *page; struct address_space *mapping; - char *kaddr; int status; mapping = ip->i_mapping; @@ -155,15 +154,13 @@ 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) { @@ -172,7 +169,6 @@ xfs_iozero( } unlock: - kunmap(page); unlock_page(page); page_cache_release(page); if (status) -- cgit v1.2.3