Fix removing of folder when the folder is locked on windows.

When the folder is locked on windows, rmdir fails and the folmder is not
removed.  But on the next sync, one should try to remove that folder again, and
not upload it to the server as we did before.

There was two problems:

1- The removed folder is still in the DB, so when csync_update read from
DB, for the remote, it still finds it.  Fix that by storing an empty MD5
for directories that should have been deleted.

2- The folder is likely to be modified since its contents are gone.
Which means next sync will try to sync it back to the server.
Fix that by refreshing the mtime in the tree
This commit is contained in:
Olivier Goffart 2013-02-13 18:12:20 +01:00
parent b028c64325
commit 355a807775
2 changed files with 27 additions and 4 deletions

View file

@ -125,6 +125,9 @@ csync_vio_method_handle_t *csync_dbtree_opendir(CSYNC *ctx, const char *name)
} }
if( cnt < tpath_len ) continue; if( cnt < tpath_len ) continue;
if (!list->vector[base+8][0])
continue; /* If md5 is empty, the file was removed on the server */
fs = csync_vio_file_stat_new(); fs = csync_vio_file_stat_new();
fs->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE; fs->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;

View file

@ -1079,6 +1079,27 @@ out:
return rc; return rc;
} }
/* If a remove operation failed, we need to update the st so the information
that will be stored in the database will make it so that we try to remove
again on the next sync. */
static void _csync_remove_error(CSYNC *ctx, csync_file_stat_t *st, char *uri) {
/* Write it back to statedb, that we try to delete it next time. */
st->instruction = CSYNC_INSTRUCTION_NONE;
if (ctx->replica == LOCAL_REPLICA) {
/* Update the mtime */
csync_vio_file_stat_t* vst = csync_vio_file_stat_new();
if (csync_vio_stat(ctx, uri, vst) == 0) {
st->inode = vst->inode;
st->modtime = vst->mtime;
}
csync_vio_file_stat_destroy(vst);
/* don't write the md5 to the database */
SAFE_FREE(st->md5);
}
}
static int _csync_remove_dir(CSYNC *ctx, csync_file_stat_t *st) { static int _csync_remove_dir(CSYNC *ctx, csync_file_stat_t *st) {
c_list_t *list = NULL; c_list_t *list = NULL;
char errbuf[256] = {0}; char errbuf[256] = {0};
@ -1150,13 +1171,13 @@ static int _csync_remove_dir(CSYNC *ctx, csync_file_stat_t *st) {
rc = 0; rc = 0;
out: out:
SAFE_FREE(uri);
/* set instruction for the statedb merger */ /* set instruction for the statedb merger */
if (rc != 0) { if (rc != 0) {
st->instruction = CSYNC_INSTRUCTION_NONE; _csync_remove_error(ctx, st, uri);
} }
SAFE_FREE(uri);
return rc; return rc;
} }
@ -1352,8 +1373,7 @@ static int _csync_propagation_cleanup(CSYNC *ctx) {
} }
if (csync_vio_rmdir(ctx, dir) < 0) { if (csync_vio_rmdir(ctx, dir) < 0) {
/* Write it back to statedb, that we try to delete it next time. */ _csync_remove_error(ctx, st, uri);
st->instruction = CSYNC_INSTRUCTION_NONE;
} else { } else {
st->instruction = CSYNC_INSTRUCTION_DELETED; st->instruction = CSYNC_INSTRUCTION_DELETED;
} }