diff options
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 268 |
1 files changed, 215 insertions, 53 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index b3bd912df6bf..d964195ea0e2 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -383,6 +383,21 @@ static int __check_block_validity(struct inode *inode, const char *func, | |||
383 | return 0; | 383 | return 0; |
384 | } | 384 | } |
385 | 385 | ||
386 | int ext4_issue_zeroout(struct inode *inode, ext4_lblk_t lblk, ext4_fsblk_t pblk, | ||
387 | ext4_lblk_t len) | ||
388 | { | ||
389 | int ret; | ||
390 | |||
391 | if (ext4_encrypted_inode(inode)) | ||
392 | return ext4_encrypted_zeroout(inode, lblk, pblk, len); | ||
393 | |||
394 | ret = sb_issue_zeroout(inode->i_sb, pblk, len, GFP_NOFS); | ||
395 | if (ret > 0) | ||
396 | ret = 0; | ||
397 | |||
398 | return ret; | ||
399 | } | ||
400 | |||
386 | #define check_block_validity(inode, map) \ | 401 | #define check_block_validity(inode, map) \ |
387 | __check_block_validity((inode), __func__, __LINE__, (map)) | 402 | __check_block_validity((inode), __func__, __LINE__, (map)) |
388 | 403 | ||
@@ -403,8 +418,7 @@ static void ext4_map_blocks_es_recheck(handle_t *handle, | |||
403 | * out taking i_data_sem. So at the time the unwritten extent | 418 | * out taking i_data_sem. So at the time the unwritten extent |
404 | * could be converted. | 419 | * could be converted. |
405 | */ | 420 | */ |
406 | if (!(flags & EXT4_GET_BLOCKS_NO_LOCK)) | 421 | down_read(&EXT4_I(inode)->i_data_sem); |
407 | down_read(&EXT4_I(inode)->i_data_sem); | ||
408 | if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) { | 422 | if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) { |
409 | retval = ext4_ext_map_blocks(handle, inode, map, flags & | 423 | retval = ext4_ext_map_blocks(handle, inode, map, flags & |
410 | EXT4_GET_BLOCKS_KEEP_SIZE); | 424 | EXT4_GET_BLOCKS_KEEP_SIZE); |
@@ -412,8 +426,7 @@ static void ext4_map_blocks_es_recheck(handle_t *handle, | |||
412 | retval = ext4_ind_map_blocks(handle, inode, map, flags & | 426 | retval = ext4_ind_map_blocks(handle, inode, map, flags & |
413 | EXT4_GET_BLOCKS_KEEP_SIZE); | 427 | EXT4_GET_BLOCKS_KEEP_SIZE); |
414 | } | 428 | } |
415 | if (!(flags & EXT4_GET_BLOCKS_NO_LOCK)) | 429 | up_read((&EXT4_I(inode)->i_data_sem)); |
416 | up_read((&EXT4_I(inode)->i_data_sem)); | ||
417 | 430 | ||
418 | /* | 431 | /* |
419 | * We don't check m_len because extent will be collpased in status | 432 | * We don't check m_len because extent will be collpased in status |
@@ -509,8 +522,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, | |||
509 | * Try to see if we can get the block without requesting a new | 522 | * Try to see if we can get the block without requesting a new |
510 | * file system block. | 523 | * file system block. |
511 | */ | 524 | */ |
512 | if (!(flags & EXT4_GET_BLOCKS_NO_LOCK)) | 525 | down_read(&EXT4_I(inode)->i_data_sem); |
513 | down_read(&EXT4_I(inode)->i_data_sem); | ||
514 | if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) { | 526 | if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) { |
515 | retval = ext4_ext_map_blocks(handle, inode, map, flags & | 527 | retval = ext4_ext_map_blocks(handle, inode, map, flags & |
516 | EXT4_GET_BLOCKS_KEEP_SIZE); | 528 | EXT4_GET_BLOCKS_KEEP_SIZE); |
@@ -541,8 +553,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, | |||
541 | if (ret < 0) | 553 | if (ret < 0) |
542 | retval = ret; | 554 | retval = ret; |
543 | } | 555 | } |
544 | if (!(flags & EXT4_GET_BLOCKS_NO_LOCK)) | 556 | up_read((&EXT4_I(inode)->i_data_sem)); |
545 | up_read((&EXT4_I(inode)->i_data_sem)); | ||
546 | 557 | ||
547 | found: | 558 | found: |
548 | if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) { | 559 | if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) { |
@@ -626,13 +637,29 @@ found: | |||
626 | } | 637 | } |
627 | 638 | ||
628 | /* | 639 | /* |
640 | * We have to zeroout blocks before inserting them into extent | ||
641 | * status tree. Otherwise someone could look them up there and | ||
642 | * use them before they are really zeroed. | ||
643 | */ | ||
644 | if (flags & EXT4_GET_BLOCKS_ZERO && | ||
645 | map->m_flags & EXT4_MAP_MAPPED && | ||
646 | map->m_flags & EXT4_MAP_NEW) { | ||
647 | ret = ext4_issue_zeroout(inode, map->m_lblk, | ||
648 | map->m_pblk, map->m_len); | ||
649 | if (ret) { | ||
650 | retval = ret; | ||
651 | goto out_sem; | ||
652 | } | ||
653 | } | ||
654 | |||
655 | /* | ||
629 | * If the extent has been zeroed out, we don't need to update | 656 | * If the extent has been zeroed out, we don't need to update |
630 | * extent status tree. | 657 | * extent status tree. |
631 | */ | 658 | */ |
632 | if ((flags & EXT4_GET_BLOCKS_PRE_IO) && | 659 | if ((flags & EXT4_GET_BLOCKS_PRE_IO) && |
633 | ext4_es_lookup_extent(inode, map->m_lblk, &es)) { | 660 | ext4_es_lookup_extent(inode, map->m_lblk, &es)) { |
634 | if (ext4_es_is_written(&es)) | 661 | if (ext4_es_is_written(&es)) |
635 | goto has_zeroout; | 662 | goto out_sem; |
636 | } | 663 | } |
637 | status = map->m_flags & EXT4_MAP_UNWRITTEN ? | 664 | status = map->m_flags & EXT4_MAP_UNWRITTEN ? |
638 | EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN; | 665 | EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN; |
@@ -643,11 +670,13 @@ found: | |||
643 | status |= EXTENT_STATUS_DELAYED; | 670 | status |= EXTENT_STATUS_DELAYED; |
644 | ret = ext4_es_insert_extent(inode, map->m_lblk, map->m_len, | 671 | ret = ext4_es_insert_extent(inode, map->m_lblk, map->m_len, |
645 | map->m_pblk, status); | 672 | map->m_pblk, status); |
646 | if (ret < 0) | 673 | if (ret < 0) { |
647 | retval = ret; | 674 | retval = ret; |
675 | goto out_sem; | ||
676 | } | ||
648 | } | 677 | } |
649 | 678 | ||
650 | has_zeroout: | 679 | out_sem: |
651 | up_write((&EXT4_I(inode)->i_data_sem)); | 680 | up_write((&EXT4_I(inode)->i_data_sem)); |
652 | if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) { | 681 | if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) { |
653 | ret = check_block_validity(inode, map); | 682 | ret = check_block_validity(inode, map); |
@@ -674,7 +703,7 @@ static int _ext4_get_block(struct inode *inode, sector_t iblock, | |||
674 | map.m_lblk = iblock; | 703 | map.m_lblk = iblock; |
675 | map.m_len = bh->b_size >> inode->i_blkbits; | 704 | map.m_len = bh->b_size >> inode->i_blkbits; |
676 | 705 | ||
677 | if (flags && !(flags & EXT4_GET_BLOCKS_NO_LOCK) && !handle) { | 706 | if (flags && !handle) { |
678 | /* Direct IO write... */ | 707 | /* Direct IO write... */ |
679 | if (map.m_len > DIO_MAX_BLOCKS) | 708 | if (map.m_len > DIO_MAX_BLOCKS) |
680 | map.m_len = DIO_MAX_BLOCKS; | 709 | map.m_len = DIO_MAX_BLOCKS; |
@@ -694,16 +723,6 @@ static int _ext4_get_block(struct inode *inode, sector_t iblock, | |||
694 | 723 | ||
695 | map_bh(bh, inode->i_sb, map.m_pblk); | 724 | map_bh(bh, inode->i_sb, map.m_pblk); |
696 | bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags; | 725 | bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags; |
697 | if (IS_DAX(inode) && buffer_unwritten(bh)) { | ||
698 | /* | ||
699 | * dgc: I suspect unwritten conversion on ext4+DAX is | ||
700 | * fundamentally broken here when there are concurrent | ||
701 | * read/write in progress on this inode. | ||
702 | */ | ||
703 | WARN_ON_ONCE(io_end); | ||
704 | bh->b_assoc_map = inode->i_mapping; | ||
705 | bh->b_private = (void *)(unsigned long)iblock; | ||
706 | } | ||
707 | if (io_end && io_end->flag & EXT4_IO_END_UNWRITTEN) | 726 | if (io_end && io_end->flag & EXT4_IO_END_UNWRITTEN) |
708 | set_buffer_defer_completion(bh); | 727 | set_buffer_defer_completion(bh); |
709 | bh->b_size = inode->i_sb->s_blocksize * map.m_len; | 728 | bh->b_size = inode->i_sb->s_blocksize * map.m_len; |
@@ -879,9 +898,6 @@ int do_journal_get_write_access(handle_t *handle, | |||
879 | return ret; | 898 | return ret; |
880 | } | 899 | } |
881 | 900 | ||
882 | static int ext4_get_block_write_nolock(struct inode *inode, sector_t iblock, | ||
883 | struct buffer_head *bh_result, int create); | ||
884 | |||
885 | #ifdef CONFIG_EXT4_FS_ENCRYPTION | 901 | #ifdef CONFIG_EXT4_FS_ENCRYPTION |
886 | static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len, | 902 | static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len, |
887 | get_block_t *get_block) | 903 | get_block_t *get_block) |
@@ -3054,25 +3070,96 @@ int ext4_get_block_write(struct inode *inode, sector_t iblock, | |||
3054 | EXT4_GET_BLOCKS_IO_CREATE_EXT); | 3070 | EXT4_GET_BLOCKS_IO_CREATE_EXT); |
3055 | } | 3071 | } |
3056 | 3072 | ||
3057 | static int ext4_get_block_write_nolock(struct inode *inode, sector_t iblock, | 3073 | static int ext4_get_block_overwrite(struct inode *inode, sector_t iblock, |
3058 | struct buffer_head *bh_result, int create) | 3074 | struct buffer_head *bh_result, int create) |
3059 | { | 3075 | { |
3060 | ext4_debug("ext4_get_block_write_nolock: inode %lu, create flag %d\n", | 3076 | int ret; |
3077 | |||
3078 | ext4_debug("ext4_get_block_overwrite: inode %lu, create flag %d\n", | ||
3061 | inode->i_ino, create); | 3079 | inode->i_ino, create); |
3062 | return _ext4_get_block(inode, iblock, bh_result, | 3080 | ret = _ext4_get_block(inode, iblock, bh_result, 0); |
3063 | EXT4_GET_BLOCKS_NO_LOCK); | 3081 | /* |
3082 | * Blocks should have been preallocated! ext4_file_write_iter() checks | ||
3083 | * that. | ||
3084 | */ | ||
3085 | WARN_ON_ONCE(!buffer_mapped(bh_result)); | ||
3086 | |||
3087 | return ret; | ||
3064 | } | 3088 | } |
3065 | 3089 | ||
3066 | int ext4_get_block_dax(struct inode *inode, sector_t iblock, | 3090 | #ifdef CONFIG_FS_DAX |
3067 | struct buffer_head *bh_result, int create) | 3091 | int ext4_dax_mmap_get_block(struct inode *inode, sector_t iblock, |
3092 | struct buffer_head *bh_result, int create) | ||
3068 | { | 3093 | { |
3069 | int flags = EXT4_GET_BLOCKS_PRE_IO | EXT4_GET_BLOCKS_UNWRIT_EXT; | 3094 | int ret, err; |
3070 | if (create) | 3095 | int credits; |
3071 | flags |= EXT4_GET_BLOCKS_CREATE; | 3096 | struct ext4_map_blocks map; |
3072 | ext4_debug("ext4_get_block_dax: inode %lu, create flag %d\n", | 3097 | handle_t *handle = NULL; |
3098 | int flags = 0; | ||
3099 | |||
3100 | ext4_debug("ext4_dax_mmap_get_block: inode %lu, create flag %d\n", | ||
3073 | inode->i_ino, create); | 3101 | inode->i_ino, create); |
3074 | return _ext4_get_block(inode, iblock, bh_result, flags); | 3102 | map.m_lblk = iblock; |
3103 | map.m_len = bh_result->b_size >> inode->i_blkbits; | ||
3104 | credits = ext4_chunk_trans_blocks(inode, map.m_len); | ||
3105 | if (create) { | ||
3106 | flags |= EXT4_GET_BLOCKS_PRE_IO | EXT4_GET_BLOCKS_CREATE_ZERO; | ||
3107 | handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS, credits); | ||
3108 | if (IS_ERR(handle)) { | ||
3109 | ret = PTR_ERR(handle); | ||
3110 | return ret; | ||
3111 | } | ||
3112 | } | ||
3113 | |||
3114 | ret = ext4_map_blocks(handle, inode, &map, flags); | ||
3115 | if (create) { | ||
3116 | err = ext4_journal_stop(handle); | ||
3117 | if (ret >= 0 && err < 0) | ||
3118 | ret = err; | ||
3119 | } | ||
3120 | if (ret <= 0) | ||
3121 | goto out; | ||
3122 | if (map.m_flags & EXT4_MAP_UNWRITTEN) { | ||
3123 | int err2; | ||
3124 | |||
3125 | /* | ||
3126 | * We are protected by i_mmap_sem so we know block cannot go | ||
3127 | * away from under us even though we dropped i_data_sem. | ||
3128 | * Convert extent to written and write zeros there. | ||
3129 | * | ||
3130 | * Note: We may get here even when create == 0. | ||
3131 | */ | ||
3132 | handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS, credits); | ||
3133 | if (IS_ERR(handle)) { | ||
3134 | ret = PTR_ERR(handle); | ||
3135 | goto out; | ||
3136 | } | ||
3137 | |||
3138 | err = ext4_map_blocks(handle, inode, &map, | ||
3139 | EXT4_GET_BLOCKS_CONVERT | EXT4_GET_BLOCKS_CREATE_ZERO); | ||
3140 | if (err < 0) | ||
3141 | ret = err; | ||
3142 | err2 = ext4_journal_stop(handle); | ||
3143 | if (err2 < 0 && ret > 0) | ||
3144 | ret = err2; | ||
3145 | } | ||
3146 | out: | ||
3147 | WARN_ON_ONCE(ret == 0 && create); | ||
3148 | if (ret > 0) { | ||
3149 | map_bh(bh_result, inode->i_sb, map.m_pblk); | ||
3150 | bh_result->b_state = (bh_result->b_state & ~EXT4_MAP_FLAGS) | | ||
3151 | map.m_flags; | ||
3152 | /* | ||
3153 | * At least for now we have to clear BH_New so that DAX code | ||
3154 | * doesn't attempt to zero blocks again in a racy way. | ||
3155 | */ | ||
3156 | bh_result->b_state &= ~(1 << BH_New); | ||
3157 | bh_result->b_size = map.m_len << inode->i_blkbits; | ||
3158 | ret = 0; | ||
3159 | } | ||
3160 | return ret; | ||
3075 | } | 3161 | } |
3162 | #endif | ||
3076 | 3163 | ||
3077 | static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset, | 3164 | static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset, |
3078 | ssize_t size, void *private) | 3165 | ssize_t size, void *private) |
@@ -3143,10 +3230,8 @@ static ssize_t ext4_ext_direct_IO(struct kiocb *iocb, struct iov_iter *iter, | |||
3143 | /* If we do a overwrite dio, i_mutex locking can be released */ | 3230 | /* If we do a overwrite dio, i_mutex locking can be released */ |
3144 | overwrite = *((int *)iocb->private); | 3231 | overwrite = *((int *)iocb->private); |
3145 | 3232 | ||
3146 | if (overwrite) { | 3233 | if (overwrite) |
3147 | down_read(&EXT4_I(inode)->i_data_sem); | ||
3148 | mutex_unlock(&inode->i_mutex); | 3234 | mutex_unlock(&inode->i_mutex); |
3149 | } | ||
3150 | 3235 | ||
3151 | /* | 3236 | /* |
3152 | * We could direct write to holes and fallocate. | 3237 | * We could direct write to holes and fallocate. |
@@ -3189,7 +3274,7 @@ static ssize_t ext4_ext_direct_IO(struct kiocb *iocb, struct iov_iter *iter, | |||
3189 | } | 3274 | } |
3190 | 3275 | ||
3191 | if (overwrite) { | 3276 | if (overwrite) { |
3192 | get_block_func = ext4_get_block_write_nolock; | 3277 | get_block_func = ext4_get_block_overwrite; |
3193 | } else { | 3278 | } else { |
3194 | get_block_func = ext4_get_block_write; | 3279 | get_block_func = ext4_get_block_write; |
3195 | dio_flags = DIO_LOCKING; | 3280 | dio_flags = DIO_LOCKING; |
@@ -3245,10 +3330,8 @@ retake_lock: | |||
3245 | if (iov_iter_rw(iter) == WRITE) | 3330 | if (iov_iter_rw(iter) == WRITE) |
3246 | inode_dio_end(inode); | 3331 | inode_dio_end(inode); |
3247 | /* take i_mutex locking again if we do a ovewrite dio */ | 3332 | /* take i_mutex locking again if we do a ovewrite dio */ |
3248 | if (overwrite) { | 3333 | if (overwrite) |
3249 | up_read(&EXT4_I(inode)->i_data_sem); | ||
3250 | mutex_lock(&inode->i_mutex); | 3334 | mutex_lock(&inode->i_mutex); |
3251 | } | ||
3252 | 3335 | ||
3253 | return ret; | 3336 | return ret; |
3254 | } | 3337 | } |
@@ -3559,6 +3642,35 @@ int ext4_can_truncate(struct inode *inode) | |||
3559 | } | 3642 | } |
3560 | 3643 | ||
3561 | /* | 3644 | /* |
3645 | * We have to make sure i_disksize gets properly updated before we truncate | ||
3646 | * page cache due to hole punching or zero range. Otherwise i_disksize update | ||
3647 | * can get lost as it may have been postponed to submission of writeback but | ||
3648 | * that will never happen after we truncate page cache. | ||
3649 | */ | ||
3650 | int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset, | ||
3651 | loff_t len) | ||
3652 | { | ||
3653 | handle_t *handle; | ||
3654 | loff_t size = i_size_read(inode); | ||
3655 | |||
3656 | WARN_ON(!mutex_is_locked(&inode->i_mutex)); | ||
3657 | if (offset > size || offset + len < size) | ||
3658 | return 0; | ||
3659 | |||
3660 | if (EXT4_I(inode)->i_disksize >= size) | ||
3661 | return 0; | ||
3662 | |||
3663 | handle = ext4_journal_start(inode, EXT4_HT_MISC, 1); | ||
3664 | if (IS_ERR(handle)) | ||
3665 | return PTR_ERR(handle); | ||
3666 | ext4_update_i_disksize(inode, size); | ||
3667 | ext4_mark_inode_dirty(handle, inode); | ||
3668 | ext4_journal_stop(handle); | ||
3669 | |||
3670 | return 0; | ||
3671 | } | ||
3672 | |||
3673 | /* | ||
3562 | * ext4_punch_hole: punches a hole in a file by releaseing the blocks | 3674 | * ext4_punch_hole: punches a hole in a file by releaseing the blocks |
3563 | * associated with the given offset and length | 3675 | * associated with the given offset and length |
3564 | * | 3676 | * |
@@ -3623,17 +3735,26 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) | |||
3623 | 3735 | ||
3624 | } | 3736 | } |
3625 | 3737 | ||
3738 | /* Wait all existing dio workers, newcomers will block on i_mutex */ | ||
3739 | ext4_inode_block_unlocked_dio(inode); | ||
3740 | inode_dio_wait(inode); | ||
3741 | |||
3742 | /* | ||
3743 | * Prevent page faults from reinstantiating pages we have released from | ||
3744 | * page cache. | ||
3745 | */ | ||
3746 | down_write(&EXT4_I(inode)->i_mmap_sem); | ||
3626 | first_block_offset = round_up(offset, sb->s_blocksize); | 3747 | first_block_offset = round_up(offset, sb->s_blocksize); |
3627 | last_block_offset = round_down((offset + length), sb->s_blocksize) - 1; | 3748 | last_block_offset = round_down((offset + length), sb->s_blocksize) - 1; |
3628 | 3749 | ||
3629 | /* Now release the pages and zero block aligned part of pages*/ | 3750 | /* Now release the pages and zero block aligned part of pages*/ |
3630 | if (last_block_offset > first_block_offset) | 3751 | if (last_block_offset > first_block_offset) { |
3752 | ret = ext4_update_disksize_before_punch(inode, offset, length); | ||
3753 | if (ret) | ||
3754 | goto out_dio; | ||
3631 | truncate_pagecache_range(inode, first_block_offset, | 3755 | truncate_pagecache_range(inode, first_block_offset, |
3632 | last_block_offset); | 3756 | last_block_offset); |
3633 | 3757 | } | |
3634 | /* Wait all existing dio workers, newcomers will block on i_mutex */ | ||
3635 | ext4_inode_block_unlocked_dio(inode); | ||
3636 | inode_dio_wait(inode); | ||
3637 | 3758 | ||
3638 | if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) | 3759 | if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) |
3639 | credits = ext4_writepage_trans_blocks(inode); | 3760 | credits = ext4_writepage_trans_blocks(inode); |
@@ -3680,16 +3801,12 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) | |||
3680 | if (IS_SYNC(inode)) | 3801 | if (IS_SYNC(inode)) |
3681 | ext4_handle_sync(handle); | 3802 | ext4_handle_sync(handle); |
3682 | 3803 | ||
3683 | /* Now release the pages again to reduce race window */ | ||
3684 | if (last_block_offset > first_block_offset) | ||
3685 | truncate_pagecache_range(inode, first_block_offset, | ||
3686 | last_block_offset); | ||
3687 | |||
3688 | inode->i_mtime = inode->i_ctime = ext4_current_time(inode); | 3804 | inode->i_mtime = inode->i_ctime = ext4_current_time(inode); |
3689 | ext4_mark_inode_dirty(handle, inode); | 3805 | ext4_mark_inode_dirty(handle, inode); |
3690 | out_stop: | 3806 | out_stop: |
3691 | ext4_journal_stop(handle); | 3807 | ext4_journal_stop(handle); |
3692 | out_dio: | 3808 | out_dio: |
3809 | up_write(&EXT4_I(inode)->i_mmap_sem); | ||
3693 | ext4_inode_resume_unlocked_dio(inode); | 3810 | ext4_inode_resume_unlocked_dio(inode); |
3694 | out_mutex: | 3811 | out_mutex: |
3695 | mutex_unlock(&inode->i_mutex); | 3812 | mutex_unlock(&inode->i_mutex); |
@@ -4076,6 +4193,14 @@ static inline void ext4_iget_extra_inode(struct inode *inode, | |||
4076 | EXT4_I(inode)->i_inline_off = 0; | 4193 | EXT4_I(inode)->i_inline_off = 0; |
4077 | } | 4194 | } |
4078 | 4195 | ||
4196 | int ext4_get_projid(struct inode *inode, kprojid_t *projid) | ||
4197 | { | ||
4198 | if (!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, EXT4_FEATURE_RO_COMPAT_PROJECT)) | ||
4199 | return -EOPNOTSUPP; | ||
4200 | *projid = EXT4_I(inode)->i_projid; | ||
4201 | return 0; | ||
4202 | } | ||
4203 | |||
4079 | struct inode *ext4_iget(struct super_block *sb, unsigned long ino) | 4204 | struct inode *ext4_iget(struct super_block *sb, unsigned long ino) |
4080 | { | 4205 | { |
4081 | struct ext4_iloc iloc; | 4206 | struct ext4_iloc iloc; |
@@ -4087,6 +4212,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) | |||
4087 | int block; | 4212 | int block; |
4088 | uid_t i_uid; | 4213 | uid_t i_uid; |
4089 | gid_t i_gid; | 4214 | gid_t i_gid; |
4215 | projid_t i_projid; | ||
4090 | 4216 | ||
4091 | inode = iget_locked(sb, ino); | 4217 | inode = iget_locked(sb, ino); |
4092 | if (!inode) | 4218 | if (!inode) |
@@ -4136,12 +4262,20 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) | |||
4136 | inode->i_mode = le16_to_cpu(raw_inode->i_mode); | 4262 | inode->i_mode = le16_to_cpu(raw_inode->i_mode); |
4137 | i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); | 4263 | i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); |
4138 | i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); | 4264 | i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); |
4265 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_PROJECT) && | ||
4266 | EXT4_INODE_SIZE(sb) > EXT4_GOOD_OLD_INODE_SIZE && | ||
4267 | EXT4_FITS_IN_INODE(raw_inode, ei, i_projid)) | ||
4268 | i_projid = (projid_t)le32_to_cpu(raw_inode->i_projid); | ||
4269 | else | ||
4270 | i_projid = EXT4_DEF_PROJID; | ||
4271 | |||
4139 | if (!(test_opt(inode->i_sb, NO_UID32))) { | 4272 | if (!(test_opt(inode->i_sb, NO_UID32))) { |
4140 | i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; | 4273 | i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; |
4141 | i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; | 4274 | i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; |
4142 | } | 4275 | } |
4143 | i_uid_write(inode, i_uid); | 4276 | i_uid_write(inode, i_uid); |
4144 | i_gid_write(inode, i_gid); | 4277 | i_gid_write(inode, i_gid); |
4278 | ei->i_projid = make_kprojid(&init_user_ns, i_projid); | ||
4145 | set_nlink(inode, le16_to_cpu(raw_inode->i_links_count)); | 4279 | set_nlink(inode, le16_to_cpu(raw_inode->i_links_count)); |
4146 | 4280 | ||
4147 | ext4_clear_state_flags(ei); /* Only relevant on 32-bit archs */ | 4281 | ext4_clear_state_flags(ei); /* Only relevant on 32-bit archs */ |
@@ -4440,6 +4574,7 @@ static int ext4_do_update_inode(handle_t *handle, | |||
4440 | int need_datasync = 0, set_large_file = 0; | 4574 | int need_datasync = 0, set_large_file = 0; |
4441 | uid_t i_uid; | 4575 | uid_t i_uid; |
4442 | gid_t i_gid; | 4576 | gid_t i_gid; |
4577 | projid_t i_projid; | ||
4443 | 4578 | ||
4444 | spin_lock(&ei->i_raw_lock); | 4579 | spin_lock(&ei->i_raw_lock); |
4445 | 4580 | ||
@@ -4452,6 +4587,7 @@ static int ext4_do_update_inode(handle_t *handle, | |||
4452 | raw_inode->i_mode = cpu_to_le16(inode->i_mode); | 4587 | raw_inode->i_mode = cpu_to_le16(inode->i_mode); |
4453 | i_uid = i_uid_read(inode); | 4588 | i_uid = i_uid_read(inode); |
4454 | i_gid = i_gid_read(inode); | 4589 | i_gid = i_gid_read(inode); |
4590 | i_projid = from_kprojid(&init_user_ns, ei->i_projid); | ||
4455 | if (!(test_opt(inode->i_sb, NO_UID32))) { | 4591 | if (!(test_opt(inode->i_sb, NO_UID32))) { |
4456 | raw_inode->i_uid_low = cpu_to_le16(low_16_bits(i_uid)); | 4592 | raw_inode->i_uid_low = cpu_to_le16(low_16_bits(i_uid)); |
4457 | raw_inode->i_gid_low = cpu_to_le16(low_16_bits(i_gid)); | 4593 | raw_inode->i_gid_low = cpu_to_le16(low_16_bits(i_gid)); |
@@ -4529,6 +4665,15 @@ static int ext4_do_update_inode(handle_t *handle, | |||
4529 | cpu_to_le16(ei->i_extra_isize); | 4665 | cpu_to_le16(ei->i_extra_isize); |
4530 | } | 4666 | } |
4531 | } | 4667 | } |
4668 | |||
4669 | BUG_ON(!EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, | ||
4670 | EXT4_FEATURE_RO_COMPAT_PROJECT) && | ||
4671 | i_projid != EXT4_DEF_PROJID); | ||
4672 | |||
4673 | if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE && | ||
4674 | EXT4_FITS_IN_INODE(raw_inode, ei, i_projid)) | ||
4675 | raw_inode->i_projid = cpu_to_le32(i_projid); | ||
4676 | |||
4532 | ext4_inode_csum_set(inode, raw_inode, ei); | 4677 | ext4_inode_csum_set(inode, raw_inode, ei); |
4533 | spin_unlock(&ei->i_raw_lock); | 4678 | spin_unlock(&ei->i_raw_lock); |
4534 | if (inode->i_sb->s_flags & MS_LAZYTIME) | 4679 | if (inode->i_sb->s_flags & MS_LAZYTIME) |
@@ -4824,6 +4969,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) | |||
4824 | } else | 4969 | } else |
4825 | ext4_wait_for_tail_page_commit(inode); | 4970 | ext4_wait_for_tail_page_commit(inode); |
4826 | } | 4971 | } |
4972 | down_write(&EXT4_I(inode)->i_mmap_sem); | ||
4827 | /* | 4973 | /* |
4828 | * Truncate pagecache after we've waited for commit | 4974 | * Truncate pagecache after we've waited for commit |
4829 | * in data=journal mode to make pages freeable. | 4975 | * in data=journal mode to make pages freeable. |
@@ -4831,6 +4977,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) | |||
4831 | truncate_pagecache(inode, inode->i_size); | 4977 | truncate_pagecache(inode, inode->i_size); |
4832 | if (shrink) | 4978 | if (shrink) |
4833 | ext4_truncate(inode); | 4979 | ext4_truncate(inode); |
4980 | up_write(&EXT4_I(inode)->i_mmap_sem); | ||
4834 | } | 4981 | } |
4835 | 4982 | ||
4836 | if (!rc) { | 4983 | if (!rc) { |
@@ -5279,6 +5426,8 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
5279 | 5426 | ||
5280 | sb_start_pagefault(inode->i_sb); | 5427 | sb_start_pagefault(inode->i_sb); |
5281 | file_update_time(vma->vm_file); | 5428 | file_update_time(vma->vm_file); |
5429 | |||
5430 | down_read(&EXT4_I(inode)->i_mmap_sem); | ||
5282 | /* Delalloc case is easy... */ | 5431 | /* Delalloc case is easy... */ |
5283 | if (test_opt(inode->i_sb, DELALLOC) && | 5432 | if (test_opt(inode->i_sb, DELALLOC) && |
5284 | !ext4_should_journal_data(inode) && | 5433 | !ext4_should_journal_data(inode) && |
@@ -5348,6 +5497,19 @@ retry_alloc: | |||
5348 | out_ret: | 5497 | out_ret: |
5349 | ret = block_page_mkwrite_return(ret); | 5498 | ret = block_page_mkwrite_return(ret); |
5350 | out: | 5499 | out: |
5500 | up_read(&EXT4_I(inode)->i_mmap_sem); | ||
5351 | sb_end_pagefault(inode->i_sb); | 5501 | sb_end_pagefault(inode->i_sb); |
5352 | return ret; | 5502 | return ret; |
5353 | } | 5503 | } |
5504 | |||
5505 | int ext4_filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | ||
5506 | { | ||
5507 | struct inode *inode = file_inode(vma->vm_file); | ||
5508 | int err; | ||
5509 | |||
5510 | down_read(&EXT4_I(inode)->i_mmap_sem); | ||
5511 | err = filemap_fault(vma, vmf); | ||
5512 | up_read(&EXT4_I(inode)->i_mmap_sem); | ||
5513 | |||
5514 | return err; | ||
5515 | } | ||