get rid of block_write_begin_newtrunc
Christoph Hellwig [Fri, 4 Jun 2010 09:29:58 +0000 (11:29 +0200)]
Move the call to vmtruncate to get rid of accessive blocks to the callers
in preparation of the new truncate sequence and rename the non-truncating
version to block_write_begin.

While we're at it also remove several unused arguments to block_write_begin.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

13 files changed:
fs/bfs/file.c
fs/block_dev.c
fs/buffer.c
fs/ext2/inode.c
fs/minix/inode.c
fs/nilfs2/inode.c
fs/nilfs2/recovery.c
fs/omfs/file.c
fs/sysv/itree.c
fs/udf/inode.c
fs/ufs/inode.c
fs/xfs/linux-2.6/xfs_aops.c
include/linux/buffer_head.h

index 88b9a3f..8fc2e9c 100644 (file)
@@ -168,9 +168,17 @@ static int bfs_write_begin(struct file *file, struct address_space *mapping,
                        loff_t pos, unsigned len, unsigned flags,
                        struct page **pagep, void **fsdata)
 {
-       *pagep = NULL;
-       return block_write_begin(file, mapping, pos, len, flags,
-                                       pagep, fsdata, bfs_get_block);
+       int ret;
+
+       ret = block_write_begin(mapping, pos, len, flags, pagep,
+                               bfs_get_block);
+       if (unlikely(ret)) {
+               loff_t isize = mapping->host->i_size;
+               if (pos + len > isize)
+                       vmtruncate(mapping->host, isize);
+       }
+
+       return ret;
 }
 
 static sector_t bfs_bmap(struct address_space *mapping, sector_t block)
