Merge git://oss.sgi.com:8090/xfs/xfs-2.6
[linux-drm-fsl-dcu.git] / fs / xfs / linux-2.6 / xfs_lrw.c
index fa842f1c9fa27b3511c86725a1cad2f3334f4b9c..ff8d64eba9f8d4e20ba3457276b22ab655ab9993 100644 (file)
@@ -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;
@@ -805,7 +799,7 @@ start:
             !capable(CAP_FSETID)) {
                error = xfs_write_clear_setuid(xip);
                if (likely(!error))
-                       error = -remove_suid(file->f_dentry);
+                       error = -remove_suid(file->f_path.dentry);
                if (unlikely(error)) {
                        xfs_iunlock(xip, iolock);
                        goto out_unlock_mutex;