static int lfs_pcc_detach(int argc, char **argv);
static int lfs_pcc_detach_fid(int argc, char **argv);
static int lfs_pcc_state(int argc, char **argv);
+static int lfs_pcc_delete(int argc, char **argv);
static int lfs_pcc(int argc, char **argv);
static int lfs_pcc_list_commands(int argc, char **argv);
static int lfs_migrate_to_dom(int fd, int fdv, char *name,
{ .pc_name = "detach_fid", .pc_func = lfs_pcc_detach_fid,
.pc_help = "Detach given files from PCC by FID(s).\n"
"usage: lfs pcc detach_fid {--mnt|-m MOUNTPATH} FID...\n" },
+ { .pc_name = "delete", .pc_func = lfs_pcc_delete,
+ .pc_help = "Delete the PCC layout component for given files.\n"
+ "usage: lfs pcc delete <FILE> ...\n" },
{ .pc_name = "list-commands", .pc_func = lfs_pcc_list_commands,
.pc_help = "list commands supported by lfs pcc"},
{ .pc_name = "help", .pc_func = Parser_help, .pc_help = "help" },
* Flags for extending a mirrored file.
*/
enum mirror_flags {
- MF_NO_VERIFY = 0x1,
- MF_DESTROY = 0x2,
- MF_COMP_ID = 0x4,
- MF_COMP_POOL = 0x8,
+ MF_NO_VERIFY = 0x01,
+ MF_DESTROY = 0x02,
+ MF_COMP_ID = 0x04,
+ MF_COMP_POOL = 0x08,
+ MF_FOREIGN = 0x10,
};
/**
return rc;
}
+static int find_foreign_id(struct llapi_layout *layout, void *cbdata)
+{
+ uint32_t id;
+ int rc;
+
+ rc = llapi_layout_foreign_id_get(layout, &id);
+ if (rc < 0)
+ return rc;
+
+ if (rc == 0)
+ return LLAPI_LAYOUT_ITER_CONT;
+
+ *(uint32_t *)cbdata = id;
+ return LLAPI_LAYOUT_ITER_STOP;
+}
+
static int find_mirror_id(struct llapi_layout *layout, void *cbdata)
{
uint32_t id;
} else if (mflags & MF_COMP_ID) {
rc = llapi_layout_comp_iterate(layout, find_comp_id, &id);
mirror_id = mirror_id_of(id);
+ } else if (mflags & MF_FOREIGN) {
+ rc = llapi_layout_comp_iterate(layout, find_foreign_id, &id);
+ mirror_id = id;
} else {
rc = llapi_layout_comp_iterate(layout, find_mirror_id, &id);
mirror_id = id;
"error %s: file '%s' does not contain mirror with comp-id %u\n",
progname, fname, id);
goto free_layout;
+ } else if (mflags & MF_FOREIGN) {
+ fprintf(stderr,
+ "error %s: file '%s' does not contain foreign component\n",
+ progname, fname);
+ goto free_layout;
} else {
fprintf(stderr,
"error %s: file '%s' does not contain mirror with id %u\n",
return rc;
}
+static int lfs_pcc_delete(int argc, char **argv)
+{
+ int rc = 0;
+ const char *path;
+
+ optind = 1;
+
+ if (argc <= 1) {
+ fprintf(stderr, "%s: must specify one or more file names\n",
+ argv[0]);
+ return CMD_HELP;
+ }
+
+ while (optind < argc) {
+ int rc2;
+
+ path = argv[optind++];
+ rc2 = mirror_split(path, 0, NULL,
+ MF_DESTROY | MF_FOREIGN, NULL);
+ if (rc2 < 0) {
+ if (rc == 0)
+ rc = rc2;
+ fprintf(stderr,
+ "%s: failed to delete PCC for '%s': %s\n",
+ argv[0], path, strerror(-rc2));
+ continue;
+ }
+ }
+
+ return rc;
+}
+
/**
* lfs_pcc_list_commands() - List lfs pcc commands.
* @argc: The count of command line arguments.
}
/**
+ * Return the mirror id of the foreign layout component if existed.
+ *
+ * \param[in] layout the layout component
+ * \param[out] id stored the returned mirror ID
+ *
+ * \retval 1 on success
+ * \retval 0 the current component is not a foreign component
+ * \retval <0 if error occurs
+ */
+int llapi_layout_foreign_id_get(const struct llapi_layout *layout, uint32_t *id)
+{
+ struct llapi_layout_comp *comp;
+
+ comp = __llapi_layout_cur_comp(layout);
+ if (comp == NULL)
+ return -1;
+
+ if (id == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (comp->llc_pattern == LLAPI_LAYOUT_FOREIGN) {
+ *id = mirror_id_of(comp->llc_id);
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
* Adds a component to \a layout, the new component will be added to
* the tail of components list and it'll inherit attributes of existing
* ones. The \a layout will change it's current component pointer to