Calculate header size correctly in sa_find_sizes()
In the case where a variable-sized SA overlaps the spill block pointer and a new variable-sized SA is being added, the header size was improperly calculated to include the to-be-moved SA. This problem could be reproduced when xattr=sa enabled as follows: ln -s $(perl -e 'print "x" x 120') blah setfattr -n security.selinux -v blahblah -h blah The symlink is large enough to interfere with the spill block pointer and has a typical SA registration as follows (shown in modified "zdb -dddd" <SA attr layout obj> format): [ ... ZPL_DACL_COUNT ZPL_DACL_ACES ZPL_SYMLINK ] Adding the SA xattr will attempt to extend the registration to: [ ... ZPL_DACL_COUNT ZPL_DACL_ACES ZPL_SYMLINK ZPL_DXATTR ] but since the ZPL_SYMLINK SA interferes with the spill block pointer, it must also be moved to the spill block which will have a registration of: [ ZPL_SYMLINK ZPL_DXATTR ] This commit updates extra_hdrsize when this condition occurs, allowing hdrsize to be subsequently decreased appropriately. Signed-off-by: Tim Chase <tim@chase2k.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Ned Bass <bass6@llnl.gov> Issue #2214 Issue #2228 Issue #2316 Issue #2343
This commit is contained in:
parent
3937ab20f3
commit
83021b47c2
@ -594,7 +594,7 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_t *attr_desc, int attr_count,
|
||||
ASSERT(IS_P2ALIGNED(full_space, 8));
|
||||
|
||||
for (i = 0; i != attr_count; i++) {
|
||||
boolean_t is_var_sz;
|
||||
boolean_t is_var_sz, might_spill_here;
|
||||
|
||||
*total = P2ROUNDUP(*total, 8);
|
||||
*total += attr_desc[i].sa_length;
|
||||
@ -606,6 +606,11 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_t *attr_desc, int attr_count,
|
||||
var_size++;
|
||||
}
|
||||
|
||||
might_spill_here =
|
||||
buftype == SA_BONUS && *index == -1 &&
|
||||
(*total + P2ROUNDUP(hdrsize, 8)) >
|
||||
(full_space - sizeof (blkptr_t));
|
||||
|
||||
if (is_var_sz && var_size > 1) {
|
||||
/*
|
||||
* Don't worry that the spill block might overflow.
|
||||
@ -622,7 +627,7 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_t *attr_desc, int attr_count,
|
||||
* spill-over.
|
||||
*/
|
||||
hdrsize += sizeof (uint16_t);
|
||||
if (*index != -1)
|
||||
if (*index != -1 || might_spill_here)
|
||||
extra_hdrsize += sizeof (uint16_t);
|
||||
} else {
|
||||
ASSERT(buftype == SA_BONUS);
|
||||
@ -639,11 +644,8 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_t *attr_desc, int attr_count,
|
||||
* space. The sum is used later for sizing bonus
|
||||
* and spill buffer.
|
||||
*/
|
||||
if (buftype == SA_BONUS && *index == -1 &&
|
||||
(*total + P2ROUNDUP(hdrsize, 8)) >
|
||||
(full_space - sizeof (blkptr_t))) {
|
||||
if (might_spill_here)
|
||||
*index = i;
|
||||
}
|
||||
|
||||
if ((*total + P2ROUNDUP(hdrsize, 8)) > full_space &&
|
||||
buftype == SA_BONUS)
|
||||
|
Loading…
x
Reference in New Issue
Block a user