mirror of
https://github.com/upa/mscp.git
synced 2026-03-13 11:47:32 +08:00
add O_TRUNC when the first open() for a file
This commit is contained in:
29
src/file.c
29
src/file.c
@@ -367,6 +367,7 @@ static int file_dst_prepare(struct file *f, sftp_session sftp)
|
|||||||
|
|
||||||
pr_debug("prepare for %s\n", path);
|
pr_debug("prepare for %s\n", path);
|
||||||
|
|
||||||
|
/* mkdir -p */
|
||||||
for (p = strchr(path + 1, '/'); p; p = strchr(p + 1, '/')) {
|
for (p = strchr(path + 1, '/'); p; p = strchr(p + 1, '/')) {
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
@@ -398,6 +399,30 @@ static int file_dst_prepare(struct file *f, sftp_session sftp)
|
|||||||
*p = '/';
|
*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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -824,7 +849,7 @@ static int chunk_copy_local_to_remote(struct chunk *c, sftp_session sftp,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = O_WRONLY|O_CREAT;
|
flags = O_WRONLY;
|
||||||
mode = S_IRUSR|S_IWUSR;
|
mode = S_IRUSR|S_IWUSR;
|
||||||
if (!(sf = chunk_open_remote(f->dst_path, flags, mode, c->off, sftp))) {
|
if (!(sf = chunk_open_remote(f->dst_path, flags, mode, c->off, sftp))) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
@@ -866,7 +891,7 @@ static int chunk_copy_remote_to_local(struct chunk *c, sftp_session sftp,
|
|||||||
int fd = 0;
|
int fd = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
flags = O_WRONLY|O_CREAT;
|
flags = O_WRONLY;
|
||||||
mode = S_IRUSR|S_IWUSR;
|
mode = S_IRUSR|S_IWUSR;
|
||||||
if ((fd = chunk_open_local(f->dst_path, flags, mode, c->off)) < 0) {
|
if ((fd = chunk_open_local(f->dst_path, flags, mode, c->off)) < 0) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ struct file {
|
|||||||
* if the file state of the chunk is INIT:
|
* if the file state of the chunk is INIT:
|
||||||
* acquire the file lock
|
* acquire the file lock
|
||||||
* * if file state is INIT:
|
* * 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.
|
* set file state OPENED.
|
||||||
* // only the first thread in the lock open the destination file
|
* // only the first thread in the lock open the destination file
|
||||||
* release the file lock
|
* release the file lock
|
||||||
|
|||||||
@@ -174,3 +174,11 @@ def test_transfer_zero_bytes(mscp, src_prefix, dst_prefix):
|
|||||||
src.cleanup()
|
src.cleanup()
|
||||||
dst.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()
|
||||||
|
|||||||
Reference in New Issue
Block a user