]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.suse/ocfs2-Use-buckets-in-ocfs2_xattr_create_index_block.patch
Updated xen patches taken from suse.
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.suse / ocfs2-Use-buckets-in-ocfs2_xattr_create_index_block.patch
1 From: Joel Becker <joel.becker@oracle.com>
2 Date: Mon, 27 Oct 2008 15:18:29 -0700
3 Subject: ocfs2: Use buckets in ocfs2_xattr_create_index_block().
4 Patch-mainline: 2.6.29
5
6 Use the ocfs2_xattr_bucket abstraction in
7 ocfs2_xattr_create_index_block() and its helpers. We get more efficient
8 reads, a lot less buffer_head munging, and nicer code to boot. While
9 we're at it, ocfs2_xattr_update_xattr_search() becomes void.
10
11 Signed-off-by: Joel Becker <joel.becker@oracle.com>
12 Signed-off-by: Mark Fasheh <mfasheh@suse.com>
13 ---
14 fs/ocfs2/xattr.c | 114 +++++++++++++++--------------------------------------
15 1 files changed, 32 insertions(+), 82 deletions(-)
16
17 diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
18 index 46986c6..76969b9 100644
19 --- a/fs/ocfs2/xattr.c
20 +++ b/fs/ocfs2/xattr.c
21 @@ -2649,32 +2649,34 @@ static void swap_xe(void *a, void *b, int size)
22 /*
23 * When the ocfs2_xattr_block is filled up, new bucket will be created
24 * and all the xattr entries will be moved to the new bucket.
25 + * The header goes at the start of the bucket, and the names+values are
26 + * filled from the end. This is why *target starts as the last buffer.
27 * Note: we need to sort the entries since they are not saved in order
28 * in the ocfs2_xattr_block.
29 */
30 static void ocfs2_cp_xattr_block_to_bucket(struct inode *inode,
31 struct buffer_head *xb_bh,
32 - struct buffer_head *xh_bh,
33 - struct buffer_head *data_bh)
34 + struct ocfs2_xattr_bucket *bucket)
35 {
36 int i, blocksize = inode->i_sb->s_blocksize;
37 + int blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
38 u16 offset, size, off_change;
39 struct ocfs2_xattr_entry *xe;
40 struct ocfs2_xattr_block *xb =
41 (struct ocfs2_xattr_block *)xb_bh->b_data;
42 struct ocfs2_xattr_header *xb_xh = &xb->xb_attrs.xb_header;
43 - struct ocfs2_xattr_header *xh =
44 - (struct ocfs2_xattr_header *)xh_bh->b_data;
45 + struct ocfs2_xattr_header *xh = bucket_xh(bucket);
46 u16 count = le16_to_cpu(xb_xh->xh_count);
47 - char *target = xh_bh->b_data, *src = xb_bh->b_data;
48 + char *src = xb_bh->b_data;
49 + char *target = bucket_block(bucket, blks - 1);
50
51 mlog(0, "cp xattr from block %llu to bucket %llu\n",
52 (unsigned long long)xb_bh->b_blocknr,
53 - (unsigned long long)xh_bh->b_blocknr);
54 + (unsigned long long)bucket_blkno(bucket));
55 +
56 + for (i = 0; i < blks; i++)
57 + memset(bucket_block(bucket, i), 0, blocksize);
58
59 - memset(xh_bh->b_data, 0, blocksize);
60 - if (data_bh)
61 - memset(data_bh->b_data, 0, blocksize);
62 /*
63 * Since the xe_name_offset is based on ocfs2_xattr_header,
64 * there is a offset change corresponding to the change of
65 @@ -2686,8 +2688,6 @@ static void ocfs2_cp_xattr_block_to_bucket(struct inode *inode,
66 size = blocksize - offset;
67
68 /* copy all the names and values. */
69 - if (data_bh)
70 - target = data_bh->b_data;
71 memcpy(target + offset, src + offset, size);
72
73 /* Init new header now. */
74 @@ -2697,7 +2697,7 @@ static void ocfs2_cp_xattr_block_to_bucket(struct inode *inode,
75 xh->xh_free_start = cpu_to_le16(OCFS2_XATTR_BUCKET_SIZE - size);
76
77 /* copy all the entries. */
78 - target = xh_bh->b_data;
79 + target = bucket_block(bucket, 0);
80 offset = offsetof(struct ocfs2_xattr_header, xh_entries);
81 size = count * sizeof(struct ocfs2_xattr_entry);
82 memcpy(target + offset, (char *)xb_xh + offset, size);
83 @@ -2723,42 +2723,24 @@ static void ocfs2_cp_xattr_block_to_bucket(struct inode *inode,
84 * While if the entry is in index b-tree, "bucket" indicates the
85 * real place of the xattr.
86 */
87 -static int ocfs2_xattr_update_xattr_search(struct inode *inode,
88 - struct ocfs2_xattr_search *xs,
89 - struct buffer_head *old_bh,
90 - struct buffer_head *new_bh)
91 +static void ocfs2_xattr_update_xattr_search(struct inode *inode,
92 + struct ocfs2_xattr_search *xs,
93 + struct buffer_head *old_bh)
94 {
95 - int ret = 0;
96 char *buf = old_bh->b_data;
97 struct ocfs2_xattr_block *old_xb = (struct ocfs2_xattr_block *)buf;
98 struct ocfs2_xattr_header *old_xh = &old_xb->xb_attrs.xb_header;
99 - int i, blocksize = inode->i_sb->s_blocksize;
100 - u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
101 + int i;
102
103 - xs->bucket->bu_bhs[0] = new_bh;
104 - get_bh(new_bh);
105 xs->header = bucket_xh(xs->bucket);
106 -
107 - xs->base = new_bh->b_data;
108 + xs->base = bucket_block(xs->bucket, 0);
109 xs->end = xs->base + inode->i_sb->s_blocksize;
110
111 - if (!xs->not_found) {
112 - if (OCFS2_XATTR_BUCKET_SIZE != blocksize) {
113 - ret = ocfs2_read_blocks(inode,
114 - bucket_blkno(xs->bucket) + 1,
115 - blk_per_bucket - 1, &xs->bucket->bu_bhs[1],
116 - 0);
117 - if (ret) {
118 - mlog_errno(ret);
119 - return ret;
120 - }
121 -
122 - }
123 - i = xs->here - old_xh->xh_entries;
124 - xs->here = &xs->header->xh_entries[i];
125 - }
126 + if (xs->not_found)
127 + return;
128
129 - return ret;
130 + i = xs->here - old_xh->xh_entries;
131 + xs->here = &xs->header->xh_entries[i];
132 }
133
134 static int ocfs2_xattr_create_index_block(struct inode *inode,
135 @@ -2771,18 +2753,17 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
136 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
137 struct ocfs2_inode_info *oi = OCFS2_I(inode);
138 struct ocfs2_alloc_context *data_ac;
139 - struct buffer_head *xh_bh = NULL, *data_bh = NULL;
140 struct buffer_head *xb_bh = xs->xattr_bh;
141 struct ocfs2_xattr_block *xb =
142 (struct ocfs2_xattr_block *)xb_bh->b_data;
143 struct ocfs2_xattr_tree_root *xr;
144 u16 xb_flags = le16_to_cpu(xb->xb_flags);
145 - u16 bpb = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
146
147 mlog(0, "create xattr index block for %llu\n",
148 (unsigned long long)xb_bh->b_blocknr);
149
150 BUG_ON(xb_flags & OCFS2_XATTR_INDEXED);
151 + BUG_ON(!xs->bucket);
152
153 ret = ocfs2_reserve_clusters(osb, 1, &data_ac);
154 if (ret) {
155 @@ -2798,10 +2779,10 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
156 down_write(&oi->ip_alloc_sem);
157
158 /*
159 - * 3 more credits, one for xattr block update, one for the 1st block
160 - * of the new xattr bucket and one for the value/data.
161 + * We need more credits. One for the xattr block update and one
162 + * for each block of the new xattr bucket.
163 */
164 - credits += 3;
165 + credits += 1 + ocfs2_blocks_per_xattr_bucket(inode->i_sb);
166 handle = ocfs2_start_trans(osb, credits);
167 if (IS_ERR(handle)) {
168 ret = PTR_ERR(handle);
169 @@ -2832,51 +2813,23 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
170 mlog(0, "allocate 1 cluster from %llu to xattr block\n",
171 (unsigned long long)blkno);
172
173 - xh_bh = sb_getblk(inode->i_sb, blkno);
174 - if (!xh_bh) {
175 - ret = -EIO;
176 + ret = ocfs2_init_xattr_bucket(xs->bucket, blkno);
177 + if (ret) {
178 mlog_errno(ret);
179 goto out_commit;
180 }
181
182 - ocfs2_set_new_buffer_uptodate(inode, xh_bh);
183 -
184 - ret = ocfs2_journal_access(handle, inode, xh_bh,
185 - OCFS2_JOURNAL_ACCESS_CREATE);
186 + ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket,
187 + OCFS2_JOURNAL_ACCESS_CREATE);
188 if (ret) {
189 mlog_errno(ret);
190 goto out_commit;
191 }
192
193 - if (bpb > 1) {
194 - data_bh = sb_getblk(inode->i_sb, blkno + bpb - 1);
195 - if (!data_bh) {
196 - ret = -EIO;
197 - mlog_errno(ret);
198 - goto out_commit;
199 - }
200 -
201 - ocfs2_set_new_buffer_uptodate(inode, data_bh);
202 -
203 - ret = ocfs2_journal_access(handle, inode, data_bh,
204 - OCFS2_JOURNAL_ACCESS_CREATE);
205 - if (ret) {
206 - mlog_errno(ret);
207 - goto out_commit;
208 - }
209 - }
210 -
211 - ocfs2_cp_xattr_block_to_bucket(inode, xb_bh, xh_bh, data_bh);
212 -
213 - ocfs2_journal_dirty(handle, xh_bh);
214 - if (data_bh)
215 - ocfs2_journal_dirty(handle, data_bh);
216 + ocfs2_cp_xattr_block_to_bucket(inode, xb_bh, xs->bucket);
217 + ocfs2_xattr_bucket_journal_dirty(handle, xs->bucket);
218
219 - ret = ocfs2_xattr_update_xattr_search(inode, xs, xb_bh, xh_bh);
220 - if (ret) {
221 - mlog_errno(ret);
222 - goto out_commit;
223 - }
224 + ocfs2_xattr_update_xattr_search(inode, xs, xb_bh);
225
226 /* Change from ocfs2_xattr_header to ocfs2_xattr_tree_root */
227 memset(&xb->xb_attrs, 0, inode->i_sb->s_blocksize -
228 @@ -2911,9 +2864,6 @@ out:
229 if (data_ac)
230 ocfs2_free_alloc_context(data_ac);
231
232 - brelse(xh_bh);
233 - brelse(data_bh);
234 -
235 return ret;
236 }
237
238 --
239 1.5.6
240