diff options
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 95 |
1 files changed, 51 insertions, 44 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index feaa82fe629d..c77b0bd2c711 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -272,7 +272,7 @@ void ext4_da_update_reserve_space(struct inode *inode, | |||
272 | trace_ext4_da_update_reserve_space(inode, used, quota_claim); | 272 | trace_ext4_da_update_reserve_space(inode, used, quota_claim); |
273 | if (unlikely(used > ei->i_reserved_data_blocks)) { | 273 | if (unlikely(used > ei->i_reserved_data_blocks)) { |
274 | ext4_msg(inode->i_sb, KERN_NOTICE, "%s: ino %lu, used %d " | 274 | ext4_msg(inode->i_sb, KERN_NOTICE, "%s: ino %lu, used %d " |
275 | "with only %d reserved data blocks\n", | 275 | "with only %d reserved data blocks", |
276 | __func__, inode->i_ino, used, | 276 | __func__, inode->i_ino, used, |
277 | ei->i_reserved_data_blocks); | 277 | ei->i_reserved_data_blocks); |
278 | WARN_ON(1); | 278 | WARN_ON(1); |
@@ -1165,7 +1165,7 @@ static void ext4_da_release_space(struct inode *inode, int to_free) | |||
1165 | */ | 1165 | */ |
1166 | ext4_msg(inode->i_sb, KERN_NOTICE, "ext4_da_release_space: " | 1166 | ext4_msg(inode->i_sb, KERN_NOTICE, "ext4_da_release_space: " |
1167 | "ino %lu, to_free %d with only %d reserved " | 1167 | "ino %lu, to_free %d with only %d reserved " |
1168 | "data blocks\n", inode->i_ino, to_free, | 1168 | "data blocks", inode->i_ino, to_free, |
1169 | ei->i_reserved_data_blocks); | 1169 | ei->i_reserved_data_blocks); |
1170 | WARN_ON(1); | 1170 | WARN_ON(1); |
1171 | to_free = ei->i_reserved_data_blocks; | 1171 | to_free = ei->i_reserved_data_blocks; |
@@ -1428,20 +1428,22 @@ static void ext4_da_block_invalidatepages(struct mpage_da_data *mpd) | |||
1428 | static void ext4_print_free_blocks(struct inode *inode) | 1428 | static void ext4_print_free_blocks(struct inode *inode) |
1429 | { | 1429 | { |
1430 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | 1430 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
1431 | printk(KERN_CRIT "Total free blocks count %lld\n", | 1431 | struct super_block *sb = inode->i_sb; |
1432 | |||
1433 | ext4_msg(sb, KERN_CRIT, "Total free blocks count %lld", | ||
1432 | EXT4_C2B(EXT4_SB(inode->i_sb), | 1434 | EXT4_C2B(EXT4_SB(inode->i_sb), |
1433 | ext4_count_free_clusters(inode->i_sb))); | 1435 | ext4_count_free_clusters(inode->i_sb))); |
1434 | printk(KERN_CRIT "Free/Dirty block details\n"); | 1436 | ext4_msg(sb, KERN_CRIT, "Free/Dirty block details"); |
1435 | printk(KERN_CRIT "free_blocks=%lld\n", | 1437 | ext4_msg(sb, KERN_CRIT, "free_blocks=%lld", |
1436 | (long long) EXT4_C2B(EXT4_SB(inode->i_sb), | 1438 | (long long) EXT4_C2B(EXT4_SB(inode->i_sb), |
1437 | percpu_counter_sum(&sbi->s_freeclusters_counter))); | 1439 | percpu_counter_sum(&sbi->s_freeclusters_counter))); |
1438 | printk(KERN_CRIT "dirty_blocks=%lld\n", | 1440 | ext4_msg(sb, KERN_CRIT, "dirty_blocks=%lld", |
1439 | (long long) EXT4_C2B(EXT4_SB(inode->i_sb), | 1441 | (long long) EXT4_C2B(EXT4_SB(inode->i_sb), |
1440 | percpu_counter_sum(&sbi->s_dirtyclusters_counter))); | 1442 | percpu_counter_sum(&sbi->s_dirtyclusters_counter))); |
1441 | printk(KERN_CRIT "Block reservation details\n"); | 1443 | ext4_msg(sb, KERN_CRIT, "Block reservation details"); |
1442 | printk(KERN_CRIT "i_reserved_data_blocks=%u\n", | 1444 | ext4_msg(sb, KERN_CRIT, "i_reserved_data_blocks=%u", |
1443 | EXT4_I(inode)->i_reserved_data_blocks); | 1445 | EXT4_I(inode)->i_reserved_data_blocks); |
1444 | printk(KERN_CRIT "i_reserved_meta_blocks=%u\n", | 1446 | ext4_msg(sb, KERN_CRIT, "i_reserved_meta_blocks=%u", |
1445 | EXT4_I(inode)->i_reserved_meta_blocks); | 1447 | EXT4_I(inode)->i_reserved_meta_blocks); |
1446 | return; | 1448 | return; |
1447 | } | 1449 | } |
@@ -2482,13 +2484,14 @@ static int ext4_da_write_end(struct file *file, | |||
2482 | int write_mode = (int)(unsigned long)fsdata; | 2484 | int write_mode = (int)(unsigned long)fsdata; |
2483 | 2485 | ||
2484 | if (write_mode == FALL_BACK_TO_NONDELALLOC) { | 2486 | if (write_mode == FALL_BACK_TO_NONDELALLOC) { |
2485 | if (ext4_should_order_data(inode)) { | 2487 | switch (ext4_inode_journal_mode(inode)) { |
2488 | case EXT4_INODE_ORDERED_DATA_MODE: | ||
2486 | return ext4_ordered_write_end(file, mapping, pos, | 2489 | return ext4_ordered_write_end(file, mapping, pos, |
2487 | len, copied, page, fsdata); | 2490 | len, copied, page, fsdata); |
2488 | } else if (ext4_should_writeback_data(inode)) { | 2491 | case EXT4_INODE_WRITEBACK_DATA_MODE: |
2489 | return ext4_writeback_write_end(file, mapping, pos, | 2492 | return ext4_writeback_write_end(file, mapping, pos, |
2490 | len, copied, page, fsdata); | 2493 | len, copied, page, fsdata); |
2491 | } else { | 2494 | default: |
2492 | BUG(); | 2495 | BUG(); |
2493 | } | 2496 | } |
2494 | } | 2497 | } |
@@ -2763,7 +2766,7 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset, | |||
2763 | goto out; | 2766 | goto out; |
2764 | 2767 | ||
2765 | ext_debug("ext4_end_io_dio(): io_end 0x%p " | 2768 | ext_debug("ext4_end_io_dio(): io_end 0x%p " |
2766 | "for inode %lu, iocb 0x%p, offset %llu, size %llu\n", | 2769 | "for inode %lu, iocb 0x%p, offset %llu, size %zd\n", |
2767 | iocb->private, io_end->inode->i_ino, iocb, offset, | 2770 | iocb->private, io_end->inode->i_ino, iocb, offset, |
2768 | size); | 2771 | size); |
2769 | 2772 | ||
@@ -2795,9 +2798,6 @@ out: | |||
2795 | 2798 | ||
2796 | /* queue the work to convert unwritten extents to written */ | 2799 | /* queue the work to convert unwritten extents to written */ |
2797 | queue_work(wq, &io_end->work); | 2800 | queue_work(wq, &io_end->work); |
2798 | |||
2799 | /* XXX: probably should move into the real I/O completion handler */ | ||
2800 | inode_dio_done(inode); | ||
2801 | } | 2801 | } |
2802 | 2802 | ||
2803 | static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate) | 2803 | static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate) |
@@ -2811,8 +2811,9 @@ static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate) | |||
2811 | goto out; | 2811 | goto out; |
2812 | 2812 | ||
2813 | if (!(io_end->inode->i_sb->s_flags & MS_ACTIVE)) { | 2813 | if (!(io_end->inode->i_sb->s_flags & MS_ACTIVE)) { |
2814 | printk("sb umounted, discard end_io request for inode %lu\n", | 2814 | ext4_msg(io_end->inode->i_sb, KERN_INFO, |
2815 | io_end->inode->i_ino); | 2815 | "sb umounted, discard end_io request for inode %lu", |
2816 | io_end->inode->i_ino); | ||
2816 | ext4_free_io_end(io_end); | 2817 | ext4_free_io_end(io_end); |
2817 | goto out; | 2818 | goto out; |
2818 | } | 2819 | } |
@@ -2921,9 +2922,12 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb, | |||
2921 | iocb->private = NULL; | 2922 | iocb->private = NULL; |
2922 | EXT4_I(inode)->cur_aio_dio = NULL; | 2923 | EXT4_I(inode)->cur_aio_dio = NULL; |
2923 | if (!is_sync_kiocb(iocb)) { | 2924 | if (!is_sync_kiocb(iocb)) { |
2924 | iocb->private = ext4_init_io_end(inode, GFP_NOFS); | 2925 | ext4_io_end_t *io_end = |
2925 | if (!iocb->private) | 2926 | ext4_init_io_end(inode, GFP_NOFS); |
2927 | if (!io_end) | ||
2926 | return -ENOMEM; | 2928 | return -ENOMEM; |
2929 | io_end->flag |= EXT4_IO_END_DIRECT; | ||
2930 | iocb->private = io_end; | ||
2927 | /* | 2931 | /* |
2928 | * we save the io structure for current async | 2932 | * we save the io structure for current async |
2929 | * direct IO, so that later ext4_map_blocks() | 2933 | * direct IO, so that later ext4_map_blocks() |
@@ -2940,7 +2944,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb, | |||
2940 | ext4_get_block_write, | 2944 | ext4_get_block_write, |
2941 | ext4_end_io_dio, | 2945 | ext4_end_io_dio, |
2942 | NULL, | 2946 | NULL, |
2943 | DIO_LOCKING | DIO_SKIP_HOLES); | 2947 | DIO_LOCKING); |
2944 | if (iocb->private) | 2948 | if (iocb->private) |
2945 | EXT4_I(inode)->cur_aio_dio = NULL; | 2949 | EXT4_I(inode)->cur_aio_dio = NULL; |
2946 | /* | 2950 | /* |
@@ -3086,18 +3090,25 @@ static const struct address_space_operations ext4_da_aops = { | |||
3086 | 3090 | ||
3087 | void ext4_set_aops(struct inode *inode) | 3091 | void ext4_set_aops(struct inode *inode) |
3088 | { | 3092 | { |
3089 | if (ext4_should_order_data(inode) && | 3093 | switch (ext4_inode_journal_mode(inode)) { |
3090 | test_opt(inode->i_sb, DELALLOC)) | 3094 | case EXT4_INODE_ORDERED_DATA_MODE: |
3091 | inode->i_mapping->a_ops = &ext4_da_aops; | 3095 | if (test_opt(inode->i_sb, DELALLOC)) |
3092 | else if (ext4_should_order_data(inode)) | 3096 | inode->i_mapping->a_ops = &ext4_da_aops; |
3093 | inode->i_mapping->a_ops = &ext4_ordered_aops; | 3097 | else |
3094 | else if (ext4_should_writeback_data(inode) && | 3098 | inode->i_mapping->a_ops = &ext4_ordered_aops; |
3095 | test_opt(inode->i_sb, DELALLOC)) | 3099 | break; |
3096 | inode->i_mapping->a_ops = &ext4_da_aops; | 3100 | case EXT4_INODE_WRITEBACK_DATA_MODE: |
3097 | else if (ext4_should_writeback_data(inode)) | 3101 | if (test_opt(inode->i_sb, DELALLOC)) |
3098 | inode->i_mapping->a_ops = &ext4_writeback_aops; | 3102 | inode->i_mapping->a_ops = &ext4_da_aops; |
3099 | else | 3103 | else |
3104 | inode->i_mapping->a_ops = &ext4_writeback_aops; | ||
3105 | break; | ||
3106 | case EXT4_INODE_JOURNAL_DATA_MODE: | ||
3100 | inode->i_mapping->a_ops = &ext4_journalled_aops; | 3107 | inode->i_mapping->a_ops = &ext4_journalled_aops; |
3108 | break; | ||
3109 | default: | ||
3110 | BUG(); | ||
3111 | } | ||
3101 | } | 3112 | } |
3102 | 3113 | ||
3103 | 3114 | ||
@@ -3329,16 +3340,16 @@ int ext4_punch_hole(struct file *file, loff_t offset, loff_t length) | |||
3329 | { | 3340 | { |
3330 | struct inode *inode = file->f_path.dentry->d_inode; | 3341 | struct inode *inode = file->f_path.dentry->d_inode; |
3331 | if (!S_ISREG(inode->i_mode)) | 3342 | if (!S_ISREG(inode->i_mode)) |
3332 | return -ENOTSUPP; | 3343 | return -EOPNOTSUPP; |
3333 | 3344 | ||
3334 | if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) { | 3345 | if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) { |
3335 | /* TODO: Add support for non extent hole punching */ | 3346 | /* TODO: Add support for non extent hole punching */ |
3336 | return -ENOTSUPP; | 3347 | return -EOPNOTSUPP; |
3337 | } | 3348 | } |
3338 | 3349 | ||
3339 | if (EXT4_SB(inode->i_sb)->s_cluster_ratio > 1) { | 3350 | if (EXT4_SB(inode->i_sb)->s_cluster_ratio > 1) { |
3340 | /* TODO: Add support for bigalloc file systems */ | 3351 | /* TODO: Add support for bigalloc file systems */ |
3341 | return -ENOTSUPP; | 3352 | return -EOPNOTSUPP; |
3342 | } | 3353 | } |
3343 | 3354 | ||
3344 | return ext4_ext_punch_hole(file, offset, length); | 3355 | return ext4_ext_punch_hole(file, offset, length); |
@@ -3924,10 +3935,8 @@ static int ext4_do_update_inode(handle_t *handle, | |||
3924 | ext4_update_dynamic_rev(sb); | 3935 | ext4_update_dynamic_rev(sb); |
3925 | EXT4_SET_RO_COMPAT_FEATURE(sb, | 3936 | EXT4_SET_RO_COMPAT_FEATURE(sb, |
3926 | EXT4_FEATURE_RO_COMPAT_LARGE_FILE); | 3937 | EXT4_FEATURE_RO_COMPAT_LARGE_FILE); |
3927 | sb->s_dirt = 1; | ||
3928 | ext4_handle_sync(handle); | 3938 | ext4_handle_sync(handle); |
3929 | err = ext4_handle_dirty_metadata(handle, NULL, | 3939 | err = ext4_handle_dirty_super(handle, sb); |
3930 | EXT4_SB(sb)->s_sbh); | ||
3931 | } | 3940 | } |
3932 | } | 3941 | } |
3933 | raw_inode->i_generation = cpu_to_le32(inode->i_generation); | 3942 | raw_inode->i_generation = cpu_to_le32(inode->i_generation); |
@@ -4152,11 +4161,9 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) | |||
4152 | } | 4161 | } |
4153 | 4162 | ||
4154 | if (attr->ia_valid & ATTR_SIZE) { | 4163 | if (attr->ia_valid & ATTR_SIZE) { |
4155 | if (attr->ia_size != i_size_read(inode)) { | 4164 | if (attr->ia_size != i_size_read(inode)) |
4156 | truncate_setsize(inode, attr->ia_size); | 4165 | truncate_setsize(inode, attr->ia_size); |
4157 | ext4_truncate(inode); | 4166 | ext4_truncate(inode); |
4158 | } else if (ext4_test_inode_flag(inode, EXT4_INODE_EOFBLOCKS)) | ||
4159 | ext4_truncate(inode); | ||
4160 | } | 4167 | } |
4161 | 4168 | ||
4162 | if (!rc) { | 4169 | if (!rc) { |
@@ -4314,7 +4321,7 @@ int ext4_mark_iloc_dirty(handle_t *handle, | |||
4314 | { | 4321 | { |
4315 | int err = 0; | 4322 | int err = 0; |
4316 | 4323 | ||
4317 | if (test_opt(inode->i_sb, I_VERSION)) | 4324 | if (IS_I_VERSION(inode)) |
4318 | inode_inc_iversion(inode); | 4325 | inode_inc_iversion(inode); |
4319 | 4326 | ||
4320 | /* the do_update_inode consumes one bh->b_count */ | 4327 | /* the do_update_inode consumes one bh->b_count */ |