diff options
author | Tao Ma <tao.ma@oracle.com> | 2008-10-09 11:06:14 -0400 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2008-10-13 20:02:45 -0400 |
commit | 936b8834366ec05f2a6993f73afd8348cac9718e (patch) | |
tree | 6f1d4b4e7586599bd11ff92a88a751aa78ce1a4b | |
parent | 2057e5c6780d86939a199031cdbafb81e6f88aac (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.c | 95 |
1 files changed, 60 insertions, 35 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 092a12318986..8f522f2f84a5 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, | |||
137 | static int ocfs2_delete_xattr_index_block(struct inode *inode, | 137 | static int ocfs2_delete_xattr_index_block(struct inode *inode, |
138 | struct buffer_head *xb_bh); | 138 | struct buffer_head *xb_bh); |
139 | 139 | ||
140 | static inline struct xattr_handler *ocfs2_xattr_handler(int name_index) | 140 | static 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 | ||
150 | static u32 ocfs2_xattr_name_hash(struct inode *inode, | 150 | static 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 | ||
455 | static 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 | |||
455 | static int ocfs2_xattr_list_entries(struct inode *inode, | 479 | static 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 | ||
484 | static int ocfs2_xattr_ibody_list(struct inode *inode, | 507 | static int ocfs2_xattr_ibody_list(struct inode *inode, |
@@ -2456,6 +2479,7 @@ out: | |||
2456 | struct ocfs2_xattr_tree_list { | 2479 | struct 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 | ||
2461 | static int ocfs2_xattr_bucket_get_name_value(struct inode *inode, | 2485 | static 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; |
2558 | out: | 2583 | out: |
2559 | return ret; | 2584 | return ret; |
2560 | } | 2585 | } |