btrfs: optmize listxattr
authorChristoph Hellwig <hch@lst.de>
Thu, 28 Aug 2008 10:21:16 +0000 (06:21 -0400)
committerChris Mason <chris.mason@oracle.com>
Thu, 25 Sep 2008 15:04:07 +0000 (11:04 -0400)
The ->list handler is really not useful at all, because we always call
btrfs_xattr_generic_list anyway.  After this is done
find_btrfs_xattr_handler becomes unused, and it becomes obvious that the
temporary name buffer allocation isn't needed but we can directly copy
into the supplied buffer.

Tested with various getfattr -d calls on varying xattr lists.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/acl.c
fs/btrfs/xattr.c
fs/btrfs/xattr.h

index b95147e..2f86531 100644 (file)
@@ -320,14 +320,12 @@ int btrfs_acl_chmod(struct inode *inode)
 
 struct xattr_handler btrfs_xattr_acl_default_handler = {
        .prefix = POSIX_ACL_XATTR_DEFAULT,
-       .list   = btrfs_xattr_generic_list,
        .get    = btrfs_xattr_acl_default_get,
        .set    = btrfs_xattr_acl_default_set,
 };
 
 struct xattr_handler btrfs_xattr_acl_access_handler = {
        .prefix = POSIX_ACL_XATTR_ACCESS,
-       .list   = btrfs_xattr_generic_list,
        .get    = btrfs_xattr_acl_access_get,
        .set    = btrfs_xattr_acl_access_set,
 };
index 121c955..fdfece4 100644 (file)
@@ -50,35 +50,6 @@ struct xattr_handler *btrfs_xattr_handlers[] = {
        NULL,
 };
 
-/*
- * @param name - the xattr name
- * @return - the xattr_handler for the xattr, NULL if its not found
- *
- * use this with listxattr where we don't already know the type of xattr we
- * have
- */
-static struct xattr_handler *find_btrfs_xattr_handler(struct extent_buffer *l,
-                                                     unsigned long name_ptr,
-                                                     u16 name_len)
-{
-       struct xattr_handler *handler = NULL;
-       int i = 0;
-
-       for (handler = btrfs_xattr_handlers[i]; handler != NULL; i++,
-            handler = btrfs_xattr_handlers[i]) {
-               u16 prefix_len = strlen(handler->prefix);
-
-               if (name_len < prefix_len)
-                       continue;
-
-               if (memcmp_extent_buffer(l, handler->prefix, name_ptr,
-                                        prefix_len) == 0)
-                       break;
-       }
-
-       return handler;
-}
-
 /*
  * @param name_index - the index for the xattr handler
  * @return the xattr_handler if we found it, NULL otherwise
@@ -118,19 +89,6 @@ static inline char *get_name(const char *name, int name_index)
        return ret;
 }
 
-size_t btrfs_xattr_generic_list(struct inode *inode, char *list,
-                               size_t list_size, const char *name,
-                               size_t name_len)
-{
-       if (list && (name_len+1) <= list_size) {
-               memcpy(list, name, name_len);
-               list[name_len] = '\0';
-       } else
-               return -ERANGE;
-
-       return name_len+1;
-}
-
 ssize_t btrfs_xattr_get(struct inode *inode, int name_index,
                        const char *attr_name, void *buffer, size_t size)
 {
@@ -278,11 +236,10 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
        struct btrfs_item *item;
        struct extent_buffer *leaf;
        struct btrfs_dir_item *di;
-       struct xattr_handler *handler;
        int ret = 0, slot, advance;
-       size_t total_size = 0, size_left = size, written;
+       size_t total_size = 0, size_left = size;
        unsigned long name_ptr;
-       char *name;
+       size_t name_len;
        u32 nritems;
 
        /*
@@ -344,37 +301,24 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
 
                di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
 
-               total_size += btrfs_dir_name_len(leaf, di)+1;
+               name_len = btrfs_dir_name_len(leaf, di);
+               total_size += name_len + 1;
 
                /* we are just looking for how big our buffer needs to be */
                if (!size)
                        continue;
 
-               /* find our handler for this xattr */
-               name_ptr = (unsigned long)(di + 1);
-               handler = find_btrfs_xattr_handler(leaf, name_ptr,
-                                                  btrfs_dir_name_len(leaf, di));
-               if (!handler) {
-                       printk(KERN_ERR "btrfs: unsupported xattr found\n");
-                       continue;
-               }
-
-               name = kmalloc(btrfs_dir_name_len(leaf, di), GFP_KERNEL);
-               read_extent_buffer(leaf, name, name_ptr,
-                                  btrfs_dir_name_len(leaf, di));
-
-               /* call the list function associated with this xattr */
-               written = handler->list(inode, buffer, size_left, name,
-                                       btrfs_dir_name_len(leaf, di));
-               kfree(name);
-
-               if (written < 0) {
+               if (!buffer || (name_len + 1) > size_left) {
                        ret = -ERANGE;
                        break;
                }
 
-               size_left -= written;
-               buffer += written;
+               name_ptr = (unsigned long)(di + 1);
+               read_extent_buffer(leaf, buffer, name_ptr, name_len);
+               buffer[name_len] = '\0';
+
+               size_left -= name_len + 1;
+               buffer += name_len + 1;
        }
        ret = total_size;
 
@@ -412,28 +356,24 @@ BTRFS_XATTR_SETGET_FUNCS(trusted, BTRFS_XATTR_INDEX_TRUSTED);
 
 struct xattr_handler btrfs_xattr_security_handler = {
        .prefix = XATTR_SECURITY_PREFIX,
-       .list   = btrfs_xattr_generic_list,
        .get    = btrfs_xattr_security_get,
        .set    = btrfs_xattr_security_set,
 };
 
 struct xattr_handler btrfs_xattr_system_handler = {
        .prefix = XATTR_SYSTEM_PREFIX,
-       .list   = btrfs_xattr_generic_list,
        .get    = btrfs_xattr_system_get,
        .set    = btrfs_xattr_system_set,
 };
 
 struct xattr_handler btrfs_xattr_user_handler = {
        .prefix = XATTR_USER_PREFIX,
-       .list   = btrfs_xattr_generic_list,
        .get    = btrfs_xattr_user_get,
        .set    = btrfs_xattr_user_set,
 };
 
 struct xattr_handler btrfs_xattr_trusted_handler = {
        .prefix = XATTR_TRUSTED_PREFIX,
-       .list   = btrfs_xattr_generic_list,
        .get    = btrfs_xattr_trusted_get,
        .set    = btrfs_xattr_trusted_set,
 };
index b2e47e3..825e55b 100644 (file)
@@ -47,12 +47,4 @@ ssize_t btrfs_xattr_get(struct inode *inode, int name_index, const char *name,
 int btrfs_xattr_set(struct inode *inode, int name_index, const char *name,
                        const void *value, size_t size, int flags);
 
-/*
- * the only reason this is public is for acl.c.  There may be a point where
- * acl.c doesn't need it, and if thats the case we need to remove it and make
- * it static in xattr.c
- */
-size_t btrfs_xattr_generic_list(struct inode *inode, char *list,
-                               size_t list_size, const char *name,
-                               size_t name_len);
 #endif /* __XATTR__ */