+static int att_logical_or(struct osl_row *row, void *data)
+{
+ uint64_t *att_mask = data;
+ struct osl_object bitnum_obj;
+ int ret = osl_get_object(attribute_table, row, ATTCOL_BITNUM, &bitnum_obj);
+
+ if (ret < 0)
+ return ret;
+ *att_mask |= 1 << *(unsigned char *)bitnum_obj.data;
+ return 0;
+}
+
+/**
+ * Compute the attribute bit mask and check each afs info bitmap.
+ *
+ * \param aca The query field of \a aca is ignored.
+ *
+ * This iterates over all attributes in the attribute table and computes the
+ * logical or of 1 << b where b is the bit number of the attribute. The
+ * resulting bit mask is passed to aft_check_attributes() which performs the
+ * actual check.
+ *
+ * \return Standard.
+ *
+ * \sa \ref aft_check_attributes().
+ */
+int attribute_check_callback(struct afs_callback_arg *aca)
+{
+ int ret;
+ uint64_t att_mask = 0; /* bits corresponding to a attributes */
+
+ ret = osl_rbtree_loop(attribute_table, ATTCOL_BITNUM, &att_mask,
+ att_logical_or);
+ if (ret < 0) {
+ PARA_ERROR_LOG("attribute table loop failed: %s\n",
+ para_strerror(-ret));
+ return ret;
+ }
+ return aft_check_attributes(att_mask, &aca->pbout);
+}
+