Archived
14
0
Fork 0

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: Joel Becker <joel.becker@oracle.com>
This commit is contained in:
Joel Becker 2009-08-14 16:58:38 -07:00
parent 11179f2c92
commit bde1e5400a

View file

@ -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_wipe_namevalue(&loc); ocfs2_xa_remove_entry(&loc);
xs->here->xe_name_hash = 0; else
xs->here->xe_name_offset = 0; ocfs2_xa_wipe_namevalue(&loc);
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);