[Pkg-owncloud-commits] [owncloud-client] 22/70: Maintain the original inode value for renamed files.
Sandro Knauß
hefee-guest at moszumanska.debian.org
Sat May 17 20:01:26 UTC 2014
This is an automated email from the git hooks/post-receive script.
hefee-guest pushed a commit to branch master
in repository owncloud-client.
commit a50c39cd0cdb495868766bf4047dbd3a16498c67
Author: Klaas Freitag <freitag at owncloud.com>
Date: Tue May 6 12:55:54 2014 +0200
Maintain the original inode value for renamed files.
In case two renames are done on the same file/folder very quickly we
lost the information that the second operation was also a rename. That
was because we tried to get the inode value from a stat on the file once
the first rename was finished. But at that point, the file was already
gone because of the second rename.
Now the original inode is kept and written to db in case the file can
not be stat'ed.
This fixes bug #1737
---
csync/src/csync.c | 1 +
csync/src/csync.h | 1 +
csync/src/csync_reconcile.c | 3 ++-
csync/src/csync_update.c | 2 ++
src/mirall/syncengine.cpp | 2 ++
src/mirall/syncfileitem.h | 1 +
src/mirall/syncjournalfilerecord.cpp | 16 ++++++++++------
7 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/csync/src/csync.c b/csync/src/csync.c
index 9a3ba6c..484e165 100644
--- a/csync/src/csync.c
+++ b/csync/src/csync.c
@@ -444,6 +444,7 @@ static int _csync_treewalk_visitor(void *obj, void *data) {
trav.rename_path = cur->destpath;
trav.etag = cur->etag;
trav.file_id = cur->file_id;
+ trav.inode = cur->inode;
trav.error_status = cur->error_status;
trav.should_update_etag = cur->should_update_etag;
diff --git a/csync/src/csync.h b/csync/src/csync.h
index 1d83ada..d15ac66 100644
--- a/csync/src/csync.h
+++ b/csync/src/csync.h
@@ -170,6 +170,7 @@ enum csync_notify_type_e {
struct csync_tree_walk_file_s {
const char *path;
int64_t size;
+ int64_t inode;
time_t modtime;
#ifdef _WIN32
uint32_t uid;
diff --git a/csync/src/csync_reconcile.c b/csync/src/csync_reconcile.c
index 649b322..8cddd0a 100644
--- a/csync/src/csync_reconcile.c
+++ b/csync/src/csync_reconcile.c
@@ -183,6 +183,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
if( !c_streq(cur->file_id, "") ) {
csync_vio_set_file_id( other->file_id, cur->file_id );
}
+ other->inode = cur->inode;
cur->instruction = CSYNC_INSTRUCTION_NONE;
} else if (other->instruction == CSYNC_INSTRUCTION_REMOVE) {
other->instruction = CSYNC_INSTRUCTION_RENAME;
@@ -191,7 +192,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
if( !c_streq(cur->file_id, "") ) {
csync_vio_set_file_id( other->file_id, cur->file_id );
}
-
+ other->inode = cur->inode;
cur->instruction = CSYNC_INSTRUCTION_NONE;
} else if (other->instruction == CSYNC_INSTRUCTION_NEW) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "OOOO=> NEW detected in other tree!");
diff --git a/csync/src/csync_update.c b/csync/src/csync_update.c
index 0378e6a..444f11c 100644
--- a/csync/src/csync_update.c
+++ b/csync/src/csync_update.c
@@ -276,6 +276,8 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
/* check if it's a file and has been renamed */
if (ctx->current == LOCAL_REPLICA) {
+ CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Checking for rename based on inode # %" PRId64 "", (uint64_t) fs->inode);
+
tmp = csync_statedb_get_stat_by_inode(ctx, fs->inode);
/* translate the file type between the two stat types csync has. */
diff --git a/src/mirall/syncengine.cpp b/src/mirall/syncengine.cpp
index 1549dc0..14e42aa 100644
--- a/src/mirall/syncengine.cpp
+++ b/src/mirall/syncengine.cpp
@@ -292,6 +292,8 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
item._modtime = file->modtime;
item._etag = file->etag;
item._size = file->size;
+ item._inode = file->inode;
+
item._should_update_etag = file->should_update_etag;
switch( file->type ) {
case CSYNC_FTW_TYPE_DIR:
diff --git a/src/mirall/syncfileitem.h b/src/mirall/syncfileitem.h
index fa88e49..e062cae 100644
--- a/src/mirall/syncfileitem.h
+++ b/src/mirall/syncfileitem.h
@@ -83,6 +83,7 @@ public:
time_t _modtime;
QByteArray _etag;
quint64 _size;
+ quint64 _inode;
bool _should_update_etag;
QByteArray _fileId;
bool _blacklistedInDb;
diff --git a/src/mirall/syncjournalfilerecord.cpp b/src/mirall/syncjournalfilerecord.cpp
index 317643c..b501482 100644
--- a/src/mirall/syncjournalfilerecord.cpp
+++ b/src/mirall/syncjournalfilerecord.cpp
@@ -36,15 +36,20 @@ SyncJournalFileRecord::SyncJournalFileRecord(const SyncFileItem &item, const QSt
_type(item._type), _etag(item._etag), _fileId(item._fileId),
_uid(0), _gid(0), _mode(0)
{
+ // use the "old" inode coming with the item for the case where the
+ // filesystem stat fails. That can happen if the the file was removed
+ // or renamed meanwhile. For the rename case we still need the inode to
+ // detect the rename tough.
+ _inode = item._inode;
- // Query the inode:
- // based on code from csync_vio_local.c (csync_vio_local_stat)
#ifdef Q_OS_WIN
- /* Get the Windows file id as an inode replacement. */
+ /* Query the inode:
+ based on code from csync_vio_local.c (csync_vio_local_stat)
+ Get the Windows file id as an inode replacement. */
HANDLE h = CreateFileW( (wchar_t*)localFileName.utf16(), 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL+FILE_FLAG_BACKUP_SEMANTICS, NULL );
+
if( h == INVALID_HANDLE_VALUE ) {
- _inode = 0;
qWarning() << "Failed to query the 'inode' because CreateFileW failed for file " << localFileName;
} else {
BY_HANDLE_FILE_INFORMATION fileInfo;
@@ -60,7 +65,7 @@ SyncJournalFileRecord::SyncJournalFileRecord(const SyncFileItem &item, const QSt
_inode = FileIndex.QuadPart;
} else {
qWarning() << "Failed to query the 'inode' for file " << localFileName;
- _inode = 0;
+
}
CloseHandle(h);
}
@@ -68,7 +73,6 @@ SyncJournalFileRecord::SyncJournalFileRecord(const SyncFileItem &item, const QSt
struct stat sb;
if( stat(QFile::encodeName(localFileName).constData(), &sb) < 0) {
qWarning() << "Failed to query the 'inode' for file " << localFileName;
- _inode = 0;
} else {
_inode = sb.st_ino;
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud-client.git
More information about the Pkg-owncloud-commits
mailing list