aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTao Ma <tao.ma@oracle.com>2008-10-09 11:06:14 -0400
committerMark Fasheh <mfasheh@suse.com>2008-10-13 20:02:45 -0400
commit936b8834366ec05f2a6993f73afd8348cac9718e (patch)
tree6f1d4b4e7586599bd11ff92a88a751aa78ce1a4b
parent2057e5c6780d86939a199031cdbafb81e6f88aac (diff)
ocfs2: Refactor xattr list and remove ocfs2_xattr_handler().
According to Christoph Hellwig's advice, we really don't need a ->list to handle one xattr's list. Just a map from index to xattr prefix is enough. And I also refactor the old list method with the reference from fs/xfs/linux-2.6/xfs_xattr.c and the xattr list method in btrfs. Signed-off-by: Tao Ma <tao.ma@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
-rw-r--r--fs/ocfs2/xattr.c95
1 files changed, 60 insertions, 35 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 092a1231898..8f522f2f84a 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -137,14 +137,14 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode,
137static int ocfs2_delete_xattr_index_block(struct inode *inode, 137static int ocfs2_delete_xattr_index_block(struct inode *inode,
138 struct buffer_head *xb_bh); 138 struct buffer_head *xb_bh);
139 139
140static inline struct xattr_handler *ocfs2_xattr_handler(int name_index) 140static inline const char *ocfs2_xattr_prefix(int name_index)
141{ 141{
142 struct xattr_handler *handler = NULL; 142 struct xattr_handler *handler = NULL;
143 143
144 if (name_index > 0 && name_index < OCFS2_XATTR_MAX) 144 if (name_index > 0 && name_index < OCFS2_XATTR_MAX)
145 handler = ocfs2_xattr_handler_map[name_index]; 145 handler = ocfs2_xattr_handler_map[name_index];
146 146
147 return handler; 147 return handler ? handler->prefix : NULL;
148} 148}
149 149
150static u32 ocfs2_xattr_name_hash(struct inode *inode, 150static u32 ocfs2_xattr_name_hash(struct inode *inode,
@@ -452,33 +452,56 @@ static int ocfs2_xattr_value_truncate(struct inode *inode,
452 return ret; 452 return ret;
453} 453}
454 454
455static int ocfs2_xattr_list_entry(char *buffer, size_t size,
456 size_t *result, const char *prefix,
457 const char *name, int name_len)
458{
459 char *p = buffer + *result;
460 int prefix_len = strlen(prefix);
461 int total_len = prefix_len + name_len + 1;
462
463 *result += total_len;
464
465 /* we are just looking for how big our buffer needs to be */
466 if (!size)
467 return 0;
468
469 if (*result > size)
470 return -ERANGE;
471
472 memcpy(p, prefix, prefix_len);
473 memcpy(p + prefix_len, name, name_len);
474 p[prefix_len + name_len] = '\0';
475
476 return 0;
477}
478
455static int ocfs2_xattr_list_entries(struct inode *inode, 479static int ocfs2_xattr_list_entries(struct inode *inode,
456 struct ocfs2_xattr_header *header, 480 struct ocfs2_xattr_header *header,
457 char *buffer, size_t buffer_size) 481 char *buffer, size_t buffer_size)
458{ 482{
459 size_t rest = buffer_size; 483 size_t result = 0;
460 int i; 484 int i, type, ret;
485 const char *prefix, *name;
461 486
462 for (i = 0 ; i < le16_to_cpu(header->xh_count); i++) { 487 for (i = 0 ; i < le16_to_cpu(header->xh_count); i++) {
463 struct ocfs2_xattr_entry *entry = &header->xh_entries[i]; 488 struct ocfs2_xattr_entry *entry = &header->xh_entries[i];
464 struct xattr_handler *handler = 489 type = ocfs2_xattr_get_type(entry);
465 ocfs2_xattr_handler(ocfs2_xattr_get_type(entry)); 490 prefix = ocfs2_xattr_prefix(type);
466 491
467 if (handler) { 492 if (prefix) {
468 size_t size = handler->list(inode, buffer, rest, 493 name = (const char *)header +
469 ((char *)header + 494 le16_to_cpu(entry->xe_name_offset);
470 le16_to_cpu(entry->xe_name_offset)), 495
471 entry->xe_name_len); 496 ret = ocfs2_xattr_list_entry(buffer, buffer_size,
472 if (buffer) { 497 &result, prefix, name,
473 if (size > rest) 498 entry->xe_name_len);
474 return -ERANGE; 499 if (ret)
475 buffer += size; 500 return ret;
476 }
477 rest -= size;
478 } 501 }
479 } 502 }
480 503
481 return buffer_size - rest; 504 return result;
482} 505}
483 506
484static int ocfs2_xattr_ibody_list(struct inode *inode, 507static int ocfs2_xattr_ibody_list(struct inode *inode,
@@ -2456,6 +2479,7 @@ out:
2456struct ocfs2_xattr_tree_list { 2479struct ocfs2_xattr_tree_list {
2457 char *buffer; 2480 char *buffer;
2458 size_t buffer_size; 2481 size_t buffer_size;
2482 size_t result;
2459}; 2483};
2460 2484
2461static int ocfs2_xattr_bucket_get_name_value(struct inode *inode, 2485static int ocfs2_xattr_bucket_get_name_value(struct inode *inode,
@@ -2481,17 +2505,17 @@ static int ocfs2_list_xattr_bucket(struct inode *inode,
2481 struct ocfs2_xattr_bucket *bucket, 2505 struct ocfs2_xattr_bucket *bucket,
2482 void *para) 2506 void *para)
2483{ 2507{
2484 int ret = 0; 2508 int ret = 0, type;
2485 struct ocfs2_xattr_tree_list *xl = (struct ocfs2_xattr_tree_list *)para; 2509 struct ocfs2_xattr_tree_list *xl = (struct ocfs2_xattr_tree_list *)para;
2486 size_t size;
2487 int i, block_off, new_offset; 2510 int i, block_off, new_offset;
2511 const char *prefix, *name;
2488 2512
2489 for (i = 0 ; i < le16_to_cpu(bucket->xh->xh_count); i++) { 2513 for (i = 0 ; i < le16_to_cpu(bucket->xh->xh_count); i++) {
2490 struct ocfs2_xattr_entry *entry = &bucket->xh->xh_entries[i]; 2514 struct ocfs2_xattr_entry *entry = &bucket->xh->xh_entries[i];
2491 struct xattr_handler *handler = 2515 type = ocfs2_xattr_get_type(entry);
2492 ocfs2_xattr_handler(ocfs2_xattr_get_type(entry)); 2516 prefix = ocfs2_xattr_prefix(type);
2493 2517
2494 if (handler) { 2518 if (prefix) {
2495 ret = ocfs2_xattr_bucket_get_name_value(inode, 2519 ret = ocfs2_xattr_bucket_get_name_value(inode,
2496 bucket->xh, 2520 bucket->xh,
2497 i, 2521 i,
@@ -2499,16 +2523,16 @@ static int ocfs2_list_xattr_bucket(struct inode *inode,
2499 &new_offset); 2523 &new_offset);
2500 if (ret) 2524 if (ret)
2501 break; 2525 break;
2502 size = handler->list(inode, xl->buffer, xl->buffer_size, 2526
2503 bucket->bhs[block_off]->b_data + 2527 name = (const char *)bucket->bhs[block_off]->b_data +
2504 new_offset, 2528 new_offset;
2505 entry->xe_name_len); 2529 ret = ocfs2_xattr_list_entry(xl->buffer,
2506 if (xl->buffer) { 2530 xl->buffer_size,
2507 if (size > xl->buffer_size) 2531 &xl->result,
2508 return -ERANGE; 2532 prefix, name,
2509 xl->buffer += size; 2533 entry->xe_name_len);
2510 } 2534 if (ret)
2511 xl->buffer_size -= size; 2535 break;
2512 } 2536 }
2513 } 2537 }
2514 2538
@@ -2527,6 +2551,7 @@ static int ocfs2_xattr_tree_list_index_block(struct inode *inode,
2527 struct ocfs2_xattr_tree_list xl = { 2551 struct ocfs2_xattr_tree_list xl = {
2528 .buffer = buffer, 2552 .buffer = buffer,
2529 .buffer_size = buffer_size, 2553 .buffer_size = buffer_size,
2554 .result = 0,
2530 }; 2555 };
2531 2556
2532 if (le16_to_cpu(el->l_next_free_rec) == 0) 2557 if (le16_to_cpu(el->l_next_free_rec) == 0)
@@ -2554,7 +2579,7 @@ static int ocfs2_xattr_tree_list_index_block(struct inode *inode,
2554 name_hash = e_cpos - 1; 2579 name_hash = e_cpos - 1;
2555 } 2580 }
2556 2581
2557 ret = buffer_size - xl.buffer_size; 2582 ret = xl.result;
2558out: 2583out:
2559 return ret; 2584 return ret;
2560} 2585}