[Btrfs-devel] [PATCH 1/2] small ea support for btrfs

Yan Zheng yanzheng at 21cn.com
Sat Sep 15 07:42:14 PDT 2007


2007/9/10, Josef Bacik <jbacik at redhat.com>:
> Hello,
>
> This patch adds small ea support for btrfs.  This handles EA's that will fit
> inline in a dir item, so basically this works for SELinux and most everything
> else.  I've tested it by doing random xattr stuff as well as turning SELinux on
> and doing a bunch of labeling stuff and making sure SELinux did what it was
> supposed to do.  I've added the ACL stuff in here simply so it will compile, ACL
> support is by no means done, its just there and ready to be added, something I
> will do in the near future hopefully.  I copied what ext3 does for the xattr
> handling stuff so it should be relatively easy to follow.  I've also done the
> necessary work in order to make adding support for EA's that wont fit inline
> pretty easy, instead of bugging out when we try to insert a dir_item thats too
> large we return ENOSPC so I can handle it appropriately.  Let me know what you
> think.  Thank you,
>
> Josef
>
> diff -r 9cb5f0f5c713 ctree.c
> --- a/ctree.c   Thu Aug 30 12:16:51 2007 -0400
> +++ b/ctree.c   Wed Sep 05 13:05:29 2007 -0400
> @@ -1826,7 +1826,7 @@ int btrfs_extend_item(struct btrfs_trans
>         data_end = leaf_data_end(root, leaf);
>
>         if (btrfs_leaf_free_space(root, leaf) < data_size)
> -               BUG();
> +               return -ENOSPC;
>         slot = path->slots[0];
>         old_data = btrfs_item_end(leaf->items + slot);
>
> @@ -1896,7 +1896,7 @@ int btrfs_insert_empty_item(struct btrfs
>
>         if (btrfs_leaf_free_space(root, leaf) <
>             sizeof(struct btrfs_item) + data_size) {
> -               BUG();
> +               return -ENOSPC;
>         }
Change 'BUG()' to 'return -ENOSPC' isn't appropriate here. Free space
is guaranteed by btrfs_search_slot. It's really a bug if free space
isn't enough here.

>         slot = path->slots[0];
>         BUG_ON(slot < 0);
>diff -r 9cb5f0f5c713 dir-item.c
> --- a/dir-item.c        Thu Aug 30 12:16:51 2007 -0400
> +++ b/dir-item.c        Wed Sep 05 13:05:29 2007 -0400
> @@ -55,6 +52,65 @@ static struct btrfs_dir_item *insert_wit
>         BUG_ON(data_size > btrfs_item_size(item));
>         ptr += btrfs_item_size(item) - data_size;
>         return (struct btrfs_dir_item *)ptr;
> +}
> +
> +int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans,
> +                           struct btrfs_root *root, const char *name,
> +                           int name_len, const void *data, int data_len,
> +                           u64 dir, u8 type)
> +{
> +       int ret = 0;
> +       struct btrfs_path *path;
> +       struct btrfs_dir_item *dir_item;
> +       char *name_ptr, *data_ptr;
> +       struct btrfs_key key;
> +       struct btrfs_key location;
> +       u32 data_size;
> +
> +       key.objectid = dir;
> +       key.flags = 0;
> +       btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY);
> +       ret = btrfs_name_hash(name, name_len, &key.offset);
> +       BUG_ON(ret);
> +       path = btrfs_alloc_path();
> +       data_size = sizeof(*dir_item) + name_len + data_len;
> +       dir_item = insert_with_overflow(trans, root, path, &key, data_size,
> +                                       name, name_len);
> +       if (IS_ERR(dir_item)) {
> +               ret = PTR_ERR(dir_item);
> +
> +               /* ok we can't embed this xattr into a dir item, plan b */
> +               if (ret == -ENOSPC) {
> +                       data_size = sizeof(*dir_item) + name_len;
> +                       dir_item = insert_with_overflow(trans, root, path,
> +                                                       &key, data_size, name,
> +                                                       name_len);
> +                       if (IS_ERR(dir_item)) {
> +                               /* seriously now, wtf */
> +                               ret = PTR_ERR(dir_item);
> +                               goto out;
> +                       }
> +                       /* alright here is where we add a file for this */
> +               }
Content of the dir item l random, it's not good.

> +
> +               goto out;
> +       }
> +
> +       memset(&location, 0, sizeof(location));
> +       btrfs_cpu_key_to_disk(&dir_item->location, &location);
> +       btrfs_set_dir_type(dir_item, type);
> +       btrfs_set_dir_name_len(dir_item, name_len);
> +       btrfs_set_dir_data_len(dir_item, data_len);
> +       name_ptr = (char *)(dir_item + 1);
> +       data_ptr = (char *)(name_ptr + name_len);
> +
> +       btrfs_memcpy(root, path->nodes[0]->b_data, name_ptr, name, name_len);
> +       btrfs_memcpy(root, path->nodes[0]->b_data, data_ptr, data, data_len);
> +       btrfs_mark_buffer_dirty(path->nodes[0]);
> +
> +out:
> +       btrfs_free_path(path);
> +       return ret;
>  }
>
>  int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root

Regards
YZ



More information about the Btrfs-devel mailing list