gvfs/smb-Fix-offset-after-truncate-when-appending.patch
Ondrej Holy e4beaf57e2 Add edit mode support for smb backend
Resolves: RHEL-45163
2025-02-13 10:05:50 +01:00

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