aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/xattr.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-10-24 22:13:20 -0400
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:34:17 -0500
commitba937127596ec2c61437006741f7d29999284de4 (patch)
treee5be4c76939ed4d87c256ff17f30e58bbebfb413 /fs/ocfs2/xattr.c
parent4980c6daba967124ed6420032960abd2b48412e2 (diff)
ocfs2: Take ocfs2_xattr_bucket structures off of the stack.
The ocfs2_xattr_bucket structure is a nice abstraction, but it is a bit large to have on the stack. Just like ocfs2_path, let's allocate it with a ocfs2_xattr_bucket_new() function. We can now store the inode on the bucket, cleaning up all the other bucket functions. While we're here, we catch another place or two that wasn't using ocfs2_read_xattr_bucket(). Updates: - No longer allocating xis.bucket, as it will never be used. Signed-off-by: Joel Becker <joel.becker@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs/ocfs2/xattr.c')
-rw-r--r--fs/ocfs2/xattr.c281
1 files changed, 166 insertions, 115 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 71d9e7bdd30a..766494ed6e11 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -61,7 +61,14 @@ struct ocfs2_xattr_def_value_root {
61}; 61};
62 62
63struct ocfs2_xattr_bucket { 63struct ocfs2_xattr_bucket {
64 /* The inode these xattrs are associated with */
65 struct inode *bu_inode;
66
67 /* The actual buffers that make up the bucket */
64 struct buffer_head *bu_bhs[OCFS2_XATTR_MAX_BLOCKS_PER_BUCKET]; 68 struct buffer_head *bu_bhs[OCFS2_XATTR_MAX_BLOCKS_PER_BUCKET];
69
70 /* How many blocks make up one bucket for this filesystem */
71 int bu_blocks;
65}; 72};
66 73
67#define OCFS2_XATTR_ROOT_SIZE (sizeof(struct ocfs2_xattr_def_value_root)) 74#define OCFS2_XATTR_ROOT_SIZE (sizeof(struct ocfs2_xattr_def_value_root))
@@ -97,7 +104,7 @@ struct ocfs2_xattr_search {
97 */ 104 */
98 struct buffer_head *xattr_bh; 105 struct buffer_head *xattr_bh;
99 struct ocfs2_xattr_header *header; 106 struct ocfs2_xattr_header *header;
100 struct ocfs2_xattr_bucket bucket; 107 struct ocfs2_xattr_bucket *bucket;
101 void *base; 108 void *base;
102 void *end; 109 void *end;
103 struct ocfs2_xattr_entry *here; 110 struct ocfs2_xattr_entry *here;
@@ -157,69 +164,91 @@ static inline u16 ocfs2_xattr_max_xe_in_bucket(struct super_block *sb)
157#define bucket_block(_b, _n) ((_b)->bu_bhs[(_n)]->b_data) 164#define bucket_block(_b, _n) ((_b)->bu_bhs[(_n)]->b_data)
158#define bucket_xh(_b) ((struct ocfs2_xattr_header *)bucket_block((_b), 0)) 165#define bucket_xh(_b) ((struct ocfs2_xattr_header *)bucket_block((_b), 0))
159 166
160static void ocfs2_xattr_bucket_relse(struct inode *inode, 167static struct ocfs2_xattr_bucket *ocfs2_xattr_bucket_new(struct inode *inode)
161 struct ocfs2_xattr_bucket *bucket)
162{ 168{
163 int i, blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb); 169 struct ocfs2_xattr_bucket *bucket;
170 int blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
164 171
165 for (i = 0; i < blks; i++) { 172 BUG_ON(blks > OCFS2_XATTR_MAX_BLOCKS_PER_BUCKET);
173
174 bucket = kzalloc(sizeof(struct ocfs2_xattr_bucket), GFP_NOFS);
175 if (bucket) {
176 bucket->bu_inode = inode;
177 bucket->bu_blocks = blks;
178 }
179
180 return bucket;
181}
182
183static void ocfs2_xattr_bucket_relse(struct ocfs2_xattr_bucket *bucket)
184{
185 int i;
186
187 for (i = 0; i < bucket->bu_blocks; i++) {
166 brelse(bucket->bu_bhs[i]); 188 brelse(bucket->bu_bhs[i]);
167 bucket->bu_bhs[i] = NULL; 189 bucket->bu_bhs[i] = NULL;
168 } 190 }
169} 191}
170 192
193static void ocfs2_xattr_bucket_free(struct ocfs2_xattr_bucket *bucket)
194{
195 if (bucket) {
196 ocfs2_xattr_bucket_relse(bucket);
197 bucket->bu_inode = NULL;
198 kfree(bucket);
199 }
200}
201
171/* 202/*
172 * A bucket that has never been written to disk doesn't need to be 203 * A bucket that has never been written to disk doesn't need to be
173 * read. We just need the buffer_heads. Don't call this for 204 * read. We just need the buffer_heads. Don't call this for
174 * buckets that are already on disk. ocfs2_read_xattr_bucket() initializes 205 * buckets that are already on disk. ocfs2_read_xattr_bucket() initializes
175 * them fully. 206 * them fully.
176 */ 207 */
177static int ocfs2_init_xattr_bucket(struct inode *inode, 208static int ocfs2_init_xattr_bucket(struct ocfs2_xattr_bucket *bucket,
178 struct ocfs2_xattr_bucket *bucket,
179 u64 xb_blkno) 209 u64 xb_blkno)
180{ 210{
181 int i, rc = 0; 211 int i, rc = 0;
182 int blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
183 212
184 for (i = 0; i < blks; i++) { 213 for (i = 0; i < bucket->bu_blocks; i++) {
185 bucket->bu_bhs[i] = sb_getblk(inode->i_sb, xb_blkno + i); 214 bucket->bu_bhs[i] = sb_getblk(bucket->bu_inode->i_sb,
215 xb_blkno + i);
186 if (!bucket->bu_bhs[i]) { 216 if (!bucket->bu_bhs[i]) {
187 rc = -EIO; 217 rc = -EIO;
188 mlog_errno(rc); 218 mlog_errno(rc);
189 break; 219 break;
190 } 220 }
191 221
192 ocfs2_set_new_buffer_uptodate(inode, bucket->bu_bhs[i]); 222 ocfs2_set_new_buffer_uptodate(bucket->bu_inode,
223 bucket->bu_bhs[i]);
193 } 224 }
194 225
195 if (rc) 226 if (rc)
196 ocfs2_xattr_bucket_relse(inode, bucket); 227 ocfs2_xattr_bucket_relse(bucket);
197 return rc; 228 return rc;
198} 229}
199 230
200/* Read the xattr bucket at xb_blkno */ 231/* Read the xattr bucket at xb_blkno */
201static int ocfs2_read_xattr_bucket(struct inode *inode, 232static int ocfs2_read_xattr_bucket(struct ocfs2_xattr_bucket *bucket,
202 struct ocfs2_xattr_bucket *bucket,
203 u64 xb_blkno) 233 u64 xb_blkno)
204{ 234{
205 int rc, blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb); 235 int rc;
206 236
207 rc = ocfs2_read_blocks(inode, xb_blkno, blks, bucket->bu_bhs, 0); 237 rc = ocfs2_read_blocks(bucket->bu_inode, xb_blkno,
238 bucket->bu_blocks, bucket->bu_bhs, 0);
208 if (rc) 239 if (rc)
209 ocfs2_xattr_bucket_relse(inode, bucket); 240 ocfs2_xattr_bucket_relse(bucket);
210 return rc; 241 return rc;
211} 242}
212 243
213static int ocfs2_xattr_bucket_journal_access(handle_t *handle, 244static int ocfs2_xattr_bucket_journal_access(handle_t *handle,
214 struct inode *inode,
215 struct ocfs2_xattr_bucket *bucket, 245 struct ocfs2_xattr_bucket *bucket,
216 int type) 246 int type)
217{ 247{
218 int i, rc = 0; 248 int i, rc = 0;
219 int blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
220 249
221 for (i = 0; i < blks; i++) { 250 for (i = 0; i < bucket->bu_blocks; i++) {
222 rc = ocfs2_journal_access(handle, inode, 251 rc = ocfs2_journal_access(handle, bucket->bu_inode,
223 bucket->bu_bhs[i], type); 252 bucket->bu_bhs[i], type);
224 if (rc) { 253 if (rc) {
225 mlog_errno(rc); 254 mlog_errno(rc);
@@ -231,24 +260,24 @@ static int ocfs2_xattr_bucket_journal_access(handle_t *handle,
231} 260}
232 261
233static void ocfs2_xattr_bucket_journal_dirty(handle_t *handle, 262static void ocfs2_xattr_bucket_journal_dirty(handle_t *handle,
234 struct inode *inode,
235 struct ocfs2_xattr_bucket *bucket) 263 struct ocfs2_xattr_bucket *bucket)
236{ 264{
237 int i, blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb); 265 int i;
238 266
239 for (i = 0; i < blks; i++) 267 for (i = 0; i < bucket->bu_blocks; i++)
240 ocfs2_journal_dirty(handle, bucket->bu_bhs[i]); 268 ocfs2_journal_dirty(handle, bucket->bu_bhs[i]);
241} 269}
242 270
243static void ocfs2_xattr_bucket_copy_data(struct inode *inode, 271static void ocfs2_xattr_bucket_copy_data(struct ocfs2_xattr_bucket *dest,
244 struct ocfs2_xattr_bucket *dest,
245 struct ocfs2_xattr_bucket *src) 272 struct ocfs2_xattr_bucket *src)
246{ 273{
247 int i; 274 int i;
248 int blocksize = inode->i_sb->s_blocksize; 275 int blocksize = src->bu_inode->i_sb->s_blocksize;
249 int blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb); 276
277 BUG_ON(dest->bu_blocks != src->bu_blocks);
278 BUG_ON(dest->bu_inode != src->bu_inode);
250 279
251 for (i = 0; i < blks; i++) { 280 for (i = 0; i < src->bu_blocks; i++) {
252 memcpy(bucket_block(dest, i), bucket_block(src, i), 281 memcpy(bucket_block(dest, i), bucket_block(src, i),
253 blocksize); 282 blocksize);
254 } 283 }
@@ -869,7 +898,12 @@ static int ocfs2_xattr_block_get(struct inode *inode,
869 size_t size; 898 size_t size;
870 int ret = -ENODATA, name_offset, name_len, block_off, i; 899 int ret = -ENODATA, name_offset, name_len, block_off, i;
871 900
872 memset(&xs->bucket, 0, sizeof(xs->bucket)); 901 xs->bucket = ocfs2_xattr_bucket_new(inode);
902 if (!xs->bucket) {
903 ret = -ENOMEM;
904 mlog_errno(ret);
905 goto cleanup;
906 }
873 907
874 ret = ocfs2_xattr_block_find(inode, name_index, name, xs); 908 ret = ocfs2_xattr_block_find(inode, name_index, name, xs);
875 if (ret) { 909 if (ret) {
@@ -895,11 +929,11 @@ static int ocfs2_xattr_block_get(struct inode *inode,
895 929
896 if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED) { 930 if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED) {
897 ret = ocfs2_xattr_bucket_get_name_value(inode, 931 ret = ocfs2_xattr_bucket_get_name_value(inode,
898 bucket_xh(&xs->bucket), 932 bucket_xh(xs->bucket),
899 i, 933 i,
900 &block_off, 934 &block_off,
901 &name_offset); 935 &name_offset);
902 xs->base = bucket_block(&xs->bucket, block_off); 936 xs->base = bucket_block(xs->bucket, block_off);
903 } 937 }
904 if (ocfs2_xattr_is_local(xs->here)) { 938 if (ocfs2_xattr_is_local(xs->here)) {
905 memcpy(buffer, (void *)xs->base + 939 memcpy(buffer, (void *)xs->base +
@@ -917,8 +951,7 @@ static int ocfs2_xattr_block_get(struct inode *inode,
917 } 951 }
918 ret = size; 952 ret = size;
919cleanup: 953cleanup:
920 ocfs2_xattr_bucket_relse(inode, &xs->bucket); 954 ocfs2_xattr_bucket_free(xs->bucket);
921 memset(&xs->bucket, 0, sizeof(xs->bucket));
922 955
923 brelse(xs->xattr_bh); 956 brelse(xs->xattr_bh);
924 xs->xattr_bh = NULL; 957 xs->xattr_bh = NULL;
@@ -2047,10 +2080,20 @@ int ocfs2_xattr_set(struct inode *inode,
2047 if (!ocfs2_supports_xattr(OCFS2_SB(inode->i_sb))) 2080 if (!ocfs2_supports_xattr(OCFS2_SB(inode->i_sb)))
2048 return -EOPNOTSUPP; 2081 return -EOPNOTSUPP;
2049 2082
2083 /*
2084 * Only xbs will be used on indexed trees. xis doesn't need a
2085 * bucket.
2086 */
2087 xbs.bucket = ocfs2_xattr_bucket_new(inode);
2088 if (!xbs.bucket) {
2089 mlog_errno(-ENOMEM);
2090 return -ENOMEM;
2091 }
2092
2050 ret = ocfs2_inode_lock(inode, &di_bh, 1); 2093 ret = ocfs2_inode_lock(inode, &di_bh, 1);
2051 if (ret < 0) { 2094 if (ret < 0) {
2052 mlog_errno(ret); 2095 mlog_errno(ret);
2053 return ret; 2096 goto cleanup_nolock;
2054 } 2097 }
2055 xis.inode_bh = xbs.inode_bh = di_bh; 2098 xis.inode_bh = xbs.inode_bh = di_bh;
2056 di = (struct ocfs2_dinode *)di_bh->b_data; 2099 di = (struct ocfs2_dinode *)di_bh->b_data;
@@ -2127,9 +2170,10 @@ int ocfs2_xattr_set(struct inode *inode,
2127cleanup: 2170cleanup:
2128 up_write(&OCFS2_I(inode)->ip_xattr_sem); 2171 up_write(&OCFS2_I(inode)->ip_xattr_sem);
2129 ocfs2_inode_unlock(inode, 1); 2172 ocfs2_inode_unlock(inode, 1);
2173cleanup_nolock:
2130 brelse(di_bh); 2174 brelse(di_bh);
2131 brelse(xbs.xattr_bh); 2175 brelse(xbs.xattr_bh);
2132 ocfs2_xattr_bucket_relse(inode, &xbs.bucket); 2176 ocfs2_xattr_bucket_free(xbs.bucket);
2133 2177
2134 return ret; 2178 return ret;
2135} 2179}
@@ -2373,11 +2417,11 @@ static int ocfs2_xattr_bucket_find(struct inode *inode,
2373 lower_bh = bh; 2417 lower_bh = bh;
2374 bh = NULL; 2418 bh = NULL;
2375 } 2419 }
2376 xs->bucket.bu_bhs[0] = lower_bh; 2420 xs->bucket->bu_bhs[0] = lower_bh;
2377 lower_bh = NULL; 2421 lower_bh = NULL;
2378 2422
2379 xs->header = bucket_xh(&xs->bucket); 2423 xs->header = bucket_xh(xs->bucket);
2380 xs->base = bucket_block(&xs->bucket, 0); 2424 xs->base = bucket_block(xs->bucket, 0);
2381 xs->end = xs->base + inode->i_sb->s_blocksize; 2425 xs->end = xs->base + inode->i_sb->s_blocksize;
2382 2426
2383 if (found) { 2427 if (found) {
@@ -2385,8 +2429,8 @@ static int ocfs2_xattr_bucket_find(struct inode *inode,
2385 * If we have found the xattr enty, read all the blocks in 2429 * If we have found the xattr enty, read all the blocks in
2386 * this bucket. 2430 * this bucket.
2387 */ 2431 */
2388 ret = ocfs2_read_blocks(inode, bucket_blkno(&xs->bucket) + 1, 2432 ret = ocfs2_read_blocks(inode, bucket_blkno(xs->bucket) + 1,
2389 blk_per_bucket - 1, &xs->bucket.bu_bhs[1], 2433 blk_per_bucket - 1, &xs->bucket->bu_bhs[1],
2390 0); 2434 0);
2391 if (ret) { 2435 if (ret) {
2392 mlog_errno(ret); 2436 mlog_errno(ret);
@@ -2395,7 +2439,7 @@ static int ocfs2_xattr_bucket_find(struct inode *inode,
2395 2439
2396 xs->here = &xs->header->xh_entries[index]; 2440 xs->here = &xs->header->xh_entries[index];
2397 mlog(0, "find xattr %s in bucket %llu, entry = %u\n", name, 2441 mlog(0, "find xattr %s in bucket %llu, entry = %u\n", name,
2398 (unsigned long long)bucket_blkno(&xs->bucket), index); 2442 (unsigned long long)bucket_blkno(xs->bucket), index);
2399 } else 2443 } else
2400 ret = -ENODATA; 2444 ret = -ENODATA;
2401 2445
@@ -2453,22 +2497,24 @@ static int ocfs2_iterate_xattr_buckets(struct inode *inode,
2453 void *para) 2497 void *para)
2454{ 2498{
2455 int i, ret = 0; 2499 int i, ret = 0;
2456 int blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
2457 u32 bpc = ocfs2_xattr_buckets_per_cluster(OCFS2_SB(inode->i_sb)); 2500 u32 bpc = ocfs2_xattr_buckets_per_cluster(OCFS2_SB(inode->i_sb));
2458 u32 num_buckets = clusters * bpc; 2501 u32 num_buckets = clusters * bpc;
2459 struct ocfs2_xattr_bucket bucket; 2502 struct ocfs2_xattr_bucket *bucket;
2460 2503
2461 memset(&bucket, 0, sizeof(bucket)); 2504 bucket = ocfs2_xattr_bucket_new(inode);
2505 if (!bucket) {
2506 mlog_errno(-ENOMEM);
2507 return -ENOMEM;
2508 }
2462 2509
2463 mlog(0, "iterating xattr buckets in %u clusters starting from %llu\n", 2510 mlog(0, "iterating xattr buckets in %u clusters starting from %llu\n",
2464 clusters, (unsigned long long)blkno); 2511 clusters, (unsigned long long)blkno);
2465 2512
2466 for (i = 0; i < num_buckets; i++, blkno += blk_per_bucket) { 2513 for (i = 0; i < num_buckets; i++, blkno += bucket->bu_blocks) {
2467 ret = ocfs2_read_blocks(inode, blkno, blk_per_bucket, 2514 ret = ocfs2_read_xattr_bucket(bucket, blkno);
2468 bucket.bu_bhs, 0);
2469 if (ret) { 2515 if (ret) {
2470 mlog_errno(ret); 2516 mlog_errno(ret);
2471 goto out; 2517 break;
2472 } 2518 }
2473 2519
2474 /* 2520 /*
@@ -2476,26 +2522,24 @@ static int ocfs2_iterate_xattr_buckets(struct inode *inode,
2476 * in the 1st bucket. 2522 * in the 1st bucket.
2477 */ 2523 */
2478 if (i == 0) 2524 if (i == 0)
2479 num_buckets = le16_to_cpu(bucket_xh(&bucket)->xh_num_buckets); 2525 num_buckets = le16_to_cpu(bucket_xh(bucket)->xh_num_buckets);
2480 2526
2481 mlog(0, "iterating xattr bucket %llu, first hash %u\n", 2527 mlog(0, "iterating xattr bucket %llu, first hash %u\n",
2482 (unsigned long long)blkno, 2528 (unsigned long long)blkno,
2483 le32_to_cpu(bucket_xh(&bucket)->xh_entries[0].xe_name_hash)); 2529 le32_to_cpu(bucket_xh(bucket)->xh_entries[0].xe_name_hash));
2484 if (func) { 2530 if (func) {
2485 ret = func(inode, &bucket, para); 2531 ret = func(inode, bucket, para);
2486 if (ret) { 2532 if (ret)
2487 mlog_errno(ret); 2533 mlog_errno(ret);
2488 break; 2534 /* Fall through to bucket_relse() */
2489 }
2490 } 2535 }
2491 2536
2492 ocfs2_xattr_bucket_relse(inode, &bucket); 2537 ocfs2_xattr_bucket_relse(bucket);
2493 memset(&bucket, 0, sizeof(bucket)); 2538 if (ret)
2539 break;
2494 } 2540 }
2495 2541
2496out: 2542 ocfs2_xattr_bucket_free(bucket);
2497 ocfs2_xattr_bucket_relse(inode, &bucket);
2498
2499 return ret; 2543 return ret;
2500} 2544}
2501 2545
@@ -2718,9 +2762,9 @@ static int ocfs2_xattr_update_xattr_search(struct inode *inode,
2718 int i, blocksize = inode->i_sb->s_blocksize; 2762 int i, blocksize = inode->i_sb->s_blocksize;
2719 u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb); 2763 u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
2720 2764
2721 xs->bucket.bu_bhs[0] = new_bh; 2765 xs->bucket->bu_bhs[0] = new_bh;
2722 get_bh(new_bh); 2766 get_bh(new_bh);
2723 xs->header = bucket_xh(&xs->bucket); 2767 xs->header = bucket_xh(xs->bucket);
2724 2768
2725 xs->base = new_bh->b_data; 2769 xs->base = new_bh->b_data;
2726 xs->end = xs->base + inode->i_sb->s_blocksize; 2770 xs->end = xs->base + inode->i_sb->s_blocksize;
@@ -2728,8 +2772,8 @@ static int ocfs2_xattr_update_xattr_search(struct inode *inode,
2728 if (!xs->not_found) { 2772 if (!xs->not_found) {
2729 if (OCFS2_XATTR_BUCKET_SIZE != blocksize) { 2773 if (OCFS2_XATTR_BUCKET_SIZE != blocksize) {
2730 ret = ocfs2_read_blocks(inode, 2774 ret = ocfs2_read_blocks(inode,
2731 bucket_blkno(&xs->bucket) + 1, 2775 bucket_blkno(xs->bucket) + 1,
2732 blk_per_bucket - 1, &xs->bucket.bu_bhs[1], 2776 blk_per_bucket - 1, &xs->bucket->bu_bhs[1],
2733 0); 2777 0);
2734 if (ret) { 2778 if (ret) {
2735 mlog_errno(ret); 2779 mlog_errno(ret);
@@ -3244,8 +3288,7 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode,
3244{ 3288{
3245 int ret, i; 3289 int ret, i;
3246 int count, start, len, name_value_len = 0, xe_len, name_offset = 0; 3290 int count, start, len, name_value_len = 0, xe_len, name_offset = 0;
3247 u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb); 3291 struct ocfs2_xattr_bucket *s_bucket = NULL, *t_bucket = NULL;
3248 struct ocfs2_xattr_bucket s_bucket, t_bucket;
3249 struct ocfs2_xattr_header *xh; 3292 struct ocfs2_xattr_header *xh;
3250 struct ocfs2_xattr_entry *xe; 3293 struct ocfs2_xattr_entry *xe;
3251 int blocksize = inode->i_sb->s_blocksize; 3294 int blocksize = inode->i_sb->s_blocksize;
@@ -3253,16 +3296,21 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode,
3253 mlog(0, "move some of xattrs from bucket %llu to %llu\n", 3296 mlog(0, "move some of xattrs from bucket %llu to %llu\n",
3254 (unsigned long long)blk, (unsigned long long)new_blk); 3297 (unsigned long long)blk, (unsigned long long)new_blk);
3255 3298
3256 memset(&s_bucket, 0, sizeof(struct ocfs2_xattr_bucket)); 3299 s_bucket = ocfs2_xattr_bucket_new(inode);
3257 memset(&t_bucket, 0, sizeof(struct ocfs2_xattr_bucket)); 3300 t_bucket = ocfs2_xattr_bucket_new(inode);
3301 if (!s_bucket || !t_bucket) {
3302 ret = -ENOMEM;
3303 mlog_errno(ret);
3304 goto out;
3305 }
3258 3306
3259 ret = ocfs2_read_xattr_bucket(inode, &s_bucket, blk); 3307 ret = ocfs2_read_xattr_bucket(s_bucket, blk);
3260 if (ret) { 3308 if (ret) {
3261 mlog_errno(ret); 3309 mlog_errno(ret);
3262 goto out; 3310 goto out;
3263 } 3311 }
3264 3312
3265 ret = ocfs2_xattr_bucket_journal_access(handle, inode, &s_bucket, 3313 ret = ocfs2_xattr_bucket_journal_access(handle, s_bucket,
3266 OCFS2_JOURNAL_ACCESS_WRITE); 3314 OCFS2_JOURNAL_ACCESS_WRITE);
3267 if (ret) { 3315 if (ret) {
3268 mlog_errno(ret); 3316 mlog_errno(ret);
@@ -3273,13 +3321,13 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode,
3273 * Even if !new_bucket_head, we're overwriting t_bucket. Thus, 3321 * Even if !new_bucket_head, we're overwriting t_bucket. Thus,
3274 * there's no need to read it. 3322 * there's no need to read it.
3275 */ 3323 */
3276 ret = ocfs2_init_xattr_bucket(inode, &t_bucket, new_blk); 3324 ret = ocfs2_init_xattr_bucket(t_bucket, new_blk);
3277 if (ret) { 3325 if (ret) {
3278 mlog_errno(ret); 3326 mlog_errno(ret);
3279 goto out; 3327 goto out;
3280 } 3328 }
3281 3329
3282 ret = ocfs2_xattr_bucket_journal_access(handle, inode, &t_bucket, 3330 ret = ocfs2_xattr_bucket_journal_access(handle, t_bucket,
3283 new_bucket_head ? 3331 new_bucket_head ?
3284 OCFS2_JOURNAL_ACCESS_CREATE : 3332 OCFS2_JOURNAL_ACCESS_CREATE :
3285 OCFS2_JOURNAL_ACCESS_WRITE); 3333 OCFS2_JOURNAL_ACCESS_WRITE);
@@ -3288,7 +3336,7 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode,
3288 goto out; 3336 goto out;
3289 } 3337 }
3290 3338
3291 xh = bucket_xh(&s_bucket); 3339 xh = bucket_xh(s_bucket);
3292 count = le16_to_cpu(xh->xh_count); 3340 count = le16_to_cpu(xh->xh_count);
3293 start = ocfs2_xattr_find_divide_pos(xh); 3341 start = ocfs2_xattr_find_divide_pos(xh);
3294 3342
@@ -3300,10 +3348,10 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode,
3300 * The hash value is set as one larger than 3348 * The hash value is set as one larger than
3301 * that of the last entry in the previous bucket. 3349 * that of the last entry in the previous bucket.
3302 */ 3350 */
3303 for (i = 0; i < blk_per_bucket; i++) 3351 for (i = 0; i < t_bucket->bu_blocks; i++)
3304 memset(bucket_block(&t_bucket, i), 0, blocksize); 3352 memset(bucket_block(t_bucket, i), 0, blocksize);
3305 3353
3306 xh = bucket_xh(&t_bucket); 3354 xh = bucket_xh(t_bucket);
3307 xh->xh_free_start = cpu_to_le16(blocksize); 3355 xh->xh_free_start = cpu_to_le16(blocksize);
3308 xh->xh_entries[0].xe_name_hash = xe->xe_name_hash; 3356 xh->xh_entries[0].xe_name_hash = xe->xe_name_hash;
3309 le32_add_cpu(&xh->xh_entries[0].xe_name_hash, 1); 3357 le32_add_cpu(&xh->xh_entries[0].xe_name_hash, 1);
@@ -3312,10 +3360,10 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode,
3312 } 3360 }
3313 3361
3314 /* copy the whole bucket to the new first. */ 3362 /* copy the whole bucket to the new first. */
3315 ocfs2_xattr_bucket_copy_data(inode, &t_bucket, &s_bucket); 3363 ocfs2_xattr_bucket_copy_data(t_bucket, s_bucket);
3316 3364
3317 /* update the new bucket. */ 3365 /* update the new bucket. */
3318 xh = bucket_xh(&t_bucket); 3366 xh = bucket_xh(t_bucket);
3319 3367
3320 /* 3368 /*
3321 * Calculate the total name/value len and xh_free_start for 3369 * Calculate the total name/value len and xh_free_start for
@@ -3379,7 +3427,7 @@ set_num_buckets:
3379 else 3427 else
3380 xh->xh_num_buckets = 0; 3428 xh->xh_num_buckets = 0;
3381 3429
3382 ocfs2_xattr_bucket_journal_dirty(handle, inode, &t_bucket); 3430 ocfs2_xattr_bucket_journal_dirty(handle, t_bucket);
3383 3431
3384 /* store the first_hash of the new bucket. */ 3432 /* store the first_hash of the new bucket. */
3385 if (first_hash) 3433 if (first_hash)
@@ -3393,18 +3441,18 @@ set_num_buckets:
3393 if (start == count) 3441 if (start == count)
3394 goto out; 3442 goto out;
3395 3443
3396 xh = bucket_xh(&s_bucket); 3444 xh = bucket_xh(s_bucket);
3397 memset(&xh->xh_entries[start], 0, 3445 memset(&xh->xh_entries[start], 0,
3398 sizeof(struct ocfs2_xattr_entry) * (count - start)); 3446 sizeof(struct ocfs2_xattr_entry) * (count - start));
3399 xh->xh_count = cpu_to_le16(start); 3447 xh->xh_count = cpu_to_le16(start);
3400 xh->xh_free_start = cpu_to_le16(name_offset); 3448 xh->xh_free_start = cpu_to_le16(name_offset);
3401 xh->xh_name_value_len = cpu_to_le16(name_value_len); 3449 xh->xh_name_value_len = cpu_to_le16(name_value_len);
3402 3450
3403 ocfs2_xattr_bucket_journal_dirty(handle, inode, &s_bucket); 3451 ocfs2_xattr_bucket_journal_dirty(handle, s_bucket);
3404 3452
3405out: 3453out:
3406 ocfs2_xattr_bucket_relse(inode, &s_bucket); 3454 ocfs2_xattr_bucket_free(s_bucket);
3407 ocfs2_xattr_bucket_relse(inode, &t_bucket); 3455 ocfs2_xattr_bucket_free(t_bucket);
3408 3456
3409 return ret; 3457 return ret;
3410} 3458}
@@ -3422,7 +3470,7 @@ static int ocfs2_cp_xattr_bucket(struct inode *inode,
3422 int t_is_new) 3470 int t_is_new)
3423{ 3471{
3424 int ret; 3472 int ret;
3425 struct ocfs2_xattr_bucket s_bucket, t_bucket; 3473 struct ocfs2_xattr_bucket *s_bucket = NULL, *t_bucket = NULL;
3426 3474
3427 BUG_ON(s_blkno == t_blkno); 3475 BUG_ON(s_blkno == t_blkno);
3428 3476
@@ -3430,10 +3478,15 @@ static int ocfs2_cp_xattr_bucket(struct inode *inode,
3430 (unsigned long long)s_blkno, (unsigned long long)t_blkno, 3478 (unsigned long long)s_blkno, (unsigned long long)t_blkno,
3431 t_is_new); 3479 t_is_new);
3432 3480
3433 memset(&s_bucket, 0, sizeof(struct ocfs2_xattr_bucket)); 3481 s_bucket = ocfs2_xattr_bucket_new(inode);
3434 memset(&t_bucket, 0, sizeof(struct ocfs2_xattr_bucket)); 3482 t_bucket = ocfs2_xattr_bucket_new(inode);
3435 3483 if (!s_bucket || !t_bucket) {
3436 ret = ocfs2_read_xattr_bucket(inode, &s_bucket, s_blkno); 3484 ret = -ENOMEM;
3485 mlog_errno(ret);
3486 goto out;
3487 }
3488
3489 ret = ocfs2_read_xattr_bucket(s_bucket, s_blkno);
3437 if (ret) 3490 if (ret)
3438 goto out; 3491 goto out;
3439 3492
@@ -3441,23 +3494,23 @@ static int ocfs2_cp_xattr_bucket(struct inode *inode,
3441 * Even if !t_is_new, we're overwriting t_bucket. Thus, 3494 * Even if !t_is_new, we're overwriting t_bucket. Thus,
3442 * there's no need to read it. 3495 * there's no need to read it.
3443 */ 3496 */
3444 ret = ocfs2_init_xattr_bucket(inode, &t_bucket, t_blkno); 3497 ret = ocfs2_init_xattr_bucket(t_bucket, t_blkno);
3445 if (ret) 3498 if (ret)
3446 goto out; 3499 goto out;
3447 3500
3448 ret = ocfs2_xattr_bucket_journal_access(handle, inode, &t_bucket, 3501 ret = ocfs2_xattr_bucket_journal_access(handle, t_bucket,
3449 t_is_new ? 3502 t_is_new ?
3450 OCFS2_JOURNAL_ACCESS_CREATE : 3503 OCFS2_JOURNAL_ACCESS_CREATE :
3451 OCFS2_JOURNAL_ACCESS_WRITE); 3504 OCFS2_JOURNAL_ACCESS_WRITE);
3452 if (ret) 3505 if (ret)
3453 goto out; 3506 goto out;
3454 3507
3455 ocfs2_xattr_bucket_copy_data(inode, &t_bucket, &s_bucket); 3508 ocfs2_xattr_bucket_copy_data(t_bucket, s_bucket);
3456 ocfs2_xattr_bucket_journal_dirty(handle, inode, &t_bucket); 3509 ocfs2_xattr_bucket_journal_dirty(handle, t_bucket);
3457 3510
3458out: 3511out:
3459 ocfs2_xattr_bucket_relse(inode, &s_bucket); 3512 ocfs2_xattr_bucket_free(t_bucket);
3460 ocfs2_xattr_bucket_relse(inode, &t_bucket); 3513 ocfs2_xattr_bucket_free(s_bucket);
3461 3514
3462 return ret; 3515 return ret;
3463} 3516}
@@ -4009,7 +4062,7 @@ static void ocfs2_xattr_set_entry_normal(struct inode *inode,
4009 xe->xe_value_size = 0; 4062 xe->xe_value_size = 0;
4010 4063
4011 val = ocfs2_xattr_bucket_get_val(inode, 4064 val = ocfs2_xattr_bucket_get_val(inode,
4012 &xs->bucket, offs); 4065 xs->bucket, offs);
4013 memset(val + OCFS2_XATTR_SIZE(name_len), 0, 4066 memset(val + OCFS2_XATTR_SIZE(name_len), 0,
4014 size - OCFS2_XATTR_SIZE(name_len)); 4067 size - OCFS2_XATTR_SIZE(name_len));
4015 if (OCFS2_XATTR_SIZE(xi->value_len) > 0) 4068 if (OCFS2_XATTR_SIZE(xi->value_len) > 0)
@@ -4087,8 +4140,7 @@ set_new_name_value:
4087 xh->xh_free_start = cpu_to_le16(offs); 4140 xh->xh_free_start = cpu_to_le16(offs);
4088 } 4141 }
4089 4142
4090 val = ocfs2_xattr_bucket_get_val(inode, 4143 val = ocfs2_xattr_bucket_get_val(inode, xs->bucket, offs - size);
4091 &xs->bucket, offs - size);
4092 xe->xe_name_offset = cpu_to_le16(offs - size); 4144 xe->xe_name_offset = cpu_to_le16(offs - size);
4093 4145
4094 memset(val, 0, size); 4146 memset(val, 0, size);
@@ -4122,12 +4174,12 @@ static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode,
4122 4174
4123 mlog(0, "Set xattr entry len = %lu index = %d in bucket %llu\n", 4175 mlog(0, "Set xattr entry len = %lu index = %d in bucket %llu\n",
4124 (unsigned long)xi->value_len, xi->name_index, 4176 (unsigned long)xi->value_len, xi->name_index,
4125 (unsigned long long)bucket_blkno(&xs->bucket)); 4177 (unsigned long long)bucket_blkno(xs->bucket));
4126 4178
4127 if (!xs->bucket.bu_bhs[1]) { 4179 if (!xs->bucket->bu_bhs[1]) {
4128 ret = ocfs2_read_blocks(inode, 4180 ret = ocfs2_read_blocks(inode,
4129 bucket_blkno(&xs->bucket) + 1, 4181 bucket_blkno(xs->bucket) + 1,
4130 blk_per_bucket - 1, &xs->bucket.bu_bhs[1], 4182 blk_per_bucket - 1, &xs->bucket->bu_bhs[1],
4131 0); 4183 0);
4132 if (ret) { 4184 if (ret) {
4133 mlog_errno(ret); 4185 mlog_errno(ret);
@@ -4143,7 +4195,7 @@ static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode,
4143 goto out; 4195 goto out;
4144 } 4196 }
4145 4197
4146 ret = ocfs2_xattr_bucket_journal_access(handle, inode, &xs->bucket, 4198 ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket,
4147 OCFS2_JOURNAL_ACCESS_WRITE); 4199 OCFS2_JOURNAL_ACCESS_WRITE);
4148 if (ret < 0) { 4200 if (ret < 0) {
4149 mlog_errno(ret); 4201 mlog_errno(ret);
@@ -4151,7 +4203,7 @@ static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode,
4151 } 4203 }
4152 4204
4153 ocfs2_xattr_set_entry_normal(inode, xi, xs, name_hash, local); 4205 ocfs2_xattr_set_entry_normal(inode, xi, xs, name_hash, local);
4154 ocfs2_xattr_bucket_journal_dirty(handle, inode, &xs->bucket); 4206 ocfs2_xattr_bucket_journal_dirty(handle, xs->bucket);
4155 4207
4156out: 4208out:
4157 ocfs2_commit_trans(osb, handle); 4209 ocfs2_commit_trans(osb, handle);
@@ -4264,10 +4316,10 @@ static int ocfs2_xattr_bucket_value_truncate_xs(struct inode *inode,
4264 struct ocfs2_xattr_entry *xe = xs->here; 4316 struct ocfs2_xattr_entry *xe = xs->here;
4265 struct ocfs2_xattr_header *xh = (struct ocfs2_xattr_header *)xs->base; 4317 struct ocfs2_xattr_header *xh = (struct ocfs2_xattr_header *)xs->base;
4266 4318
4267 BUG_ON(!xs->bucket.bu_bhs[0] || !xe || ocfs2_xattr_is_local(xe)); 4319 BUG_ON(!xs->bucket->bu_bhs[0] || !xe || ocfs2_xattr_is_local(xe));
4268 4320
4269 offset = xe - xh->xh_entries; 4321 offset = xe - xh->xh_entries;
4270 ret = ocfs2_xattr_bucket_value_truncate(inode, xs->bucket.bu_bhs[0], 4322 ret = ocfs2_xattr_bucket_value_truncate(inode, xs->bucket->bu_bhs[0],
4271 offset, len); 4323 offset, len);
4272 if (ret) 4324 if (ret)
4273 mlog_errno(ret); 4325 mlog_errno(ret);
@@ -4387,7 +4439,7 @@ static void ocfs2_xattr_bucket_remove_xs(struct inode *inode,
4387 struct ocfs2_xattr_search *xs) 4439 struct ocfs2_xattr_search *xs)
4388{ 4440{
4389 handle_t *handle = NULL; 4441 handle_t *handle = NULL;
4390 struct ocfs2_xattr_header *xh = bucket_xh(&xs->bucket); 4442 struct ocfs2_xattr_header *xh = bucket_xh(xs->bucket);
4391 struct ocfs2_xattr_entry *last = &xh->xh_entries[ 4443 struct ocfs2_xattr_entry *last = &xh->xh_entries[
4392 le16_to_cpu(xh->xh_count) - 1]; 4444 le16_to_cpu(xh->xh_count) - 1];
4393 int ret = 0; 4445 int ret = 0;
@@ -4400,7 +4452,7 @@ static void ocfs2_xattr_bucket_remove_xs(struct inode *inode,
4400 return; 4452 return;
4401 } 4453 }
4402 4454
4403 ret = ocfs2_xattr_bucket_journal_access(handle, inode, &xs->bucket, 4455 ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket,
4404 OCFS2_JOURNAL_ACCESS_WRITE); 4456 OCFS2_JOURNAL_ACCESS_WRITE);
4405 if (ret) { 4457 if (ret) {
4406 mlog_errno(ret); 4458 mlog_errno(ret);
@@ -4413,7 +4465,7 @@ static void ocfs2_xattr_bucket_remove_xs(struct inode *inode,
4413 memset(last, 0, sizeof(struct ocfs2_xattr_entry)); 4465 memset(last, 0, sizeof(struct ocfs2_xattr_entry));
4414 le16_add_cpu(&xh->xh_count, -1); 4466 le16_add_cpu(&xh->xh_count, -1);
4415 4467
4416 ocfs2_xattr_bucket_journal_dirty(handle, inode, &xs->bucket); 4468 ocfs2_xattr_bucket_journal_dirty(handle, xs->bucket);
4417 4469
4418out_commit: 4470out_commit:
4419 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); 4471 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
@@ -4565,7 +4617,7 @@ try_again:
4565 4617
4566 mlog_bug_on_msg(header_size > blocksize, "bucket %llu has header size " 4618 mlog_bug_on_msg(header_size > blocksize, "bucket %llu has header size "
4567 "of %u which exceed block size\n", 4619 "of %u which exceed block size\n",
4568 (unsigned long long)bucket_blkno(&xs->bucket), 4620 (unsigned long long)bucket_blkno(xs->bucket),
4569 header_size); 4621 header_size);
4570 4622
4571 if (xi->value && xi->value_len > OCFS2_XATTR_INLINE_SIZE) 4623 if (xi->value && xi->value_len > OCFS2_XATTR_INLINE_SIZE)
@@ -4605,7 +4657,7 @@ try_again:
4605 mlog(0, "xs->not_found = %d, in xattr bucket %llu: free = %d, " 4657 mlog(0, "xs->not_found = %d, in xattr bucket %llu: free = %d, "
4606 "need = %d, max_free = %d, xh_free_start = %u, xh_name_value_len =" 4658 "need = %d, max_free = %d, xh_free_start = %u, xh_name_value_len ="
4607 " %u\n", xs->not_found, 4659 " %u\n", xs->not_found,
4608 (unsigned long long)bucket_blkno(&xs->bucket), 4660 (unsigned long long)bucket_blkno(xs->bucket),
4609 free, need, max_free, le16_to_cpu(xh->xh_free_start), 4661 free, need, max_free, le16_to_cpu(xh->xh_free_start),
4610 le16_to_cpu(xh->xh_name_value_len)); 4662 le16_to_cpu(xh->xh_name_value_len));
4611 4663
@@ -4617,7 +4669,7 @@ try_again:
4617 * name/value will be moved, the xe shouldn't be changed 4669 * name/value will be moved, the xe shouldn't be changed
4618 * in xs. 4670 * in xs.
4619 */ 4671 */
4620 ret = ocfs2_defrag_xattr_bucket(inode, &xs->bucket); 4672 ret = ocfs2_defrag_xattr_bucket(inode, xs->bucket);
4621 if (ret) { 4673 if (ret) {
4622 mlog_errno(ret); 4674 mlog_errno(ret);
4623 goto out; 4675 goto out;
@@ -4649,7 +4701,7 @@ try_again:
4649 * add a new bucket for the insert. 4701 * add a new bucket for the insert.
4650 */ 4702 */
4651 ret = ocfs2_check_xattr_bucket_collision(inode, 4703 ret = ocfs2_check_xattr_bucket_collision(inode,
4652 &xs->bucket, 4704 xs->bucket,
4653 xi->name); 4705 xi->name);
4654 if (ret) { 4706 if (ret) {
4655 mlog_errno(ret); 4707 mlog_errno(ret);
@@ -4658,14 +4710,13 @@ try_again:
4658 4710
4659 ret = ocfs2_add_new_xattr_bucket(inode, 4711 ret = ocfs2_add_new_xattr_bucket(inode,
4660 xs->xattr_bh, 4712 xs->xattr_bh,
4661 xs->bucket.bu_bhs[0]); 4713 xs->bucket->bu_bhs[0]);
4662 if (ret) { 4714 if (ret) {
4663 mlog_errno(ret); 4715 mlog_errno(ret);
4664 goto out; 4716 goto out;
4665 } 4717 }
4666 4718
4667 ocfs2_xattr_bucket_relse(inode, &xs->bucket); 4719 ocfs2_xattr_bucket_relse(xs->bucket);
4668 memset(&xs->bucket, 0, sizeof(xs->bucket));
4669 4720
4670 ret = ocfs2_xattr_index_block_find(inode, xs->xattr_bh, 4721 ret = ocfs2_xattr_index_block_find(inode, xs->xattr_bh,
4671 xi->name_index, 4722 xi->name_index,