mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-26 06:55:59 +03:00
csync: Do not ignore hard links anymore
There is no reason to ignore them. Downloading a file that is hardlinked will break the link. Will solve syncing NTFS directories #3241
This commit is contained in:
parent
4a541a9ab4
commit
575ca50aac
7 changed files with 53 additions and 50 deletions
|
@ -100,7 +100,6 @@ enum csync_status_codes_e {
|
|||
CSYNC_STATUS_ABORTED,
|
||||
/* Codes for file individual status: */
|
||||
CSYNC_STATUS_INDIVIDUAL_IS_SYMLINK,
|
||||
CSYNC_STATUS_INDIVIDUAL_IS_HARDLINK,
|
||||
CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST,
|
||||
CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS,
|
||||
CSYNC_STATUS_INDIVIDUAL_EXCLUDE_LONG_FILENAME,
|
||||
|
@ -174,7 +173,7 @@ enum csync_vio_file_stat_fields_e {
|
|||
CSYNC_VIO_FILE_STAT_FIELDS_FLAGS = 1 << 2,
|
||||
CSYNC_VIO_FILE_STAT_FIELDS_DEVICE = 1 << 3,
|
||||
CSYNC_VIO_FILE_STAT_FIELDS_INODE = 1 << 4,
|
||||
CSYNC_VIO_FILE_STAT_FIELDS_LINK_COUNT = 1 << 5,
|
||||
// CSYNC_VIO_FILE_STAT_FIELDS_LINK_COUNT = 1 << 5,
|
||||
CSYNC_VIO_FILE_STAT_FIELDS_SIZE = 1 << 6,
|
||||
// CSYNC_VIO_FILE_STAT_FIELDS_BLOCK_COUNT = 1 << 7, /* will be removed */
|
||||
// CSYNC_VIO_FILE_STAT_FIELDS_BLOCK_SIZE = 1 << 8, /* will be removed */
|
||||
|
@ -213,7 +212,6 @@ struct csync_vio_file_stat_s {
|
|||
|
||||
dev_t device;
|
||||
uint64_t inode;
|
||||
nlink_t nlink;
|
||||
|
||||
int fields; // actually enum csync_vio_file_stat_fields_e fields;
|
||||
enum csync_vio_file_type_e type;
|
||||
|
|
|
@ -183,7 +183,6 @@ struct csync_file_stat_s {
|
|||
size_t pathlen; /* u64 */
|
||||
uint64_t inode; /* u64 */
|
||||
mode_t mode; /* u32 */
|
||||
int nlink; /* u32 */
|
||||
int type; /* u32 */
|
||||
int child_modified;/*bool*/
|
||||
int should_update_etag; /*bool */
|
||||
|
|
|
@ -210,11 +210,6 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
|
|||
|
||||
/* check hardlink count */
|
||||
if (type == CSYNC_FTW_TYPE_FILE ) {
|
||||
if( fs->nlink > 1) {
|
||||
st->instruction = CSYNC_INSTRUCTION_IGNORE;
|
||||
st->error_status = CSYNC_STATUS_INDIVIDUAL_IS_HARDLINK;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (fs->mtime == 0) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s - mtime is zero!", path);
|
||||
|
@ -442,7 +437,6 @@ out:
|
|||
st->mode = fs->mode;
|
||||
st->size = fs->size;
|
||||
st->modtime = fs->mtime;
|
||||
st->nlink = fs->nlink;
|
||||
st->type = type;
|
||||
st->etag = NULL;
|
||||
if( fs->etag ) {
|
||||
|
|
|
@ -338,9 +338,6 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
|
|||
buf->ctime = sb.st_ctime;
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME;
|
||||
|
||||
buf->nlink = sb.st_nlink;
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_LINK_COUNT;
|
||||
|
||||
buf->size = sb.st_size;
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
|
||||
|
||||
|
|
|
@ -167,7 +167,6 @@ static void teardown_rm(void **state) {
|
|||
/* create a file stat, caller must free memory */
|
||||
static csync_vio_file_stat_t* create_fstat(const char *name,
|
||||
ino_t inode,
|
||||
nlink_t nlink,
|
||||
time_t mtime)
|
||||
{
|
||||
csync_vio_file_stat_t *fs = NULL;
|
||||
|
@ -207,12 +206,6 @@ static csync_vio_file_stat_t* create_fstat(const char *name,
|
|||
fs->size = 157459;
|
||||
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
|
||||
|
||||
if (nlink == 0) {
|
||||
fs->nlink = 1;
|
||||
} else {
|
||||
fs->nlink = nlink;
|
||||
}
|
||||
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_LINK_COUNT;
|
||||
|
||||
|
||||
if (mtime == 0) {
|
||||
|
@ -383,31 +376,6 @@ static void check_csync_detect_update_db_new(void **state)
|
|||
csync_vio_file_stat_destroy(fs);
|
||||
}
|
||||
|
||||
static void check_csync_detect_update_nlink(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
csync_file_stat_t *st;
|
||||
csync_vio_file_stat_t *fs;
|
||||
int rc;
|
||||
|
||||
/* create vio file stat with nlink greater than 1 */
|
||||
fs = create_fstat("file.txt", 0, 7, 0);
|
||||
assert_non_null(fs);
|
||||
|
||||
/* add it to local tree */
|
||||
rc = _csync_detect_update(csync,
|
||||
"/tmp/check_csync1/file.txt",
|
||||
fs,
|
||||
CSYNC_FTW_TYPE_FILE);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
/* the instruction should be set to ignore */
|
||||
st = c_rbtree_node_data(csync->local.tree->root);
|
||||
assert_int_equal(st->instruction, CSYNC_INSTRUCTION_IGNORE);
|
||||
|
||||
csync_vio_file_stat_destroy(fs);
|
||||
}
|
||||
|
||||
static void check_csync_detect_update_null(void **state)
|
||||
{
|
||||
CSYNC *csync = *state;
|
||||
|
@ -467,7 +435,6 @@ int torture_run_tests(void)
|
|||
unit_test_setup_teardown(check_csync_detect_update_db_eval, setup, teardown),
|
||||
unit_test_setup_teardown(check_csync_detect_update_db_rename, setup, teardown),
|
||||
unit_test_setup_teardown(check_csync_detect_update_db_new, setup, teardown_rm),
|
||||
unit_test_setup_teardown(check_csync_detect_update_nlink, setup, teardown_rm),
|
||||
unit_test_setup_teardown(check_csync_detect_update_null, setup, teardown_rm),
|
||||
|
||||
unit_test_setup_teardown(check_csync_ftw, setup_ftw, teardown_rm),
|
||||
|
|
|
@ -29,7 +29,16 @@ use ownCloud::Test;
|
|||
|
||||
use strict;
|
||||
|
||||
print "Hello, this is t4, a tester for A) files that cannot be stated and B) excluded files\n";
|
||||
sub getInode($)
|
||||
{
|
||||
my ($filename) = @_;
|
||||
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
|
||||
$atime,$mtime,$ctime,$blksize,$blocks) = stat($filename);
|
||||
|
||||
return $ino;
|
||||
}
|
||||
|
||||
print "Hello, this is t4, a tester for A) files that cannot be stated and B) excluded files C) hard links\n";
|
||||
# stat error occours on windsows when the file is busy for example
|
||||
|
||||
initTesting();
|
||||
|
@ -167,6 +176,48 @@ assertLocalAndRemoteDir( '', 0 );
|
|||
assert(! -e localDir(). 'anotherdir' );
|
||||
|
||||
|
||||
printInfo("Test hardlinks\n");
|
||||
#make a hard link
|
||||
mkdir( localDir() . 'subdir' );
|
||||
createLocalFile( localDir() .'subdir/original.data', 1568 );
|
||||
system( "ln " . localDir() . 'subdir/original.data ' . localDir() . 'file.link');
|
||||
csync();
|
||||
assertLocalAndRemoteDir( '', 0 );
|
||||
my $inode = getInode(localDir() . 'subdir/original.data');
|
||||
my $inode2 = getInode(localDir() . 'file.link');
|
||||
assert( $inode == $inode2, "Inode is not the same!");
|
||||
|
||||
|
||||
printInfo("Modify hard link\n");
|
||||
system( "echo 'another line' >> " . localDir() . 'file.link');
|
||||
csync();
|
||||
assertLocalAndRemoteDir( '', 0 );
|
||||
my $inode1 = getInode(localDir() .'subdir/original.data');
|
||||
$inode2 = getInode( localDir() .'file.link');
|
||||
assert( $inode == $inode1, "Inode is not the same!");
|
||||
assert( $inode == $inode2, "Inode is not the same!");
|
||||
|
||||
|
||||
printInfo("Rename a hard link\n");
|
||||
move( localDir() . 'subdir/original.data', localDir() . 'subdir/kernelcrash.txt' );
|
||||
csync();
|
||||
assertLocalAndRemoteDir( '', 0 );
|
||||
$inode1 = getInode(localDir() .'subdir/kernelcrash.txt');
|
||||
$inode2 = getInode(localDir() .'file.link');
|
||||
assert( $inode == $inode1, "Inode is not the same!");
|
||||
assert( $inode == $inode2, "Inode is not the same!");
|
||||
|
||||
printInfo("Modify a hard link on the server\n");
|
||||
put_to_dir( '/tmp/kernelcrash.txt', 'subdir' );
|
||||
csync();
|
||||
assertLocalAndRemoteDir( '', 0 );
|
||||
$inode1 = getInode(localDir() .'subdir/kernelcrash.txt');
|
||||
$inode2 = getInode( localDir() .'file.link');
|
||||
# only the first inode must change
|
||||
print(" $inode $inode1 $inode2" );
|
||||
assert( $inode != $inode1, "Inode did not change");
|
||||
assert( $inode == $inode2, "Inode is not the same!");
|
||||
|
||||
cleanup();
|
||||
|
||||
# --
|
||||
|
|
|
@ -367,9 +367,6 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
|
|||
case CSYNC_STATUS_INDIVIDUAL_IS_SYMLINK:
|
||||
item->_errorString = tr("Symbolic links are not supported in syncing.");
|
||||
break;
|
||||
case CSYNC_STATUS_INDIVIDUAL_IS_HARDLINK:
|
||||
item->_errorString = tr("Hard links are not supported in syncing.");
|
||||
break;
|
||||
case CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST:
|
||||
item->_errorString = tr("File is listed on the ignore list.");
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue