diff options
author | Alex Tomas <alex@clusterfs.com> | 2008-01-29 00:19:52 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2008-01-29 00:19:52 -0500 |
commit | c9de560ded61faa5b754137b7753da252391c55a (patch) | |
tree | 2c4311377c4aa72450e27f531e198fe3e1c67db0 /fs/ext4/super.c | |
parent | 1988b51e476bd097d910c9245b53f2e38aedaf0d (diff) |
ext4: Add multi block allocator for ext4
Signed-off-by: Alex Tomas <alex@clusterfs.com>
Signed-off-by: Andreas Dilger <adilger@clusterfs.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 64fc7f111734..3a51ffc47790 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -503,6 +503,7 @@ static void ext4_put_super (struct super_block * sb) | |||
503 | struct ext4_super_block *es = sbi->s_es; | 503 | struct ext4_super_block *es = sbi->s_es; |
504 | int i; | 504 | int i; |
505 | 505 | ||
506 | ext4_mb_release(sb); | ||
506 | ext4_ext_release(sb); | 507 | ext4_ext_release(sb); |
507 | ext4_xattr_put_super(sb); | 508 | ext4_xattr_put_super(sb); |
508 | jbd2_journal_destroy(sbi->s_journal); | 509 | jbd2_journal_destroy(sbi->s_journal); |
@@ -569,6 +570,8 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
569 | ei->i_block_alloc_info = NULL; | 570 | ei->i_block_alloc_info = NULL; |
570 | ei->vfs_inode.i_version = 1; | 571 | ei->vfs_inode.i_version = 1; |
571 | memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache)); | 572 | memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache)); |
573 | INIT_LIST_HEAD(&ei->i_prealloc_list); | ||
574 | spin_lock_init(&ei->i_prealloc_lock); | ||
572 | return &ei->vfs_inode; | 575 | return &ei->vfs_inode; |
573 | } | 576 | } |
574 | 577 | ||
@@ -881,6 +884,7 @@ enum { | |||
881 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, | 884 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, |
882 | Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, | 885 | Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, |
883 | Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version, | 886 | Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version, |
887 | Opt_mballoc, Opt_nomballoc, Opt_stripe, | ||
884 | }; | 888 | }; |
885 | 889 | ||
886 | static match_table_t tokens = { | 890 | static match_table_t tokens = { |
@@ -935,6 +939,9 @@ static match_table_t tokens = { | |||
935 | {Opt_extents, "extents"}, | 939 | {Opt_extents, "extents"}, |
936 | {Opt_noextents, "noextents"}, | 940 | {Opt_noextents, "noextents"}, |
937 | {Opt_i_version, "i_version"}, | 941 | {Opt_i_version, "i_version"}, |
942 | {Opt_mballoc, "mballoc"}, | ||
943 | {Opt_nomballoc, "nomballoc"}, | ||
944 | {Opt_stripe, "stripe=%u"}, | ||
938 | {Opt_err, NULL}, | 945 | {Opt_err, NULL}, |
939 | {Opt_resize, "resize"}, | 946 | {Opt_resize, "resize"}, |
940 | }; | 947 | }; |
@@ -1284,6 +1291,19 @@ clear_qf_name: | |||
1284 | set_opt(sbi->s_mount_opt, I_VERSION); | 1291 | set_opt(sbi->s_mount_opt, I_VERSION); |
1285 | sb->s_flags |= MS_I_VERSION; | 1292 | sb->s_flags |= MS_I_VERSION; |
1286 | break; | 1293 | break; |
1294 | case Opt_mballoc: | ||
1295 | set_opt(sbi->s_mount_opt, MBALLOC); | ||
1296 | break; | ||
1297 | case Opt_nomballoc: | ||
1298 | clear_opt(sbi->s_mount_opt, MBALLOC); | ||
1299 | break; | ||
1300 | case Opt_stripe: | ||
1301 | if (match_int(&args[0], &option)) | ||
1302 | return 0; | ||
1303 | if (option < 0) | ||
1304 | return 0; | ||
1305 | sbi->s_stripe = option; | ||
1306 | break; | ||
1287 | default: | 1307 | default: |
1288 | printk (KERN_ERR | 1308 | printk (KERN_ERR |
1289 | "EXT4-fs: Unrecognized mount option \"%s\" " | 1309 | "EXT4-fs: Unrecognized mount option \"%s\" " |
@@ -1742,6 +1762,34 @@ static ext4_fsblk_t descriptor_loc(struct super_block *sb, | |||
1742 | return (has_super + ext4_group_first_block_no(sb, bg)); | 1762 | return (has_super + ext4_group_first_block_no(sb, bg)); |
1743 | } | 1763 | } |
1744 | 1764 | ||
1765 | /** | ||
1766 | * ext4_get_stripe_size: Get the stripe size. | ||
1767 | * @sbi: In memory super block info | ||
1768 | * | ||
1769 | * If we have specified it via mount option, then | ||
1770 | * use the mount option value. If the value specified at mount time is | ||
1771 | * greater than the blocks per group use the super block value. | ||
1772 | * If the super block value is greater than blocks per group return 0. | ||
1773 | * Allocator needs it be less than blocks per group. | ||
1774 | * | ||
1775 | */ | ||
1776 | static unsigned long ext4_get_stripe_size(struct ext4_sb_info *sbi) | ||
1777 | { | ||
1778 | unsigned long stride = le16_to_cpu(sbi->s_es->s_raid_stride); | ||
1779 | unsigned long stripe_width = | ||
1780 | le32_to_cpu(sbi->s_es->s_raid_stripe_width); | ||
1781 | |||
1782 | if (sbi->s_stripe && sbi->s_stripe <= sbi->s_blocks_per_group) | ||
1783 | return sbi->s_stripe; | ||
1784 | |||
1785 | if (stripe_width <= sbi->s_blocks_per_group) | ||
1786 | return stripe_width; | ||
1787 | |||
1788 | if (stride <= sbi->s_blocks_per_group) | ||
1789 | return stride; | ||
1790 | |||
1791 | return 0; | ||
1792 | } | ||
1745 | 1793 | ||
1746 | static int ext4_fill_super (struct super_block *sb, void *data, int silent) | 1794 | static int ext4_fill_super (struct super_block *sb, void *data, int silent) |
1747 | __releases(kernel_sem) | 1795 | __releases(kernel_sem) |
@@ -2091,6 +2139,8 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
2091 | sbi->s_rsv_window_head.rsv_goal_size = 0; | 2139 | sbi->s_rsv_window_head.rsv_goal_size = 0; |
2092 | ext4_rsv_window_add(sb, &sbi->s_rsv_window_head); | 2140 | ext4_rsv_window_add(sb, &sbi->s_rsv_window_head); |
2093 | 2141 | ||
2142 | sbi->s_stripe = ext4_get_stripe_size(sbi); | ||
2143 | |||
2094 | /* | 2144 | /* |
2095 | * set up enough so that it can read an inode | 2145 | * set up enough so that it can read an inode |
2096 | */ | 2146 | */ |
@@ -2250,6 +2300,7 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
2250 | "writeback"); | 2300 | "writeback"); |
2251 | 2301 | ||
2252 | ext4_ext_init(sb); | 2302 | ext4_ext_init(sb); |
2303 | ext4_mb_init(sb, needs_recovery); | ||
2253 | 2304 | ||
2254 | lock_kernel(); | 2305 | lock_kernel(); |
2255 | return 0; | 2306 | return 0; |
@@ -3232,9 +3283,15 @@ static struct file_system_type ext4dev_fs_type = { | |||
3232 | 3283 | ||
3233 | static int __init init_ext4_fs(void) | 3284 | static int __init init_ext4_fs(void) |
3234 | { | 3285 | { |
3235 | int err = init_ext4_xattr(); | 3286 | int err; |
3287 | |||
3288 | err = init_ext4_mballoc(); | ||
3236 | if (err) | 3289 | if (err) |
3237 | return err; | 3290 | return err; |
3291 | |||
3292 | err = init_ext4_xattr(); | ||
3293 | if (err) | ||
3294 | goto out2; | ||
3238 | err = init_inodecache(); | 3295 | err = init_inodecache(); |
3239 | if (err) | 3296 | if (err) |
3240 | goto out1; | 3297 | goto out1; |
@@ -3246,6 +3303,8 @@ out: | |||
3246 | destroy_inodecache(); | 3303 | destroy_inodecache(); |
3247 | out1: | 3304 | out1: |
3248 | exit_ext4_xattr(); | 3305 | exit_ext4_xattr(); |
3306 | out2: | ||
3307 | exit_ext4_mballoc(); | ||
3249 | return err; | 3308 | return err; |
3250 | } | 3309 | } |
3251 | 3310 | ||
@@ -3254,6 +3313,7 @@ static void __exit exit_ext4_fs(void) | |||
3254 | unregister_filesystem(&ext4dev_fs_type); | 3313 | unregister_filesystem(&ext4dev_fs_type); |
3255 | destroy_inodecache(); | 3314 | destroy_inodecache(); |
3256 | exit_ext4_xattr(); | 3315 | exit_ext4_xattr(); |
3316 | exit_ext4_mballoc(); | ||
3257 | } | 3317 | } |
3258 | 3318 | ||
3259 | MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); | 3319 | MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); |