zfsonlinux/zfs — pull request #2321 by dweeezil (2014-05-11 01:22:08+00:00)
Title: Caculate 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 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 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 of:

[ 5 6 4 12 13 7 11 0 1 2 3 8 16 19 17 ]

Adding the SA xattr will, effectively require a registration of:

[ 5 6 4 12 13 7 11 0 1 2 3 8 16 19 17 20 ]

Since the symlink (17) interferes with the spill block pointer, it must
also be moved to the spill block which should have a registration of:

[ 17 20 ]

This patch simply re-uses the logic within sa_find_sizes() in which the
"split point" is calculated (near the comment "find index of where spill
*could* occur" to update extra_hdrsize in this particular case.