diff options
Diffstat (limited to 'fs/ext4/inode.c')
| -rw-r--r-- | fs/ext4/inode.c | 135 |
1 files changed, 84 insertions, 51 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 6e39895a91b8..5b0d2c7d5408 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
| 39 | #include <linux/ratelimit.h> | 39 | #include <linux/ratelimit.h> |
| 40 | #include <linux/aio.h> | 40 | #include <linux/aio.h> |
| 41 | #include <linux/bitops.h> | ||
| 41 | 42 | ||
| 42 | #include "ext4_jbd2.h" | 43 | #include "ext4_jbd2.h" |
| 43 | #include "xattr.h" | 44 | #include "xattr.h" |
| @@ -214,7 +215,7 @@ void ext4_evict_inode(struct inode *inode) | |||
| 214 | jbd2_complete_transaction(journal, commit_tid); | 215 | jbd2_complete_transaction(journal, commit_tid); |
| 215 | filemap_write_and_wait(&inode->i_data); | 216 | filemap_write_and_wait(&inode->i_data); |
| 216 | } | 217 | } |
| 217 | truncate_inode_pages(&inode->i_data, 0); | 218 | truncate_inode_pages_final(&inode->i_data); |
| 218 | 219 | ||
| 219 | WARN_ON(atomic_read(&EXT4_I(inode)->i_ioend_count)); | 220 | WARN_ON(atomic_read(&EXT4_I(inode)->i_ioend_count)); |
| 220 | goto no_delete; | 221 | goto no_delete; |
| @@ -225,7 +226,7 @@ void ext4_evict_inode(struct inode *inode) | |||
| 225 | 226 | ||
| 226 | if (ext4_should_order_data(inode)) | 227 | if (ext4_should_order_data(inode)) |
| 227 | ext4_begin_ordered_truncate(inode, 0); | 228 | ext4_begin_ordered_truncate(inode, 0); |
| 228 | truncate_inode_pages(&inode->i_data, 0); | 229 | truncate_inode_pages_final(&inode->i_data); |
| 229 | 230 | ||
| 230 | WARN_ON(atomic_read(&EXT4_I(inode)->i_ioend_count)); | 231 | WARN_ON(atomic_read(&EXT4_I(inode)->i_ioend_count)); |
| 231 | if (is_bad_inode(inode)) | 232 | if (is_bad_inode(inode)) |
| @@ -503,6 +504,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, | |||
| 503 | { | 504 | { |
| 504 | struct extent_status es; | 505 | struct extent_status es; |
| 505 | int retval; | 506 | int retval; |
| 507 | int ret = 0; | ||
| 506 | #ifdef ES_AGGRESSIVE_TEST | 508 | #ifdef ES_AGGRESSIVE_TEST |
| 507 | struct ext4_map_blocks orig_map; | 509 | struct ext4_map_blocks orig_map; |
| 508 | 510 | ||
| @@ -514,6 +516,12 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, | |||
| 514 | "logical block %lu\n", inode->i_ino, flags, map->m_len, | 516 | "logical block %lu\n", inode->i_ino, flags, map->m_len, |
| 515 | (unsigned long) map->m_lblk); | 517 | (unsigned long) map->m_lblk); |
| 516 | 518 | ||
| 519 | /* | ||
| 520 | * ext4_map_blocks returns an int, and m_len is an unsigned int | ||
| 521 | */ | ||
| 522 | if (unlikely(map->m_len > INT_MAX)) | ||
| 523 | map->m_len = INT_MAX; | ||
| 524 | |||
| 517 | /* Lookup extent status tree firstly */ | 525 | /* Lookup extent status tree firstly */ |
| 518 | if (ext4_es_lookup_extent(inode, map->m_lblk, &es)) { | 526 | if (ext4_es_lookup_extent(inode, map->m_lblk, &es)) { |
| 519 | ext4_es_lru_add(inode); | 527 | ext4_es_lru_add(inode); |
| @@ -552,7 +560,6 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, | |||
| 552 | EXT4_GET_BLOCKS_KEEP_SIZE); | 560 | EXT4_GET_BLOCKS_KEEP_SIZE); |
| 553 | } | 561 | } |
| 554 | if (retval > 0) { | 562 | if (retval > 0) { |
| 555 | int ret; | ||
| 556 | unsigned int status; | 563 | unsigned int status; |
| 557 | 564 | ||
| 558 | if (unlikely(retval != map->m_len)) { | 565 | if (unlikely(retval != map->m_len)) { |
| @@ -579,7 +586,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, | |||
| 579 | 586 | ||
| 580 | found: | 587 | found: |
| 581 | if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) { | 588 | if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) { |
| 582 | int ret = check_block_validity(inode, map); | 589 | ret = check_block_validity(inode, map); |
| 583 | if (ret != 0) | 590 | if (ret != 0) |
| 584 | return ret; | 591 | return ret; |
| 585 | } | 592 | } |
| @@ -596,7 +603,13 @@ found: | |||
| 596 | * with buffer head unmapped. | 603 | * with buffer head unmapped. |
| 597 | */ | 604 | */ |
| 598 | if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) | 605 | if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) |
| 599 | return retval; | 606 | /* |
| 607 | * If we need to convert extent to unwritten | ||
| 608 | * we continue and do the actual work in | ||
| 609 | * ext4_ext_map_blocks() | ||
| 610 | */ | ||
| 611 | if (!(flags & EXT4_GET_BLOCKS_CONVERT_UNWRITTEN)) | ||
| 612 | return retval; | ||
| 600 | 613 | ||
| 601 | /* | 614 | /* |
| 602 | * Here we clear m_flags because after allocating an new extent, | 615 | * Here we clear m_flags because after allocating an new extent, |
| @@ -652,7 +665,6 @@ found: | |||
| 652 | ext4_clear_inode_state(inode, EXT4_STATE_DELALLOC_RESERVED); | 665 | ext4_clear_inode_state(inode, EXT4_STATE_DELALLOC_RESERVED); |
| 653 | 666 | ||
| 654 | if (retval > 0) { | 667 | if (retval > 0) { |
| 655 | int ret; | ||
| 656 | unsigned int status; | 668 | unsigned int status; |
| 657 | 669 | ||
| 658 | if (unlikely(retval != map->m_len)) { | 670 | if (unlikely(retval != map->m_len)) { |
| @@ -687,7 +699,7 @@ found: | |||
| 687 | has_zeroout: | 699 | has_zeroout: |
| 688 | up_write((&EXT4_I(inode)->i_data_sem)); | 700 | up_write((&EXT4_I(inode)->i_data_sem)); |
| 689 | if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) { | 701 | if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) { |
| 690 | int ret = check_block_validity(inode, map); | 702 | ret = check_block_validity(inode, map); |
| 691 | if (ret != 0) | 703 | if (ret != 0) |
| 692 | return ret; | 704 | return ret; |
| 693 | } | 705 | } |
| @@ -3312,33 +3324,13 @@ void ext4_set_aops(struct inode *inode) | |||
| 3312 | } | 3324 | } |
| 3313 | 3325 | ||
| 3314 | /* | 3326 | /* |
| 3315 | * ext4_block_truncate_page() zeroes out a mapping from file offset `from' | ||
| 3316 | * up to the end of the block which corresponds to `from'. | ||
| 3317 | * This required during truncate. We need to physically zero the tail end | ||
| 3318 | * of that block so it doesn't yield old data if the file is later grown. | ||
| 3319 | */ | ||
| 3320 | int ext4_block_truncate_page(handle_t *handle, | ||
| 3321 | struct address_space *mapping, loff_t from) | ||
| 3322 | { | ||
| 3323 | unsigned offset = from & (PAGE_CACHE_SIZE-1); | ||
| 3324 | unsigned length; | ||
| 3325 | unsigned blocksize; | ||
| 3326 | struct inode *inode = mapping->host; | ||
| 3327 | |||
| 3328 | blocksize = inode->i_sb->s_blocksize; | ||
| 3329 | length = blocksize - (offset & (blocksize - 1)); | ||
| 3330 | |||
| 3331 | return ext4_block_zero_page_range(handle, mapping, from, length); | ||
| 3332 | } | ||
| 3333 | |||
| 3334 | /* | ||
| 3335 | * ext4_block_zero_page_range() zeros out a mapping of length 'length' | 3327 | * ext4_block_zero_page_range() zeros out a mapping of length 'length' |
| 3336 | * starting from file offset 'from'. The range to be zero'd must | 3328 | * starting from file offset 'from'. The range to be zero'd must |
| 3337 | * be contained with in one block. If the specified range exceeds | 3329 | * be contained with in one block. If the specified range exceeds |
| 3338 | * the end of the block it will be shortened to end of the block | 3330 | * the end of the block it will be shortened to end of the block |
| 3339 | * that cooresponds to 'from' | 3331 | * that cooresponds to 'from' |
| 3340 | */ | 3332 | */ |
| 3341 | int ext4_block_zero_page_range(handle_t *handle, | 3333 | static int ext4_block_zero_page_range(handle_t *handle, |
| 3342 | struct address_space *mapping, loff_t from, loff_t length) | 3334 | struct address_space *mapping, loff_t from, loff_t length) |
| 3343 | { | 3335 | { |
| 3344 | ext4_fsblk_t index = from >> PAGE_CACHE_SHIFT; | 3336 | ext4_fsblk_t index = from >> PAGE_CACHE_SHIFT; |
| @@ -3428,6 +3420,26 @@ unlock: | |||
| 3428 | return err; | 3420 | return err; |
| 3429 | } | 3421 | } |
| 3430 | 3422 | ||
| 3423 | /* | ||
| 3424 | * ext4_block_truncate_page() zeroes out a mapping from file offset `from' | ||
| 3425 | * up to the end of the block which corresponds to `from'. | ||
| 3426 | * This required during truncate. We need to physically zero the tail end | ||
| 3427 | * of that block so it doesn't yield old data if the file is later grown. | ||
| 3428 | */ | ||
| 3429 | int ext4_block_truncate_page(handle_t *handle, | ||
| 3430 | struct address_space *mapping, loff_t from) | ||
| 3431 | { | ||
| 3432 | unsigned offset = from & (PAGE_CACHE_SIZE-1); | ||
| 3433 | unsigned length; | ||
| 3434 | unsigned blocksize; | ||
| 3435 | struct inode *inode = mapping->host; | ||
| 3436 | |||
| 3437 | blocksize = inode->i_sb->s_blocksize; | ||
| 3438 | length = blocksize - (offset & (blocksize - 1)); | ||
| 3439 | |||
| 3440 | return ext4_block_zero_page_range(handle, mapping, from, length); | ||
| 3441 | } | ||
| 3442 | |||
| 3431 | int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, | 3443 | int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, |
| 3432 | loff_t lstart, loff_t length) | 3444 | loff_t lstart, loff_t length) |
| 3433 | { | 3445 | { |
| @@ -3501,7 +3513,7 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) | |||
| 3501 | if (!S_ISREG(inode->i_mode)) | 3513 | if (!S_ISREG(inode->i_mode)) |
| 3502 | return -EOPNOTSUPP; | 3514 | return -EOPNOTSUPP; |
| 3503 | 3515 | ||
| 3504 | trace_ext4_punch_hole(inode, offset, length); | 3516 | trace_ext4_punch_hole(inode, offset, length, 0); |
| 3505 | 3517 | ||
| 3506 | /* | 3518 | /* |
| 3507 | * Write out all dirty pages to avoid race conditions | 3519 | * Write out all dirty pages to avoid race conditions |
| @@ -3608,6 +3620,12 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) | |||
| 3608 | up_write(&EXT4_I(inode)->i_data_sem); | 3620 | up_write(&EXT4_I(inode)->i_data_sem); |
| 3609 | if (IS_SYNC(inode)) | 3621 | if (IS_SYNC(inode)) |
| 3610 | ext4_handle_sync(handle); | 3622 | ext4_handle_sync(handle); |
| 3623 | |||
| 3624 | /* Now release the pages again to reduce race window */ | ||
| 3625 | if (last_block_offset > first_block_offset) | ||
| 3626 | truncate_pagecache_range(inode, first_block_offset, | ||
| 3627 | last_block_offset); | ||
| 3628 | |||
| 3611 | inode->i_mtime = inode->i_ctime = ext4_current_time(inode); | 3629 | inode->i_mtime = inode->i_ctime = ext4_current_time(inode); |
| 3612 | ext4_mark_inode_dirty(handle, inode); | 3630 | ext4_mark_inode_dirty(handle, inode); |
| 3613 | out_stop: | 3631 | out_stop: |
| @@ -3681,7 +3699,7 @@ void ext4_truncate(struct inode *inode) | |||
| 3681 | 3699 | ||
| 3682 | /* | 3700 | /* |
| 3683 | * There is a possibility that we're either freeing the inode | 3701 | * There is a possibility that we're either freeing the inode |
| 3684 | * or it completely new indode. In those cases we might not | 3702 | * or it's a completely new inode. In those cases we might not |
| 3685 | * have i_mutex locked because it's not necessary. | 3703 | * have i_mutex locked because it's not necessary. |
| 3686 | */ | 3704 | */ |
| 3687 | if (!(inode->i_state & (I_NEW|I_FREEING))) | 3705 | if (!(inode->i_state & (I_NEW|I_FREEING))) |
| @@ -3921,18 +3939,20 @@ int ext4_get_inode_loc(struct inode *inode, struct ext4_iloc *iloc) | |||
| 3921 | void ext4_set_inode_flags(struct inode *inode) | 3939 | void ext4_set_inode_flags(struct inode *inode) |
| 3922 | { | 3940 | { |
| 3923 | unsigned int flags = EXT4_I(inode)->i_flags; | 3941 | unsigned int flags = EXT4_I(inode)->i_flags; |
| 3942 | unsigned int new_fl = 0; | ||
| 3924 | 3943 | ||
| 3925 | inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); | ||
| 3926 | if (flags & EXT4_SYNC_FL) | 3944 | if (flags & EXT4_SYNC_FL) |
| 3927 | inode->i_flags |= S_SYNC; | 3945 | new_fl |= S_SYNC; |
| 3928 | if (flags & EXT4_APPEND_FL) | 3946 | if (flags & EXT4_APPEND_FL) |
| 3929 | inode->i_flags |= S_APPEND; | 3947 | new_fl |= S_APPEND; |
| 3930 | if (flags & EXT4_IMMUTABLE_FL) | 3948 | if (flags & EXT4_IMMUTABLE_FL) |
| 3931 | inode->i_flags |= S_IMMUTABLE; | 3949 | new_fl |= S_IMMUTABLE; |
| 3932 | if (flags & EXT4_NOATIME_FL) | 3950 | if (flags & EXT4_NOATIME_FL) |
| 3933 | inode->i_flags |= S_NOATIME; | 3951 | new_fl |= S_NOATIME; |
| 3934 | if (flags & EXT4_DIRSYNC_FL) | 3952 | if (flags & EXT4_DIRSYNC_FL) |
| 3935 | inode->i_flags |= S_DIRSYNC; | 3953 | new_fl |= S_DIRSYNC; |
| 3954 | inode_set_flags(inode, new_fl, | ||
| 3955 | S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); | ||
| 3936 | } | 3956 | } |
| 3937 | 3957 | ||
| 3938 | /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */ | 3958 | /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */ |
| @@ -4151,11 +4171,13 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) | |||
| 4151 | EXT4_INODE_GET_XTIME(i_atime, inode, raw_inode); | 4171 | EXT4_INODE_GET_XTIME(i_atime, inode, raw_inode); |
| 4152 | EXT4_EINODE_GET_XTIME(i_crtime, ei, raw_inode); | 4172 | EXT4_EINODE_GET_XTIME(i_crtime, ei, raw_inode); |
| 4153 | 4173 | ||
| 4154 | inode->i_version = le32_to_cpu(raw_inode->i_disk_version); | 4174 | if (likely(!test_opt2(inode->i_sb, HURD_COMPAT))) { |
| 4155 | if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) { | 4175 | inode->i_version = le32_to_cpu(raw_inode->i_disk_version); |
| 4156 | if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi)) | 4176 | if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) { |
| 4157 | inode->i_version |= | 4177 | if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi)) |
| 4158 | (__u64)(le32_to_cpu(raw_inode->i_version_hi)) << 32; | 4178 | inode->i_version |= |
| 4179 | (__u64)(le32_to_cpu(raw_inode->i_version_hi)) << 32; | ||
| 4180 | } | ||
| 4159 | } | 4181 | } |
| 4160 | 4182 | ||
| 4161 | ret = 0; | 4183 | ret = 0; |
| @@ -4325,8 +4347,7 @@ static int ext4_do_update_inode(handle_t *handle, | |||
| 4325 | goto out_brelse; | 4347 | goto out_brelse; |
| 4326 | raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); | 4348 | raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); |
| 4327 | raw_inode->i_flags = cpu_to_le32(ei->i_flags & 0xFFFFFFFF); | 4349 | raw_inode->i_flags = cpu_to_le32(ei->i_flags & 0xFFFFFFFF); |
| 4328 | if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != | 4350 | if (likely(!test_opt2(inode->i_sb, HURD_COMPAT))) |
| 4329 | cpu_to_le32(EXT4_OS_HURD)) | ||
| 4330 | raw_inode->i_file_acl_high = | 4351 | raw_inode->i_file_acl_high = |
| 4331 | cpu_to_le16(ei->i_file_acl >> 32); | 4352 | cpu_to_le16(ei->i_file_acl >> 32); |
| 4332 | raw_inode->i_file_acl_lo = cpu_to_le32(ei->i_file_acl); | 4353 | raw_inode->i_file_acl_lo = cpu_to_le32(ei->i_file_acl); |
| @@ -4371,12 +4392,15 @@ static int ext4_do_update_inode(handle_t *handle, | |||
| 4371 | raw_inode->i_block[block] = ei->i_data[block]; | 4392 | raw_inode->i_block[block] = ei->i_data[block]; |
| 4372 | } | 4393 | } |
| 4373 | 4394 | ||
| 4374 | raw_inode->i_disk_version = cpu_to_le32(inode->i_version); | 4395 | if (likely(!test_opt2(inode->i_sb, HURD_COMPAT))) { |
| 4375 | if (ei->i_extra_isize) { | 4396 | raw_inode->i_disk_version = cpu_to_le32(inode->i_version); |
| 4376 | if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi)) | 4397 | if (ei->i_extra_isize) { |
| 4377 | raw_inode->i_version_hi = | 4398 | if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi)) |
| 4378 | cpu_to_le32(inode->i_version >> 32); | 4399 | raw_inode->i_version_hi = |
| 4379 | raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize); | 4400 | cpu_to_le32(inode->i_version >> 32); |
| 4401 | raw_inode->i_extra_isize = | ||
| 4402 | cpu_to_le16(ei->i_extra_isize); | ||
| 4403 | } | ||
| 4380 | } | 4404 | } |
| 4381 | 4405 | ||
| 4382 | ext4_inode_csum_set(inode, raw_inode, ei); | 4406 | ext4_inode_csum_set(inode, raw_inode, ei); |
| @@ -4443,7 +4467,12 @@ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
| 4443 | return -EIO; | 4467 | return -EIO; |
| 4444 | } | 4468 | } |
| 4445 | 4469 | ||
| 4446 | if (wbc->sync_mode != WB_SYNC_ALL) | 4470 | /* |
| 4471 | * No need to force transaction in WB_SYNC_NONE mode. Also | ||
| 4472 | * ext4_sync_fs() will force the commit after everything is | ||
| 4473 | * written. | ||
| 4474 | */ | ||
| 4475 | if (wbc->sync_mode != WB_SYNC_ALL || wbc->for_sync) | ||
| 4447 | return 0; | 4476 | return 0; |
| 4448 | 4477 | ||
| 4449 | err = ext4_force_commit(inode->i_sb); | 4478 | err = ext4_force_commit(inode->i_sb); |
| @@ -4453,7 +4482,11 @@ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
| 4453 | err = __ext4_get_inode_loc(inode, &iloc, 0); | 4482 | err = __ext4_get_inode_loc(inode, &iloc, 0); |
| 4454 | if (err) | 4483 | if (err) |
| 4455 | return err; | 4484 | return err; |
| 4456 | if (wbc->sync_mode == WB_SYNC_ALL) | 4485 | /* |
| 4486 | * sync(2) will flush the whole buffer cache. No need to do | ||
| 4487 | * it here separately for each inode. | ||
| 4488 | */ | ||
| 4489 | if (wbc->sync_mode == WB_SYNC_ALL && !wbc->for_sync) | ||
| 4457 | sync_dirty_buffer(iloc.bh); | 4490 | sync_dirty_buffer(iloc.bh); |
| 4458 | if (buffer_req(iloc.bh) && !buffer_uptodate(iloc.bh)) { | 4491 | if (buffer_req(iloc.bh) && !buffer_uptodate(iloc.bh)) { |
| 4459 | EXT4_ERROR_INODE_BLOCK(inode, iloc.bh->b_blocknr, | 4492 | EXT4_ERROR_INODE_BLOCK(inode, iloc.bh->b_blocknr, |
