]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - attribute.c
afs: Make afs callbacks more flexible.
[paraslash.git] / attribute.c
index af1400c8a8e218d832d86cf0016a81388ab72f7b..313f7af9ccb322b691ad7fed4375cc5abd559456 100644 (file)
@@ -149,15 +149,15 @@ static int print_attribute(struct osl_table *table, struct osl_row *row,
        return 1;
 }
 
-static int com_lsatt_callback(int fd, const struct osl_object *query)
+static int com_lsatt_callback(struct afs_callback_arg *aca)
 {
        int ret;
        struct lsatt_action_data laad = {
-               .flags = *(unsigned *) query->data,
+               .flags = *(unsigned *)aca->query.data,
                .pb = {
                        .max_size = shm_get_shmmax(),
                        .private_data = &(struct afs_max_size_handler_data) {
-                               .fd = fd,
+                               .fd = aca->fd,
                                .band = SBD_OUTPUT
                        },
                        .max_size_handler = afs_max_size_handler
@@ -168,8 +168,8 @@ static int com_lsatt_callback(int fd, const struct osl_object *query)
                .table = attribute_table,
                .loop_col_num = ATTCOL_BITNUM,
                .match_col_num = ATTCOL_NAME,
-               .patterns = {.data = (char *)query->data + sizeof(laad.flags),
-                       .size = query->size - sizeof(laad.flags)},
+               .patterns = {.data = (char *)aca->query.data + sizeof(laad.flags),
+                       .size = aca->query.size - sizeof(laad.flags)},
                .pm_flags = PM_NO_PATTERN_MATCHES_EVERYTHING,
                .data = &laad,
                .action = print_attribute
@@ -225,21 +225,25 @@ struct addatt_event_data {
 };
 
 
-static int com_addatt_callback(int fd, const struct osl_object *query)
+static int com_addatt_callback(struct afs_callback_arg *aca)
 {
        char *p;
        int ret = 1;
        struct para_buffer pb = {
                .max_size = shm_get_shmmax(),
                .private_data = &(struct afs_max_size_handler_data) {
-                       .fd = fd,
+                       .fd = aca->fd,
                        .band = SBD_OUTPUT
                },
                .max_size_handler = afs_max_size_handler
        };
        size_t len;
 
-       for (p = query->data; p < (char *)query->data + query->size; p += len + 1) {
+       for (
+               p = aca->query.data;
+               p < (char *)aca->query.data + aca->query.size;
+               p += len + 1
+       ) {
                struct osl_object objs[NUM_ATT_COLUMNS];
                struct osl_row *row;
                unsigned char bitnum;
@@ -280,7 +284,9 @@ static int com_addatt_callback(int fd, const struct osl_object *query)
                        goto out;
                aed.name = p;
                aed.bitnum = bitnum;
-               afs_event(ATTRIBUTE_ADD, &pb, &aed);
+               ret = afs_event(ATTRIBUTE_ADD, &pb, &aed);
+               if (ret < 0)
+                       goto out;
                greatest_att_bitnum = PARA_MAX(greatest_att_bitnum, (int)bitnum);
        }
 out:
@@ -303,9 +309,9 @@ int com_addatt(struct command_context *cc)
        return ret;
 }
 
-static int com_mvatt_callback(int fd, const struct osl_object *query)
+static int com_mvatt_callback(struct afs_callback_arg *aca)
 {
-       char *old = query->data;
+       char *old = aca->query.data;
        size_t size = strlen(old) + 1;
        char *new = old + size;
        struct osl_object obj = {.data = old, .size = size};
@@ -313,7 +319,7 @@ static int com_mvatt_callback(int fd, const struct osl_object *query)
        struct para_buffer pb = {
                .max_size = shm_get_shmmax(),
                .private_data = &(struct afs_max_size_handler_data) {
-                       .fd = fd,
+                       .fd = aca->fd,
                        .band = SBD_OUTPUT
                },
                .max_size_handler = afs_max_size_handler,
@@ -330,7 +336,7 @@ out:
        if (ret < 0)
                para_printf(&pb, "cannot rename %s to %s\n", old, new);
        else
-               afs_event(ATTRIBUTE_RENAME, &pb, NULL);
+               ret = afs_event(ATTRIBUTE_RENAME, &pb, NULL);
        flush_and_free_pb(&pb);
        return ret;
 }
@@ -361,16 +367,15 @@ static int remove_attribute(struct osl_table *table, struct osl_row *row,
                para_printf(pb, "cannot remove %s\n", name);
                return ret;
        }
-       afs_event(ATTRIBUTE_REMOVE, pb, &red);
-       return 1;
+       return afs_event(ATTRIBUTE_REMOVE, pb, &red);
 }
 
-static int com_rmatt_callback(int fd, const struct osl_object *query)
+static int com_rmatt_callback(struct afs_callback_arg *aca)
 {
        struct para_buffer pb = {
                .max_size = shm_get_shmmax(),
                .private_data = &(struct afs_max_size_handler_data) {
-                       .fd = fd,
+                       .fd = aca->fd,
                        .band = SBD_OUTPUT
                },
                .max_size_handler = afs_max_size_handler,
@@ -378,7 +383,7 @@ static int com_rmatt_callback(int fd, const struct osl_object *query)
        int ret;
        struct pattern_match_data pmd = {
                .table = attribute_table,
-               .patterns = *query,
+               .patterns = aca->query,
                .loop_col_num = ATTCOL_BITNUM,
                .match_col_num = ATTCOL_NAME,
                .data = &pb,
@@ -475,6 +480,57 @@ err:
        return ret;
 }
 
+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 */
+       struct para_buffer pb = {
+               .max_size = shm_get_shmmax(),
+               .private_data = &(struct afs_max_size_handler_data) {
+                       .fd = aca->fd,
+                       .band = SBD_OUTPUT
+               },
+               .max_size_handler = afs_max_size_handler,
+       };
+
+       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;
+       }
+       ret = aft_check_attributes(att_mask, &pb);
+       flush_and_free_pb(&pb);
+       return ret;
+}
+
 /**
  * Close the attribute table.
  *