diff options
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 120 |
1 files changed, 99 insertions, 21 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 8416fa28c422..a4848e04a5ed 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); |
@@ -2886,7 +2903,7 @@ int ext4_write_inode(struct inode *inode, int wait) | |||
2886 | return 0; | 2903 | return 0; |
2887 | 2904 | ||
2888 | if (ext4_journal_current_handle()) { | 2905 | if (ext4_journal_current_handle()) { |
2889 | jbd_debug(0, "called recursively, non-PF_MEMALLOC!\n"); | 2906 | jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n"); |
2890 | dump_stack(); | 2907 | dump_stack(); |
2891 | return -EIO; | 2908 | return -EIO; |
2892 | } | 2909 | } |
@@ -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); |