mirror of
https://github.com/nextcloud/desktop.git
synced 2024-10-24 05:15:40 +03:00
Journal: Don't use a ._ path if it won't work #5633
When synchronizing a folder on a samba share, creating files that begin with ._ is often forbidden. This prevented the client from creating its ._sync_abcdef.db file. Now, it'll check whether the preferred filename is creatable, and if it isn't it'll use .sync_abcdef.db instead. The disadvantage is that this alternative path won't be ignored by older clients - that was the reason for the ._ prefix.
This commit is contained in:
parent
b50706a7aa
commit
4291ea47f7
8 changed files with 73 additions and 8 deletions
|
@ -235,6 +235,11 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
|
|||
match = CSYNC_FILE_SILENTLY_EXCLUDED;
|
||||
goto out;
|
||||
}
|
||||
rc = csync_fnmatch(".sync_*.db*", bname, 0);
|
||||
if (rc == 0) {
|
||||
match = CSYNC_FILE_SILENTLY_EXCLUDED;
|
||||
goto out;
|
||||
}
|
||||
rc = csync_fnmatch(".csync_journal.db*", bname, 0);
|
||||
if (rc == 0) {
|
||||
match = CSYNC_FILE_SILENTLY_EXCLUDED;
|
||||
|
|
|
@ -157,7 +157,16 @@ static void check_csync_excluded(void **state)
|
|||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "subdir/._sync_5bdd60bdfcfa.db", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
|
||||
|
||||
rc = csync_excluded_no_ctx(csync->excludes, ".sync_5bdd60bdfcfa.db", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, ".sync_5bdd60bdfcfa.db.ctmp", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, ".sync_5bdd60bdfcfa.db-shm", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "subdir/.sync_5bdd60bdfcfa.db", CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
|
||||
|
||||
|
||||
/* pattern ]*.directory - ignore and remove */
|
||||
rc = csync_excluded_no_ctx(csync->excludes, "my.~directory", CSYNC_FTW_TYPE_FILE);
|
||||
|
|
|
@ -469,7 +469,7 @@ restart_sync:
|
|||
}
|
||||
|
||||
Cmd cmd;
|
||||
QString dbPath = options.source_dir + SyncJournalDb::makeDbName(credentialFreeUrl, folder, user);
|
||||
QString dbPath = options.source_dir + SyncJournalDb::makeDbName(options.source_dir, credentialFreeUrl, folder, user);
|
||||
SyncJournalDb db(dbPath);
|
||||
|
||||
if (!selectiveSyncList.empty()) {
|
||||
|
|
|
@ -1003,7 +1003,7 @@ QString FolderDefinition::absoluteJournalPath() const
|
|||
|
||||
QString FolderDefinition::defaultJournalPath(AccountPtr account)
|
||||
{
|
||||
return SyncJournalDb::makeDbName(account->url(), targetPath, account->credentials()->user());
|
||||
return SyncJournalDb::makeDbName(localPath, account->url(), targetPath, account->credentials()->user());
|
||||
}
|
||||
|
||||
} // namespace OCC
|
||||
|
|
|
@ -235,11 +235,22 @@ void FolderMan::setupFoldersHelper(QSettings &settings, AccountStatePtr account,
|
|||
foreach (const auto& folderAlias, settings.childGroups()) {
|
||||
FolderDefinition folderDefinition;
|
||||
if (FolderDefinition::load(settings, folderAlias, &folderDefinition)) {
|
||||
auto defaultJournalPath = folderDefinition.defaultJournalPath(account->account());
|
||||
|
||||
// Migration: Old settings don't have journalPath
|
||||
if (folderDefinition.journalPath.isEmpty()) {
|
||||
folderDefinition.journalPath = folderDefinition.defaultJournalPath(account->account());
|
||||
folderDefinition.journalPath = defaultJournalPath;
|
||||
}
|
||||
folderDefinition.defaultJournalPath(account->account());
|
||||
|
||||
// Migration: ._ files sometimes don't work
|
||||
// So if the configured journalPath is the default one ("._sync_*.db")
|
||||
// but the current default doesn't have the underscore, switch to the
|
||||
// new default. See SyncJournalDb::makeDbName().
|
||||
if (folderDefinition.journalPath.startsWith("._sync_")
|
||||
&& defaultJournalPath.startsWith(".sync_")) {
|
||||
folderDefinition.journalPath = defaultJournalPath;
|
||||
}
|
||||
|
||||
// Migration: If an old db is found, move it to the new name.
|
||||
if (backwardsCompatible) {
|
||||
SyncJournalDb::maybeMigrateDb(folderDefinition.localPath, folderDefinition.absoluteJournalPath());
|
||||
|
|
|
@ -171,7 +171,8 @@ void FolderWatcherPrivate::slotReceivedNotification(int fd)
|
|||
// qDebug() << Q_FUNC_INFO << event->name;
|
||||
if (fileName.startsWith("._sync_") ||
|
||||
fileName.startsWith(".csync_journal.db") ||
|
||||
fileName.startsWith(".owncloudsync.log")) {
|
||||
fileName.startsWith(".owncloudsync.log") ||
|
||||
fileName.startsWith(".sync_")) {
|
||||
// qDebug() << "ignore journal";
|
||||
} else {
|
||||
const QString p = _watches[event->wd] + '/' + fileName;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <QDebug>
|
||||
#include <QElapsedTimer>
|
||||
#include <QUrl>
|
||||
#include <QDir>
|
||||
|
||||
#include "ownsql.h"
|
||||
|
||||
|
@ -41,7 +42,8 @@ SyncJournalDb::SyncJournalDb(const QString& dbFilePath, QObject *parent) :
|
|||
|
||||
}
|
||||
|
||||
QString SyncJournalDb::makeDbName(const QUrl& remoteUrl,
|
||||
QString SyncJournalDb::makeDbName(const QString& localPath,
|
||||
const QUrl& remoteUrl,
|
||||
const QString& remotePath,
|
||||
const QString& user)
|
||||
{
|
||||
|
@ -56,6 +58,42 @@ QString SyncJournalDb::makeDbName(const QUrl& remoteUrl,
|
|||
journalPath.append( ba.left(6).toHex() );
|
||||
journalPath.append(".db");
|
||||
|
||||
// If the journal doesn't exist and we can't create a file
|
||||
// at that location, try again with a journal name that doesn't
|
||||
// have the ._ prefix.
|
||||
//
|
||||
// The disadvantage of that filename is that it will only be ignored
|
||||
// by client versions >2.3.2.
|
||||
//
|
||||
// See #5633: "._*" is often forbidden on samba shared folders.
|
||||
|
||||
// If it exists already, the path is clearly usable
|
||||
QFile file(QDir(localPath).filePath(journalPath));
|
||||
if (file.exists()) {
|
||||
return journalPath;
|
||||
}
|
||||
|
||||
// Try to create a file there
|
||||
if (file.open(QIODevice::ReadWrite)) {
|
||||
// Ok, all good.
|
||||
file.close();
|
||||
file.remove();
|
||||
return journalPath;
|
||||
}
|
||||
|
||||
// Can we create it if we drop the underscore?
|
||||
QString alternateJournalPath = journalPath.mid(2).prepend(".");
|
||||
QFile file2(QDir(localPath).filePath(alternateJournalPath));
|
||||
if (file2.open(QIODevice::ReadWrite)) {
|
||||
// The alternative worked, use it
|
||||
qDebug() << "Using alternate database path" << alternateJournalPath;
|
||||
file2.close();
|
||||
file2.remove();
|
||||
return alternateJournalPath;
|
||||
}
|
||||
|
||||
// Neither worked, just keep the original and throw errors later
|
||||
qDebug() << "Could not find a writable database path" << file.fileName();
|
||||
return journalPath;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,8 @@ public:
|
|||
virtual ~SyncJournalDb();
|
||||
|
||||
/// Create a journal path for a specific configuration
|
||||
static QString makeDbName(const QUrl& remoteUrl,
|
||||
static QString makeDbName(const QString& localPath,
|
||||
const QUrl& remoteUrl,
|
||||
const QString& remotePath,
|
||||
const QString& user);
|
||||
|
||||
|
|
Loading…
Reference in a new issue