aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/buffer.c37
-rw-r--r--fs/ext2/inode.c9
-rw-r--r--fs/jfs/inode.c11
-rw-r--r--include/linux/buffer_head.h6
4 files changed, 17 insertions, 46 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index d54812b198e9..559daf76bca4 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2510,11 +2510,11 @@ static void attach_nobh_buffers(struct page *page, struct buffer_head *head)
2510} 2510}
2511 2511
2512/* 2512/*
2513 * Filesystems implementing the new truncate sequence should use the 2513 * On entry, the page is fully not uptodate.
2514 * _newtrunc postfix variant which won't incorrectly call vmtruncate. 2514 * On exit the page is fully uptodate in the areas outside (from,to)
2515 * The filesystem needs to handle block truncation upon failure. 2515 * The filesystem needs to handle block truncation upon failure.
2516 */ 2516 */
2517int nobh_write_begin_newtrunc(struct file *file, struct address_space *mapping, 2517int nobh_write_begin(struct address_space *mapping,
2518 loff_t pos, unsigned len, unsigned flags, 2518 loff_t pos, unsigned len, unsigned flags,
2519 struct page **pagep, void **fsdata, 2519 struct page **pagep, void **fsdata,
2520 get_block_t *get_block) 2520 get_block_t *get_block)
@@ -2547,7 +2547,7 @@ int nobh_write_begin_newtrunc(struct file *file, struct address_space *mapping,
2547 unlock_page(page); 2547 unlock_page(page);
2548 page_cache_release(page); 2548 page_cache_release(page);
2549 *pagep = NULL; 2549 *pagep = NULL;
2550 return block_write_begin_newtrunc(file, mapping, pos, len, 2550 return block_write_begin_newtrunc(NULL, mapping, pos, len,
2551 flags, pagep, fsdata, get_block); 2551 flags, pagep, fsdata, get_block);
2552 } 2552 }
2553 2553
@@ -2654,35 +2654,6 @@ out_release:
2654 2654
2655 return ret; 2655 return ret;
2656} 2656}
2657EXPORT_SYMBOL(nobh_write_begin_newtrunc);
2658
2659/*
2660 * On entry, the page is fully not uptodate.
2661 * On exit the page is fully uptodate in the areas outside (from,to)
2662 */
2663int nobh_write_begin(struct file *file, struct address_space *mapping,
2664 loff_t pos, unsigned len, unsigned flags,
2665 struct page **pagep, void **fsdata,
2666 get_block_t *get_block)
2667{
2668 int ret;
2669
2670 ret = nobh_write_begin_newtrunc(file, mapping, pos, len, flags,
2671 pagep, fsdata, get_block);
2672
2673 /*
2674 * prepare_write() may have instantiated a few blocks
2675 * outside i_size. Trim these off again. Don't need
2676 * i_size_read because we hold i_mutex.
2677 */
2678 if (unlikely(ret)) {
2679 loff_t isize = mapping->host->i_size;
2680 if (pos + len > isize)
2681 vmtruncate(mapping->host, isize);
2682 }
2683
2684 return ret;
2685}
2686EXPORT_SYMBOL(nobh_write_begin); 2657EXPORT_SYMBOL(nobh_write_begin);
2687 2658
2688int nobh_write_end(struct file *file, struct address_space *mapping, 2659int nobh_write_end(struct file *file, struct address_space *mapping,
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index f36e967e4fde..348805cd4109 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -806,13 +806,8 @@ ext2_nobh_write_begin(struct file *file, struct address_space *mapping,
806{ 806{
807 int ret; 807 int ret;
808 808
809 /* 809 ret = nobh_write_begin(mapping, pos, len, flags, pagep, fsdata,
810 * Dir-in-pagecache still uses ext2_write_begin. Would have to rework 810 ext2_get_block);
811 * directory handling code to pass around offsets rather than struct
812 * pages in order to make this work easily.
813 */
814 ret = nobh_write_begin_newtrunc(file, mapping, pos, len, flags, pagep,
815 fsdata, ext2_get_block);
816 if (ret < 0) 811 if (ret < 0)
817 ext2_write_failed(mapping, pos + len); 812 ext2_write_failed(mapping, pos + len);
818 return ret; 813 return ret;
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 79e6cda28181..c38dc1806281 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -303,8 +303,17 @@ static int jfs_write_begin(struct file *file, struct address_space *mapping,
303 loff_t pos, unsigned len, unsigned flags, 303 loff_t pos, unsigned len, unsigned flags,
304 struct page **pagep, void **fsdata) 304 struct page **pagep, void **fsdata)
305{ 305{
306 return nobh_write_begin(file, mapping, pos, len, flags, pagep, fsdata, 306 int ret;
307
308 ret = nobh_write_begin(mapping, pos, len, flags, pagep, fsdata,
307 jfs_get_block); 309 jfs_get_block);
310 if (unlikely(ret)) {
311 loff_t isize = mapping->host->i_size;
312 if (pos + len > isize)
313 vmtruncate(mapping->host, isize);
314 }
315
316 return ret;
308} 317}
309 318
310static sector_t jfs_bmap(struct address_space *mapping, sector_t block) 319static sector_t jfs_bmap(struct address_space *mapping, sector_t block)
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 1b9ba193b789..cfda5f0b2a4b 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -231,11 +231,7 @@ void block_sync_page(struct page *);
231sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *); 231sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *);
232int block_truncate_page(struct address_space *, loff_t, get_block_t *); 232int block_truncate_page(struct address_space *, loff_t, get_block_t *);
233int file_fsync(struct file *, int); 233int file_fsync(struct file *, int);
234int nobh_write_begin_newtrunc(struct file *, struct address_space *, 234int nobh_write_begin(struct address_space *, loff_t, unsigned, unsigned,
235 loff_t, unsigned, unsigned,
236 struct page **, void **, get_block_t*);
237int nobh_write_begin(struct file *, struct address_space *,
238 loff_t, unsigned, unsigned,
239 struct page **, void **, get_block_t*); 235 struct page **, void **, get_block_t*);
240int nobh_write_end(struct file *, struct address_space *, 236int nobh_write_end(struct file *, struct address_space *,
241 loff_t, unsigned, unsigned, 237 loff_t, unsigned, unsigned,