Add edit mode support for smb backend
Resolves: RHEL-71089
This commit is contained in:
parent
a4ea8b83a6
commit
0c0c3e8f18
94
daemon-Add-support-for-edit-mode.patch
Normal file
94
daemon-Add-support-for-edit-mode.patch
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
From 1d4acb8d95612384f603aa5c0c8d20060010fbc7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ondrej Holy <oholy@redhat.com>
|
||||||
|
Date: Thu, 1 Aug 2024 12:35:43 +0200
|
||||||
|
Subject: [PATCH] daemon: Add support for edit mode
|
||||||
|
|
||||||
|
Currently, it is impossible to open the output stream without truncating
|
||||||
|
the file or appending it. This is a problem for many POSIX applications
|
||||||
|
relying on our FUSE daemon. Let's add an edit mode that could be used for
|
||||||
|
this purpose.
|
||||||
|
|
||||||
|
Related: https://gitlab.gnome.org/GNOME/gvfs/-/issues/249
|
||||||
|
---
|
||||||
|
daemon/gvfsbackend.h | 8 ++++++++
|
||||||
|
daemon/gvfsjobopenforwrite.c | 23 +++++++++++++++++++++++
|
||||||
|
daemon/gvfsjobopenforwrite.h | 3 ++-
|
||||||
|
3 files changed, 33 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/daemon/gvfsbackend.h b/daemon/gvfsbackend.h
|
||||||
|
index 9c7476cf..0f97cff6 100644
|
||||||
|
--- a/daemon/gvfsbackend.h
|
||||||
|
+++ b/daemon/gvfsbackend.h
|
||||||
|
@@ -211,6 +211,14 @@ struct _GVfsBackendClass
|
||||||
|
const char *etag,
|
||||||
|
gboolean make_backup,
|
||||||
|
GFileCreateFlags flags);
|
||||||
|
+ gboolean (*try_edit) (GVfsBackend *backend,
|
||||||
|
+ GVfsJobOpenForWrite *job,
|
||||||
|
+ const char *filename,
|
||||||
|
+ GFileCreateFlags flags);
|
||||||
|
+ void (*edit) (GVfsBackend *backend,
|
||||||
|
+ GVfsJobOpenForWrite *job,
|
||||||
|
+ const char *filename,
|
||||||
|
+ GFileCreateFlags flags);
|
||||||
|
void (*close_write) (GVfsBackend *backend,
|
||||||
|
GVfsJobCloseWrite *job,
|
||||||
|
GVfsBackendHandle handle);
|
||||||
|
diff --git a/daemon/gvfsjobopenforwrite.c b/daemon/gvfsjobopenforwrite.c
|
||||||
|
index 439b63c4..5b6e8033 100644
|
||||||
|
--- a/daemon/gvfsjobopenforwrite.c
|
||||||
|
+++ b/daemon/gvfsjobopenforwrite.c
|
||||||
|
@@ -220,6 +220,20 @@ run (GVfsJob *job)
|
||||||
|
op_job->make_backup,
|
||||||
|
op_job->flags);
|
||||||
|
}
|
||||||
|
+ else if (op_job->mode == OPEN_FOR_WRITE_EDIT)
|
||||||
|
+ {
|
||||||
|
+ if (class->edit == NULL)
|
||||||
|
+ {
|
||||||
|
+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||||
|
+ _("Operation not supported"));
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ class->edit (op_job->backend,
|
||||||
|
+ op_job,
|
||||||
|
+ op_job->filename,
|
||||||
|
+ op_job->flags);
|
||||||
|
+ }
|
||||||
|
else
|
||||||
|
g_assert_not_reached (); /* Handled in try */
|
||||||
|
}
|
||||||
|
@@ -259,6 +273,15 @@ try (GVfsJob *job)
|
||||||
|
op_job->make_backup,
|
||||||
|
op_job->flags);
|
||||||
|
}
|
||||||
|
+ else if (op_job->mode == OPEN_FOR_WRITE_EDIT)
|
||||||
|
+ {
|
||||||
|
+ if (class->try_edit == NULL)
|
||||||
|
+ return FALSE;
|
||||||
|
+ return class->try_edit (op_job->backend,
|
||||||
|
+ op_job,
|
||||||
|
+ op_job->filename,
|
||||||
|
+ op_job->flags);
|
||||||
|
+ }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
diff --git a/daemon/gvfsjobopenforwrite.h b/daemon/gvfsjobopenforwrite.h
|
||||||
|
index 141189f3..e070d0ea 100644
|
||||||
|
--- a/daemon/gvfsjobopenforwrite.h
|
||||||
|
+++ b/daemon/gvfsjobopenforwrite.h
|
||||||
|
@@ -41,7 +41,8 @@ typedef struct _GVfsJobOpenForWriteClass GVfsJobOpenForWriteClass;
|
||||||
|
typedef enum {
|
||||||
|
OPEN_FOR_WRITE_CREATE = 0,
|
||||||
|
OPEN_FOR_WRITE_APPEND = 1,
|
||||||
|
- OPEN_FOR_WRITE_REPLACE = 2
|
||||||
|
+ OPEN_FOR_WRITE_REPLACE = 2,
|
||||||
|
+ OPEN_FOR_WRITE_EDIT = 3
|
||||||
|
} GVfsJobOpenForWriteMode;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
--
|
||||||
|
2.46.2
|
||||||
|
|
39
fuse-Use-edit-mode-instead-of-returning-ENOTSUP.patch
Normal file
39
fuse-Use-edit-mode-instead-of-returning-ENOTSUP.patch
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
From fabacfef29e24628f7a1a303be4b54cb006431bb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ondrej Holy <oholy@redhat.com>
|
||||||
|
Date: Thu, 1 Aug 2024 12:40:15 +0200
|
||||||
|
Subject: [PATCH] fuse: Use edit mode instead of returning ENOTSUP
|
||||||
|
|
||||||
|
Currently, the FUSE daemon fails with the `ENOTSUP` error when opening
|
||||||
|
a file for writing without `O_APPEND` or `O_TRUNC`. This is a problem
|
||||||
|
for many POSIX applications. Let's try the newly added edit mode instead.
|
||||||
|
|
||||||
|
Fixes: https://gitlab.gnome.org/GNOME/gvfs/-/issues/249
|
||||||
|
---
|
||||||
|
client/gvfsfusedaemon.c | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/client/gvfsfusedaemon.c b/client/gvfsfusedaemon.c
|
||||||
|
index ff5641ae..9ec4e3d8 100644
|
||||||
|
--- a/client/gvfsfusedaemon.c
|
||||||
|
+++ b/client/gvfsfusedaemon.c
|
||||||
|
@@ -1003,6 +1003,8 @@ setup_input_stream (GFile *file, FileHandle *fh)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#define _g_file_edit(file, flags, cancellable, error) g_file_append_to(file, flags | (1 << 15), cancellable, error)
|
||||||
|
+
|
||||||
|
static gint
|
||||||
|
setup_output_stream (GFile *file, FileHandle *fh, int flags)
|
||||||
|
{
|
||||||
|
@@ -1032,7 +1034,7 @@ setup_output_stream (GFile *file, FileHandle *fh, int flags)
|
||||||
|
else if (flags & O_APPEND)
|
||||||
|
fh->stream = g_file_append_to (file, 0, NULL, &error);
|
||||||
|
else
|
||||||
|
- result = -ENOTSUP;
|
||||||
|
+ fh->stream = _g_file_edit (file, 0, NULL, &error);
|
||||||
|
if (fh->stream)
|
||||||
|
fh->pos = g_seekable_tell (G_SEEKABLE (fh->stream));
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.46.2
|
||||||
|
|
52
gdaemonfile-Use-edit-mode-when-private-edit-flag-is-.patch
Normal file
52
gdaemonfile-Use-edit-mode-when-private-edit-flag-is-.patch
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
From 5dd5f5b97bc753cdf32a04e3de4bddce651ceb9b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ondrej Holy <oholy@redhat.com>
|
||||||
|
Date: Thu, 1 Aug 2024 12:39:49 +0200
|
||||||
|
Subject: [PATCH] gdaemonfile: Use edit mode when private edit flag is used
|
||||||
|
|
||||||
|
The newly added edit mode is meant only for private use by our FUSE
|
||||||
|
daemon. Let's add a new private flag for the append operation to enable
|
||||||
|
the edit mode.
|
||||||
|
---
|
||||||
|
client/gdaemonfile.c | 12 ++++++++++--
|
||||||
|
1 file changed, 10 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c
|
||||||
|
index 485698b2..d66d0934 100644
|
||||||
|
--- a/client/gdaemonfile.c
|
||||||
|
+++ b/client/gdaemonfile.c
|
||||||
|
@@ -57,6 +57,8 @@ G_DEFINE_TYPE_WITH_CODE (GDaemonFile, g_daemon_file, G_TYPE_OBJECT,
|
||||||
|
G_IMPLEMENT_INTERFACE (G_TYPE_FILE,
|
||||||
|
g_daemon_file_file_iface_init))
|
||||||
|
|
||||||
|
+#define PRIVATE_EDIT_FLAG (1 << 15)
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
g_daemon_file_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
@@ -1198,7 +1200,10 @@ g_daemon_file_append_to (GFile *file,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
- return file_open_write (file, 1, "", FALSE, flags, cancellable, error);
|
||||||
|
+ if (flags & PRIVATE_EDIT_FLAG)
|
||||||
|
+ return file_open_write (file, 3, "", FALSE, flags, cancellable, error);
|
||||||
|
+ else
|
||||||
|
+ return file_open_write (file, 1, "", FALSE, flags, cancellable, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GFileOutputStream *
|
||||||
|
@@ -3130,7 +3135,10 @@ g_daemon_file_append_to_async (GFile *file,
|
||||||
|
g_task_set_source_tag (task, g_daemon_file_append_to_async);
|
||||||
|
g_task_set_priority (task, io_priority);
|
||||||
|
|
||||||
|
- file_open_write_async (file, task, 1, "", FALSE, flags);
|
||||||
|
+ if (flags & PRIVATE_EDIT_FLAG)
|
||||||
|
+ file_open_write_async (file, task, 3, "", FALSE, flags);
|
||||||
|
+ else
|
||||||
|
+ file_open_write_async (file, task, 1, "", FALSE, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GFileOutputStream *
|
||||||
|
--
|
||||||
|
2.46.2
|
||||||
|
|
14
gvfs.spec
14
gvfs.spec
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
Name: gvfs
|
Name: gvfs
|
||||||
Version: 1.54.4
|
Version: 1.54.4
|
||||||
Release: 1%{?dist}
|
Release: 2%{?dist}
|
||||||
Summary: Backends for the gio framework in GLib
|
Summary: Backends for the gio framework in GLib
|
||||||
|
|
||||||
License: LGPL-2.0-or-later AND GPL-3.0-only AND MPL-2.0 AND BSD-3-Clause-Sun
|
License: LGPL-2.0-or-later AND GPL-3.0-only AND MPL-2.0 AND BSD-3-Clause-Sun
|
||||||
@ -33,6 +33,15 @@ Source0: https://download.gnome.org/sources/gvfs/1.54/gvfs-%{version}.tar.xz
|
|||||||
# https://issues.redhat.com/browse/RHEL-52355
|
# https://issues.redhat.com/browse/RHEL-52355
|
||||||
Patch: trash-Add-support-for-x-gvfs-trash-mount-option.patch
|
Patch: trash-Add-support-for-x-gvfs-trash-mount-option.patch
|
||||||
|
|
||||||
|
# https://issues.redhat.com/browse/RHEL-71089
|
||||||
|
Patch: daemon-Add-support-for-edit-mode.patch
|
||||||
|
Patch: gdaemonfile-Use-edit-mode-when-private-edit-flag-is-.patch
|
||||||
|
Patch: fuse-Use-edit-mode-instead-of-returning-ENOTSUP.patch
|
||||||
|
Patch: smb-Fail-when-initial_offset-can-t-be-determined.patch
|
||||||
|
Patch: smb-Disable-seek-support-when-appening.patch
|
||||||
|
Patch: smb-Fix-offset-after-truncate-when-appending.patch
|
||||||
|
Patch: smb-Implement-support-for-edit-mode.patch
|
||||||
|
|
||||||
BuildRequires: meson
|
BuildRequires: meson
|
||||||
BuildRequires: gcc
|
BuildRequires: gcc
|
||||||
BuildRequires: pkgconfig(glib-2.0) >= %{glib2_version}
|
BuildRequires: pkgconfig(glib-2.0) >= %{glib2_version}
|
||||||
@ -434,6 +443,9 @@ killall -USR1 gvfsd >&/dev/null || :
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Feb 13 2025 Ondrej Holy <oholy@redhat.com> - 1.54.4-2
|
||||||
|
- Add edit mode support for smb backend (RHEL-71089)
|
||||||
|
|
||||||
* Wed Nov 06 2024 nmontero <nmontero@redhat.com> - 1.54.4-1
|
* Wed Nov 06 2024 nmontero <nmontero@redhat.com> - 1.54.4-1
|
||||||
- Update to 1.54.4
|
- Update to 1.54.4
|
||||||
|
|
||||||
|
36
smb-Disable-seek-support-when-appening.patch
Normal file
36
smb-Disable-seek-support-when-appening.patch
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
From b17f15558194ab3025c8a5cb1a2767c54333f28e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ondrej Holy <oholy@redhat.com>
|
||||||
|
Date: Wed, 13 Nov 2024 11:22:27 +0100
|
||||||
|
Subject: [PATCH] smb: Disable seek support when appening
|
||||||
|
|
||||||
|
The seek is currently enabled when appending. However, the libsmbclient
|
||||||
|
doesn't support O_APPEND flag property [1]. The offset is not reset after
|
||||||
|
seeking. Let's disable seek support when appending to deal with it. The
|
||||||
|
seek operation doesn't make sense when appening anyway.
|
||||||
|
|
||||||
|
[1] https://github.com/samba-team/samba/blob/e4e3f05/source3/libsmb/libsmb_file.c#L162-L183
|
||||||
|
---
|
||||||
|
daemon/gvfsbackendsmb.c | 7 ++++++-
|
||||||
|
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/daemon/gvfsbackendsmb.c b/daemon/gvfsbackendsmb.c
|
||||||
|
index dafbb71c..c2075555 100644
|
||||||
|
--- a/daemon/gvfsbackendsmb.c
|
||||||
|
+++ b/daemon/gvfsbackendsmb.c
|
||||||
|
@@ -871,7 +871,12 @@ do_append_to (GVfsBackend *backend,
|
||||||
|
handle->file = file;
|
||||||
|
|
||||||
|
g_vfs_job_open_for_write_set_initial_offset (job, initial_offset);
|
||||||
|
- g_vfs_job_open_for_write_set_can_seek (job, TRUE);
|
||||||
|
+
|
||||||
|
+ /* 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));
|
||||||
|
--
|
||||||
|
2.46.2
|
||||||
|
|
54
smb-Fail-when-initial_offset-can-t-be-determined.patch
Normal file
54
smb-Fail-when-initial_offset-can-t-be-determined.patch
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
From 885bcc18b65ebd6d3c5bac56994f9f631cb9d363 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ondrej Holy <oholy@redhat.com>
|
||||||
|
Date: Wed, 6 Nov 2024 14:58:18 +0100
|
||||||
|
Subject: [PATCH] smb: Fail when initial_offset can't be determined
|
||||||
|
|
||||||
|
Currently, when the initial_offset can't be determined, the seek and
|
||||||
|
truncate operations are disabled. Let's fail immediatelly instead to
|
||||||
|
simplify the code as a preparation for the follow-up changes. Just a
|
||||||
|
note tha this situation can't happen with the current libsmbclient
|
||||||
|
codebase.
|
||||||
|
---
|
||||||
|
daemon/gvfsbackendsmb.c | 22 ++++++++++++----------
|
||||||
|
1 file changed, 12 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemon/gvfsbackendsmb.c b/daemon/gvfsbackendsmb.c
|
||||||
|
index c1c2d5f0..dafbb71c 100644
|
||||||
|
--- a/daemon/gvfsbackendsmb.c
|
||||||
|
+++ b/daemon/gvfsbackendsmb.c
|
||||||
|
@@ -857,20 +857,22 @@ do_append_to (GVfsBackend *backend,
|
||||||
|
g_vfs_job_failed_from_errno (G_VFS_JOB (job), fixup_open_errno (errno));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
- handle = g_new0 (SmbWriteHandle, 1);
|
||||||
|
- handle->file = file;
|
||||||
|
-
|
||||||
|
smbc_lseek = smbc_getFunctionLseek (op_backend->smb_context);
|
||||||
|
initial_offset = smbc_lseek (op_backend->smb_context, file,
|
||||||
|
0, SEEK_CUR);
|
||||||
|
if (initial_offset == (off_t) -1)
|
||||||
|
- g_vfs_job_open_for_write_set_can_seek (job, FALSE);
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- g_vfs_job_open_for_write_set_initial_offset (job, initial_offset);
|
||||||
|
- 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_failed_from_errno (G_VFS_JOB (job),
|
||||||
|
+ fixup_open_errno (errno));
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ handle = g_new0 (SmbWriteHandle, 1);
|
||||||
|
+ handle->file = file;
|
||||||
|
+
|
||||||
|
+ g_vfs_job_open_for_write_set_initial_offset (job, initial_offset);
|
||||||
|
+ 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));
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.46.2
|
||||||
|
|
85
smb-Fix-offset-after-truncate-when-appending.patch
Normal file
85
smb-Fix-offset-after-truncate-when-appending.patch
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
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
|
||||||
|
|
177
smb-Implement-support-for-edit-mode.patch
Normal file
177
smb-Implement-support-for-edit-mode.patch
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user