[Ocfs2-tools-devel] [PATCH 8/9] ocfs2-tools: add xattr support in fsck.ocfs2

Joel Becker Joel.Becker at oracle.com
Fri Dec 19 14:54:57 PST 2008


On Fri, Dec 19, 2008 at 05:42:05PM +0800, Tiger Yang wrote:
> This patch will check all extended attributes related with each inode,
> It will check xattr extent tree in index block and xattr's value tree,
> mark all xattr block/cluster as used.
> 

<snip>

> +static errcode_t check_xattr(o2fsck_state *ost,
> +			     struct ocfs2_dinode *di,
> +			     struct ocfs2_xattr_header *xh,
> +			     int *changed)
> +{
> +	int i;
> +	struct extent_info ei = {0, };
> +	errcode_t ret = 0;
> +
> +	for (i = 0 ; i < xh->xh_count; i++) {
> +		int change = 0;
> +		struct ocfs2_xattr_entry *xe = &xh->xh_entries[i];
> +
> +		if (!ocfs2_xattr_is_local(xe)) {
> +			struct ocfs2_xattr_value_root *xv =
> +				(struct ocfs2_xattr_value_root *)
> +				((void *)xh + xe->xe_name_offset +
> +				OCFS2_XATTR_SIZE(xe->xe_name_len));
> +			struct ocfs2_extent_list *el = &xv->xr_list;
> +			ret = check_el(ost, &ei, di, el, 1, &change);
> +			if (ret)
> +				return ret;
> +			if (change)
> +				*changed = 1;
> +		}
> +	}
> +
> +	return ret;
> +}

	I would think this should check the fields of ocfs2_xattr_header
and correct them if necessary.  Ignore the checksum fields.  But
xh_count, xh_free_start, and xh_name_value_len certainly can be
out-of-bounds and corrected.
	Similarly, when walking the entries, xe_name_offset and
xe_name_len can be checked and fixed.  I wonder, too, if xe_name_hash
can be checked and fixed - I bet it can.

> +static errcode_t ocfs2_check_xattr_buckets(o2fsck_state *ost,
> +					   struct ocfs2_dinode *di,
> +					   uint64_t blkno,
> +					   uint32_t clusters)
> +{
> +	int i;
> +	errcode_t ret = 0;
> +	char *bucket = NULL;
> +	struct ocfs2_xattr_header *xh;
> +	int blk_per_bucket = ocfs2_blocks_per_xattr_bucket(ost->ost_fs);
> +	uint32_t bpc = ocfs2_xattr_buckets_per_cluster(ost->ost_fs);
> +	uint32_t num_buckets = clusters * bpc;
> +
> +	ret = ocfs2_malloc_blocks(ost->ost_fs->fs_io, blk_per_bucket, &bucket);
> +	if (ret) {
> +		com_err(whoami, ret, "while allocating room to read bucket "
> +			"of xattr data");
> +		goto out;
> +	}
> +
> +	for (i = 0; i < num_buckets; i++, blkno += blk_per_bucket) {
> +		int changed = 0;
> +
> +		ret = io_read_block(ost->ost_fs->fs_io, blkno,
> +				    blk_per_bucket, bucket);
> +		if (ret) {
> +			com_err(whoami, ret, "while reading blocks of xattr "
> +				"bucket");
> +			goto out;
> +		}
> +
> +		xh = (struct ocfs2_xattr_header *)bucket;
> +		ocfs2_swap_xattr_header(xh);
> +		ocfs2_swap_xattr_entries_to_cpu(xh);
> +		/*
> +		 * The real bucket num in this series of blocks is stored
> +		 * in the 1st bucket.
> +		 */
> +		if (i == 0)
> +			num_buckets = xh->xh_num_buckets;

	The number of buckets can be checked and fixed, as well.

> +		ret = check_xattr(ost, di, xh, &changed);
> +		if (ret)
> +			break;
> +		if (changed) {
> +			ocfs2_swap_xattr_entries_from_cpu(xh);
> +			ocfs2_swap_xattr_header(xh);
> +			io_write_block(ost->ost_fs->fs_io, blkno,
> +				       blk_per_bucket, bucket);
> +		}

	Right here, you'll break the checksum, because you don't
calculate it.

> +static errcode_t o2fsck_check_xattr_block(o2fsck_state *ost,
> +					  struct ocfs2_dinode *di)
> +{
> +	errcode_t ret;
> +	char *blk = NULL;
> +	struct ocfs2_xattr_block *xb = NULL;
> +	int changed = 0;
> +
> +	ret = ocfs2_malloc_block(ost->ost_fs->fs_io, &blk);
> +	if (ret) {
> +		com_err(whoami, ret, "while allocating room to read block "
> +			"of xattr.");
> +		return ret;
> +	}
> +
> +	ret = ocfs2_read_xattr_block(ost->ost_fs, di->i_xattr_loc, blk);
> +	if (ret) {
> +		com_err(whoami, ret, "while reading externel block of xattr.");
> +		return ret;
> +	}
> +
> +	xb = (struct ocfs2_xattr_block *)blk;

	Check and fix the fields of the xattr block here.
	Basically, this fsck patch validates the xattr tree structures,
but not the xattr fields themselves.  I think we should have that for
this to be ready to go.

Joel

-- 

"Win95 file and print sharing are for relatively friendly nets."
	- Paul Leach, Microsoft

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127



More information about the Ocfs2-tools-devel mailing list