diff options
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/ext4.h | 1 | ||||
-rw-r--r-- | fs/ext4/inode.c | 5 | ||||
-rw-r--r-- | fs/ext4/ioctl.c | 24 | ||||
-rw-r--r-- | fs/ext4/namei.c | 2 | ||||
-rw-r--r-- | fs/ext4/page-io.c | 4 | ||||
-rw-r--r-- | fs/ext4/resize.c | 5 | ||||
-rw-r--r-- | fs/ext4/super.c | 23 |
7 files changed, 52 insertions, 12 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 6a5edea2d70b..94ce3d7a1c4b 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -910,6 +910,7 @@ struct ext4_inode_info { | |||
910 | #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ | 910 | #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ |
911 | #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ | 911 | #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ |
912 | #define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */ | 912 | #define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */ |
913 | #define EXT4_MOUNT_MBLK_IO_SUBMIT 0x4000000 /* multi-block io submits */ | ||
913 | #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */ | 914 | #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */ |
914 | #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */ | 915 | #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */ |
915 | #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */ | 916 | #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */ |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index bdbe69902207..e659597b690b 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -2125,9 +2125,12 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, | |||
2125 | */ | 2125 | */ |
2126 | if (unlikely(journal_data && PageChecked(page))) | 2126 | if (unlikely(journal_data && PageChecked(page))) |
2127 | err = __ext4_journalled_writepage(page, len); | 2127 | err = __ext4_journalled_writepage(page, len); |
2128 | else | 2128 | else if (test_opt(inode->i_sb, MBLK_IO_SUBMIT)) |
2129 | err = ext4_bio_write_page(&io_submit, page, | 2129 | err = ext4_bio_write_page(&io_submit, page, |
2130 | len, mpd->wbc); | 2130 | len, mpd->wbc); |
2131 | else | ||
2132 | err = block_write_full_page(page, | ||
2133 | noalloc_get_block_write, mpd->wbc); | ||
2131 | 2134 | ||
2132 | if (!err) | 2135 | if (!err) |
2133 | mpd->pages_written++; | 2136 | mpd->pages_written++; |
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index bf5ae883b1bd..eb3bc2fe647e 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
@@ -331,6 +331,30 @@ mext_out: | |||
331 | return err; | 331 | return err; |
332 | } | 332 | } |
333 | 333 | ||
334 | case FITRIM: | ||
335 | { | ||
336 | struct super_block *sb = inode->i_sb; | ||
337 | struct fstrim_range range; | ||
338 | int ret = 0; | ||
339 | |||
340 | if (!capable(CAP_SYS_ADMIN)) | ||
341 | return -EPERM; | ||
342 | |||
343 | if (copy_from_user(&range, (struct fstrim_range *)arg, | ||
344 | sizeof(range))) | ||
345 | return -EFAULT; | ||
346 | |||
347 | ret = ext4_trim_fs(sb, &range); | ||
348 | if (ret < 0) | ||
349 | return ret; | ||
350 | |||
351 | if (copy_to_user((struct fstrim_range *)arg, &range, | ||
352 | sizeof(range))) | ||
353 | return -EFAULT; | ||
354 | |||
355 | return 0; | ||
356 | } | ||
357 | |||
334 | default: | 358 | default: |
335 | return -ENOTTY; | 359 | return -ENOTTY; |
336 | } | 360 | } |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 92203b8a099f..dc40e75cba88 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -872,7 +872,7 @@ static struct buffer_head * ext4_find_entry (struct inode *dir, | |||
872 | if (namelen > EXT4_NAME_LEN) | 872 | if (namelen > EXT4_NAME_LEN) |
873 | return NULL; | 873 | return NULL; |
874 | if ((namelen <= 2) && (name[0] == '.') && | 874 | if ((namelen <= 2) && (name[0] == '.') && |
875 | (name[1] == '.' || name[1] == '0')) { | 875 | (name[1] == '.' || name[1] == '\0')) { |
876 | /* | 876 | /* |
877 | * "." or ".." will only be in the first block | 877 | * "." or ".." will only be in the first block |
878 | * NFS may look up ".."; "." should be handled by the VFS | 878 | * NFS may look up ".."; "." should be handled by the VFS |
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 7f5451cd1d38..beacce11ac50 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c | |||
@@ -237,8 +237,6 @@ static void ext4_end_bio(struct bio *bio, int error) | |||
237 | } while (bh != head); | 237 | } while (bh != head); |
238 | } | 238 | } |
239 | 239 | ||
240 | put_io_page(io_end->pages[i]); | ||
241 | |||
242 | /* | 240 | /* |
243 | * If this is a partial write which happened to make | 241 | * If this is a partial write which happened to make |
244 | * all buffers uptodate then we can optimize away a | 242 | * all buffers uptodate then we can optimize away a |
@@ -248,6 +246,8 @@ static void ext4_end_bio(struct bio *bio, int error) | |||
248 | */ | 246 | */ |
249 | if (!partial_write) | 247 | if (!partial_write) |
250 | SetPageUptodate(page); | 248 | SetPageUptodate(page); |
249 | |||
250 | put_io_page(io_end->pages[i]); | ||
251 | } | 251 | } |
252 | io_end->num_io_pages = 0; | 252 | io_end->num_io_pages = 0; |
253 | inode = io_end->inode; | 253 | inode = io_end->inode; |
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index dc963929de65..981c8477adab 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
@@ -232,6 +232,8 @@ static int setup_new_group_blocks(struct super_block *sb, | |||
232 | GFP_NOFS); | 232 | GFP_NOFS); |
233 | if (err) | 233 | if (err) |
234 | goto exit_bh; | 234 | goto exit_bh; |
235 | for (i = 0, bit = gdblocks + 1; i < reserved_gdb; i++, bit++) | ||
236 | ext4_set_bit(bit, bh->b_data); | ||
235 | 237 | ||
236 | ext4_debug("mark block bitmap %#04llx (+%llu)\n", input->block_bitmap, | 238 | ext4_debug("mark block bitmap %#04llx (+%llu)\n", input->block_bitmap, |
237 | input->block_bitmap - start); | 239 | input->block_bitmap - start); |
@@ -247,6 +249,9 @@ static int setup_new_group_blocks(struct super_block *sb, | |||
247 | err = sb_issue_zeroout(sb, block, sbi->s_itb_per_group, GFP_NOFS); | 249 | err = sb_issue_zeroout(sb, block, sbi->s_itb_per_group, GFP_NOFS); |
248 | if (err) | 250 | if (err) |
249 | goto exit_bh; | 251 | goto exit_bh; |
252 | for (i = 0, bit = input->inode_table - start; | ||
253 | i < sbi->s_itb_per_group; i++, bit++) | ||
254 | ext4_set_bit(bit, bh->b_data); | ||
250 | 255 | ||
251 | if ((err = extend_or_restart_transaction(handle, 2, bh))) | 256 | if ((err = extend_or_restart_transaction(handle, 2, bh))) |
252 | goto exit_bh; | 257 | goto exit_bh; |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 61182fe6254e..fb15c9c0be74 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -1026,6 +1026,8 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
1026 | !(def_mount_opts & EXT4_DEFM_NODELALLOC)) | 1026 | !(def_mount_opts & EXT4_DEFM_NODELALLOC)) |
1027 | seq_puts(seq, ",nodelalloc"); | 1027 | seq_puts(seq, ",nodelalloc"); |
1028 | 1028 | ||
1029 | if (test_opt(sb, MBLK_IO_SUBMIT)) | ||
1030 | seq_puts(seq, ",mblk_io_submit"); | ||
1029 | if (sbi->s_stripe) | 1031 | if (sbi->s_stripe) |
1030 | seq_printf(seq, ",stripe=%lu", sbi->s_stripe); | 1032 | seq_printf(seq, ",stripe=%lu", sbi->s_stripe); |
1031 | /* | 1033 | /* |
@@ -1197,7 +1199,6 @@ static const struct super_operations ext4_sops = { | |||
1197 | .quota_write = ext4_quota_write, | 1199 | .quota_write = ext4_quota_write, |
1198 | #endif | 1200 | #endif |
1199 | .bdev_try_to_free_page = bdev_try_to_free_page, | 1201 | .bdev_try_to_free_page = bdev_try_to_free_page, |
1200 | .trim_fs = ext4_trim_fs | ||
1201 | }; | 1202 | }; |
1202 | 1203 | ||
1203 | static const struct super_operations ext4_nojournal_sops = { | 1204 | static const struct super_operations ext4_nojournal_sops = { |
@@ -1240,8 +1241,8 @@ enum { | |||
1240 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, | 1241 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, |
1241 | Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, | 1242 | Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, |
1242 | Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version, | 1243 | Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version, |
1243 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, | 1244 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit, |
1244 | Opt_block_validity, Opt_noblock_validity, | 1245 | Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity, |
1245 | Opt_inode_readahead_blks, Opt_journal_ioprio, | 1246 | Opt_inode_readahead_blks, Opt_journal_ioprio, |
1246 | Opt_dioread_nolock, Opt_dioread_lock, | 1247 | Opt_dioread_nolock, Opt_dioread_lock, |
1247 | Opt_discard, Opt_nodiscard, | 1248 | Opt_discard, Opt_nodiscard, |
@@ -1305,6 +1306,8 @@ static const match_table_t tokens = { | |||
1305 | {Opt_resize, "resize"}, | 1306 | {Opt_resize, "resize"}, |
1306 | {Opt_delalloc, "delalloc"}, | 1307 | {Opt_delalloc, "delalloc"}, |
1307 | {Opt_nodelalloc, "nodelalloc"}, | 1308 | {Opt_nodelalloc, "nodelalloc"}, |
1309 | {Opt_mblk_io_submit, "mblk_io_submit"}, | ||
1310 | {Opt_nomblk_io_submit, "nomblk_io_submit"}, | ||
1308 | {Opt_block_validity, "block_validity"}, | 1311 | {Opt_block_validity, "block_validity"}, |
1309 | {Opt_noblock_validity, "noblock_validity"}, | 1312 | {Opt_noblock_validity, "noblock_validity"}, |
1310 | {Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, | 1313 | {Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, |
@@ -1726,6 +1729,12 @@ set_qf_format: | |||
1726 | case Opt_nodelalloc: | 1729 | case Opt_nodelalloc: |
1727 | clear_opt(sbi->s_mount_opt, DELALLOC); | 1730 | clear_opt(sbi->s_mount_opt, DELALLOC); |
1728 | break; | 1731 | break; |
1732 | case Opt_mblk_io_submit: | ||
1733 | set_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT); | ||
1734 | break; | ||
1735 | case Opt_nomblk_io_submit: | ||
1736 | clear_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT); | ||
1737 | break; | ||
1729 | case Opt_stripe: | 1738 | case Opt_stripe: |
1730 | if (match_int(&args[0], &option)) | 1739 | if (match_int(&args[0], &option)) |
1731 | return 0; | 1740 | return 0; |
@@ -2799,9 +2808,6 @@ static void ext4_clear_request_list(void) | |||
2799 | struct ext4_li_request *elr; | 2808 | struct ext4_li_request *elr; |
2800 | 2809 | ||
2801 | mutex_lock(&ext4_li_info->li_list_mtx); | 2810 | mutex_lock(&ext4_li_info->li_list_mtx); |
2802 | if (list_empty(&ext4_li_info->li_request_list)) | ||
2803 | return; | ||
2804 | |||
2805 | list_for_each_safe(pos, n, &ext4_li_info->li_request_list) { | 2811 | list_for_each_safe(pos, n, &ext4_li_info->li_request_list) { |
2806 | elr = list_entry(pos, struct ext4_li_request, | 2812 | elr = list_entry(pos, struct ext4_li_request, |
2807 | lr_request); | 2813 | lr_request); |
@@ -3268,13 +3274,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3268 | * Test whether we have more sectors than will fit in sector_t, | 3274 | * Test whether we have more sectors than will fit in sector_t, |
3269 | * and whether the max offset is addressable by the page cache. | 3275 | * and whether the max offset is addressable by the page cache. |
3270 | */ | 3276 | */ |
3271 | ret = generic_check_addressable(sb->s_blocksize_bits, | 3277 | err = generic_check_addressable(sb->s_blocksize_bits, |
3272 | ext4_blocks_count(es)); | 3278 | ext4_blocks_count(es)); |
3273 | if (ret) { | 3279 | if (err) { |
3274 | ext4_msg(sb, KERN_ERR, "filesystem" | 3280 | ext4_msg(sb, KERN_ERR, "filesystem" |
3275 | " too large to mount safely on this system"); | 3281 | " too large to mount safely on this system"); |
3276 | if (sizeof(sector_t) < 8) | 3282 | if (sizeof(sector_t) < 8) |
3277 | ext4_msg(sb, KERN_WARNING, "CONFIG_LBDAF not enabled"); | 3283 | ext4_msg(sb, KERN_WARNING, "CONFIG_LBDAF not enabled"); |
3284 | ret = err; | ||
3278 | goto failed_mount; | 3285 | goto failed_mount; |
3279 | } | 3286 | } |
3280 | 3287 | ||