/* * remove_hdrs_replica -- (internal) remove headers from the replica */ static int remove_hdrs_replica(struct pool_set *set_in, struct pool_set *set_out, unsigned repn) { LOG(3, "set %p, repn %u", set_in, repn); int ret = 0; /* open all part files of the input replica */ if (replica_open_replica_part_files(set_in, repn)) { LOG(1, "opening replica %u, part files failed", repn); ret = -1; goto out; } /* share part file descriptors between poolset structures */ copy_part_fds(set_out, set_in); /* map the whole input replica */ if (util_replica_open(set_in, repn, MAP_SHARED)) { LOG(1, "opening input replica failed: replica %u", repn); ret = -1; goto out_close; } /* map the whole output replica */ if (util_replica_open(set_out, repn, MAP_SHARED)) { LOG(1, "opening output replica failed: replica %u", repn); ret = -1; goto out_unmap_in; } /* move data between the two mappings of the replica */ if (REP(set_in, repn)->nparts > 1) copy_replica_data_fw(set_out, set_in, repn); /* make changes to the first part's header */ update_replica_header(set_out, repn); util_replica_close(set_out, repn); out_unmap_in: util_replica_close(set_in, repn); out_close: util_replica_fdclose(REP(set_in, repn)); out: return ret; }
/* * replica_open_replica_part_files -- open all part files for a replica */ int replica_open_replica_part_files(struct pool_set *set, unsigned repn) { struct pool_replica *rep = set->replica[repn]; for (unsigned p = 0; p < rep->nparts; ++p) { /* skip already opened files */ if (rep->part[p].fd != -1) continue; if (util_part_open(&rep->part[p], 0, 0)) { LOG(1, "part files open failed for replica %u, part %u", repn, p); errno = EINVAL; goto err; } } return 0; err: util_replica_fdclose(set->replica[repn]); return -1; }
/* * add_hdrs_replica -- (internal) add lacking headers to the replica * * when the operation fails and returns -1, the replica remains untouched */ static int add_hdrs_replica(struct pool_set *set_in, struct pool_set *set_out, unsigned repn) { LOG(3, "set %p, repn %u", set_in, repn); int ret = 0; /* open all part files of the input replica */ if (replica_open_replica_part_files(set_in, repn)) { LOG(1, "opening replica %u, part files failed", repn); ret = -1; goto out; } /* share part file descriptors between poolset structures */ copy_part_fds(set_out, set_in); /* map the whole input replica */ if (util_replica_open(set_in, repn, MAP_SHARED)) { LOG(1, "opening input replica failed: replica %u", repn); ret = -1; goto out_close; } /* map the whole output replica */ if (util_replica_open(set_out, repn, MAP_SHARED)) { LOG(1, "opening output replica failed: replica %u", repn); ret = -1; goto out_unmap_in; } /* generate new uuids for lacking headers */ if (fill_replica_struct_uuids(set_out, repn)) { LOG(1, "generating lacking uuids for parts failed: replica %u", repn); ret = -1; goto out_unmap_out; } /* copy data between the two mappings of the replica */ if (REP(set_in, repn)->nparts > 1) copy_replica_data_bw(set_out, set_in, repn); /* create the missing headers */ if (create_missing_headers(set_out, repn)) { LOG(1, "creating lacking headers failed: replica %u", repn); /* * copy the data back, so we could fall back to the original * state */ if (REP(set_in, repn)->nparts > 1) copy_replica_data_fw(set_in, set_out, repn); ret = -1; goto out_unmap_out; } /* make changes to the first part's header */ update_replica_header(set_out, repn); /* store new uuids in all headers and update linkage in the replica */ update_uuids(set_out, repn); out_unmap_out: util_replica_close(set_out, repn); out_unmap_in: util_replica_close(set_in, repn); out_close: util_replica_fdclose(REP(set_in, repn)); out: return ret; }