index 65a0c26..63c9d60 100644 (file)
@@ -308,9 +308,8 @@ static int blkdev_write_begin(struct file *file, struct address_space *mapping,
                        loff_t pos, unsigned len, unsigned flags,
                        struct page **pagep, void **fsdata)
 {
-       *pagep = NULL;
-       return block_write_begin_newtrunc(file, mapping, pos, len, flags,
-                               pagep, fsdata, blkdev_get_block);
+       return block_write_begin(mapping, pos, len, flags, pagep,
+                                blkdev_get_block);
 }
 
 static int blkdev_write_end(struct file *file, struct address_space *mapping,
index c319c49..50efa33 100644 (file)
@@ -1962,14 +1962,13 @@ int __block_write_begin(struct page *page, loff_t pos, unsigned len,
 EXPORT_SYMBOL(__block_write_begin);
 
 /*
- * Filesystems implementing the new truncate sequence should use the
- * _newtrunc postfix variant which won't incorrectly call vmtruncate.
+ * block_write_begin takes care of the basic task of block allocation and
+ * bringing partial write blocks uptodate first.
+ *
  * The filesystem needs to handle block truncation upon failure.
  */
-int block_write_begin_newtrunc(struct file *file, struct address_space *mapping,
-                       loff_t pos, unsigned len, unsigned flags,
-                       struct page **pagep, void **fsdata,
-                       get_block_t *get_block)
+int block_write_begin(struct address_space *mapping, loff_t pos, unsigned len,
+               unsigned flags, struct page **pagep, get_block_t *get_block)
 {
        pgoff_t index = pos >> PAGE_CACHE_SHIFT;
        struct page *page;
@@ -1989,44 +1988,6 @@ int block_write_begin_newtrunc(struct file *file, struct address_space *mapping,
        *pagep = page;
        return status;
 }
-EXPORT_SYMBOL(block_write_begin_newtrunc);
-
-/*
- * block_write_begin takes care of the basic task of block allocation and
- * bringing partial write blocks uptodate first.
- *
- * If *pagep is not NULL, then block_write_begin uses the locked page
- * at *pagep rather than allocating its own. In this case, the page will
- * not be unlocked or deallocated on failure.
- */
-int block_write_begin(struct file *file, struct address_space *mapping,
-                       loff_t pos, unsigned len, unsigned flags,
-                       struct page **pagep, void **fsdata,
-                       get_block_t *get_block)
-{
-       int ret;
-
-       ret = block_write_begin_newtrunc(file, mapping, pos, len, flags,
-                                       pagep, fsdata, get_block);
-
-       /*
-        * prepare_write() may have instantiated a few blocks
-        * outside i_size.  Trim these off again. Don't need
-        * i_size_read because we hold i_mutex.
-        *
-        * Filesystems which pass down their own page also cannot
-        * call into vmtruncate here because it would lead to lock
-        * inversion problems (*pagep is locked). This is a further
-        * example of where the old truncate sequence is inadequate.
-        */
-       if (unlikely(ret) && *pagep == NULL) {
-               loff_t isize = mapping->host->i_size;
-               if (pos + len > isize)
-                       vmtruncate(mapping->host, isize);
-       }
-
-       return ret;
-}
 EXPORT_SYMBOL(block_write_begin);
 
 int block_write_end(struct file *file, struct address_space *mapping,
@@ -2357,7 +2318,7 @@ int cont_write_begin(struct file *file, struct address_space *mapping,
 
        err = cont_expand_zero(file, mapping, pos, bytes);
        if (err)
-               goto out;
+               return err;
 
        zerofrom = *bytes & ~PAGE_CACHE_MASK;
        if (pos+len > *bytes && zerofrom & (blocksize-1)) {
@@ -2365,11 +2326,7 @@ int cont_write_begin(struct file *file, struct address_space *mapping,
                (*bytes)++;
        }
 
-       *pagep = NULL;
-       err = block_write_begin_newtrunc(file, mapping, pos, len,
-                               flags, pagep, fsdata, get_block);
-out:
-       return err;
+       return block_write_begin(mapping, pos, len, flags, pagep, get_block);
 }
 EXPORT_SYMBOL(cont_write_begin);
 
@@ -2511,8 +2468,8 @@ int nobh_write_begin(struct address_space *mapping,
                unlock_page(page);
                page_cache_release(page);
                *pagep = NULL;
-               return block_write_begin_newtrunc(NULL, mapping, pos, len,
-                                       flags, pagep, fsdata, get_block);
+               return block_write_begin(mapping, pos, len, flags, pagep,
+                                        get_block);
        }
 
        if (PageMappedToDisk(page))
index 2f4dfbc..74dfe5f 100644 (file)
@@ -772,9 +772,8 @@ ext2_write_begin(struct file *file, struct address_space *mapping,
 {
        int ret;
 
-       *pagep = NULL;
-       ret = block_write_begin_newtrunc(file, mapping, pos, len, flags,
-                                        pagep, fsdata, ext2_get_block);
+       ret = block_write_begin(mapping, pos, len, flags, pagep,
+                               ext2_get_block);
        if (ret < 0)
                ext2_write_failed(mapping, pos + len);
        return ret;
index 6b29e73..125062f 100644 (file)
@@ -366,9 +366,17 @@ static int minix_write_begin(struct file *file, struct address_space *mapping,
                        loff_t pos, unsigned len, unsigned flags,
                        struct page **pagep, void **fsdata)
 {
-       *pagep = NULL;
-       return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+       int ret;
+
+       ret = block_write_begin(mapping, pos, len, flags, pagep,
                                minix_get_block);
+       if (unlikely(ret)) {
+               loff_t isize = mapping->host->i_size;
+               if (pos + len > isize)
+                       vmtruncate(mapping->host, isize);
+       }
+
+       return ret;
 }
 
 static sector_t minix_bmap(struct address_space *mapping, sector_t block)
index 1dd9e6a..5c694ec 100644 (file)
@@ -197,11 +197,15 @@ static int nilfs_write_begin(struct file *file, struct address_space *mapping,
        if (unlikely(err))
                return err;
 
-       *pagep = NULL;
-       err = block_write_begin(file, mapping, pos, len, flags, pagep,
-                               fsdata, nilfs_get_block);
-       if (unlikely(err))
+       err = block_write_begin(mapping, pos, len, flags, pagep,
+                               nilfs_get_block);
+       if (unlikely(err)) {
+               loff_t isize = mapping->host->i_size;
+               if (pos + len > isize)
+                       vmtruncate(mapping->host, isize);
+
                nilfs_transaction_abort(inode->i_sb);
+       }
        return err;
 }
 
index bae2a51..2f11f08 100644 (file)
@@ -505,11 +505,14 @@ static int recover_dsync_blocks(struct nilfs_sb_info *sbi,
                }
 
                pos = rb->blkoff << inode->i_blkbits;
-               page = NULL;
-               err = block_write_begin(NULL, inode->i_mapping, pos, blocksize,
-                                       0, &page, NULL, nilfs_get_block);
-               if (unlikely(err))
+               err = block_write_begin(inode->i_mapping, pos, blocksize,
+                                       0, &page, nilfs_get_block);
+               if (unlikely(err)) {
+                       loff_t isize = inode->i_size;
+                       if (pos + blocksize > isize)
+                               vmtruncate(inode, isize);
                        goto failed_inode;
+               }
 
                err = nilfs_recovery_copy_block(sbi, rb, page);
                if (unlikely(err))
index 6e7a329..810cff3 100644 (file)
@@ -312,9 +312,17 @@ static int omfs_write_begin(struct file *file, struct address_space *mapping,
                        loff_t pos, unsigned len, unsigned flags,
                        struct page **pagep, void **fsdata)
 {
-       *pagep = NULL;
-       return block_write_begin(file, mapping, pos, len, flags,
-                               pagep, fsdata, omfs_get_block);
+       int ret;
+
+       ret = block_write_begin(mapping, pos, len, flags, pagep,
+                               omfs_get_block);
+       if (unlikely(ret)) {
+               loff_t isize = mapping->host->i_size;
+               if (pos + len > isize)
+                       vmtruncate(mapping->host, isize);
+       }
+
+       return ret;
 }
 
 static sector_t omfs_bmap(struct address_space *mapping, sector_t block)
index 82a005c..9ca6627 100644 (file)
@@ -468,9 +468,16 @@ static int sysv_write_begin(struct file *file, struct address_space *mapping,
                        loff_t pos, unsigned len, unsigned flags,
                        struct page **pagep, void **fsdata)
 {
-       *pagep = NULL;
-       return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
-                               get_block);
+       int ret;
+
+       ret = block_write_begin(mapping, pos, len, flags, pagep, get_block);
+       if (unlikely(ret)) {
+               loff_t isize = mapping->host->i_size;
+               if (pos + len > isize)
+                       vmtruncate(mapping->host, isize);
+       }
+
+       return ret;
 }
 
 static sector_t sysv_bmap(struct address_space *mapping, sector_t block)
index 124852b..ecddcc2 100644 (file)
@@ -127,9 +127,16 @@ static int udf_write_begin(struct file *file, struct address_space *mapping,
                        loff_t pos, unsigned len, unsigned flags,
                        struct page **pagep, void **fsdata)
 {
-       *pagep = NULL;
-       return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
-                               udf_get_block);
+       int ret;
+
+       ret = block_write_begin(mapping, pos, len, flags, pagep, udf_get_block);
+       if (unlikely(ret)) {
+               loff_t isize = mapping->host->i_size;
+               if (pos + len > isize)
+                       vmtruncate(mapping->host, isize);
+       }
+
+       return ret;
 }
 
 static sector_t udf_bmap(struct address_space *mapping, sector_t block)
index 45ce323..45cafa9 100644 (file)
@@ -567,9 +567,17 @@ static int ufs_write_begin(struct file *file, struct address_space *mapping,
                        loff_t pos, unsigned len, unsigned flags,
                        struct page **pagep, void **fsdata)
 {
-       *pagep = NULL;
-       return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+       int ret;
+
+       ret = block_write_begin(mapping, pos, len, flags, pagep,
                                ufs_getfrag_block);
+       if (unlikely(ret)) {
+               loff_t isize = mapping->host->i_size;
+               if (pos + len > isize)
+                       vmtruncate(mapping->host, isize);
+       }
+
+       return ret;
 }
 
 static sector_t ufs_bmap(struct address_space *mapping, sector_t block)
index 7968d41..bf7aad0 100644 (file)
@@ -1504,9 +1504,17 @@ xfs_vm_write_begin(
        struct page             **pagep,
        void                    **fsdata)
 {
-       *pagep = NULL;
-       return block_write_begin(file, mapping, pos, len, flags | AOP_FLAG_NOFS,
-                                pagep, fsdata, xfs_get_blocks);
+       int                     ret;
+
+       ret = block_write_begin(mapping, pos, len, flags | AOP_FLAG_NOFS,
+                               pagep, xfs_get_blocks);
+       if (unlikely(ret)) {
+               loff_t isize = mapping->host->i_size;
+               if (pos + len > isize)
+                       vmtruncate(mapping->host, isize);
+       }
+
+       return ret;
 }
 
 STATIC sector_t
index accc9f8..3f69054 100644 (file)
@@ -203,12 +203,8 @@ int block_write_full_page_endio(struct page *page, get_block_t *get_block,
 int block_read_full_page(struct page*, get_block_t*);
 int block_is_partially_uptodate(struct page *page, read_descriptor_t *desc,
                                unsigned long from);
-int block_write_begin_newtrunc(struct file *, struct address_space *,
-                               loff_t, unsigned, unsigned,
-                               struct page **, void **, get_block_t*);
-int block_write_begin(struct file *, struct address_space *,
-                               loff_t, unsigned, unsigned,
-                               struct page **, void **, get_block_t*);
+int block_write_begin(struct address_space *mapping, loff_t pos, unsigned len,
+               unsigned flags, struct page **pagep, get_block_t *get_block);
 int __block_write_begin(struct page *page, loff_t pos, unsigned len,
                get_block_t *get_block);
 int block_write_end(struct file *, struct address_space *,