+/*
+ * Given the attributes listed in asp and those supported
+ * in the vap, fixup the asp attributes to reflect any
+ * missing attributes from the file system
+ */
+static void
+getattrlist_fixupattrs(attribute_set_t *asp, struct vnode_attr *vap)
+{
+ struct getattrlist_attrtab *tab;
+
+ if (asp->commonattr) {
+ tab = getattrlist_common_tab;
+ do {
+ /*
+ * This if() statement is slightly confusing. We're trying to
+ * iterate through all of the bits listed in the array
+ * getattr_common_tab, and see if the filesystem was expected
+ * to support it, and whether or not we need to do anything about this.
+ *
+ * This array is full of structs that have 4 fields (attr, bits, size, action).
+ * The first is used to store the ATTR_CMN_* bit that was being requested
+ * from userland. The second stores the VATTR_BIT corresponding to the field
+ * filled in vnode_attr struct. If it is 0, then we don't typically expect
+ * the filesystem to fill in this field. The third is the size of the field,
+ * and the fourth is the type of kauth actions needed.
+ *
+ * So, for all of the ATTR_CMN bits listed in this array, we iterate through
+ * them, and check to see if it was both passed down to the filesystem via the
+ * va_active bitfield, and whether or not we expect it to be emitted from
+ * the filesystem. If it wasn't supported, then we un-twiddle the bit and move
+ * on. This is done so that we can uncheck those bits and re-request
+ * a vnode_getattr from the filesystem again.
+ */
+ if ((tab->attr & asp->commonattr) &&
+ (tab->bits & vap->va_active) &&
+ (tab->bits & vap->va_supported) == 0) {
+ asp->commonattr &= ~tab->attr;
+ }
+ } while ((++tab)->attr != 0);
+ }
+ if (asp->dirattr) {
+ tab = getattrlist_dir_tab;
+ do {
+ if ((tab->attr & asp->dirattr) &&
+ (tab->bits & vap->va_active) &&
+ (vap->va_supported & tab->bits) == 0) {
+ asp->dirattr &= ~tab->attr;
+ }
+ } while ((++tab)->attr != 0);
+ }
+ if (asp->fileattr) {
+ tab = getattrlist_file_tab;
+ do {
+ if ((tab->attr & asp->fileattr) &&
+ (tab->bits & vap->va_active) &&
+ (vap->va_supported & tab->bits) == 0) {
+ asp->fileattr &= ~tab->attr;
+ }
+ } while ((++tab)->attr != 0);
+ }
+}
+