[Ocfs2-tools-devel] [PATCH 2/3] ocfs2-tools: Add extended attribute support in libocfs2
Tao Ma
tao.ma at oracle.com
Mon Aug 25 23:38:19 PDT 2008
Tiger Yang wrote:
> This patch add some APIs for xattr operation in libocfs2.
>
> Signed-off-by: Tiger Yang <tiger.yang at oracle.com>
> ---
> include/ocfs2/ocfs2.h | 22 ++++
> libocfs2/extend_file.c | 4 +-
> libocfs2/extent_map.c | 2 +-
> libocfs2/feature_string.c | 4 +
> libocfs2/ocfs2_err.et | 4 +-
> libocfs2/xattr.c | 261 +++++++++++++++++++++++++++++++++++++++++++++
> 6 files changed, 293 insertions(+), 4 deletions(-)
>
> #endif /* _FILESYS_H */
> diff --git a/libocfs2/extend_file.c b/libocfs2/extend_file.c
> index 73e4033..217ea51 100644
> --- a/libocfs2/extend_file.c
> +++ b/libocfs2/extend_file.c
> @@ -997,16 +997,16 @@ static int ocfs2_find_path(ocfs2_filesys *fs, struct ocfs2_path *path,
> * This function doesn't handle non btree extent lists.
> */
> int ocfs2_find_leaf(ocfs2_filesys *fs, struct ocfs2_dinode *di,
> + struct ocfs2_extent_list *el,
> uint32_t cpos, char **leaf_buf)
I think we don't need to pass "di" into this function any more.
> {
> int ret;
> char *buf = NULL;
> struct ocfs2_path *path = NULL;
> - struct ocfs2_extent_list *el = &di->id2.i_list;
>
> assert(el->l_tree_depth > 0);
>
> - path = ocfs2_new_inode_path(fs, di);
> + path = ocfs2_new_path(fs, (char *)di, el);
> if (!path) {
> ret = OCFS2_ET_NO_MEMORY;
> goto out;
> diff --git a/libocfs2/feature_string.c b/libocfs2/feature_string.c
> index 369203e..d48dc84 100644
> --- a/libocfs2/feature_string.c
> +++ b/libocfs2/feature_string.c
> @@ -171,6 +171,10 @@ static struct feature_name ocfs2_feature_names[] = {
> .fn_flag = {0, OCFS2_FEATURE_INCOMPAT_INLINE_DATA, 0},
> },
> {
> + .fn_name = "Xattr",
> + .fn_flag = {0, OCFS2_FEATURE_INCOMPAT_XATTR, 0},
> + },
> + {
> .fn_name = NULL,
> },
> };
> diff --git a/libocfs2/ocfs2_err.et b/libocfs2/ocfs2_err.et
> index e278876..cbfa9d4 100644
> --- a/libocfs2/ocfs2_err.et
> +++ b/libocfs2/ocfs2_err.et
> @@ -171,10 +171,12 @@ ec OCFS2_ET_NO_BACKUP_SUPER,
> ec OCFS2_ET_TOO_MANY_SLOTS,
> "Too many slots for slot map"
>
> -
> ec OCFS2_ET_CANNOT_INLINE_DATA,
> "Can't write the data inline"
>
> +ec OCFS2_ET_BAD_XATTR_BLOCK_MAGIC,
> + "Bad magic number in xattr block"
> +
> ec OCFS2_ET_UNKNOWN_FEATURE,
> "Unknown feature"
>
> diff --git a/libocfs2/xattr.c b/libocfs2/xattr.c
> index d198743..d65e013 100644
> --- a/libocfs2/xattr.c
> +++ b/libocfs2/xattr.c
> @@ -23,6 +23,26 @@
> #include "ocfs2/byteorder.h"
> #include "ocfs2/ocfs2.h"
>
> +int ocfs2_extent_recs_per_xattr_block(int blocksize)
> +{
> + int size;
> +
> + size = blocksize - offsetof(struct ocfs2_xattr_block,
> + xb_attrs.xb_root.xt_list.l_recs);
> +
> + return size / sizeof(struct ocfs2_extent_rec);
> +}
> +
> +uint16_t ocfs2_xattr_buckets_per_cluster(ocfs2_filesys *fs)
> +{
> + return fs->fs_clustersize / OCFS2_XATTR_BUCKET_SIZE;
> +}
> +
> +uint16_t ocfs2_blocks_per_xattr_bucket(ocfs2_filesys *fs)
> +{
> + return OCFS2_XATTR_BUCKET_SIZE / fs->fs_blocksize;
> +}
> +
> uint32_t xattr_uuid_hash(unsigned char *uuid)
> {
> uint32_t i, hash = 0;
> @@ -35,3 +55,244 @@ uint32_t xattr_uuid_hash(unsigned char *uuid)
> return hash;
> }
>
> +static void ocfs2_swap_xattr_tree_root(struct ocfs2_xattr_tree_root *xt)
> +{
> + xt->xt_clusters = bswap_32(xt->xt_clusters);
> + xt->xt_last_eb_blk = bswap_64(xt->xt_last_eb_blk);
> +}
> +
> +static void ocfs2_swap_xattr_value_root(struct ocfs2_xattr_value_root *xr)
> +{
> + xr->xr_clusters = bswap_32(xr->xr_clusters);
> + xr->xr_last_eb_blk = bswap_64(xr->xr_last_eb_blk);
> +}
> +
> +static void ocfs2_swap_xattr_block_header(struct ocfs2_xattr_block *xb)
> +{
> + xb->xb_suballoc_slot = bswap_16(xb->xb_suballoc_slot);
> + xb->xb_suballoc_bit = bswap_16(xb->xb_suballoc_bit);
> + xb->xb_fs_generation = bswap_32(xb->xb_fs_generation);
> + xb->xb_blkno = bswap_64(xb->xb_blkno);
> + xb->xb_csum = bswap_64(xb->xb_csum);
> + xb->xb_flags = bswap_16(xb->xb_flags);
> +}
> +
> +void ocfs2_swap_xattr_entries_to_cpu(struct ocfs2_xattr_header *xh)
> +{
> + uint16_t i;
> +
> + if (cpu_is_little_endian)
> + return;
> +
> + for (i = 0; i < xh->xh_count; i++) {
> + struct ocfs2_xattr_entry *xe = &xh->xh_entries[i];
> +
> + xe->xe_name_offset = bswap_16(xe->xe_name_offset);
> + xe->xe_value_size = bswap_64(xe->xe_value_size);
> +
> + if (!ocfs2_xattr_is_local(xe)) {
> + struct ocfs2_xattr_value_root *xr =
> + (struct ocfs2_xattr_value_root *)
> + ((char *)xh + xe->xe_name_offset +
> + OCFS2_XATTR_SIZE(xe->xe_name_len));
> +
> + ocfs2_swap_xattr_value_root(xr);
> + ocfs2_swap_extent_list_to_cpu(&xr->xr_list);
> + }
> + }
> +}
> +
> +void ocfs2_swap_xattr_entries_from_cpu(struct ocfs2_xattr_header *xh)
> +{
> + uint16_t i;
> +
> + if (cpu_is_little_endian)
> + return;
> +
> + for (i = 0; i < xh->xh_count; i++) {
> + struct ocfs2_xattr_entry *xe = &xh->xh_entries[i];
> +
> + if (!ocfs2_xattr_is_local(xe)) {
> + struct ocfs2_xattr_value_root *xr =
> + (struct ocfs2_xattr_value_root *)
> + ((char *)xh + xe->xe_name_offset +
> + OCFS2_XATTR_SIZE(xe->xe_name_len));
> +
> + ocfs2_swap_xattr_value_root(xr);
> + }
> + xe->xe_name_offset = bswap_16(xe->xe_name_offset);
> + xe->xe_value_size = bswap_64(xe->xe_value_size);
> + }
> +}
> +
> +void ocfs2_swap_xattr_header(struct ocfs2_xattr_header *xh)
> +{
> + if (cpu_is_little_endian)
> + return;
> +
> + xh->xh_count = bswap_16(xh->xh_count);
> + xh->xh_offset = bswap_16(xh->xh_offset);
> + xh->xh_name_value_len = bswap_16(xh->xh_name_value_len);
> + xh->xh_num_buckets = bswap_16(xh->xh_num_buckets);
> + xh->xh_csum = bswap_64(xh->xh_csum);
> +}
> +
> +void ocfs2_swap_xattr_block_from_cpu(struct ocfs2_xattr_block *xb)
> +{
> + if (cpu_is_little_endian)
> + return;
> +
> + if (!(xb->xb_flags & OCFS2_XATTR_INDEXED)) {
> + ocfs2_swap_xattr_entries_from_cpu(&xb->xb_attrs.xb_header);
> + ocfs2_swap_xattr_header(&xb->xb_attrs.xb_header);
> + } else {
> + ocfs2_swap_xattr_tree_root(&xb->xb_attrs.xb_root);
here you miss ocfs2_swap_extent_list_from_cpu I guess.
> + }
> +
> + ocfs2_swap_xattr_block_header(xb);
> +}
> +
> +void ocfs2_swap_xattr_block_to_cpu(struct ocfs2_xattr_block *xb)
> +{
> + if (cpu_is_little_endian)
> + return;
> +
> + ocfs2_swap_xattr_block_header(xb);
> + if (!(xb->xb_flags & OCFS2_XATTR_INDEXED)) {
> + ocfs2_swap_xattr_header(&xb->xb_attrs.xb_header);
> + ocfs2_swap_xattr_entries_to_cpu(&xb->xb_attrs.xb_header);
> + } else {
> + ocfs2_swap_xattr_tree_root(&xb->xb_attrs.xb_root);
> + ocfs2_swap_extent_list_to_cpu(&xb->xb_attrs.xb_root.xt_list);
> + }
> +}
> +
More information about the Ocfs2-tools-devel
mailing list