Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Properly handle updates of variably-sized SA entries.
During the update process in sa_modify_attrs(), the sizes of existing variably-sized SA entries are obtained from sa_lengths[]. The case where a variably-sized SA was being replaced neglected to increment the index into sa_lengths[], so subsequent variable-length SAs would be rewritten with the wrong length. This patch adds the missing increment operation so all variably-sized SA entries are stored with their correct lengths. Previously, a size-changing update of a variably-sized SA that occurred when there were other variably-sized SAs in the bonus buffer would cause the subsequent SAs to be corrupted. The most common case in which this would occur is when a mode change caused the ZPL_DACL_ACES entry to change size when a ZPL_DXATTR (SA xattr) entry already existed. The following sequence would have caused a failure when xattr=sa was in force and would corrupt the bonus buffer: open(filename, O_WRONLY | O_CREAT, 0600); ... lsetxattr(filename, ...); /* create xattr SA */ chmod(filename, 0650); /* enlarges the ACL */
- Loading branch information
6eed38e
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, after much brow furrowing in getting an understanding of the wider context, this code looks good to me.
The only thing I don't understand, and it's not related to these changes, is why does it
ASSERT(length == 0)
(which I understand is the equivalent of the original ASSERT) in theaction == SA_REPLACE
case? I.e. why aren't we expecting to be replacing any of the fixed length attrs? (I'm hoping the answer doesn't tell me I haven't understood anything at all!)...oh, is it because the only place this is called with SA_REPLACE is from sa_attr_op(), and that already has a special case for updating equal length attrs (as fixed length attrs must be)? I.e.:
If that's the case, then the ASSERT in sa_modify_attrs() seems little "spooky action at a distance" - it's not confirming something required for the correct operation of the function, but simply a (very) obscure way of saying "there's a better way of dealing with fixed length attrs", and it doesn't even catch the case of variable length attrs with the same length . Perhaps replace it with something like:
Either way:
Reviewed by: Chris Dunlop chris@onthe.net.au
6eed38e
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For what it's worth... I've run this patch, including the expanded ASSERT (after changing from perl to C comment markers - doh!), on the filesystems where I was previously seeing the problem per openzfs#1978, and saw no corruptions (and, obviously, no ASSERTs).