From 355a8077750078145d96e4a9589eb73b662bec16 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 13 Feb 2013 18:12:20 +0100 Subject: [PATCH] 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 --- src/csync_dbtree.c | 3 +++ src/csync_propagate.c | 28 ++++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/csync_dbtree.c b/src/csync_dbtree.c index ba0317848..49581801f 100644 --- a/src/csync_dbtree.c +++ b/src/csync_dbtree.c @@ -125,6 +125,9 @@ csync_vio_method_handle_t *csync_dbtree_opendir(CSYNC *ctx, const char *name) } 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->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE; diff --git a/src/csync_propagate.c b/src/csync_propagate.c index 85da92d89..0ce19af67 100644 --- a/src/csync_propagate.c +++ b/src/csync_propagate.c @@ -1079,6 +1079,27 @@ out: 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) { c_list_t *list = NULL; char errbuf[256] = {0}; @@ -1150,13 +1171,13 @@ static int _csync_remove_dir(CSYNC *ctx, csync_file_stat_t *st) { rc = 0; out: - SAFE_FREE(uri); /* set instruction for the statedb merger */ if (rc != 0) { - st->instruction = CSYNC_INSTRUCTION_NONE; + _csync_remove_error(ctx, st, uri); } + SAFE_FREE(uri); return rc; } @@ -1352,8 +1373,7 @@ static int _csync_propagation_cleanup(CSYNC *ctx) { } if (csync_vio_rmdir(ctx, dir) < 0) { - /* Write it back to statedb, that we try to delete it next time. */ - st->instruction = CSYNC_INSTRUCTION_NONE; + _csync_remove_error(ctx, st, uri); } else { st->instruction = CSYNC_INSTRUCTION_DELETED; }