Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bde1e540 authored by Joel Becker's avatar Joel Becker
Browse files

ocfs2: Remove xattrs via ocfs2_xa_loc



Add ocfs2_xa_remove_entry(), which will remove an xattr entry from its
storage via the ocfs2_xa_loc descriptor.

Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
parent 11179f2c
Loading
Loading
Loading
Loading
+29 −33
Original line number Original line Diff line number Diff line
@@ -1573,7 +1573,29 @@ static const struct ocfs2_xa_loc_operations ocfs2_xa_bucket_loc_ops = {


static void ocfs2_xa_remove_entry(struct ocfs2_xa_loc *loc)
static void ocfs2_xa_remove_entry(struct ocfs2_xa_loc *loc)
{
{
	int index, count;
	struct ocfs2_xattr_header *xh = loc->xl_header;
	struct ocfs2_xattr_entry *entry = loc->xl_entry;

	ocfs2_xa_wipe_namevalue(loc);
	ocfs2_xa_wipe_namevalue(loc);
	loc->xl_entry = NULL;

	le16_add_cpu(&xh->xh_count, -1);
	count = le16_to_cpu(xh->xh_count);

	/*
	 * Only zero out the entry if there are more remaining.  This is
	 * important for an empty bucket, as it keeps track of the
	 * bucket's hash value.  It doesn't hurt empty block storage.
	 */
	if (count) {
		index = ((char *)entry - (char *)&xh->xh_entries) /
			sizeof(struct ocfs2_xattr_entry);
		memmove(&xh->xh_entries[index], &xh->xh_entries[index + 1],
			(count - index) * sizeof(struct ocfs2_xattr_entry));
		memset(&xh->xh_entries[count], 0,
		       sizeof(struct ocfs2_xattr_entry));
	}
}
}


static void ocfs2_init_dinode_xa_loc(struct ocfs2_xa_loc *loc,
static void ocfs2_init_dinode_xa_loc(struct ocfs2_xa_loc *loc,
@@ -1638,7 +1660,6 @@ static void ocfs2_xattr_set_entry_local(struct inode *inode,
					size_t min_offs)
					size_t min_offs)
{
{
	size_t name_len = strlen(xi->name);
	size_t name_len = strlen(xi->name);
	int i;
	struct ocfs2_xa_loc loc;
	struct ocfs2_xa_loc loc;


	if (xs->xattr_bh == xs->inode_bh)
	if (xs->xattr_bh == xs->inode_bh)
@@ -1686,25 +1707,12 @@ static void ocfs2_xattr_set_entry_local(struct inode *inode,
			return;
			return;
		}
		}


		/* Remove the old name+value. */
		if (!xi->value)
			ocfs2_xa_remove_entry(&loc);
		else
			ocfs2_xa_wipe_namevalue(&loc);
			ocfs2_xa_wipe_namevalue(&loc);
		xs->here->xe_name_hash = 0;
		xs->here->xe_name_offset = 0;
		ocfs2_xattr_set_local(xs->here, 1);
		xs->here->xe_value_size = 0;


		min_offs += size;
		min_offs += size;

		if (!xi->value) {
			/* Remove the old entry. */
			i = le16_to_cpu(xs->header->xh_count) - 1;
			last = &xs->header->xh_entries[i];
			xs->header->xh_count = cpu_to_le16(i);

			memmove(xs->here, xs->here + 1,
				(void *)last - (void *)xs->here);
			memset(last, 0, sizeof(struct ocfs2_xattr_entry));
		}
	}
	}
	if (xi->value) {
	if (xi->value) {
		/* Insert the new name+value. */
		/* Insert the new name+value. */
@@ -5001,8 +5009,8 @@ static void ocfs2_xattr_set_entry_normal(struct inode *inode,
		new_size = OCFS2_XATTR_SIZE(name_len) +
		new_size = OCFS2_XATTR_SIZE(name_len) +
			   OCFS2_XATTR_SIZE(xi->value_len);
			   OCFS2_XATTR_SIZE(xi->value_len);


		ocfs2_xa_wipe_namevalue(&loc);
		if (xi->value) {
		if (xi->value) {
			ocfs2_xa_wipe_namevalue(&loc);
			if (new_size > size)
			if (new_size > size)
				goto set_new_name_value;
				goto set_new_name_value;


@@ -5024,20 +5032,8 @@ static void ocfs2_xattr_set_entry_normal(struct inode *inode,
			ocfs2_xattr_set_local(xe, local);
			ocfs2_xattr_set_local(xe, local);
			return;
			return;
		} else {
		} else {
			/*
			ocfs2_xa_remove_entry(&loc);
			 * Remove the old entry if there is more than one.
			if (!xh->xh_count)
			 * We don't remove the last entry so that we can
			 * use it to indicate the hash value of the empty
			 * bucket.
			 */
			last -= 1;
			le16_add_cpu(&xh->xh_count, -1);
			if (xh->xh_count) {
				memmove(xe, xe + 1,
					(void *)last - (void *)xe);
				memset(last, 0,
				       sizeof(struct ocfs2_xattr_entry));
			} else
				xh->xh_free_start =
				xh->xh_free_start =
					cpu_to_le16(OCFS2_XATTR_BUCKET_SIZE);
					cpu_to_le16(OCFS2_XATTR_BUCKET_SIZE);