]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Tao Ma <tao.ma@oracle.com> |
2 | Subject: [PATCH 13/16] ocfs2: Optionally limit extent size in ocfs2_insert_extent() | |
3 | Patch-mainline: 2.6.28? | |
4 | References: FATE302067 | |
5 | ||
6 | In xattr bucket, we want to limit the maximum size of a btree leaf, | |
7 | otherwise we'll lose the benefits of hashing because we'll have to search | |
8 | large leaves. | |
9 | ||
10 | So add a new field in ocfs2_extent_tree which indicates the maximum leaf cluster | |
11 | size we want so that we can prevent ocfs2_insert_extent() from merging the leaf | |
12 | record even if it is contiguous with an adjacent record. | |
13 | ||
14 | Other btree types are not affected by this change. | |
15 | ||
16 | Signed-off-by: Tao Ma <tao.ma@oracle.com> | |
17 | Signed-off-by: Mark Fasheh <mfasheh@suse.com> | |
18 | --- | |
19 | fs/ocfs2/alloc.c | 39 ++++++++++++++++++++++++++++++--------- | |
20 | fs/ocfs2/alloc.h | 5 +++++ | |
21 | 2 files changed, 35 insertions(+), 9 deletions(-) | |
22 | ||
23 | diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c | |
24 | index 47cdea6..16879bd 100644 | |
25 | --- a/fs/ocfs2/alloc.c | |
26 | +++ b/fs/ocfs2/alloc.c | |
27 | @@ -79,6 +79,7 @@ struct ocfs2_extent_tree { | |
28 | struct buffer_head *root_bh; | |
29 | struct ocfs2_extent_list *root_el; | |
30 | void *private; | |
31 | + unsigned int max_leaf_clusters; | |
32 | }; | |
33 | ||
34 | static void ocfs2_dinode_set_last_eb_blk(struct ocfs2_extent_tree *et, | |
35 | @@ -220,7 +221,8 @@ static struct ocfs2_extent_tree_operations ocfs2_xattr_tree_et_ops = { | |
36 | }; | |
37 | ||
38 | static struct ocfs2_extent_tree* | |
39 | - ocfs2_new_extent_tree(struct buffer_head *bh, | |
40 | + ocfs2_new_extent_tree(struct inode *inode, | |
41 | + struct buffer_head *bh, | |
42 | enum ocfs2_extent_tree_type et_type, | |
43 | void *private) | |
44 | { | |
45 | @@ -248,6 +250,8 @@ static struct ocfs2_extent_tree* | |
46 | (struct ocfs2_xattr_block *)bh->b_data; | |
47 | et->root_el = &xb->xb_attrs.xb_root.xt_list; | |
48 | et->eops = &ocfs2_xattr_tree_et_ops; | |
49 | + et->max_leaf_clusters = ocfs2_clusters_for_bytes(inode->i_sb, | |
50 | + OCFS2_MAX_XATTR_TREE_LEAF_SIZE); | |
51 | } | |
52 | ||
53 | return et; | |
54 | @@ -4118,7 +4122,8 @@ out: | |
55 | static void ocfs2_figure_contig_type(struct inode *inode, | |
56 | struct ocfs2_insert_type *insert, | |
57 | struct ocfs2_extent_list *el, | |
58 | - struct ocfs2_extent_rec *insert_rec) | |
59 | + struct ocfs2_extent_rec *insert_rec, | |
60 | + struct ocfs2_extent_tree *et) | |
61 | { | |
62 | int i; | |
63 | enum ocfs2_contig_type contig_type = CONTIG_NONE; | |
64 | @@ -4134,6 +4139,20 @@ static void ocfs2_figure_contig_type(struct inode *inode, | |
65 | } | |
66 | } | |
67 | insert->ins_contig = contig_type; | |
68 | + | |
69 | + if (insert->ins_contig != CONTIG_NONE) { | |
70 | + struct ocfs2_extent_rec *rec = | |
71 | + &el->l_recs[insert->ins_contig_index]; | |
72 | + unsigned int len = le16_to_cpu(rec->e_leaf_clusters) + | |
73 | + le16_to_cpu(insert_rec->e_leaf_clusters); | |
74 | + | |
75 | + /* | |
76 | + * Caller might want us to limit the size of extents, don't | |
77 | + * calculate contiguousness if we might exceed that limit. | |
78 | + */ | |
79 | + if (et->max_leaf_clusters && len > et->max_leaf_clusters) | |
80 | + insert->ins_contig = CONTIG_NONE; | |
81 | + } | |
82 | } | |
83 | ||
84 | /* | |
85 | @@ -4241,7 +4260,7 @@ static int ocfs2_figure_insert_type(struct inode *inode, | |
86 | le16_to_cpu(el->l_next_free_rec); | |
87 | ||
88 | if (!insert->ins_tree_depth) { | |
89 | - ocfs2_figure_contig_type(inode, insert, el, insert_rec); | |
90 | + ocfs2_figure_contig_type(inode, insert, el, insert_rec, et); | |
91 | ocfs2_figure_appending_type(insert, el, insert_rec); | |
92 | return 0; | |
93 | } | |
94 | @@ -4275,7 +4294,7 @@ static int ocfs2_figure_insert_type(struct inode *inode, | |
95 | * into two types of appends: simple record append, or a | |
96 | * rotate inside the tail leaf. | |
97 | */ | |
98 | - ocfs2_figure_contig_type(inode, insert, el, insert_rec); | |
99 | + ocfs2_figure_contig_type(inode, insert, el, insert_rec, et); | |
100 | ||
101 | /* | |
102 | * The insert code isn't quite ready to deal with all cases of | |
103 | @@ -4411,7 +4430,7 @@ int ocfs2_dinode_insert_extent(struct ocfs2_super *osb, | |
104 | int status; | |
105 | struct ocfs2_extent_tree *et = NULL; | |
106 | ||
107 | - et = ocfs2_new_extent_tree(root_bh, OCFS2_DINODE_EXTENT, NULL); | |
108 | + et = ocfs2_new_extent_tree(inode, root_bh, OCFS2_DINODE_EXTENT, NULL); | |
109 | if (!et) { | |
110 | status = -ENOMEM; | |
111 | mlog_errno(status); | |
112 | @@ -4442,7 +4461,8 @@ int ocfs2_xattr_value_insert_extent(struct ocfs2_super *osb, | |
113 | int status; | |
114 | struct ocfs2_extent_tree *et = NULL; | |
115 | ||
116 | - et = ocfs2_new_extent_tree(root_bh, OCFS2_XATTR_VALUE_EXTENT, private); | |
117 | + et = ocfs2_new_extent_tree(inode, root_bh, | |
118 | + OCFS2_XATTR_VALUE_EXTENT, private); | |
119 | if (!et) { | |
120 | status = -ENOMEM; | |
121 | mlog_errno(status); | |
122 | @@ -4472,7 +4492,8 @@ int ocfs2_xattr_tree_insert_extent(struct ocfs2_super *osb, | |
123 | int status; | |
124 | struct ocfs2_extent_tree *et = NULL; | |
125 | ||
126 | - et = ocfs2_new_extent_tree(root_bh, OCFS2_XATTR_TREE_EXTENT, NULL); | |
127 | + et = ocfs2_new_extent_tree(inode, root_bh, OCFS2_XATTR_TREE_EXTENT, | |
128 | + NULL); | |
129 | if (!et) { | |
130 | status = -ENOMEM; | |
131 | mlog_errno(status); | |
132 | @@ -4888,7 +4909,7 @@ int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *root_bh, | |
133 | goto out; | |
134 | } | |
135 | ||
136 | - et = ocfs2_new_extent_tree(root_bh, et_type, private); | |
137 | + et = ocfs2_new_extent_tree(inode, root_bh, et_type, private); | |
138 | if (!et) { | |
139 | ret = -ENOMEM; | |
140 | mlog_errno(ret); | |
141 | @@ -5186,7 +5207,7 @@ int ocfs2_remove_extent(struct inode *inode, struct buffer_head *root_bh, | |
142 | struct ocfs2_path *path = NULL; | |
143 | struct ocfs2_extent_tree *et = NULL; | |
144 | ||
145 | - et = ocfs2_new_extent_tree(root_bh, et_type, private); | |
146 | + et = ocfs2_new_extent_tree(inode, root_bh, et_type, private); | |
147 | if (!et) { | |
148 | ret = -ENOMEM; | |
149 | mlog_errno(ret); | |
150 | diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h | |
151 | index b8cfc53..ff40c8f 100644 | |
152 | --- a/fs/ocfs2/alloc.h | |
153 | +++ b/fs/ocfs2/alloc.h | |
154 | @@ -32,6 +32,11 @@ enum ocfs2_extent_tree_type { | |
155 | OCFS2_XATTR_TREE_EXTENT, | |
156 | }; | |
157 | ||
158 | +/* | |
159 | + * For xattr tree leaf, we limit the leaf byte size to be 64K. | |
160 | + */ | |
161 | +#define OCFS2_MAX_XATTR_TREE_LEAF_SIZE 65536 | |
162 | + | |
163 | struct ocfs2_alloc_context; | |
164 | int ocfs2_dinode_insert_extent(struct ocfs2_super *osb, | |
165 | handle_t *handle, | |
166 | -- | |
167 | 1.5.4.5 | |
168 |