+++ /dev/null
-From: Tao Ma <tao.ma@oracle.com>
-Subject: ocfs2: Refactor xattr list and remove ocfs2_xattr_handler().
-Patch-mainline: 2.6.28
-
-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>
----
- fs/ocfs2/xattr.c | 95 ++++++++++++++++++++++++++++++++++--------------------
- 1 files changed, 60 insertions(+), 35 deletions(-)
-
-Index: linux-2.6.27/fs/ocfs2/xattr.c
-===================================================================
---- linux-2.6.27.orig/fs/ocfs2/xattr.c
-+++ linux-2.6.27/fs/ocfs2/xattr.c
-@@ -153,14 +153,14 @@ static int ocfs2_xattr_set_entry_index_b
- static int ocfs2_delete_xattr_index_block(struct inode *inode,
- struct buffer_head *xb_bh);
-
--static inline struct xattr_handler *ocfs2_xattr_handler(int name_index)
-+static inline const char *ocfs2_xattr_prefix(int name_index)
- {
- struct xattr_handler *handler = NULL;
-
- if (name_index > 0 && name_index < OCFS2_XATTR_MAX)
- handler = ocfs2_xattr_handler_map[name_index];
-
-- return handler;
-+ return handler ? handler->prefix : NULL;
- }
-
- static u32 ocfs2_xattr_name_hash(struct inode *inode,
-@@ -468,33 +468,56 @@ static int ocfs2_xattr_value_truncate(st
- return ret;
- }
-
-+static int ocfs2_xattr_list_entry(char *buffer, size_t size,
-+ size_t *result, const char *prefix,
-+ const char *name, int name_len)
-+{
-+ char *p = buffer + *result;
-+ int prefix_len = strlen(prefix);
-+ int total_len = prefix_len + name_len + 1;
-+
-+ *result += total_len;
-+
-+ /* we are just looking for how big our buffer needs to be */
-+ if (!size)
-+ return 0;
-+
-+ if (*result > size)
-+ return -ERANGE;
-+
-+ memcpy(p, prefix, prefix_len);
-+ memcpy(p + prefix_len, name, name_len);
-+ p[prefix_len + name_len] = '\0';
-+
-+ return 0;
-+}
-+
- static int ocfs2_xattr_list_entries(struct inode *inode,
- struct ocfs2_xattr_header *header,
- char *buffer, size_t buffer_size)
- {
-- size_t rest = buffer_size;
-- int i;
-+ size_t result = 0;
-+ int i, type, ret;
-+ const char *prefix, *name;
-
- for (i = 0 ; i < le16_to_cpu(header->xh_count); i++) {
- struct ocfs2_xattr_entry *entry = &header->xh_entries[i];
-- struct xattr_handler *handler =
-- ocfs2_xattr_handler(ocfs2_xattr_get_type(entry));
-+ type = ocfs2_xattr_get_type(entry);
-+ prefix = ocfs2_xattr_prefix(type);
-
-- if (handler) {
-- size_t size = handler->list(inode, buffer, rest,
-- ((char *)header +
-- le16_to_cpu(entry->xe_name_offset)),
-- entry->xe_name_len);
-- if (buffer) {
-- if (size > rest)
-- return -ERANGE;
-- buffer += size;
-- }
-- rest -= size;
-+ if (prefix) {
-+ name = (const char *)header +
-+ le16_to_cpu(entry->xe_name_offset);
-+
-+ ret = ocfs2_xattr_list_entry(buffer, buffer_size,
-+ &result, prefix, name,
-+ entry->xe_name_len);
-+ if (ret)
-+ return ret;
- }
- }
-
-- return buffer_size - rest;
-+ return result;
- }
-
- static int ocfs2_xattr_ibody_list(struct inode *inode,
-@@ -2472,6 +2495,7 @@ out:
- struct ocfs2_xattr_tree_list {
- char *buffer;
- size_t buffer_size;
-+ size_t result;
- };
-
- static int ocfs2_xattr_bucket_get_name_value(struct inode *inode,
-@@ -2497,17 +2521,17 @@ static int ocfs2_list_xattr_bucket(struc
- struct ocfs2_xattr_bucket *bucket,
- void *para)
- {
-- int ret = 0;
-+ int ret = 0, type;
- struct ocfs2_xattr_tree_list *xl = (struct ocfs2_xattr_tree_list *)para;
-- size_t size;
- int i, block_off, new_offset;
-+ const char *prefix, *name;
-
- for (i = 0 ; i < le16_to_cpu(bucket->xh->xh_count); i++) {
- struct ocfs2_xattr_entry *entry = &bucket->xh->xh_entries[i];
-- struct xattr_handler *handler =
-- ocfs2_xattr_handler(ocfs2_xattr_get_type(entry));
-+ type = ocfs2_xattr_get_type(entry);
-+ prefix = ocfs2_xattr_prefix(type);
-
-- if (handler) {
-+ if (prefix) {
- ret = ocfs2_xattr_bucket_get_name_value(inode,
- bucket->xh,
- i,
-@@ -2515,16 +2539,16 @@ static int ocfs2_list_xattr_bucket(struc
- &new_offset);
- if (ret)
- break;
-- size = handler->list(inode, xl->buffer, xl->buffer_size,
-- bucket->bhs[block_off]->b_data +
-- new_offset,
-- entry->xe_name_len);
-- if (xl->buffer) {
-- if (size > xl->buffer_size)
-- return -ERANGE;
-- xl->buffer += size;
-- }
-- xl->buffer_size -= size;
-+
-+ name = (const char *)bucket->bhs[block_off]->b_data +
-+ new_offset;
-+ ret = ocfs2_xattr_list_entry(xl->buffer,
-+ xl->buffer_size,
-+ &xl->result,
-+ prefix, name,
-+ entry->xe_name_len);
-+ if (ret)
-+ break;
- }
- }
-
-@@ -2543,6 +2567,7 @@ static int ocfs2_xattr_tree_list_index_b
- struct ocfs2_xattr_tree_list xl = {
- .buffer = buffer,
- .buffer_size = buffer_size,
-+ .result = 0,
- };
-
- if (le16_to_cpu(el->l_next_free_rec) == 0)
-@@ -2570,7 +2595,7 @@ static int ocfs2_xattr_tree_list_index_b
- name_hash = e_cpos - 1;
- }
-
-- ret = buffer_size - xl.buffer_size;
-+ ret = xl.result;
- out:
- return ret;
- }