scoutfs: reserve at least one xattr item value

Even when we're setting an xattr with no value we still have a file
system item value that contains the xattr value header which tells us
that this is the last value.

This fixes a warning that would be issued if we tried to set an xattr
with a zero length value.  We'd try to dirty an item value with the
header after having reserved zero bytes for item values.  To hit the
warning the inode couldn't already be dirty so that the xattr value
didn't get to hide in the unsed reservation for dirtying the inode
item's value.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2018-02-28 12:46:06 -08:00
committed by Zach Brown
parent f9e282048f
commit 241b52d55a

View File

@@ -184,19 +184,22 @@ static inline const struct scoutfs_item_count SIC_RENAME(unsigned old_len,
/*
* Setting an xattr results in a dirty set of items with values for the
* size of the xattr. Any previously existing items from a larger xattr
* are deleted which dirties their key but removes their value. We
* don't know the size of a possibly existing xattr so we assume max
* parts.
* size of the xattr. There's always at least one item with a value
* header. Any previously existing items from a larger xattr are
* deleted which dirties their key but removes their value. We don't
* know the size of a possibly existing xattr so we assume max parts.
*/
static inline const struct scoutfs_item_count SIC_XATTR_SET(unsigned name_len,
unsigned size)
{
struct scoutfs_item_count cnt = {0,};
unsigned val_parts = DIV_ROUND_UP(size, SCOUTFS_XATTR_PART_SIZE);
unsigned val_parts;
__count_dirty_inode(&cnt);
val_parts = max_t(unsigned, 1,
DIV_ROUND_UP(size, SCOUTFS_XATTR_PART_SIZE));
cnt.items += SCOUTFS_XATTR_MAX_PARTS;
cnt.keys += SCOUTFS_XATTR_MAX_PARTS *
(offsetof(struct scoutfs_xattr_key, name[name_len]) +