+static void com_rmblob_callback(struct osl_table *table, int fd,
+ const struct osl_object *query)
+{
+ int ret, ret2 = 0;
+ struct rmblob_data rmbd = {
+ .pb = {
+ .max_size = shm_get_shmmax(),
+ .private_data = &fd,
+ .max_size_handler = pass_buffer_as_shm
+ }
+ };
+ struct pattern_match_data pmd = {
+ .table = table,
+ .patterns = *query,
+ .loop_col_num = BLOBCOL_NAME,
+ .match_col_num = BLOBCOL_NAME,
+ .pm_flags = PM_SKIP_EMPTY_NAME,
+ .data = &rmbd,
+ .action = remove_blob
+ };
+ ret = for_each_matching_row(&pmd);
+ if (ret < 0) {
+ ret2 = para_printf(&rmbd.pb, "%s\n", para_strerror(-ret));
+ if (ret2 < 0)
+ goto out;
+ }
+ if (pmd.num_matches == 0)
+ ret2 = para_printf(&rmbd.pb, "no matches, nothing removed\n");
+ else {
+ ret2 = para_printf(&rmbd.pb, "removed %d blobs\n", pmd.num_matches);
+ afs_event(BLOB_RENAME, NULL, table);
+ }
+out:
+ if (ret2 >= 0 && rmbd.pb.offset)
+ pass_buffer_as_shm(rmbd.pb.buf, rmbd.pb.offset, &fd);
+ free(rmbd.pb.buf);
+}
+
+static int com_rmblob(callback_function *f, struct command_context *cc)
+{
+ if (cc->argc < 2)
+ return -E_MOOD_SYNTAX;
+ return send_option_arg_callback_request(NULL, cc->argc - 1, cc->argv + 1, f,
+ sc_send_result, cc);
+}
+
+static void com_addblob_callback(struct osl_table *table, __a_unused int fd,
+ const struct osl_object *query)