aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r--fs/ext4/inode.c143
1 files changed, 19 insertions, 124 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index aa8efa6572d6..feaa82fe629d 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -71,6 +71,9 @@ static int ext4_set_bh_endio(struct buffer_head *bh, struct inode *inode);
71static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate); 71static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate);
72static int __ext4_journalled_writepage(struct page *page, unsigned int len); 72static int __ext4_journalled_writepage(struct page *page, unsigned int len);
73static int ext4_bh_delay_or_unwritten(handle_t *handle, struct buffer_head *bh); 73static int ext4_bh_delay_or_unwritten(handle_t *handle, struct buffer_head *bh);
74static int ext4_discard_partial_page_buffers_no_lock(handle_t *handle,
75 struct inode *inode, struct page *page, loff_t from,
76 loff_t length, int flags);
74 77
75/* 78/*
76 * Test whether an inode is a fast symlink. 79 * Test whether an inode is a fast symlink.
@@ -2759,7 +2762,7 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
2759 if (!io_end || !size) 2762 if (!io_end || !size)
2760 goto out; 2763 goto out;
2761 2764
2762 ext_debug("ext4_end_io_dio(): io_end 0x%p" 2765 ext_debug("ext4_end_io_dio(): io_end 0x%p "
2763 "for inode %lu, iocb 0x%p, offset %llu, size %llu\n", 2766 "for inode %lu, iocb 0x%p, offset %llu, size %llu\n",
2764 iocb->private, io_end->inode->i_ino, iocb, offset, 2767 iocb->private, io_end->inode->i_ino, iocb, offset,
2765 size); 2768 size);
@@ -3160,7 +3163,7 @@ int ext4_discard_partial_page_buffers(handle_t *handle,
3160 * 3163 *
3161 * Returns zero on sucess or negative on failure. 3164 * Returns zero on sucess or negative on failure.
3162 */ 3165 */
3163int ext4_discard_partial_page_buffers_no_lock(handle_t *handle, 3166static int ext4_discard_partial_page_buffers_no_lock(handle_t *handle,
3164 struct inode *inode, struct page *page, loff_t from, 3167 struct inode *inode, struct page *page, loff_t from,
3165 loff_t length, int flags) 3168 loff_t length, int flags)
3166{ 3169{
@@ -3300,126 +3303,6 @@ next:
3300 return err; 3303 return err;
3301} 3304}
3302 3305
3303/*
3304 * ext4_block_truncate_page() zeroes out a mapping from file offset `from'
3305 * up to the end of the block which corresponds to `from'.
3306 * This required during truncate. We need to physically zero the tail end
3307 * of that block so it doesn't yield old data if the file is later grown.
3308 */
3309int ext4_block_truncate_page(handle_t *handle,
3310 struct address_space *mapping, loff_t from)
3311{
3312 unsigned offset = from & (PAGE_CACHE_SIZE-1);
3313 unsigned length;
3314 unsigned blocksize;
3315 struct inode *inode = mapping->host;
3316
3317 blocksize = inode->i_sb->s_blocksize;
3318 length = blocksize - (offset & (blocksize - 1));
3319
3320 return ext4_block_zero_page_range(handle, mapping, from, length);
3321}
3322
3323/*
3324 * ext4_block_zero_page_range() zeros out a mapping of length 'length'
3325 * starting from file offset 'from'. The range to be zero'd must
3326 * be contained with in one block. If the specified range exceeds
3327 * the end of the block it will be shortened to end of the block
3328 * that cooresponds to 'from'
3329 */
3330int ext4_block_zero_page_range(handle_t *handle,
3331 struct address_space *mapping, loff_t from, loff_t length)
3332{
3333 ext4_fsblk_t index = from >> PAGE_CACHE_SHIFT;
3334 unsigned offset = from & (PAGE_CACHE_SIZE-1);
3335 unsigned blocksize, max, pos;
3336 ext4_lblk_t iblock;
3337 struct inode *inode = mapping->host;
3338 struct buffer_head *bh;
3339 struct page *page;
3340 int err = 0;
3341
3342 page = find_or_create_page(mapping, from >> PAGE_CACHE_SHIFT,
3343 mapping_gfp_mask(mapping) & ~__GFP_FS);
3344 if (!page)
3345 return -ENOMEM;
3346
3347 blocksize = inode->i_sb->s_blocksize;
3348 max = blocksize - (offset & (blocksize - 1));
3349
3350 /*
3351 * correct length if it does not fall between
3352 * 'from' and the end of the block
3353 */
3354 if (length > max || length < 0)
3355 length = max;
3356
3357 iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
3358
3359 if (!page_has_buffers(page))
3360 create_empty_buffers(page, blocksize, 0);
3361
3362 /* Find the buffer that contains "offset" */
3363 bh = page_buffers(page);
3364 pos = blocksize;
3365 while (offset >= pos) {
3366 bh = bh->b_this_page;
3367 iblock++;
3368 pos += blocksize;
3369 }
3370
3371 err = 0;
3372 if (buffer_freed(bh)) {
3373 BUFFER_TRACE(bh, "freed: skip");
3374 goto unlock;
3375 }
3376
3377 if (!buffer_mapped(bh)) {
3378 BUFFER_TRACE(bh, "unmapped");
3379 ext4_get_block(inode, iblock, bh, 0);
3380 /* unmapped? It's a hole - nothing to do */
3381 if (!buffer_mapped(bh)) {
3382 BUFFER_TRACE(bh, "still unmapped");
3383 goto unlock;
3384 }
3385 }
3386
3387 /* Ok, it's mapped. Make sure it's up-to-date */
3388 if (PageUptodate(page))
3389 set_buffer_uptodate(bh);
3390
3391 if (!buffer_uptodate(bh)) {
3392 err = -EIO;
3393 ll_rw_block(READ, 1, &bh);
3394 wait_on_buffer(bh);
3395 /* Uhhuh. Read error. Complain and punt. */
3396 if (!buffer_uptodate(bh))
3397 goto unlock;
3398 }
3399
3400 if (ext4_should_journal_data(inode)) {
3401 BUFFER_TRACE(bh, "get write access");
3402 err = ext4_journal_get_write_access(handle, bh);
3403 if (err)
3404 goto unlock;
3405 }
3406
3407 zero_user(page, offset, length);
3408
3409 BUFFER_TRACE(bh, "zeroed end of block");
3410
3411 err = 0;
3412 if (ext4_should_journal_data(inode)) {
3413 err = ext4_handle_dirty_metadata(handle, inode, bh);
3414 } else
3415 mark_buffer_dirty(bh);
3416
3417unlock:
3418 unlock_page(page);
3419 page_cache_release(page);
3420 return err;
3421}
3422
3423int ext4_can_truncate(struct inode *inode) 3306int ext4_can_truncate(struct inode *inode)
3424{ 3307{
3425 if (S_ISREG(inode->i_mode)) 3308 if (S_ISREG(inode->i_mode))
@@ -4646,9 +4529,19 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
4646 return 0; 4529 return 0;
4647 if (is_journal_aborted(journal)) 4530 if (is_journal_aborted(journal))
4648 return -EROFS; 4531 return -EROFS;
4532 /* We have to allocate physical blocks for delalloc blocks
4533 * before flushing journal. otherwise delalloc blocks can not
4534 * be allocated any more. even more truncate on delalloc blocks
4535 * could trigger BUG by flushing delalloc blocks in journal.
4536 * There is no delalloc block in non-journal data mode.
4537 */
4538 if (val && test_opt(inode->i_sb, DELALLOC)) {
4539 err = ext4_alloc_da_blocks(inode);
4540 if (err < 0)
4541 return err;
4542 }
4649 4543
4650 jbd2_journal_lock_updates(journal); 4544 jbd2_journal_lock_updates(journal);
4651 jbd2_journal_flush(journal);
4652 4545
4653 /* 4546 /*
4654 * OK, there are no updates running now, and all cached data is 4547 * OK, there are no updates running now, and all cached data is
@@ -4660,8 +4553,10 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
4660 4553
4661 if (val) 4554 if (val)
4662 ext4_set_inode_flag(inode, EXT4_INODE_JOURNAL_DATA); 4555 ext4_set_inode_flag(inode, EXT4_INODE_JOURNAL_DATA);
4663 else 4556 else {
4557 jbd2_journal_flush(journal);
4664 ext4_clear_inode_flag(inode, EXT4_INODE_JOURNAL_DATA); 4558 ext4_clear_inode_flag(inode, EXT4_INODE_JOURNAL_DATA);
4559 }
4665 ext4_set_aops(inode); 4560 ext4_set_aops(inode);
4666 4561
4667 jbd2_journal_unlock_updates(journal); 4562 jbd2_journal_unlock_updates(journal);