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

178 lines
5.8 KiB
Diff

From bcbf85cc1f9bd8c1cb673a5d7d3f9907d84e3caa Mon Sep 17 00:00:00 2001
From: Ondrej Holy <oholy@redhat.com>
Date: Wed, 13 Nov 2024 11:52:28 +0100
Subject: [PATCH] smb: Implement support for edit mode
Implement support for the newly added edit mode in the SMB backend.
Related: https://gitlab.gnome.org/GNOME/gvfs/-/issues/249
---
daemon/gvfsbackendsmb.c | 109 +++++++++++++++++++---------------------
1 file changed, 53 insertions(+), 56 deletions(-)
diff --git a/daemon/gvfsbackendsmb.c b/daemon/gvfsbackendsmb.c
index f287264b..4fbdfd23 100644
--- a/daemon/gvfsbackendsmb.c
+++ b/daemon/gvfsbackendsmb.c
@@ -793,10 +793,11 @@ smb_write_handle_free (SmbWriteHandle *handle)
}
static void
-do_create (GVfsBackend *backend,
- GVfsJobOpenForWrite *job,
- const char *filename,
- GFileCreateFlags flags)
+open_for_write (GVfsBackend *backend,
+ GVfsJobOpenForWrite *job,
+ const char *filename,
+ GFileCreateFlags flags,
+ int open_flags)
{
GVfsBackendSmb *op_backend = G_VFS_BACKEND_SMB (backend);
char *uri;
@@ -804,12 +805,12 @@ do_create (GVfsBackend *backend,
SmbWriteHandle *handle;
smbc_open_fn smbc_open;
int errsv;
+ off_t initial_offset = 0;
uri = create_smb_uri (op_backend->server, op_backend->port, op_backend->share, filename);
smbc_open = smbc_getFunctionOpen (op_backend->smb_context);
errno = 0;
- file = smbc_open (op_backend->smb_context, uri,
- O_CREAT|O_RDWR|O_EXCL, 0666);
+ file = smbc_open (op_backend->smb_context, uri, open_flags, 0666);
g_free (uri);
if (file == NULL)
@@ -817,48 +818,16 @@ do_create (GVfsBackend *backend,
errsv = fixup_open_errno (errno);
/* We guarantee EEXIST on create on existing dir */
- if (errsv == EISDIR)
+ if (job->mode == OPEN_FOR_WRITE_CREATE && errsv == EISDIR)
errsv = EEXIST;
g_vfs_job_failed_from_errno (G_VFS_JOB (job), errsv);
+ return;
}
- else
- {
- 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);
- g_vfs_job_open_for_write_set_handle (job, handle);
- g_vfs_job_succeeded (G_VFS_JOB (job));
- }
-}
-static void
-do_append_to (GVfsBackend *backend,
- GVfsJobOpenForWrite *job,
- const char *filename,
- GFileCreateFlags flags)
-{
- GVfsBackendSmb *op_backend = G_VFS_BACKEND_SMB (backend);
- char *uri;
- SMBCFILE *file;
- SmbWriteHandle *handle;
- off_t initial_offset;
- smbc_open_fn smbc_open;
- smbc_lseek_fn smbc_lseek;
-
- uri = create_smb_uri (op_backend->server, op_backend->port, op_backend->share, filename);
- smbc_open = smbc_getFunctionOpen (op_backend->smb_context);
- errno = 0;
- file = smbc_open (op_backend->smb_context, uri,
- O_CREAT|O_RDWR|O_APPEND, 0666);
- g_free (uri);
-
- if (file == NULL)
- g_vfs_job_failed_from_errno (G_VFS_JOB (job), fixup_open_errno (errno));
- else
+ if (job->mode == OPEN_FOR_WRITE_APPEND)
{
+ smbc_lseek_fn smbc_lseek;
+
smbc_lseek = smbc_getFunctionLseek (op_backend->smb_context);
initial_offset = smbc_lseek (op_backend->smb_context, file,
0, SEEK_CUR);
@@ -868,24 +837,51 @@ do_append_to (GVfsBackend *backend,
fixup_open_errno (errno));
return;
}
+ }
- handle = g_new0 (SmbWriteHandle, 1);
- handle->file = file;
- handle->mode = job->mode;
+ handle = g_new0 (SmbWriteHandle, 1);
+ handle->file = file;
+ handle->mode = job->mode;
- g_vfs_job_open_for_write_set_initial_offset (job, initial_offset);
+ g_vfs_job_open_for_write_set_initial_offset (job, initial_offset);
- /* The O_APPEND flag is not properly supported by the libsmbclient library
- * when seeking. See:
- * https://github.com/samba-team/samba/blob/e4e3f05/source3/libsmb/libsmb_file.c#L162-L183
- */
- g_vfs_job_open_for_write_set_can_seek (job, FALSE);
- g_vfs_job_open_for_write_set_can_truncate (job, TRUE);
- g_vfs_job_open_for_write_set_handle (job, handle);
- g_vfs_job_succeeded (G_VFS_JOB (job));
- }
+ /* The O_APPEND flag is not properly supported by the libsmbclient library
+ * when seeking. See:
+ * https://github.com/samba-team/samba/blob/e4e3f05/source3/libsmb/libsmb_file.c#L162-L183
+ */
+ g_vfs_job_open_for_write_set_can_seek (job,
+ job->mode != OPEN_FOR_WRITE_APPEND);
+ g_vfs_job_open_for_write_set_can_truncate (job, TRUE);
+ g_vfs_job_open_for_write_set_handle (job, handle);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
}
+static void
+do_create (GVfsBackend *backend,
+ GVfsJobOpenForWrite *job,
+ const char *filename,
+ GFileCreateFlags flags)
+{
+ open_for_write (backend, job, filename, flags, O_CREAT|O_RDWR|O_EXCL);
+}
+
+static void
+do_append_to (GVfsBackend *backend,
+ GVfsJobOpenForWrite *job,
+ const char *filename,
+ GFileCreateFlags flags)
+{
+ open_for_write (backend, job, filename, flags, O_CREAT|O_RDWR|O_APPEND);
+}
+
+static void
+do_edit (GVfsBackend *backend,
+ GVfsJobOpenForWrite *job,
+ const char *filename,
+ GFileCreateFlags flags)
+{
+ open_for_write (backend, job, filename, flags, O_CREAT|O_RDWR);
+}
static char *
get_dir_from_uri (const char *uri)
@@ -2153,6 +2149,7 @@ g_vfs_backend_smb_class_init (GVfsBackendSmbClass *klass)
backend_class->close_read = do_close_read;
backend_class->create = do_create;
backend_class->append_to = do_append_to;
+ backend_class->edit = do_edit;
backend_class->replace = do_replace;
backend_class->write = do_write;
backend_class->seek_on_write = do_seek_on_write;
--
2.46.2