diff options
-rw-r--r-- | fs/buffer.c | 37 | ||||
-rw-r--r-- | fs/ext2/inode.c | 9 | ||||
-rw-r--r-- | fs/jfs/inode.c | 11 | ||||
-rw-r--r-- | include/linux/buffer_head.h | 6 |
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 | */ |
2517 | int nobh_write_begin_newtrunc(struct file *file, struct address_space *mapping, | 2517 | int 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 | } |
2657 | EXPORT_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 | */ | ||
2663 | int 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 | } | ||
2686 | EXPORT_SYMBOL(nobh_write_begin); | 2657 | EXPORT_SYMBOL(nobh_write_begin); |
2687 | 2658 | ||
2688 | int nobh_write_end(struct file *file, struct address_space *mapping, | 2659 | int 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 | ||
310 | static sector_t jfs_bmap(struct address_space *mapping, sector_t block) | 319 | static 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 *); | |||
231 | sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *); | 231 | sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *); |
232 | int block_truncate_page(struct address_space *, loff_t, get_block_t *); | 232 | int block_truncate_page(struct address_space *, loff_t, get_block_t *); |
233 | int file_fsync(struct file *, int); | 233 | int file_fsync(struct file *, int); |
234 | int nobh_write_begin_newtrunc(struct file *, struct address_space *, | 234 | int nobh_write_begin(struct address_space *, loff_t, unsigned, unsigned, |
235 | loff_t, unsigned, unsigned, | ||
236 | struct page **, void **, get_block_t*); | ||
237 | int 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*); |
240 | int nobh_write_end(struct file *, struct address_space *, | 236 | int nobh_write_end(struct file *, struct address_space *, |
241 | loff_t, unsigned, unsigned, | 237 | loff_t, unsigned, unsigned, |