Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
[safe/jmp/linux-2.6] / fs / xfs / linux-2.6 / xfs_aops.c
index 7ec89fc..c2e30ee 100644 (file)
@@ -186,19 +186,37 @@ xfs_destroy_ioend(
 }
 
 /*
+ * If the end of the current ioend is beyond the current EOF,
+ * return the new EOF value, otherwise zero.
+ */
+STATIC xfs_fsize_t
+xfs_ioend_new_eof(
+       xfs_ioend_t             *ioend)
+{
+       xfs_inode_t             *ip = XFS_I(ioend->io_inode);
+       xfs_fsize_t             isize;
+       xfs_fsize_t             bsize;
+
+       bsize = ioend->io_offset + ioend->io_size;
+       isize = MAX(ip->i_size, ip->i_new_size);
+       isize = MIN(isize, bsize);
+       return isize > ip->i_d.di_size ? isize : 0;
+}
+
+/*
  * Update on-disk file size now that data has been written to disk.
  * The current in-memory file size is i_size.  If a write is beyond
  * eof i_new_size will be the intended file size until i_size is
  * updated.  If this write does not extend all the way to the valid
  * file size then restrict this update to the end of the write.
  */
+
 STATIC void
 xfs_setfilesize(
        xfs_ioend_t             *ioend)
 {
        xfs_inode_t             *ip = XFS_I(ioend->io_inode);
        xfs_fsize_t             isize;
-       xfs_fsize_t             bsize;
 
        ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG);
        ASSERT(ioend->io_type != IOMAP_READ);
@@ -206,17 +224,10 @@ xfs_setfilesize(
        if (unlikely(ioend->io_error))
                return;
 
-       bsize = ioend->io_offset + ioend->io_size;
-
        xfs_ilock(ip, XFS_ILOCK_EXCL);
-
-       isize = MAX(ip->i_size, ip->i_new_size);
-       isize = MIN(isize, bsize);
-
-       if (ip->i_d.di_size < isize) {
+       isize = xfs_ioend_new_eof(ioend);
+       if (isize) {
                ip->i_d.di_size = isize;
-               ip->i_update_core = 1;
-               ip->i_update_size = 1;
                xfs_mark_inode_dirty_sync(ip);
        }
 
@@ -405,10 +416,16 @@ xfs_submit_ioend_bio(
        struct bio      *bio)
 {
        atomic_inc(&ioend->io_remaining);
-
        bio->bi_private = ioend;
        bio->bi_end_io = xfs_end_bio;
 
+       /*
+        * If the I/O is beyond EOF we mark the inode dirty immediately
+        * but don't update the inode size until I/O completion.
+        */
+       if (xfs_ioend_new_eof(ioend))
+               xfs_mark_inode_dirty_sync(XFS_I(ioend->io_inode));
+
        submit_bio(WRITE, bio);
        ASSERT(!bio_flagged(bio, BIO_EOPNOTSUPP));
        bio_put(bio);
@@ -1268,6 +1285,14 @@ xfs_vm_writepage(
        if (!page_has_buffers(page))
                create_empty_buffers(page, 1 << inode->i_blkbits, 0);
 
+
+       /*
+        *  VM calculation for nr_to_write seems off.  Bump it way
+        *  up, this gets simple streaming writes zippy again.
+        *  To be reviewed again after Jens' writeback changes.
+        */
+       wbc->nr_to_write *= 4;
+
        /*
         * Convert delayed allocate, unwritten or unmapped space
         * to real space and flush out to disk.
@@ -1628,4 +1653,5 @@ const struct address_space_operations xfs_address_space_operations = {
        .direct_IO              = xfs_vm_direct_IO,
        .migratepage            = buffer_migrate_page,
        .is_partially_uptodate  = block_is_partially_uptodate,
+       .error_remove_page      = generic_error_remove_page,
 };