86 lines
2.7 KiB
Diff
86 lines
2.7 KiB
Diff
From b4ff6ddb32296f43439b4be79c7864f7ae7d14f1 Mon Sep 17 00:00:00 2001
|
|
From: Ondrej Holy <oholy@redhat.com>
|
|
Date: Wed, 13 Nov 2024 11:34:19 +0100
|
|
Subject: [PATCH] smb: Fix offset after truncate when appending
|
|
|
|
The truncate operation is currently enabled when appending. However,
|
|
the libsmbclient doesn't support O_APPEND flag property [1]. The
|
|
offset is not reset after the truncate operation. This may lead to
|
|
data corruptions. Let's explicitely seek to the desired offset when
|
|
truncating to prevent this.
|
|
|
|
[1] https://github.com/samba-team/samba/blob/e4e3f05/source3/libsmb/libsmb_file.c#L162-L183
|
|
---
|
|
daemon/gvfsbackendsmb.c | 27 ++++++++++++++++++++++++---
|
|
1 file changed, 24 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/daemon/gvfsbackendsmb.c b/daemon/gvfsbackendsmb.c
|
|
index c2075555..f287264b 100644
|
|
--- a/daemon/gvfsbackendsmb.c
|
|
+++ b/daemon/gvfsbackendsmb.c
|
|
@@ -780,6 +780,7 @@ typedef struct {
|
|
char *uri;
|
|
char *tmp_uri;
|
|
char *backup_uri;
|
|
+ GVfsJobOpenForWriteMode mode;
|
|
} SmbWriteHandle;
|
|
|
|
static void
|
|
@@ -824,6 +825,7 @@ do_create (GVfsBackend *backend,
|
|
{
|
|
handle = g_new0 (SmbWriteHandle, 1);
|
|
handle->file = file;
|
|
+ handle->mode = job->mode;
|
|
|
|
g_vfs_job_open_for_write_set_can_seek (job, TRUE);
|
|
g_vfs_job_open_for_write_set_can_truncate (job, TRUE);
|
|
@@ -869,6 +871,7 @@ do_append_to (GVfsBackend *backend,
|
|
|
|
handle = g_new0 (SmbWriteHandle, 1);
|
|
handle->file = file;
|
|
+ handle->mode = job->mode;
|
|
|
|
g_vfs_job_open_for_write_set_initial_offset (job, initial_offset);
|
|
|
|
@@ -1141,6 +1144,7 @@ do_replace (GVfsBackend *backend,
|
|
handle->uri = uri;
|
|
handle->tmp_uri = tmp_uri;
|
|
handle->backup_uri = backup_uri;
|
|
+ handle->mode = job->mode;
|
|
|
|
g_vfs_job_open_for_write_set_can_seek (job, TRUE);
|
|
g_vfs_job_open_for_write_set_can_truncate (job, TRUE);
|
|
@@ -1229,9 +1233,26 @@ do_truncate (GVfsBackend *backend,
|
|
|
|
smbc_ftruncate = smbc_getFunctionFtruncate (op_backend->smb_context);
|
|
if (smbc_ftruncate (op_backend->smb_context, handle->file, size) == -1)
|
|
- g_vfs_job_failed_from_errno (G_VFS_JOB (job), errno);
|
|
- else
|
|
- g_vfs_job_succeeded (G_VFS_JOB (job));
|
|
+ {
|
|
+ g_vfs_job_failed_from_errno (G_VFS_JOB (job), errno);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (handle->mode == OPEN_FOR_WRITE_APPEND)
|
|
+ {
|
|
+ smbc_lseek_fn smbc_lseek;
|
|
+ off_t res;
|
|
+
|
|
+ smbc_lseek = smbc_getFunctionLseek (op_backend->smb_context);
|
|
+ res = smbc_lseek (op_backend->smb_context, handle->file, size, SEEK_SET);
|
|
+ if (res == (off_t)-1)
|
|
+ {
|
|
+ g_vfs_job_failed_from_errno (G_VFS_JOB (job), errno);
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ g_vfs_job_succeeded (G_VFS_JOB (job));
|
|
}
|
|
|
|
static void
|
|
--
|
|
2.46.2
|
|
|