[Ocfs2-tools-devel] [PATCH 4/7] libocfs2: add two types of trees operation of xattr

Tristan tristan.ye at oracle.com
Sun Oct 25 20:14:49 PDT 2009


Tiger Yang wrote:
> This patch add ocfs2_xattr_tree_et_ops for extending
> xattr records and ocfs2_xattr_value_et_ops for xattr values store.
> And abstract ocfs2_tree_extend_allocation for general tree extending.
>
> Signed-off-by: Tiger Yang <tiger.yang at oracle.com>
> ---
>  libocfs2/extend_file.c |   25 +++++++----
>  libocfs2/extent_tree.c |  110 ++++++++++++++++++++++++++++++++++++++++++++++++
>  libocfs2/extent_tree.h |   10 ++++
>  libocfs2/xattr.h       |   19 ++++++++
>  4 files changed, 156 insertions(+), 8 deletions(-)
>  create mode 100644 libocfs2/xattr.h
>
> diff --git a/libocfs2/extend_file.c b/libocfs2/extend_file.c
> index fbb770a..cad69e6 100644
> --- a/libocfs2/extend_file.c
> +++ b/libocfs2/extend_file.c
> @@ -77,16 +77,15 @@ errcode_t ocfs2_cached_inode_insert_extent(ocfs2_cached_inode *ci,
>  					clusters, flag);
>  }
>  
> -errcode_t ocfs2_cached_inode_extend_allocation(ocfs2_cached_inode *ci,
> -					       uint32_t new_clusters)
> +errcode_t ocfs2_tree_extend_allocation(ocfs2_filesys *fs,
> +				       uint32_t new_clusters,
> +				       struct ocfs2_extent_tree *et)
>  {
>  	errcode_t ret = 0;
>  	uint32_t n_clusters = 0, cpos;
> -	uint64_t blkno, file_size;
> -	ocfs2_filesys *fs = ci->ci_fs;
> +	uint64_t blkno;
>  
> -	file_size = ci->ci_inode->i_size;
> -	cpos = (file_size + fs->fs_clustersize - 1) / fs->fs_clustersize;
> +	cpos = et->et_ops->eo_get_clusters(et);
>   


I suddenly hit a bug there when applying your patches to do the xattr 
corruptions,

Actually, the function ptr 'eo_get_clusters' you used here is NULL, 
refer to ocfs2_dinode_et_opts's initialization in /libocfs2/extent_tree.c:

static struct ocfs2_extent_tree_operations ocfs2_dinode_et_ops = {
.eo_set_last_eb_blk = ocfs2_dinode_set_last_eb_blk,
.eo_get_last_eb_blk = ocfs2_dinode_get_last_eb_blk,
.eo_update_clusters = ocfs2_dinode_update_clusters,
.eo_fill_root_el = ocfs2_dinode_fill_root_el,
};

As you seen, memeber 'eo_get_clusters' didn't get initialized here.


>  	while (new_clusters) {
>  		n_clusters = 1;
>  		ret = ocfs2_new_clusters(fs, 1, new_clusters, &blkno,
> @@ -94,8 +93,8 @@ errcode_t ocfs2_cached_inode_extend_allocation(ocfs2_cached_inode *ci,
>  		if (ret)
>  			break;
>  
> -		ret = ocfs2_cached_inode_insert_extent(ci, cpos, blkno,
> -						       n_clusters, 0);
> +		ret = ocfs2_tree_insert_extent(fs, et, cpos, blkno,
> +						n_clusters, 0);
>  		if (ret) {
>  			/* XXX: We don't wan't to overwrite the error
>  			 * from insert_extent().  But we probably need
> @@ -110,6 +109,16 @@ errcode_t ocfs2_cached_inode_extend_allocation(ocfs2_cached_inode *ci,
>  	return ret;
>  }
>  
> +errcode_t ocfs2_cached_inode_extend_allocation(ocfs2_cached_inode *ci,
> +					       uint32_t new_clusters)
> +{
> +	struct ocfs2_extent_tree et;
> +
> +	ocfs2_init_dinode_extent_tree(&et, ci->ci_fs, (char *)ci->ci_inode,
> +				      ci->ci_inode->i_blkno);
> +	return ocfs2_tree_extend_allocation(ci->ci_fs, new_clusters, &et);
> +}
> +
>  errcode_t ocfs2_extend_allocation(ocfs2_filesys *fs, uint64_t ino,
>  				  uint32_t new_clusters)
>  {
> diff --git a/libocfs2/extent_tree.c b/libocfs2/extent_tree.c
> index 499ce1b..99d0451 100644
> --- a/libocfs2/extent_tree.c
> +++ b/libocfs2/extent_tree.c
> @@ -23,6 +23,7 @@
>  #include "ocfs2/byteorder.h"
>  #include "ocfs2/ocfs2.h"
>  #include "extent_tree.h"
> +#include "xattr.h"
>  
>  static void ocfs2_dinode_set_last_eb_blk(struct ocfs2_extent_tree *et,
>  					 uint64_t blkno)
> @@ -60,6 +61,98 @@ static struct ocfs2_extent_tree_operations ocfs2_dinode_et_ops = {
>  	.eo_fill_root_el	= ocfs2_dinode_fill_root_el,
>  };
>  
> +static void ocfs2_xattr_value_fill_root_el(struct ocfs2_extent_tree *et)
> +{
> +	struct ocfs2_xattr_value_root *xv = et->et_object;
> +
> +	et->et_root_el = &xv->xr_list;
> +}
> +
> +static void ocfs2_xattr_value_set_last_eb_blk(struct ocfs2_extent_tree *et,
> +					      uint64_t blkno)
> +{
> +	struct ocfs2_xattr_value_root *xv = et->et_object;
> +
> +	xv->xr_last_eb_blk = blkno;
> +}
> +
> +static uint64_t ocfs2_xattr_value_get_last_eb_blk(struct ocfs2_extent_tree *et)
> +{
> +	struct ocfs2_xattr_value_root *xv = et->et_object;
> +
> +	return xv->xr_last_eb_blk;
> +}
> +
> +static void ocfs2_xattr_value_update_clusters(struct ocfs2_extent_tree *et,
> +					      uint32_t clusters)
> +{
> +	struct ocfs2_xattr_value_root *xv = et->et_object;
> +
> +	xv->xr_clusters += clusters;
> +}
> +
> +static uint32_t ocfs2_xattr_value_get_clusters(struct ocfs2_extent_tree *et)
> +{
> +	struct ocfs2_xattr_value_root *xv = et->et_object;
> +
> +	return xv->xr_clusters;
> +}
> +
> +static struct ocfs2_extent_tree_operations ocfs2_xattr_value_et_ops = {
> +	.eo_set_last_eb_blk	= ocfs2_xattr_value_set_last_eb_blk,
> +	.eo_get_last_eb_blk	= ocfs2_xattr_value_get_last_eb_blk,
> +	.eo_update_clusters	= ocfs2_xattr_value_update_clusters,
> +	.eo_get_clusters	= ocfs2_xattr_value_get_clusters,
> +	.eo_fill_root_el	= ocfs2_xattr_value_fill_root_el,
> +};
> +
> +static void ocfs2_xattr_tree_fill_root_el(struct ocfs2_extent_tree *et)
> +{
> +	struct ocfs2_xattr_block *xb = et->et_object;
> +
> +	et->et_root_el = &xb->xb_attrs.xb_root.xt_list;
> +}
> +
> +static void ocfs2_xattr_tree_fill_max_leaf_clusters(ocfs2_filesys *fs,
> +						struct ocfs2_extent_tree *et)
> +{
> +	et->et_max_leaf_clusters =
> +		ocfs2_clusters_in_bytes(fs, OCFS2_MAX_XATTR_TREE_LEAF_SIZE);
> +}
> +
> +static void ocfs2_xattr_tree_set_last_eb_blk(struct ocfs2_extent_tree *et,
> +					     uint64_t blkno)
> +{
> +	struct ocfs2_xattr_block *xb = et->et_object;
> +	struct ocfs2_xattr_tree_root *xt = &xb->xb_attrs.xb_root;
> +
> +	xt->xt_last_eb_blk = blkno;
> +}
> +
> +static uint64_t ocfs2_xattr_tree_get_last_eb_blk(struct ocfs2_extent_tree *et)
> +{
> +	struct ocfs2_xattr_block *xb = et->et_object;
> +	struct ocfs2_xattr_tree_root *xt = &xb->xb_attrs.xb_root;
> +
> +	return xt->xt_last_eb_blk;
> +}
> +
> +static void ocfs2_xattr_tree_update_clusters(struct ocfs2_extent_tree *et,
> +					     uint32_t clusters)
> +{
> +	struct ocfs2_xattr_block *xb = et->et_object;
> +
> +	xb->xb_attrs.xb_root.xt_clusters += clusters;
> +}
> +
> +static struct ocfs2_extent_tree_operations ocfs2_xattr_tree_et_ops = {
> +	.eo_set_last_eb_blk	= ocfs2_xattr_tree_set_last_eb_blk,
> +	.eo_get_last_eb_blk	= ocfs2_xattr_tree_get_last_eb_blk,
> +	.eo_update_clusters	= ocfs2_xattr_tree_update_clusters,
> +	.eo_fill_root_el	= ocfs2_xattr_tree_fill_root_el,
> +	.eo_fill_max_leaf_clusters = ocfs2_xattr_tree_fill_max_leaf_clusters,
> +};
> +
>  static void __ocfs2_init_extent_tree(struct ocfs2_extent_tree *et,
>  				     ocfs2_filesys *fs,
>  				     char *buf,
> @@ -90,6 +183,23 @@ void ocfs2_init_dinode_extent_tree(struct ocfs2_extent_tree *et,
>  				 buf, &ocfs2_dinode_et_ops);
>  }
>  
> +void ocfs2_init_xattr_tree_extent_tree(struct ocfs2_extent_tree *et,
> +					ocfs2_filesys *fs,
> +					char *buf, uint64_t blkno)
> +{
> +	__ocfs2_init_extent_tree(et, fs, buf, blkno, ocfs2_write_xattr_block,
> +				 buf, &ocfs2_xattr_tree_et_ops);
> +}
> +
> +void ocfs2_init_xattr_value_extent_tree(struct ocfs2_extent_tree *et,
> +					ocfs2_filesys *fs,
> +					char *buf, uint64_t blkno,
> +					struct ocfs2_xattr_value_root *xv)
> +{
> +	__ocfs2_init_extent_tree(et, fs, buf, blkno, ocfs2_write_xattr_block,
> +				 xv, &ocfs2_xattr_value_et_ops);
> +}
> +
>  static inline void ocfs2_et_set_last_eb_blk(struct ocfs2_extent_tree *et,
>  					    uint64_t new_last_eb_blk)
>  {
> diff --git a/libocfs2/extent_tree.h b/libocfs2/extent_tree.h
> index 4e6e091..a504811 100644
> --- a/libocfs2/extent_tree.h
> +++ b/libocfs2/extent_tree.h
> @@ -97,6 +97,9 @@ struct ocfs2_extent_tree_operations {
>  void ocfs2_init_dinode_extent_tree(struct ocfs2_extent_tree *et,
>  				   ocfs2_filesys *fs,
>  				   char *buf, uint64_t blkno);
> +errcode_t ocfs2_tree_extend_allocation(ocfs2_filesys *fs,
> +				       uint32_t new_clusters,
> +				       struct ocfs2_extent_tree *et);
>  errcode_t ocfs2_tree_insert_extent(ocfs2_filesys *fs,
>  				   struct ocfs2_extent_tree *et,
>  				   uint32_t cpos, uint64_t c_blkno,
> @@ -109,3 +112,10 @@ int ocfs2_change_extent_flag(ocfs2_filesys *fs,
>  int ocfs2_remove_extent(ocfs2_filesys *fs,
>  			struct ocfs2_extent_tree *et,
>  			uint32_t cpos, uint32_t len);
> +void ocfs2_init_xattr_tree_extent_tree(struct ocfs2_extent_tree *et,
> +					ocfs2_filesys *fs,
> +					char *buf, uint64_t blkno);
> +void ocfs2_init_xattr_value_extent_tree(struct ocfs2_extent_tree *et,
> +					ocfs2_filesys *fs,
> +					char *buf, uint64_t blkno,
> +					struct ocfs2_xattr_value_root *xv);
> diff --git a/libocfs2/xattr.h b/libocfs2/xattr.h
> new file mode 100644
> index 0000000..475f0f2
> --- /dev/null
> +++ b/libocfs2/xattr.h
> @@ -0,0 +1,19 @@
> +/* -*- mode: c; c-basic-offset: 8; -*-
> + * vim: noexpandtab sw=8 ts=8 sts=0:
> + *
> + * xattr.h
> + *
> + * Copyright (C) 2004, 2008 Oracle.  All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public
> + * License version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License for more details.
> + */
> +
> +#define OCFS2_MAX_XATTR_TREE_LEAF_SIZE	65536
> +
>   




More information about the Ocfs2-tools-devel mailing list