am 0de2351e: Merge "Don\'t remove existing explicitly stashed blocks"
* commit '0de2351e6a6be685e1d68661dcf5f4902898cacd': Don't remove existing explicitly stashed blocks
This commit is contained in:
+28
-10
@@ -635,12 +635,13 @@ lsout:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int WriteStash(const char* base, const char* id, int blocks, uint8_t* buffer,
|
static int WriteStash(const char* base, const char* id, int blocks, uint8_t* buffer,
|
||||||
int checkspace) {
|
int checkspace, int *exists) {
|
||||||
char *fn = NULL;
|
char *fn = NULL;
|
||||||
char *cn = NULL;
|
char *cn = NULL;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
int res;
|
int res;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
if (base == NULL || buffer == NULL) {
|
if (base == NULL || buffer == NULL) {
|
||||||
goto wsout;
|
goto wsout;
|
||||||
@@ -658,6 +659,22 @@ static int WriteStash(const char* base, const char* id, int blocks, uint8_t* buf
|
|||||||
goto wsout;
|
goto wsout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (exists) {
|
||||||
|
res = stat(cn, &st);
|
||||||
|
|
||||||
|
if (res == 0) {
|
||||||
|
// The file already exists and since the name is the hash of the contents,
|
||||||
|
// it's safe to assume the contents are identical (accidental hash collisions
|
||||||
|
// are unlikely)
|
||||||
|
fprintf(stderr, " skipping %d existing blocks in %s\n", blocks, cn);
|
||||||
|
*exists = 1;
|
||||||
|
rc = 0;
|
||||||
|
goto wsout;
|
||||||
|
}
|
||||||
|
|
||||||
|
*exists = 0;
|
||||||
|
}
|
||||||
|
|
||||||
fprintf(stderr, " writing %d blocks to %s\n", blocks, cn);
|
fprintf(stderr, " writing %d blocks to %s\n", blocks, cn);
|
||||||
|
|
||||||
fd = TEMP_FAILURE_RETRY(open(fn, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, STASH_FILE_MODE));
|
fd = TEMP_FAILURE_RETRY(open(fn, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, STASH_FILE_MODE));
|
||||||
@@ -821,7 +838,7 @@ static int SaveStash(const char* base, char** wordsave, uint8_t** buffer, size_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "stashing %d blocks to %s\n", blocks, id);
|
fprintf(stderr, "stashing %d blocks to %s\n", blocks, id);
|
||||||
return WriteStash(base, id, blocks, *buffer, 0);
|
return WriteStash(base, id, blocks, *buffer, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int FreeStash(const char* base, const char* id) {
|
static int FreeStash(const char* base, const char* id) {
|
||||||
@@ -997,6 +1014,7 @@ static int LoadSrcTgtVersion3(CommandParameters* params, RangeSet** tgt, int* sr
|
|||||||
int onehash, int* overlap) {
|
int onehash, int* overlap) {
|
||||||
char* srchash = NULL;
|
char* srchash = NULL;
|
||||||
char* tgthash = NULL;
|
char* tgthash = NULL;
|
||||||
|
int stash_exists = 0;
|
||||||
int overlap_blocks = 0;
|
int overlap_blocks = 0;
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
uint8_t* tgtbuffer = NULL;
|
uint8_t* tgtbuffer = NULL;
|
||||||
@@ -1052,13 +1070,16 @@ static int LoadSrcTgtVersion3(CommandParameters* params, RangeSet** tgt, int* sr
|
|||||||
fprintf(stderr, "stashing %d overlapping blocks to %s\n", *src_blocks,
|
fprintf(stderr, "stashing %d overlapping blocks to %s\n", *src_blocks,
|
||||||
srchash);
|
srchash);
|
||||||
|
|
||||||
if (WriteStash(params->stashbase, srchash, *src_blocks, params->buffer, 1) != 0) {
|
if (WriteStash(params->stashbase, srchash, *src_blocks, params->buffer, 1,
|
||||||
|
&stash_exists) != 0) {
|
||||||
fprintf(stderr, "failed to stash overlapping source blocks\n");
|
fprintf(stderr, "failed to stash overlapping source blocks\n");
|
||||||
goto v3out;
|
goto v3out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can be deleted when the write has completed
|
// Can be deleted when the write has completed
|
||||||
params->freestash = srchash;
|
if (!stash_exists) {
|
||||||
|
params->freestash = srchash;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Source blocks have expected content, command can proceed
|
// Source blocks have expected content, command can proceed
|
||||||
@@ -1068,12 +1089,9 @@ static int LoadSrcTgtVersion3(CommandParameters* params, RangeSet** tgt, int* sr
|
|||||||
|
|
||||||
if (*overlap && LoadStash(params->stashbase, srchash, 1, NULL, ¶ms->buffer,
|
if (*overlap && LoadStash(params->stashbase, srchash, 1, NULL, ¶ms->buffer,
|
||||||
¶ms->bufsize, 1) == 0) {
|
¶ms->bufsize, 1) == 0) {
|
||||||
// Overlapping source blocks were previously stashed, command can proceed
|
// Overlapping source blocks were previously stashed, command can proceed.
|
||||||
if (params->canwrite) {
|
// We are recovering from an interrupted command, so we don't know if the
|
||||||
// We didn't create the stash, so delete after write only if we will
|
// stash can safely be deleted after this command.
|
||||||
// actually perform the write
|
|
||||||
params->freestash = srchash;
|
|
||||||
}
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
goto v3out;
|
goto v3out;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user