diff options
author | Tao Ma <tao.ma@oracle.com> | 2008-08-18 05:38:52 -0400 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2008-10-13 19:57:03 -0400 |
commit | ca12b7c48942d21b2e7890b820db9d578bc291cd (patch) | |
tree | e051e6ceb77a05db7dd1d749d7f3f1682c69196c /fs/ocfs2 | |
parent | 589dc2602f2a1b7fa5e59b90f548af189f128d77 (diff) |
ocfs2: Optionally limit extent size in ocfs2_insert_extent()
In xattr bucket, we want to limit the maximum size of a btree leaf,
otherwise we'll lose the benefits of hashing because we'll have to search
large leaves.
So add a new field in ocfs2_extent_tree which indicates the maximum leaf cluster
size we want so that we can prevent ocfs2_insert_extent() from merging the leaf
record even if it is contiguous with an adjacent record.
Other btree types are not affected by this change.
Signed-off-by: Tao Ma <tao.ma@oracle.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/alloc.c | 39 | ||||
-rw-r--r-- | fs/ocfs2/alloc.h | 5 |
2 files changed, 35 insertions, 9 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 06ea7913c134..f65cb43edb7c 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -79,6 +79,7 @@ struct ocfs2_extent_tree { | |||
79 | struct buffer_head *root_bh; | 79 | struct buffer_head *root_bh; |
80 | struct ocfs2_extent_list *root_el; | 80 | struct ocfs2_extent_list *root_el; |
81 | void *private; | 81 | void *private; |
82 | unsigned int max_leaf_clusters; | ||
82 | }; | 83 | }; |
83 | 84 | ||
84 | static void ocfs2_dinode_set_last_eb_blk(struct ocfs2_extent_tree *et, | 85 | static void ocfs2_dinode_set_last_eb_blk(struct ocfs2_extent_tree *et, |
@@ -220,7 +221,8 @@ static struct ocfs2_extent_tree_operations ocfs2_xattr_tree_et_ops = { | |||
220 | }; | 221 | }; |
221 | 222 | ||
222 | static struct ocfs2_extent_tree* | 223 | static struct ocfs2_extent_tree* |
223 | ocfs2_new_extent_tree(struct buffer_head *bh, | 224 | ocfs2_new_extent_tree(struct inode *inode, |
225 | struct buffer_head *bh, | ||
224 | enum ocfs2_extent_tree_type et_type, | 226 | enum ocfs2_extent_tree_type et_type, |
225 | void *private) | 227 | void *private) |
226 | { | 228 | { |
@@ -248,6 +250,8 @@ static struct ocfs2_extent_tree* | |||
248 | (struct ocfs2_xattr_block *)bh->b_data; | 250 | (struct ocfs2_xattr_block *)bh->b_data; |
249 | et->root_el = &xb->xb_attrs.xb_root.xt_list; | 251 | et->root_el = &xb->xb_attrs.xb_root.xt_list; |
250 | et->eops = &ocfs2_xattr_tree_et_ops; | 252 | et->eops = &ocfs2_xattr_tree_et_ops; |
253 | et->max_leaf_clusters = ocfs2_clusters_for_bytes(inode->i_sb, | ||
254 | OCFS2_MAX_XATTR_TREE_LEAF_SIZE); | ||
251 | } | 255 | } |
252 | 256 | ||
253 | return et; | 257 | return et; |
@@ -4109,7 +4113,8 @@ out: | |||
4109 | static void ocfs2_figure_contig_type(struct inode *inode, | 4113 | static void ocfs2_figure_contig_type(struct inode *inode, |
4110 | struct ocfs2_insert_type *insert, | 4114 | struct ocfs2_insert_type *insert, |
4111 | struct ocfs2_extent_list *el, | 4115 | struct ocfs2_extent_list *el, |
4112 | struct ocfs2_extent_rec *insert_rec) | 4116 | struct ocfs2_extent_rec *insert_rec, |
4117 | struct ocfs2_extent_tree *et) | ||
4113 | { | 4118 | { |
4114 | int i; | 4119 | int i; |
4115 | enum ocfs2_contig_type contig_type = CONTIG_NONE; | 4120 | enum ocfs2_contig_type contig_type = CONTIG_NONE; |
@@ -4125,6 +4130,20 @@ static void ocfs2_figure_contig_type(struct inode *inode, | |||
4125 | } | 4130 | } |
4126 | } | 4131 | } |
4127 | insert->ins_contig = contig_type; | 4132 | insert->ins_contig = contig_type; |
4133 | |||
4134 | if (insert->ins_contig != CONTIG_NONE) { | ||
4135 | struct ocfs2_extent_rec *rec = | ||
4136 | &el->l_recs[insert->ins_contig_index]; | ||
4137 | unsigned int len = le16_to_cpu(rec->e_leaf_clusters) + | ||
4138 | le16_to_cpu(insert_rec->e_leaf_clusters); | ||
4139 | |||
4140 | /* | ||
4141 | * Caller might want us to limit the size of extents, don't | ||
4142 | * calculate contiguousness if we might exceed that limit. | ||
4143 | */ | ||
4144 | if (et->max_leaf_clusters && len > et->max_leaf_clusters) | ||
4145 | insert->ins_contig = CONTIG_NONE; | ||
4146 | } | ||
4128 | } | 4147 | } |
4129 | 4148 | ||
4130 | /* | 4149 | /* |
@@ -4232,7 +4251,7 @@ static int ocfs2_figure_insert_type(struct inode *inode, | |||
4232 | le16_to_cpu(el->l_next_free_rec); | 4251 | le16_to_cpu(el->l_next_free_rec); |
4233 | 4252 | ||
4234 | if (!insert->ins_tree_depth) { | 4253 | if (!insert->ins_tree_depth) { |
4235 | ocfs2_figure_contig_type(inode, insert, el, insert_rec); | 4254 | ocfs2_figure_contig_type(inode, insert, el, insert_rec, et); |
4236 | ocfs2_figure_appending_type(insert, el, insert_rec); | 4255 | ocfs2_figure_appending_type(insert, el, insert_rec); |
4237 | return 0; | 4256 | return 0; |
4238 | } | 4257 | } |
@@ -4266,7 +4285,7 @@ static int ocfs2_figure_insert_type(struct inode *inode, | |||
4266 | * into two types of appends: simple record append, or a | 4285 | * into two types of appends: simple record append, or a |
4267 | * rotate inside the tail leaf. | 4286 | * rotate inside the tail leaf. |
4268 | */ | 4287 | */ |
4269 | ocfs2_figure_contig_type(inode, insert, el, insert_rec); | 4288 | ocfs2_figure_contig_type(inode, insert, el, insert_rec, et); |
4270 | 4289 | ||
4271 | /* | 4290 | /* |
4272 | * The insert code isn't quite ready to deal with all cases of | 4291 | * The insert code isn't quite ready to deal with all cases of |
@@ -4402,7 +4421,7 @@ int ocfs2_dinode_insert_extent(struct ocfs2_super *osb, | |||
4402 | int status; | 4421 | int status; |
4403 | struct ocfs2_extent_tree *et = NULL; | 4422 | struct ocfs2_extent_tree *et = NULL; |
4404 | 4423 | ||
4405 | et = ocfs2_new_extent_tree(root_bh, OCFS2_DINODE_EXTENT, NULL); | 4424 | et = ocfs2_new_extent_tree(inode, root_bh, OCFS2_DINODE_EXTENT, NULL); |
4406 | if (!et) { | 4425 | if (!et) { |
4407 | status = -ENOMEM; | 4426 | status = -ENOMEM; |
4408 | mlog_errno(status); | 4427 | mlog_errno(status); |
@@ -4433,7 +4452,8 @@ int ocfs2_xattr_value_insert_extent(struct ocfs2_super *osb, | |||
4433 | int status; | 4452 | int status; |
4434 | struct ocfs2_extent_tree *et = NULL; | 4453 | struct ocfs2_extent_tree *et = NULL; |
4435 | 4454 | ||
4436 | et = ocfs2_new_extent_tree(root_bh, OCFS2_XATTR_VALUE_EXTENT, private); | 4455 | et = ocfs2_new_extent_tree(inode, root_bh, |
4456 | OCFS2_XATTR_VALUE_EXTENT, private); | ||
4437 | if (!et) { | 4457 | if (!et) { |
4438 | status = -ENOMEM; | 4458 | status = -ENOMEM; |
4439 | mlog_errno(status); | 4459 | mlog_errno(status); |
@@ -4463,7 +4483,8 @@ int ocfs2_xattr_tree_insert_extent(struct ocfs2_super *osb, | |||
4463 | int status; | 4483 | int status; |
4464 | struct ocfs2_extent_tree *et = NULL; | 4484 | struct ocfs2_extent_tree *et = NULL; |
4465 | 4485 | ||
4466 | et = ocfs2_new_extent_tree(root_bh, OCFS2_XATTR_TREE_EXTENT, NULL); | 4486 | et = ocfs2_new_extent_tree(inode, root_bh, OCFS2_XATTR_TREE_EXTENT, |
4487 | NULL); | ||
4467 | if (!et) { | 4488 | if (!et) { |
4468 | status = -ENOMEM; | 4489 | status = -ENOMEM; |
4469 | mlog_errno(status); | 4490 | mlog_errno(status); |
@@ -4879,7 +4900,7 @@ int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *root_bh, | |||
4879 | goto out; | 4900 | goto out; |
4880 | } | 4901 | } |
4881 | 4902 | ||
4882 | et = ocfs2_new_extent_tree(root_bh, et_type, private); | 4903 | et = ocfs2_new_extent_tree(inode, root_bh, et_type, private); |
4883 | if (!et) { | 4904 | if (!et) { |
4884 | ret = -ENOMEM; | 4905 | ret = -ENOMEM; |
4885 | mlog_errno(ret); | 4906 | mlog_errno(ret); |
@@ -5177,7 +5198,7 @@ int ocfs2_remove_extent(struct inode *inode, struct buffer_head *root_bh, | |||
5177 | struct ocfs2_path *path = NULL; | 5198 | struct ocfs2_path *path = NULL; |
5178 | struct ocfs2_extent_tree *et = NULL; | 5199 | struct ocfs2_extent_tree *et = NULL; |
5179 | 5200 | ||
5180 | et = ocfs2_new_extent_tree(root_bh, et_type, private); | 5201 | et = ocfs2_new_extent_tree(inode, root_bh, et_type, private); |
5181 | if (!et) { | 5202 | if (!et) { |
5182 | ret = -ENOMEM; | 5203 | ret = -ENOMEM; |
5183 | mlog_errno(ret); | 5204 | mlog_errno(ret); |
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index cd4e12d2b6b9..23c695ddaa52 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h | |||
@@ -32,6 +32,11 @@ enum ocfs2_extent_tree_type { | |||
32 | OCFS2_XATTR_TREE_EXTENT, | 32 | OCFS2_XATTR_TREE_EXTENT, |
33 | }; | 33 | }; |
34 | 34 | ||
35 | /* | ||
36 | * For xattr tree leaf, we limit the leaf byte size to be 64K. | ||
37 | */ | ||
38 | #define OCFS2_MAX_XATTR_TREE_LEAF_SIZE 65536 | ||
39 | |||
35 | struct ocfs2_alloc_context; | 40 | struct ocfs2_alloc_context; |
36 | int ocfs2_dinode_insert_extent(struct ocfs2_super *osb, | 41 | int ocfs2_dinode_insert_extent(struct ocfs2_super *osb, |
37 | handle_t *handle, | 42 | handle_t *handle, |