[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