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

Joel Becker Joel.Becker at oracle.com
Tue Mar 3 19:34:03 PST 2009


On Wed, Mar 04, 2009 at 09:14:16AM +0800, Tao Ma wrote:
>
>
> Joel Becker wrote:
>> On Fri, Feb 27, 2009 at 03:54:49PM +0800, Tiger Yang wrote:
>>> +static uint16_t detect_xattr_count_in_bucket(struct ocfs2_xattr_header *xh,
>>> +					     struct xattr_info *xi)
>>> +{
>>> +	uint16_t count = 0;
>>> +	struct ocfs2_xattr_entry *entry = xh->xh_entries;
>>> +	struct ocfs2_xattr_entry *pre_xe = entry;
>>> +	uint16_t max_count = (xi->max_offset - HEADER_SIZE) / ENTRY_SIZE;
>>> +
>>> +	if (xh->xh_count == 0 && xh->xh_free_start == OCFS2_XATTR_BUCKET_SIZE)
>>> +		return 0;
>>> +
>>> +	while (!IS_LAST_ENTRY(entry)) {
>>> +		/*
>>> +		 * If we could not get the reasonable count,
>>> +		 * we will remove them by setting count to zero
>>> +		 */
>>> +		if (count >= max_count)
>>> +			return 0;
>>> +		/* xattr entries in bucket had sorted by name_hash */
>>> +		if (entry->xe_name_hash < pre_xe->xe_name_hash)
>>> +			return count;
>>> +		count++;
>>> +		pre_xe = entry;
>>> +		entry++;
>>> +	}
>>> +
>>> +	return count;
>>> +}
>>
>> 	Boy, I really want this to use the pre_xe->xe_name_offset to
>> verify that the entry hasn't walked past the free_start.  There is no
>> guarantee that the start of a name value won't be greater than the
>> name_hash of the last valid entry.  This would give a false extra entry.
>> 	This is why I wish we had a consistent free_start in all types
>> of xattr structures, but it's too late for that.  I realize you didn't
>> use the xe_name_offset fields here because you haven't validated them
>> yet.  So on to that part.
> Just go through the patch. Here tiger don't use free_start and  
> name_value_len because he check them after this function. So even with a  
> consistent free_start and name_value_len, He can't use it here.

	If all block types had it (inode, block, bucket) we could check
it up front and hopefully do something sane.  But we don't, so that's
moot.

>>> +static errcode_t check_xattr_entry(o2fsck_state *ost,
>>> +				   struct ocfs2_dinode *di,
>>> +				   struct ocfs2_xattr_header *xh,
>>> +				   int *changed,
>>> +				   struct xattr_info *xi)
>>> +{
>>> +	int i;
>>> +
>>> +	for (i = 0 ; i < xh->xh_count; i++) {
>>> +		struct ocfs2_xattr_entry *xe = &xh->xh_entries[i];
>>> +		uint32_t hash;
>>> +
>>> +		/* check and fix name_offset */
>>> +		if (xe->xe_name_offset >= xi->max_offset) {
>>> +			if (prompt(ost, PY, PR_XATTR_OFFSET_INVALID,
>>> +				   "Extended attribute entry in %s #%"PRIu64
>>> +				   " refers to an invalid name offset %u,"
>>> +				   " clear this entry?",
>>> +				   xattr_object[xi->location], xi->blkno,
>>> +				   xe->xe_name_offset)) {
>>> +				/*
>>> +				 * remove the entry and left the name/value,
>>> +				 * because we don't know the correct offset
>>> +				 * of them.
>>> +				 */
>>> +				memmove((void *)xe, (void *)(xe + 1),
>>> +					(xh->xh_count - i - 1) * ENTRY_SIZE);
>>> +				memset(&xh->xh_entries[xh->xh_count - 1], 0,
>>> +					ENTRY_SIZE);
>>> +				xh->xh_count -= 1;
>>> +				i -= 1;
>>> +				*changed = 1;
>>> +				continue;
>>> +			} else
>>> +				return -1;
>>> +		}
>>
>> 	When you find invalid entries, you leave them in place.  This
>> means that name_value_len and free_start get out of sync, because
>> name_value_len only covers the good values, but free_start covers all
>> values.  I think the kernel handles this ok because it never compares
>> free_start and name_value_len, but what happens if someone doesn't
>> realize this and changes it?
>> 	I suppose we all just watch out for that in future patches.
> I just saw that tiger adjust these 2 values in check_xattr after  
> check_xattr_value.

	He adjusts them to their correct values - free_start encompasses
both the good and bad values, whereas name_value_len is set to just the
length of the good entries.  This is consistent with what I said, but
not consistent with checking them against each other.

Joel

-- 

"It is not the function of our government to keep the citizen from
 falling into error; it is the function of the citizen to keep the
 government from falling into error."
	- Robert H. Jackson

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