[packages/gvfs] - upstream libnfs 6 support (+previous nfs backend fixes, adjusted)

qboosh qboosh at pld-linux.org
Tue Jul 22 21:48:10 CEST 2025


commit 80177db127e23e95a2fcfd11df9bdd7e8fe95a23
Author: Jakub Bogusz <qboosh at pld-linux.org>
Date:   Tue Jul 22 21:49:54 2025 +0200

    - upstream libnfs 6 support (+previous nfs backend fixes, adjusted)

 gvfs-libnfs.patch | 530 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 530 insertions(+)
---
diff --git a/gvfs-libnfs.patch b/gvfs-libnfs.patch
new file mode 100644
index 0000000..7ff221f
--- /dev/null
+++ b/gvfs-libnfs.patch
@@ -0,0 +1,530 @@
+From b75208c86d842c7bc2f613f40bc80cc7594629aa Mon Sep 17 00:00:00 2001
+From: Ondrej Holy <oholy at redhat.com>
+Date: Mon, 4 Nov 2024 15:21:45 +0100
+Subject: [PATCH] nfs: Fail append with G_IO_ERROR_IS_DIRECTORY when dir exists
+
+Currently, the append/edit job succeeds for the NFS backend even though
+there is a directory. The consequent write operation fails with the
+invalid address error. As per the documentation, the append/edit
+operation should fail imediatelly with the `G_IO_ERROR_IS_DIRECTORY`
+error. Let's add an extra stat call to achieve that behavior.
+---
+ daemon/gvfsbackendnfs.c | 49 ++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 43 insertions(+), 6 deletions(-)
+
+diff --git a/daemon/gvfsbackendnfs.c b/daemon/gvfsbackendnfs.c
+index c9e9ed60b..6219895a5 100644
+--- a/daemon/gvfsbackendnfs.c
++++ b/daemon/gvfsbackendnfs.c
+@@ -727,7 +727,10 @@ write_handle_free (WriteHandle *handle)
+ }
+ 
+ static void
+-append_cb (int err, struct nfs_context *ctx, void *data, void *private_data)
++append_create_cb (int err,
++                  struct nfs_context *ctx,
++                  void *data,
++                  void *private_data)
+ {
+   GVfsJob *job = G_VFS_JOB (private_data);
+   if (err == 0)
+@@ -747,6 +750,42 @@ append_cb (int err, struct nfs_context *ctx, void *data, void *private_data)
+     }
+ }
+ 
++static void
++append_stat_cb (int err,
++                struct nfs_context *ctx,
++                void *data,
++                void *private_data)
++{
++  GVfsJob *job = G_VFS_JOB (private_data);
++  GVfsJobOpenForWrite *op_job = G_VFS_JOB_OPEN_FOR_WRITE (job);
++  GVfsBackendNfs *op_backend = G_VFS_BACKEND_NFS (op_job->backend);
++
++  if (err == 0)
++    {
++      struct nfs_stat_64 *st = data;
++
++      if (S_ISDIR (st->nfs_mode))
++        {
++          g_vfs_job_failed_literal (job,
++                                    G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY,
++                                    _("Target file is a directory"));
++          return;
++        }
++    }
++  else if (err != -ENOENT)
++    {
++      g_vfs_job_failed_from_errno (job, -err);
++      return;
++    }
++
++  nfs_create_async (op_backend->ctx,
++                    op_job->filename,
++                    O_APPEND,
++                    (op_job->flags & G_FILE_CREATE_PRIVATE ? 0600 : 0666) & ~op_backend->umask,
++                    append_create_cb,
++                    job);
++}
++
+ static gboolean
+ try_append_to (GVfsBackend *backend,
+                GVfsJobOpenForWrite *job,
+@@ -755,11 +794,9 @@ try_append_to (GVfsBackend *backend,
+ {
+   GVfsBackendNfs *op_backend = G_VFS_BACKEND_NFS (backend);
+ 
+-  nfs_create_async (op_backend->ctx,
+-                    filename,
+-                    O_APPEND,
+-                    (flags & G_FILE_CREATE_PRIVATE ? 0600 : 0666) & ~op_backend->umask,
+-                    append_cb, job);
++  /* Check for existing directory because libnfs doesn't fail in this case. */
++  nfs_stat64_async (op_backend->ctx, filename, append_stat_cb, job);
++
+   return TRUE;
+ }
+ 
+-- 
+GitLab
+
+From aa3eef707ae81cd8bab0d7eb94a8729c59061f61 Mon Sep 17 00:00:00 2001
+From: Ondrej Holy <oholy at redhat.com>
+Date: Thu, 28 Nov 2024 14:58:12 +0100
+Subject: [PATCH] nfs: Set intitial_offset when appending
+
+Currently the `initial_offset` is not set when appening. This is wrong
+as the `GDaemonOutputStream` implemetation relies on it to be set. Let's
+do so to fix the `g_seekable_tell` output.
+---
+ daemon/gvfsbackendnfs.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/daemon/gvfsbackendnfs.c b/daemon/gvfsbackendnfs.c
+index 6219895a..85632174 100644
+--- a/daemon/gvfsbackendnfs.c
++++ b/daemon/gvfsbackendnfs.c
+@@ -759,11 +759,10 @@ append_stat_cb (int err,
+   GVfsJob *job = G_VFS_JOB (private_data);
+   GVfsJobOpenForWrite *op_job = G_VFS_JOB_OPEN_FOR_WRITE (job);
+   GVfsBackendNfs *op_backend = G_VFS_BACKEND_NFS (op_job->backend);
++  struct nfs_stat_64 *st = data;
+ 
+   if (err == 0)
+     {
+-      struct nfs_stat_64 *st = data;
+-
+       if (S_ISDIR (st->nfs_mode))
+         {
+           g_vfs_job_failed_literal (job,
+@@ -778,6 +777,7 @@ append_stat_cb (int err,
+       return;
+     }
+ 
++  g_vfs_job_open_for_write_set_initial_offset (op_job, st->nfs_size);
+   nfs_create_async (op_backend->ctx,
+                     op_job->filename,
+                     O_APPEND,
+-- 
+GitLab
+
+From 56f18838f0af940284af8f22afc5ce4d122df71e Mon Sep 17 00:00:00 2001
+From: Ondrej Holy <oholy at redhat.com>
+Date: Mon, 14 Oct 2024 14:15:12 +0200
+Subject: [PATCH] nfs: Implement support for edit mode
+
+Implement support for the newly added edit mode in the NFS backend.
+
+Related: https://gitlab.gnome.org/GNOME/gvfs/-/issues/249
+---
+ daemon/gvfsbackendnfs.c | 108 +++++++++++++++++++++++-----------------
+ 1 file changed, 61 insertions(+), 47 deletions(-)
+
+diff --git a/daemon/gvfsbackendnfs.c b/daemon/gvfsbackendnfs.c
+index 85632174..925e894e 100644
+--- a/daemon/gvfsbackendnfs.c
++++ b/daemon/gvfsbackendnfs.c
+@@ -727,10 +727,10 @@ write_handle_free (WriteHandle *handle)
+ }
+ 
+ static void
+-append_create_cb (int err,
+-                  struct nfs_context *ctx,
+-                  void *data,
+-                  void *private_data)
++open_for_write_create_cb (int err,
++                          struct nfs_context *ctx,
++                          void *data,
++                          void *private_data)
+ {
+   GVfsJob *job = G_VFS_JOB (private_data);
+   if (err == 0)
+@@ -751,15 +751,32 @@ append_create_cb (int err,
+ }
+ 
+ static void
+-append_stat_cb (int err,
+-                struct nfs_context *ctx,
+-                void *data,
+-                void *private_data)
++open_for_write_create (GVfsBackend *backend,
++                       GVfsJobOpenForWrite *job,
++                       const char *filename,
++                       GFileCreateFlags flags,
++                       int open_flags)
++{
++  GVfsBackendNfs *op_backend = G_VFS_BACKEND_NFS (backend);
++
++  nfs_create_async (op_backend->ctx,
++                    filename,
++                    open_flags,
++                    (flags & G_FILE_CREATE_PRIVATE ? 0600 : 0666) & ~op_backend->umask,
++                    open_for_write_create_cb,
++                    job);
++}
++
++static void
++open_for_write_stat_cb (int err,
++                        struct nfs_context *ctx,
++                        void *data,
++                        void *private_data)
+ {
+   GVfsJob *job = G_VFS_JOB (private_data);
+   GVfsJobOpenForWrite *op_job = G_VFS_JOB_OPEN_FOR_WRITE (job);
+-  GVfsBackendNfs *op_backend = G_VFS_BACKEND_NFS (op_job->backend);
+   struct nfs_stat_64 *st = data;
++  int open_flags = 0;
+ 
+   if (err == 0)
+     {
+@@ -777,13 +794,28 @@ append_stat_cb (int err,
+       return;
+     }
+ 
+-  g_vfs_job_open_for_write_set_initial_offset (op_job, st->nfs_size);
+-  nfs_create_async (op_backend->ctx,
+-                    op_job->filename,
+-                    O_APPEND,
+-                    (op_job->flags & G_FILE_CREATE_PRIVATE ? 0600 : 0666) & ~op_backend->umask,
+-                    append_create_cb,
+-                    job);
++  if (op_job->mode == OPEN_FOR_WRITE_APPEND)
++    {
++      open_flags = O_APPEND;
++      g_vfs_job_open_for_write_set_initial_offset (op_job, st->nfs_size);
++    }
++
++  open_for_write_create (op_job->backend,
++                         op_job,
++                         op_job->filename,
++                         op_job->flags,
++                         open_flags);
++}
++
++static void
++open_for_write (GVfsBackend *backend,
++                GVfsJobOpenForWrite *job,
++                const char *filename)
++{
++  GVfsBackendNfs *op_backend = G_VFS_BACKEND_NFS (backend);
++
++  /* Check for existing directory because libnfs doesn't fail in this case. */
++  nfs_stat64_async (op_backend->ctx, filename, open_for_write_stat_cb, job);
+ }
+ 
+ static gboolean
+@@ -792,10 +824,18 @@ try_append_to (GVfsBackend *backend,
+                const char *filename,
+                GFileCreateFlags flags)
+ {
+-  GVfsBackendNfs *op_backend = G_VFS_BACKEND_NFS (backend);
++  open_for_write (backend, job, filename);
+ 
+-  /* Check for existing directory because libnfs doesn't fail in this case. */
+-  nfs_stat64_async (op_backend->ctx, filename, append_stat_cb, job);
++  return TRUE;
++}
++
++static gboolean
++try_edit (GVfsBackend *backend,
++          GVfsJobOpenForWrite *job,
++          const char *filename,
++          GFileCreateFlags flags)
++{
++  open_for_write (backend, job, filename);
+ 
+   return TRUE;
+ }
+@@ -1344,41 +1384,14 @@ try_replace (GVfsBackend *backend,
+   return TRUE;
+ }
+ 
+-static void
+-create_cb (int err, struct nfs_context *ctx, void *data, void *private_data)
+-{
+-  GVfsJob *job = G_VFS_JOB (private_data);
+-
+-  if (err == 0)
+-    {
+-      GVfsJobOpenForWrite *op_job = G_VFS_JOB_OPEN_FOR_WRITE (job);
+-      WriteHandle *handle = g_slice_new0 (WriteHandle);
+-
+-      handle->fh = data;
+-      g_vfs_job_open_for_write_set_handle (op_job, handle);
+-      g_vfs_job_open_for_write_set_can_seek (op_job, TRUE);
+-      g_vfs_job_open_for_write_set_can_truncate (op_job, TRUE);
+-      g_vfs_job_succeeded (job);
+-    }
+-  else
+-    {
+-      g_vfs_job_failed_from_errno (job, -err);
+-    }
+-}
+-
+ static gboolean
+ try_create (GVfsBackend *backend,
+             GVfsJobOpenForWrite *job,
+             const char *filename,
+             GFileCreateFlags flags)
+ {
+-  GVfsBackendNfs *op_backend = G_VFS_BACKEND_NFS (backend);
++  open_for_write_create (backend, job, filename, flags, O_EXCL);
+ 
+-  nfs_create_async (op_backend->ctx,
+-                    filename,
+-                    O_EXCL,
+-                    (flags & G_FILE_CREATE_PRIVATE ? 0600 : 0666) & ~op_backend->umask,
+-                    create_cb, job);
+   return TRUE;
+ }
+ 
+#@@ -2617,6 +2630,7 @@ g_vfs_backend_nfs_class_init (GVfsBackendNfsClass *klass)
+#   backend_class->try_make_symlink = try_make_symlink;
+#   backend_class->try_create = try_create;
+#   backend_class->try_append_to = try_append_to;
+#+  backend_class->try_edit = try_edit;
+#   backend_class->try_replace = try_replace;
+#   backend_class->try_write = try_write;
+#   backend_class->try_query_info_on_write = try_query_info_on_write;
+-- 
+GitLab
+
+From 50c0845928983830ebe12d1d2ba82a6735cec77b Mon Sep 17 00:00:00 2001
+From: Jan Alexander Steffens <jan.steffens at gmail.com>
+Date: Mon, 20 Jan 2025 10:06:08 +0000
+Subject: [PATCH] nfs: Support libnfs 6
+
+Libnfs 6 brings version 2 of its API. It is not compatible with the earlier API.
+Let's use the LIBNFS_API_V2 symbol to handle differences.
+
+Fixes: https://gitlab.gnome.org/GNOME/gvfs/-/issues/781
+---
+ daemon/gvfsbackendnfs.c | 72 +++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 72 insertions(+)
+
+diff --git a/daemon/gvfsbackendnfs.c b/daemon/gvfsbackendnfs.c
+index 925e894e..b9db96ab 100644
+--- a/daemon/gvfsbackendnfs.c
++++ b/daemon/gvfsbackendnfs.c
+@@ -407,7 +407,9 @@ read_cb (int err, struct nfs_context *ctx, void *data, void *private_data)
+     {
+       GVfsJobRead *op_job = G_VFS_JOB_READ (job);
+ 
++#ifndef LIBNFS_API_V2
+       memcpy (op_job->buffer, data, err);
++#endif
+       g_vfs_job_read_set_size (op_job, err);
+       g_vfs_job_succeeded (job);
+     }
+@@ -427,7 +429,11 @@ try_read (GVfsBackend *backend,
+   GVfsBackendNfs *op_backend = G_VFS_BACKEND_NFS (backend);
+   struct nfsfh *fh = _handle;
+ 
++#ifdef LIBNFS_API_V2
++  nfs_read_async (op_backend->ctx, fh, buffer, bytes_requested, read_cb, job);
++#else
+   nfs_read_async (op_backend->ctx, fh, bytes_requested, read_cb, job);
++#endif
+   return TRUE;
+ }
+ 
+@@ -759,12 +765,21 @@ open_for_write_create (GVfsBackend *backend,
+ {
+   GVfsBackendNfs *op_backend = G_VFS_BACKEND_NFS (backend);
+ 
++#ifdef LIBNFS_API_V2
++  nfs_open2_async (op_backend->ctx,
++                   filename,
++                   O_CREAT | open_flags,
++                   (flags & G_FILE_CREATE_PRIVATE ? 0600 : 0666) & ~op_backend->umask,
++                   open_for_write_create_cb,
++                   job);
++#else
+   nfs_create_async (op_backend->ctx,
+                     filename,
+                     open_flags,
+                     (flags & G_FILE_CREATE_PRIVATE ? 0600 : 0666) & ~op_backend->umask,
+                     open_for_write_create_cb,
+                     job);
++#endif
+ }
+ 
+ static void
+@@ -855,6 +870,9 @@ typedef struct
+   int mode;
+   CopyFileCallback cb;
+   void *private_data;
++#ifdef LIBNFS_API_V2
++  char buffer[COPY_BLKSIZE];
++#endif
+ } CopyHandle;
+ 
+ static void
+@@ -882,7 +900,11 @@ copy_write_cb (int err,
+   CopyHandle *handle = private_data;
+ 
+   if (err > 0)
++#ifdef LIBNFS_API_V2
++    nfs_read_async (ctx, handle->srcfh, handle->buffer, COPY_BLKSIZE, copy_read_cb, handle);
++#else
+     nfs_read_async (ctx, handle->srcfh, COPY_BLKSIZE, copy_read_cb, handle);
++#endif
+   else
+     copy_handle_complete (ctx, handle, FALSE);
+ }
+@@ -895,7 +917,11 @@ copy_read_cb (int err, struct nfs_context *ctx, void *data, void *private_data)
+   if (err == 0)
+     copy_handle_complete (ctx, handle, TRUE);
+   else if (err > 0)
++#ifdef LIBNFS_API_V2
++    nfs_write_async (ctx, handle->destfh, handle->buffer, err, copy_write_cb, handle);
++#else
+     nfs_write_async (ctx, handle->destfh, err, data, copy_write_cb, handle);
++#endif
+   else
+     copy_handle_complete (ctx, handle, FALSE);
+ }
+@@ -911,7 +937,11 @@ copy_open_dest_cb (int err,
+     {
+       handle->destfh = data;
+ 
++#ifdef LIBNFS_API_V2
++      nfs_read_async (ctx, handle->srcfh, handle->buffer, COPY_BLKSIZE, copy_read_cb, handle);
++#else
+       nfs_read_async (ctx, handle->srcfh, COPY_BLKSIZE, copy_read_cb, handle);
++#endif
+     }
+   else
+     {
+@@ -929,9 +959,15 @@ copy_open_source_cb (int err,
+   if (err == 0)
+     {
+       handle->srcfh = data;
++#ifdef LIBNFS_API_V2
++      nfs_open2_async (ctx,
++                       handle->dest, O_CREAT | O_TRUNC, handle->mode & 0777,
++                       copy_open_dest_cb, handle);
++#else
+       nfs_create_async (ctx,
+                         handle->dest, O_TRUNC, handle->mode & 0777,
+                         copy_open_dest_cb, handle);
++#endif
+       g_free (handle->dest);
+     }
+   else
+@@ -1012,11 +1048,19 @@ replace_backup_chown_cb (int err,
+       GVfsJobOpenForWrite *op_job = G_VFS_JOB_OPEN_FOR_WRITE (job);
+       GVfsBackendNfs *op_backend = G_VFS_BACKEND_NFS (op_job->backend);
+ 
++#ifdef LIBNFS_API_V2
++      nfs_open2_async (op_backend->ctx,
++                       op_job->filename,
++                       O_CREAT | O_TRUNC,
++                       (op_job->flags & G_FILE_CREATE_PRIVATE ? 0600 : 0666) & ~op_backend->umask,
++                       replace_trunc_cb, handle);
++#else
+       nfs_create_async (op_backend->ctx,
+                         op_job->filename,
+                         O_TRUNC,
+                         (op_job->flags & G_FILE_CREATE_PRIVATE ? 0600 : 0666) & ~op_backend->umask,
+                         replace_trunc_cb, handle);
++#endif
+     }
+   else
+     {
+@@ -1096,11 +1140,19 @@ replace_truncate (struct nfs_context *ctx, WriteHandle *handle)
+     }
+   else
+     {
++#ifdef LIBNFS_API_V2
++      nfs_open2_async (ctx,
++                       op_job->filename,
++                       O_CREAT | O_TRUNC,
++                       (op_job->flags & G_FILE_CREATE_PRIVATE ? 0600 : 0666) & ~op_backend->umask,
++                       replace_trunc_cb, handle);
++#else
+       nfs_create_async (ctx,
+                         op_job->filename,
+                         O_TRUNC,
+                         (op_job->flags & G_FILE_CREATE_PRIVATE ? 0600 : 0666) & ~op_backend->umask,
+                         replace_trunc_cb, handle);
++#endif
+     }
+ }
+ 
+@@ -1288,11 +1340,19 @@ replace_stat_cb (int err,
+               handle->tempname = g_build_filename (dirname, basename, NULL);
+               g_free (dirname);
+ 
++#ifdef LIBNFS_API_V2
++              nfs_open2_async (ctx,
++                               handle->tempname,
++                               O_CREAT | O_EXCL,
++                               (op_job->flags & G_FILE_CREATE_PRIVATE ? 0600 : 0666) & ~op_backend->umask,
++                               replace_temp_cb, handle);
++#else
+               nfs_create_async (ctx,
+                                 handle->tempname,
+                                 O_EXCL,
+                                 (op_job->flags & G_FILE_CREATE_PRIVATE ? 0600 : 0666) & ~op_backend->umask,
+                                 replace_temp_cb, handle);
++#endif
+             }
+           else
+             {
+@@ -1376,11 +1436,19 @@ try_replace (GVfsBackend *backend,
+ {
+   GVfsBackendNfs *op_backend = G_VFS_BACKEND_NFS (backend);
+ 
++#ifdef LIBNFS_API_V2
++  nfs_open2_async (op_backend->ctx,
++                   filename,
++                   O_CREAT | O_EXCL,
++                   (flags & G_FILE_CREATE_PRIVATE ? 0600 : 0666) & ~op_backend->umask,
++                   replace_create_cb, job);
++#else
+   nfs_create_async (op_backend->ctx,
+                     filename,
+                     O_EXCL,
+                     (flags & G_FILE_CREATE_PRIVATE ? 0600 : 0666) & ~op_backend->umask,
+                     replace_create_cb, job);
++#endif
+   return TRUE;
+ }
+ 
+@@ -1422,7 +1490,11 @@ try_write (GVfsBackend *backend,
+   WriteHandle *handle = _handle;
+   struct nfsfh *fh = handle->fh;
+ 
++#ifdef LIBNFS_API_V2
++  nfs_write_async (op_backend->ctx, fh, buffer, buffer_size, write_cb, job);
++#else
+   nfs_write_async (op_backend->ctx, fh, buffer_size, buffer, write_cb, job);
++#endif
+   return TRUE;
+ }
+ 
+-- 
+GitLab
+
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/gvfs.git/commitdiff/80177db127e23e95a2fcfd11df9bdd7e8fe95a23



More information about the pld-cvs-commit mailing list