diff options
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 120 |
1 files changed, 75 insertions, 45 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 175c3f933816..5b0d2c7d5408 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -504,6 +504,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, | |||
504 | { | 504 | { |
505 | struct extent_status es; | 505 | struct extent_status es; |
506 | int retval; | 506 | int retval; |
507 | int ret = 0; | ||
507 | #ifdef ES_AGGRESSIVE_TEST | 508 | #ifdef ES_AGGRESSIVE_TEST |
508 | struct ext4_map_blocks orig_map; | 509 | struct ext4_map_blocks orig_map; |
509 | 510 | ||
@@ -515,6 +516,12 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, | |||
515 | "logical block %lu\n", inode->i_ino, flags, map->m_len, | 516 | "logical block %lu\n", inode->i_ino, flags, map->m_len, |
516 | (unsigned long) map->m_lblk); | 517 | (unsigned long) map->m_lblk); |
517 | 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 | |||
518 | /* Lookup extent status tree firstly */ | 525 | /* Lookup extent status tree firstly */ |
519 | if (ext4_es_lookup_extent(inode, map->m_lblk, &es)) { | 526 | if (ext4_es_lookup_extent(inode, map->m_lblk, &es)) { |
520 | ext4_es_lru_add(inode); | 527 | ext4_es_lru_add(inode); |
@@ -553,7 +560,6 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, | |||
553 | EXT4_GET_BLOCKS_KEEP_SIZE); | 560 | EXT4_GET_BLOCKS_KEEP_SIZE); |
554 | } | 561 | } |
555 | if (retval > 0) { | 562 | if (retval > 0) { |
556 | int ret; | ||
557 | unsigned int status; | 563 | unsigned int status; |
558 | 564 | ||
559 | if (unlikely(retval != map->m_len)) { | 565 | if (unlikely(retval != map->m_len)) { |
@@ -580,7 +586,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, | |||
580 | 586 | ||
581 | found: | 587 | found: |
582 | if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) { | 588 | if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) { |
583 | int ret = check_block_validity(inode, map); | 589 | ret = check_block_validity(inode, map); |
584 | if (ret != 0) | 590 | if (ret != 0) |
585 | return ret; | 591 | return ret; |
586 | } | 592 | } |
@@ -597,7 +603,13 @@ found: | |||
597 | * with buffer head unmapped. | 603 | * with buffer head unmapped. |
598 | */ | 604 | */ |
599 | if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) | 605 | if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) |
600 | 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; | ||
601 | 613 | ||
602 | /* | 614 | /* |
603 | * Here we clear m_flags because after allocating an new extent, | 615 | * Here we clear m_flags because after allocating an new extent, |
@@ -653,7 +665,6 @@ found: | |||
653 | ext4_clear_inode_state(inode, EXT4_STATE_DELALLOC_RESERVED); | 665 | ext4_clear_inode_state(inode, EXT4_STATE_DELALLOC_RESERVED); |
654 | 666 | ||
655 | if (retval > 0) { | 667 | if (retval > 0) { |
656 | int ret; | ||
657 | unsigned int status; | 668 | unsigned int status; |
658 | 669 | ||
659 | if (unlikely(retval != map->m_len)) { | 670 | if (unlikely(retval != map->m_len)) { |
@@ -688,7 +699,7 @@ found: | |||
688 | has_zeroout: | 699 | has_zeroout: |
689 | up_write((&EXT4_I(inode)->i_data_sem)); | 700 | up_write((&EXT4_I(inode)->i_data_sem)); |
690 | if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) { | 701 | if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) { |
691 | int ret = check_block_validity(inode, map); | 702 | ret = check_block_validity(inode, map); |
692 | if (ret != 0) | 703 | if (ret != 0) |
693 | return ret; | 704 | return ret; |
694 | } | 705 | } |
@@ -3313,33 +3324,13 @@ void ext4_set_aops(struct inode *inode) | |||
3313 | } | 3324 | } |
3314 | 3325 | ||
3315 | /* | 3326 | /* |
3316 | * ext4_block_truncate_page() zeroes out a mapping from file offset `from' | ||
3317 | * up to the end of the block which corresponds to `from'. | ||
3318 | * This required during truncate. We need to physically zero the tail end | ||
3319 | * of that block so it doesn't yield old data if the file is later grown. | ||
3320 | */ | ||
3321 | int ext4_block_truncate_page(handle_t *handle, | ||
3322 | struct address_space *mapping, loff_t from) | ||
3323 | { | ||
3324 | unsigned offset = from & (PAGE_CACHE_SIZE-1); | ||
3325 | unsigned length; | ||
3326 | unsigned blocksize; | ||
3327 | struct inode *inode = mapping->host; | ||
3328 | |||
3329 | blocksize = inode->i_sb->s_blocksize; | ||
3330 | length = blocksize - (offset & (blocksize - 1)); | ||
3331 | |||
3332 | return ext4_block_zero_page_range(handle, mapping, from, length); | ||
3333 | } | ||
3334 | |||
3335 | /* | ||
3336 | * 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' |
3337 | * 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 |
3338 | * be contained with in one block. If the specified range exceeds | 3329 | * be contained with in one block. If the specified range exceeds |
3339 | * 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 |
3340 | * that cooresponds to 'from' | 3331 | * that cooresponds to 'from' |
3341 | */ | 3332 | */ |
3342 | int ext4_block_zero_page_range(handle_t *handle, | 3333 | static int ext4_block_zero_page_range(handle_t *handle, |
3343 | struct address_space *mapping, loff_t from, loff_t length) | 3334 | struct address_space *mapping, loff_t from, loff_t length) |
3344 | { | 3335 | { |
3345 | ext4_fsblk_t index = from >> PAGE_CACHE_SHIFT; | 3336 | ext4_fsblk_t index = from >> PAGE_CACHE_SHIFT; |
@@ -3429,6 +3420,26 @@ unlock: | |||
3429 | return err; | 3420 | return err; |
3430 | } | 3421 | } |
3431 | 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 | |||
3432 | int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, | 3443 | int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, |
3433 | loff_t lstart, loff_t length) | 3444 | loff_t lstart, loff_t length) |
3434 | { | 3445 | { |
@@ -3502,7 +3513,7 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) | |||
3502 | if (!S_ISREG(inode->i_mode)) | 3513 | if (!S_ISREG(inode->i_mode)) |
3503 | return -EOPNOTSUPP; | 3514 | return -EOPNOTSUPP; |
3504 | 3515 | ||
3505 | trace_ext4_punch_hole(inode, offset, length); | 3516 | trace_ext4_punch_hole(inode, offset, length, 0); |
3506 | 3517 | ||
3507 | /* | 3518 | /* |
3508 | * Write out all dirty pages to avoid race conditions | 3519 | * Write out all dirty pages to avoid race conditions |
@@ -3609,6 +3620,12 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) | |||
3609 | up_write(&EXT4_I(inode)->i_data_sem); | 3620 | up_write(&EXT4_I(inode)->i_data_sem); |
3610 | if (IS_SYNC(inode)) | 3621 | if (IS_SYNC(inode)) |
3611 | 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 | |||
3612 | inode->i_mtime = inode->i_ctime = ext4_current_time(inode); | 3629 | inode->i_mtime = inode->i_ctime = ext4_current_time(inode); |
3613 | ext4_mark_inode_dirty(handle, inode); | 3630 | ext4_mark_inode_dirty(handle, inode); |
3614 | out_stop: | 3631 | out_stop: |
@@ -3682,7 +3699,7 @@ void ext4_truncate(struct inode *inode) | |||
3682 | 3699 | ||
3683 | /* | 3700 | /* |
3684 | * There is a possibility that we're either freeing the inode | 3701 | * There is a possibility that we're either freeing the inode |
3685 | * 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 |
3686 | * have i_mutex locked because it's not necessary. | 3703 | * have i_mutex locked because it's not necessary. |
3687 | */ | 3704 | */ |
3688 | if (!(inode->i_state & (I_NEW|I_FREEING))) | 3705 | if (!(inode->i_state & (I_NEW|I_FREEING))) |
@@ -3934,8 +3951,8 @@ void ext4_set_inode_flags(struct inode *inode) | |||
3934 | new_fl |= S_NOATIME; | 3951 | new_fl |= S_NOATIME; |
3935 | if (flags & EXT4_DIRSYNC_FL) | 3952 | if (flags & EXT4_DIRSYNC_FL) |
3936 | new_fl |= S_DIRSYNC; | 3953 | new_fl |= S_DIRSYNC; |
3937 | set_mask_bits(&inode->i_flags, | 3954 | inode_set_flags(inode, new_fl, |
3938 | S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC, new_fl); | 3955 | S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); |
3939 | } | 3956 | } |
3940 | 3957 | ||
3941 | /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */ | 3958 | /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */ |
@@ -4154,11 +4171,13 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) | |||
4154 | EXT4_INODE_GET_XTIME(i_atime, inode, raw_inode); | 4171 | EXT4_INODE_GET_XTIME(i_atime, inode, raw_inode); |
4155 | EXT4_EINODE_GET_XTIME(i_crtime, ei, raw_inode); | 4172 | EXT4_EINODE_GET_XTIME(i_crtime, ei, raw_inode); |
4156 | 4173 | ||
4157 | inode->i_version = le32_to_cpu(raw_inode->i_disk_version); | 4174 | if (likely(!test_opt2(inode->i_sb, HURD_COMPAT))) { |
4158 | if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) { | 4175 | inode->i_version = le32_to_cpu(raw_inode->i_disk_version); |
4159 | if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi)) | 4176 | if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) { |
4160 | inode->i_version |= | 4177 | if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi)) |
4161 | (__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 | } | ||
4162 | } | 4181 | } |
4163 | 4182 | ||
4164 | ret = 0; | 4183 | ret = 0; |
@@ -4328,8 +4347,7 @@ static int ext4_do_update_inode(handle_t *handle, | |||
4328 | goto out_brelse; | 4347 | goto out_brelse; |
4329 | raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); | 4348 | raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); |
4330 | raw_inode->i_flags = cpu_to_le32(ei->i_flags & 0xFFFFFFFF); | 4349 | raw_inode->i_flags = cpu_to_le32(ei->i_flags & 0xFFFFFFFF); |
4331 | if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != | 4350 | if (likely(!test_opt2(inode->i_sb, HURD_COMPAT))) |
4332 | cpu_to_le32(EXT4_OS_HURD)) | ||
4333 | raw_inode->i_file_acl_high = | 4351 | raw_inode->i_file_acl_high = |
4334 | cpu_to_le16(ei->i_file_acl >> 32); | 4352 | cpu_to_le16(ei->i_file_acl >> 32); |
4335 | 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); |
@@ -4374,12 +4392,15 @@ static int ext4_do_update_inode(handle_t *handle, | |||
4374 | raw_inode->i_block[block] = ei->i_data[block]; | 4392 | raw_inode->i_block[block] = ei->i_data[block]; |
4375 | } | 4393 | } |
4376 | 4394 | ||
4377 | raw_inode->i_disk_version = cpu_to_le32(inode->i_version); | 4395 | if (likely(!test_opt2(inode->i_sb, HURD_COMPAT))) { |
4378 | if (ei->i_extra_isize) { | 4396 | raw_inode->i_disk_version = cpu_to_le32(inode->i_version); |
4379 | if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi)) | 4397 | if (ei->i_extra_isize) { |
4380 | raw_inode->i_version_hi = | 4398 | if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi)) |
4381 | cpu_to_le32(inode->i_version >> 32); | 4399 | raw_inode->i_version_hi = |
4382 | 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 | } | ||
4383 | } | 4404 | } |
4384 | 4405 | ||
4385 | ext4_inode_csum_set(inode, raw_inode, ei); | 4406 | ext4_inode_csum_set(inode, raw_inode, ei); |
@@ -4446,7 +4467,12 @@ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
4446 | return -EIO; | 4467 | return -EIO; |
4447 | } | 4468 | } |
4448 | 4469 | ||
4449 | 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) | ||
4450 | return 0; | 4476 | return 0; |
4451 | 4477 | ||
4452 | err = ext4_force_commit(inode->i_sb); | 4478 | err = ext4_force_commit(inode->i_sb); |
@@ -4456,7 +4482,11 @@ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
4456 | err = __ext4_get_inode_loc(inode, &iloc, 0); | 4482 | err = __ext4_get_inode_loc(inode, &iloc, 0); |
4457 | if (err) | 4483 | if (err) |
4458 | return err; | 4484 | return err; |
4459 | 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) | ||
4460 | sync_dirty_buffer(iloc.bh); | 4490 | sync_dirty_buffer(iloc.bh); |
4461 | if (buffer_req(iloc.bh) && !buffer_uptodate(iloc.bh)) { | 4491 | if (buffer_req(iloc.bh) && !buffer_uptodate(iloc.bh)) { |
4462 | EXT4_ERROR_INODE_BLOCK(inode, iloc.bh->b_blocknr, | 4492 | EXT4_ERROR_INODE_BLOCK(inode, iloc.bh->b_blocknr, |