diff options
author | Joel Becker <joel.becker@oracle.com> | 2009-08-14 19:58:38 -0400 |
---|---|---|
committer | Joel Becker <joel.becker@oracle.com> | 2010-02-26 18:41:09 -0500 |
commit | bde1e5400a1b21ef47932ab00446c7361ff3c139 (patch) | |
tree | 289c2e4d50fe82a122ba5ceae1d17a1281263262 | |
parent | 11179f2c92cb025b1ff0b794f9714b3fb395855f (diff) |
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>
-rw-r--r-- | fs/ocfs2/xattr.c | 62 |
1 files changed, 29 insertions, 33 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 945ca697eb25..22a60a7c35ca 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
@@ -1573,7 +1573,29 @@ static const struct ocfs2_xa_loc_operations ocfs2_xa_bucket_loc_ops = { | |||
1573 | 1573 | ||
1574 | static void ocfs2_xa_remove_entry(struct ocfs2_xa_loc *loc) | 1574 | static void ocfs2_xa_remove_entry(struct ocfs2_xa_loc *loc) |
1575 | { | 1575 | { |
1576 | int index, count; | ||
1577 | struct ocfs2_xattr_header *xh = loc->xl_header; | ||
1578 | struct ocfs2_xattr_entry *entry = loc->xl_entry; | ||
1579 | |||
1576 | ocfs2_xa_wipe_namevalue(loc); | 1580 | ocfs2_xa_wipe_namevalue(loc); |
1581 | loc->xl_entry = NULL; | ||
1582 | |||
1583 | le16_add_cpu(&xh->xh_count, -1); | ||
1584 | count = le16_to_cpu(xh->xh_count); | ||
1585 | |||
1586 | /* | ||
1587 | * Only zero out the entry if there are more remaining. This is | ||
1588 | * important for an empty bucket, as it keeps track of the | ||
1589 | * bucket's hash value. It doesn't hurt empty block storage. | ||
1590 | */ | ||
1591 | if (count) { | ||
1592 | index = ((char *)entry - (char *)&xh->xh_entries) / | ||
1593 | sizeof(struct ocfs2_xattr_entry); | ||
1594 | memmove(&xh->xh_entries[index], &xh->xh_entries[index + 1], | ||
1595 | (count - index) * sizeof(struct ocfs2_xattr_entry)); | ||
1596 | memset(&xh->xh_entries[count], 0, | ||
1597 | sizeof(struct ocfs2_xattr_entry)); | ||
1598 | } | ||
1577 | } | 1599 | } |
1578 | 1600 | ||
1579 | static void ocfs2_init_dinode_xa_loc(struct ocfs2_xa_loc *loc, | 1601 | 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, | |||
1638 | size_t min_offs) | 1660 | size_t min_offs) |
1639 | { | 1661 | { |
1640 | size_t name_len = strlen(xi->name); | 1662 | size_t name_len = strlen(xi->name); |
1641 | int i; | ||
1642 | struct ocfs2_xa_loc loc; | 1663 | struct ocfs2_xa_loc loc; |
1643 | 1664 | ||
1644 | if (xs->xattr_bh == xs->inode_bh) | 1665 | if (xs->xattr_bh == xs->inode_bh) |
@@ -1686,25 +1707,12 @@ static void ocfs2_xattr_set_entry_local(struct inode *inode, | |||
1686 | return; | 1707 | return; |
1687 | } | 1708 | } |
1688 | 1709 | ||
1689 | /* Remove the old name+value. */ | 1710 | if (!xi->value) |
1690 | ocfs2_xa_wipe_namevalue(&loc); | 1711 | ocfs2_xa_remove_entry(&loc); |
1691 | xs->here->xe_name_hash = 0; | 1712 | else |
1692 | xs->here->xe_name_offset = 0; | 1713 | ocfs2_xa_wipe_namevalue(&loc); |
1693 | ocfs2_xattr_set_local(xs->here, 1); | ||
1694 | xs->here->xe_value_size = 0; | ||
1695 | 1714 | ||
1696 | min_offs += size; | 1715 | min_offs += size; |
1697 | |||
1698 | if (!xi->value) { | ||
1699 | /* Remove the old entry. */ | ||
1700 | i = le16_to_cpu(xs->header->xh_count) - 1; | ||
1701 | last = &xs->header->xh_entries[i]; | ||
1702 | xs->header->xh_count = cpu_to_le16(i); | ||
1703 | |||
1704 | memmove(xs->here, xs->here + 1, | ||
1705 | (void *)last - (void *)xs->here); | ||
1706 | memset(last, 0, sizeof(struct ocfs2_xattr_entry)); | ||
1707 | } | ||
1708 | } | 1716 | } |
1709 | if (xi->value) { | 1717 | if (xi->value) { |
1710 | /* Insert the new name+value. */ | 1718 | /* Insert the new name+value. */ |
@@ -5001,8 +5009,8 @@ static void ocfs2_xattr_set_entry_normal(struct inode *inode, | |||
5001 | new_size = OCFS2_XATTR_SIZE(name_len) + | 5009 | new_size = OCFS2_XATTR_SIZE(name_len) + |
5002 | OCFS2_XATTR_SIZE(xi->value_len); | 5010 | OCFS2_XATTR_SIZE(xi->value_len); |
5003 | 5011 | ||
5004 | ocfs2_xa_wipe_namevalue(&loc); | ||
5005 | if (xi->value) { | 5012 | if (xi->value) { |
5013 | ocfs2_xa_wipe_namevalue(&loc); | ||
5006 | if (new_size > size) | 5014 | if (new_size > size) |
5007 | goto set_new_name_value; | 5015 | goto set_new_name_value; |
5008 | 5016 | ||
@@ -5024,20 +5032,8 @@ static void ocfs2_xattr_set_entry_normal(struct inode *inode, | |||
5024 | ocfs2_xattr_set_local(xe, local); | 5032 | ocfs2_xattr_set_local(xe, local); |
5025 | return; | 5033 | return; |
5026 | } else { | 5034 | } else { |
5027 | /* | 5035 | ocfs2_xa_remove_entry(&loc); |
5028 | * Remove the old entry if there is more than one. | 5036 | if (!xh->xh_count) |
5029 | * We don't remove the last entry so that we can | ||
5030 | * use it to indicate the hash value of the empty | ||
5031 | * bucket. | ||
5032 | */ | ||
5033 | last -= 1; | ||
5034 | le16_add_cpu(&xh->xh_count, -1); | ||
5035 | if (xh->xh_count) { | ||
5036 | memmove(xe, xe + 1, | ||
5037 | (void *)last - (void *)xe); | ||
5038 | memset(last, 0, | ||
5039 | sizeof(struct ocfs2_xattr_entry)); | ||
5040 | } else | ||
5041 | xh->xh_free_start = | 5037 | xh->xh_free_start = |
5042 | cpu_to_le16(OCFS2_XATTR_BUCKET_SIZE); | 5038 | cpu_to_le16(OCFS2_XATTR_BUCKET_SIZE); |
5043 | 5039 | ||