diff options
Diffstat (limited to 'fs/ext4/inode.c')
| -rw-r--r-- | fs/ext4/inode.c | 118 |
1 files changed, 98 insertions, 20 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 8416fa28c422..de26c25d6a18 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
| @@ -726,7 +726,7 @@ static int ext4_splice_branch(handle_t *handle, struct inode *inode, | |||
| 726 | 726 | ||
| 727 | /* We are done with atomic stuff, now do the rest of housekeeping */ | 727 | /* We are done with atomic stuff, now do the rest of housekeeping */ |
| 728 | 728 | ||
| 729 | inode->i_ctime = CURRENT_TIME_SEC; | 729 | inode->i_ctime = ext4_current_time(inode); |
| 730 | ext4_mark_inode_dirty(handle, inode); | 730 | ext4_mark_inode_dirty(handle, inode); |
| 731 | 731 | ||
| 732 | /* had we spliced it onto indirect block? */ | 732 | /* had we spliced it onto indirect block? */ |
| @@ -1766,7 +1766,6 @@ int ext4_block_truncate_page(handle_t *handle, struct page *page, | |||
| 1766 | struct inode *inode = mapping->host; | 1766 | struct inode *inode = mapping->host; |
| 1767 | struct buffer_head *bh; | 1767 | struct buffer_head *bh; |
| 1768 | int err = 0; | 1768 | int err = 0; |
| 1769 | void *kaddr; | ||
| 1770 | 1769 | ||
| 1771 | blocksize = inode->i_sb->s_blocksize; | 1770 | blocksize = inode->i_sb->s_blocksize; |
| 1772 | length = blocksize - (offset & (blocksize - 1)); | 1771 | length = blocksize - (offset & (blocksize - 1)); |
| @@ -1778,10 +1777,7 @@ int ext4_block_truncate_page(handle_t *handle, struct page *page, | |||
| 1778 | */ | 1777 | */ |
| 1779 | if (!page_has_buffers(page) && test_opt(inode->i_sb, NOBH) && | 1778 | if (!page_has_buffers(page) && test_opt(inode->i_sb, NOBH) && |
| 1780 | ext4_should_writeback_data(inode) && PageUptodate(page)) { | 1779 | ext4_should_writeback_data(inode) && PageUptodate(page)) { |
| 1781 | kaddr = kmap_atomic(page, KM_USER0); | 1780 | zero_user_page(page, offset, length, KM_USER0); |
| 1782 | memset(kaddr + offset, 0, length); | ||
| 1783 | flush_dcache_page(page); | ||
| 1784 | kunmap_atomic(kaddr, KM_USER0); | ||
| 1785 | set_page_dirty(page); | 1781 | set_page_dirty(page); |
| 1786 | goto unlock; | 1782 | goto unlock; |
| 1787 | } | 1783 | } |
| @@ -1834,10 +1830,7 @@ int ext4_block_truncate_page(handle_t *handle, struct page *page, | |||
| 1834 | goto unlock; | 1830 | goto unlock; |
| 1835 | } | 1831 | } |
| 1836 | 1832 | ||
| 1837 | kaddr = kmap_atomic(page, KM_USER0); | 1833 | zero_user_page(page, offset, length, KM_USER0); |
| 1838 | memset(kaddr + offset, 0, length); | ||
| 1839 | flush_dcache_page(page); | ||
| 1840 | kunmap_atomic(kaddr, KM_USER0); | ||
| 1841 | 1834 | ||
| 1842 | BUFFER_TRACE(bh, "zeroed end of block"); | 1835 | BUFFER_TRACE(bh, "zeroed end of block"); |
| 1843 | 1836 | ||
| @@ -2375,7 +2368,7 @@ do_indirects: | |||
| 2375 | ext4_discard_reservation(inode); | 2368 | ext4_discard_reservation(inode); |
| 2376 | 2369 | ||
| 2377 | mutex_unlock(&ei->truncate_mutex); | 2370 | mutex_unlock(&ei->truncate_mutex); |
| 2378 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; | 2371 | inode->i_mtime = inode->i_ctime = ext4_current_time(inode); |
| 2379 | ext4_mark_inode_dirty(handle, inode); | 2372 | ext4_mark_inode_dirty(handle, inode); |
| 2380 | 2373 | ||
| 2381 | /* | 2374 | /* |
| @@ -2583,6 +2576,25 @@ void ext4_set_inode_flags(struct inode *inode) | |||
| 2583 | inode->i_flags |= S_DIRSYNC; | 2576 | inode->i_flags |= S_DIRSYNC; |
| 2584 | } | 2577 | } |
| 2585 | 2578 | ||
| 2579 | /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */ | ||
| 2580 | void ext4_get_inode_flags(struct ext4_inode_info *ei) | ||
| 2581 | { | ||
| 2582 | unsigned int flags = ei->vfs_inode.i_flags; | ||
| 2583 | |||
| 2584 | ei->i_flags &= ~(EXT4_SYNC_FL|EXT4_APPEND_FL| | ||
| 2585 | EXT4_IMMUTABLE_FL|EXT4_NOATIME_FL|EXT4_DIRSYNC_FL); | ||
| 2586 | if (flags & S_SYNC) | ||
| 2587 | ei->i_flags |= EXT4_SYNC_FL; | ||
| 2588 | if (flags & S_APPEND) | ||
| 2589 | ei->i_flags |= EXT4_APPEND_FL; | ||
| 2590 | if (flags & S_IMMUTABLE) | ||
| 2591 | ei->i_flags |= EXT4_IMMUTABLE_FL; | ||
| 2592 | if (flags & S_NOATIME) | ||
| 2593 | ei->i_flags |= EXT4_NOATIME_FL; | ||
| 2594 | if (flags & S_DIRSYNC) | ||
| 2595 | ei->i_flags |= EXT4_DIRSYNC_FL; | ||
| 2596 | } | ||
| 2597 | |||
| 2586 | void ext4_read_inode(struct inode * inode) | 2598 | void ext4_read_inode(struct inode * inode) |
| 2587 | { | 2599 | { |
| 2588 | struct ext4_iloc iloc; | 2600 | struct ext4_iloc iloc; |
| @@ -2610,10 +2622,6 @@ void ext4_read_inode(struct inode * inode) | |||
| 2610 | } | 2622 | } |
| 2611 | inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); | 2623 | inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); |
| 2612 | inode->i_size = le32_to_cpu(raw_inode->i_size); | 2624 | inode->i_size = le32_to_cpu(raw_inode->i_size); |
| 2613 | inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime); | ||
| 2614 | inode->i_ctime.tv_sec = (signed)le32_to_cpu(raw_inode->i_ctime); | ||
| 2615 | inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime); | ||
| 2616 | inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0; | ||
| 2617 | 2625 | ||
| 2618 | ei->i_state = 0; | 2626 | ei->i_state = 0; |
| 2619 | ei->i_dir_start_lookup = 0; | 2627 | ei->i_dir_start_lookup = 0; |
| @@ -2691,6 +2699,11 @@ void ext4_read_inode(struct inode * inode) | |||
| 2691 | } else | 2699 | } else |
| 2692 | ei->i_extra_isize = 0; | 2700 | ei->i_extra_isize = 0; |
| 2693 | 2701 | ||
| 2702 | EXT4_INODE_GET_XTIME(i_ctime, inode, raw_inode); | ||
| 2703 | EXT4_INODE_GET_XTIME(i_mtime, inode, raw_inode); | ||
| 2704 | EXT4_INODE_GET_XTIME(i_atime, inode, raw_inode); | ||
| 2705 | EXT4_EINODE_GET_XTIME(i_crtime, ei, raw_inode); | ||
| 2706 | |||
| 2694 | if (S_ISREG(inode->i_mode)) { | 2707 | if (S_ISREG(inode->i_mode)) { |
| 2695 | inode->i_op = &ext4_file_inode_operations; | 2708 | inode->i_op = &ext4_file_inode_operations; |
| 2696 | inode->i_fop = &ext4_file_operations; | 2709 | inode->i_fop = &ext4_file_operations; |
| @@ -2744,6 +2757,7 @@ static int ext4_do_update_inode(handle_t *handle, | |||
| 2744 | if (ei->i_state & EXT4_STATE_NEW) | 2757 | if (ei->i_state & EXT4_STATE_NEW) |
| 2745 | memset(raw_inode, 0, EXT4_SB(inode->i_sb)->s_inode_size); | 2758 | memset(raw_inode, 0, EXT4_SB(inode->i_sb)->s_inode_size); |
| 2746 | 2759 | ||
| 2760 | ext4_get_inode_flags(ei); | ||
| 2747 | raw_inode->i_mode = cpu_to_le16(inode->i_mode); | 2761 | raw_inode->i_mode = cpu_to_le16(inode->i_mode); |
| 2748 | if(!(test_opt(inode->i_sb, NO_UID32))) { | 2762 | if(!(test_opt(inode->i_sb, NO_UID32))) { |
| 2749 | raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); | 2763 | raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); |
| @@ -2771,9 +2785,12 @@ static int ext4_do_update_inode(handle_t *handle, | |||
| 2771 | } | 2785 | } |
| 2772 | raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); | 2786 | raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); |
| 2773 | raw_inode->i_size = cpu_to_le32(ei->i_disksize); | 2787 | raw_inode->i_size = cpu_to_le32(ei->i_disksize); |
| 2774 | raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec); | 2788 | |
| 2775 | raw_inode->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec); | 2789 | EXT4_INODE_SET_XTIME(i_ctime, inode, raw_inode); |
| 2776 | raw_inode->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec); | 2790 | EXT4_INODE_SET_XTIME(i_mtime, inode, raw_inode); |
| 2791 | EXT4_INODE_SET_XTIME(i_atime, inode, raw_inode); | ||
| 2792 | EXT4_EINODE_SET_XTIME(i_crtime, ei, raw_inode); | ||
| 2793 | |||
| 2777 | raw_inode->i_blocks = cpu_to_le32(inode->i_blocks); | 2794 | raw_inode->i_blocks = cpu_to_le32(inode->i_blocks); |
| 2778 | raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); | 2795 | raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); |
| 2779 | raw_inode->i_flags = cpu_to_le32(ei->i_flags); | 2796 | raw_inode->i_flags = cpu_to_le32(ei->i_flags); |
| @@ -3082,6 +3099,39 @@ ext4_reserve_inode_write(handle_t *handle, struct inode *inode, | |||
| 3082 | } | 3099 | } |
| 3083 | 3100 | ||
| 3084 | /* | 3101 | /* |
| 3102 | * Expand an inode by new_extra_isize bytes. | ||
| 3103 | * Returns 0 on success or negative error number on failure. | ||
| 3104 | */ | ||
| 3105 | int ext4_expand_extra_isize(struct inode *inode, unsigned int new_extra_isize, | ||
| 3106 | struct ext4_iloc iloc, handle_t *handle) | ||
| 3107 | { | ||
| 3108 | struct ext4_inode *raw_inode; | ||
| 3109 | struct ext4_xattr_ibody_header *header; | ||
| 3110 | struct ext4_xattr_entry *entry; | ||
| 3111 | |||
| 3112 | if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) | ||
| 3113 | return 0; | ||
| 3114 | |||
| 3115 | raw_inode = ext4_raw_inode(&iloc); | ||
| 3116 | |||
| 3117 | header = IHDR(inode, raw_inode); | ||
| 3118 | entry = IFIRST(header); | ||
| 3119 | |||
| 3120 | /* No extended attributes present */ | ||
| 3121 | if (!(EXT4_I(inode)->i_state & EXT4_STATE_XATTR) || | ||
| 3122 | header->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC)) { | ||
| 3123 | memset((void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE, 0, | ||
| 3124 | new_extra_isize); | ||
| 3125 | EXT4_I(inode)->i_extra_isize = new_extra_isize; | ||
| 3126 | return 0; | ||
| 3127 | } | ||
| 3128 | |||
| 3129 | /* try to expand with EAs present */ | ||
| 3130 | return ext4_expand_extra_isize_ea(inode, new_extra_isize, | ||
| 3131 | raw_inode, handle); | ||
| 3132 | } | ||
| 3133 | |||
| 3134 | /* | ||
| 3085 | * What we do here is to mark the in-core inode as clean with respect to inode | 3135 | * What we do here is to mark the in-core inode as clean with respect to inode |
| 3086 | * dirtiness (it may still be data-dirty). | 3136 | * dirtiness (it may still be data-dirty). |
| 3087 | * This means that the in-core inode may be reaped by prune_icache | 3137 | * This means that the in-core inode may be reaped by prune_icache |
| @@ -3105,10 +3155,38 @@ ext4_reserve_inode_write(handle_t *handle, struct inode *inode, | |||
| 3105 | int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) | 3155 | int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) |
| 3106 | { | 3156 | { |
| 3107 | struct ext4_iloc iloc; | 3157 | struct ext4_iloc iloc; |
| 3108 | int err; | 3158 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
| 3159 | static unsigned int mnt_count; | ||
| 3160 | int err, ret; | ||
| 3109 | 3161 | ||
| 3110 | might_sleep(); | 3162 | might_sleep(); |
| 3111 | err = ext4_reserve_inode_write(handle, inode, &iloc); | 3163 | err = ext4_reserve_inode_write(handle, inode, &iloc); |
| 3164 | if (EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize && | ||
| 3165 | !(EXT4_I(inode)->i_state & EXT4_STATE_NO_EXPAND)) { | ||
| 3166 | /* | ||
| 3167 | * We need extra buffer credits since we may write into EA block | ||
| 3168 | * with this same handle. If journal_extend fails, then it will | ||
| 3169 | * only result in a minor loss of functionality for that inode. | ||
| 3170 | * If this is felt to be critical, then e2fsck should be run to | ||
| 3171 | * force a large enough s_min_extra_isize. | ||
| 3172 | */ | ||
| 3173 | if ((jbd2_journal_extend(handle, | ||
| 3174 | EXT4_DATA_TRANS_BLOCKS(inode->i_sb))) == 0) { | ||
| 3175 | ret = ext4_expand_extra_isize(inode, | ||
| 3176 | sbi->s_want_extra_isize, | ||
| 3177 | iloc, handle); | ||
| 3178 | if (ret) { | ||
| 3179 | EXT4_I(inode)->i_state |= EXT4_STATE_NO_EXPAND; | ||
| 3180 | if (mnt_count != sbi->s_es->s_mnt_count) { | ||
| 3181 | ext4_warning(inode->i_sb, __FUNCTION__, | ||
| 3182 | "Unable to expand inode %lu. Delete" | ||
| 3183 | " some EAs or run e2fsck.", | ||
| 3184 | inode->i_ino); | ||
| 3185 | mnt_count = sbi->s_es->s_mnt_count; | ||
| 3186 | } | ||
| 3187 | } | ||
| 3188 | } | ||
| 3189 | } | ||
| 3112 | if (!err) | 3190 | if (!err) |
| 3113 | err = ext4_mark_iloc_dirty(handle, inode, &iloc); | 3191 | err = ext4_mark_iloc_dirty(handle, inode, &iloc); |
| 3114 | return err; | 3192 | return err; |
| @@ -3197,7 +3275,7 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val) | |||
| 3197 | */ | 3275 | */ |
| 3198 | 3276 | ||
| 3199 | journal = EXT4_JOURNAL(inode); | 3277 | journal = EXT4_JOURNAL(inode); |
| 3200 | if (is_journal_aborted(journal) || IS_RDONLY(inode)) | 3278 | if (is_journal_aborted(journal)) |
| 3201 | return -EROFS; | 3279 | return -EROFS; |
| 3202 | 3280 | ||
| 3203 | jbd2_journal_lock_updates(journal); | 3281 | jbd2_journal_lock_updates(journal); |
