add O_TRUNC when the first open() for a file

This commit is contained in:
Ryo Nakamura
2022-11-18 22:30:34 +09:00
parent f4d04b848e
commit dca0241824
3 changed files with 37 additions and 3 deletions

View File

@@ -367,6 +367,7 @@ static int file_dst_prepare(struct file *f, sftp_session sftp)
pr_debug("prepare for %s\n", path);
/* mkdir -p */
for (p = strchr(path + 1, '/'); p; p = strchr(p + 1, '/')) {
*p = '\0';
@@ -398,6 +399,30 @@ static int file_dst_prepare(struct file *f, sftp_session sftp)
*p = '/';
}
/* open file with O_TRUNC to set file size 0 */
mode = O_WRONLY|O_CREAT|O_TRUNC;
if (sftp) {
sftp_file sf;
if ((sf = sftp_open(sftp, f->dst_path, mode, S_IRUSR|S_IWUSR)) == NULL) {
pr_err("sftp_open: %s\n", sftp_get_ssh_error(sftp));
return -1;
}
if (sftp_close(sf) < 0) {
pr_err("sftp_close: %s\n", sftp_get_ssh_error(sftp));
return -1;
}
} else {
int fd;
if ((fd = open(f->dst_path, mode, S_IRUSR|S_IWUSR)) < 0) {
pr_err("open: %s\n", strerrno());
return -1;
}
if (close(fd) < 0) {
pr_err("close: %s\n", strerrno());
return -1;
}
}
return 0;
}
@@ -824,7 +849,7 @@ static int chunk_copy_local_to_remote(struct chunk *c, sftp_session sftp,
goto out;
}
flags = O_WRONLY|O_CREAT;
flags = O_WRONLY;
mode = S_IRUSR|S_IWUSR;
if (!(sf = chunk_open_remote(f->dst_path, flags, mode, c->off, sftp))) {
ret = -1;
@@ -866,7 +891,7 @@ static int chunk_copy_remote_to_local(struct chunk *c, sftp_session sftp,
int fd = 0;
int ret = 0;
flags = O_WRONLY|O_CREAT;
flags = O_WRONLY;
mode = S_IRUSR|S_IWUSR;
if ((fd = chunk_open_local(f->dst_path, flags, mode, c->off)) < 0) {
ret = -1;

View File

@@ -37,7 +37,8 @@ struct file {
* if the file state of the chunk is INIT:
* acquire the file lock
* * if file state is INIT:
* create destination file and directory if necessary
* create directory if necessary
* open file with O_TRUNC and close.
* set file state OPENED.
* // only the first thread in the lock open the destination file
* release the file lock

View File

@@ -174,3 +174,11 @@ def test_transfer_zero_bytes(mscp, src_prefix, dst_prefix):
src.cleanup()
dst.cleanup()
@pytest.mark.parametrize("src_prefix, dst_prefix", param_remote_prefix)
def test_override_dst_having_larger_size(mscp, src_prefix, dst_prefix):
src = File("src", size = 1024 * 1024).make()
dst = File("dst", size = 1024 * 1024 * 2).make()
run2ok([mscp, "-H", src_prefix + src.path, dst_prefix + "dst"])
assert check_same_md5sum(src, dst)
src.cleanup()
dst.cleanup()