sal/osl/unx/file.cxx |   54 ++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 47 insertions(+), 7 deletions(-)

New commits:
commit a8814b5921676b1c01a19b0af243712c55fb0307
Author:     Kevin Ottens <kevin.ott...@enioka.com>
AuthorDate: Fri Feb 2 15:39:36 2024 +0100
Commit:     Stephan Bergmann <stephan.bergm...@allotropia.de>
CommitDate: Mon Feb 19 21:14:59 2024 +0100

    tdf#55004 Fix backup copy creation for files on mounted samba shares
    
    There is an unfortunate interaction between file locking and backup
    creation at save time.
    
    openFilePath has logic to lock a file when opening. This goes through
    fcntl to set a write lock on the file. Later on, when the user wants to
    save changes, a backup copy might be created (very likely now since this
    is the defaults in the settings). To create this backup, the file is
    opened again for reading. Unfortunately this open call fails due to the
    lock (even though it is a write lock).
    
    This commit changes the behavior. osl_file_adjustLockFlags now checks if
    the file is on a mounted samba share. If that's the case we force the
    osl_File_OpenFlag_NoLock flag. No issue is then exhibited at backup
    creation, allowing the save to proceed properly.
    
    Change-Id: Ieab252f9f68598834e13339fc5fcea440f0a4c2f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162935
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <stephan.bergm...@allotropia.de>
    (cherry picked from commit 63efbc8ad8aae12b54e649c1495d1233c1a9b33f)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163549

diff --git a/sal/osl/unx/file.cxx b/sal/osl/unx/file.cxx
index eeee7c803fd8..0ca8822016e1 100644
--- a/sal/osl/unx/file.cxx
+++ b/sal/osl/unx/file.cxx
@@ -64,6 +64,14 @@
 #include <vector>
 #endif
 
+#ifdef LINUX
+#include <sys/vfs.h>
+// As documented by the kernel
+#define SMB_SUPER_MAGIC  0x517B
+#define CIFS_SUPER_MAGIC 0xFF534D42
+#define SMB2_SUPER_MAGIC 0xFE534D42
+#endif
+
 namespace {
 
 enum class State
@@ -736,9 +744,11 @@ oslFileHandle osl::detail::createFileHandleFromFD(int fd)
     return static_cast<oslFileHandle>(pImpl);
 }
 
-static int osl_file_adjustLockFlags(const OString& path, int flags)
+static void osl_file_adjustLockFlags(const OString& path, int *flags, 
sal_uInt32 *uFlags)
 {
 #ifdef MACOSX
+    (void) uFlags;
+
     /*
      * The AFP implementation of MacOS X 10.4 treats O_EXLOCK in a way
      * that makes it impossible for OOo to create a backup copy of the
@@ -751,20 +761,50 @@ static int osl_file_adjustLockFlags(const OString& path, 
int flags)
     {
         if(strncmp("afpfs", s.f_fstypename, 5) == 0)
         {
-            flags &= ~O_EXLOCK;
-            flags |=  O_SHLOCK;
+            *flags &= ~O_EXLOCK;
+            *flags |=  O_SHLOCK;
         }
         else
         {
             /* Needed flags to allow opening a webdav file */
-            flags &= ~(O_EXLOCK | O_SHLOCK | O_NONBLOCK);
+            *flags &= ~(O_EXLOCK | O_SHLOCK | O_NONBLOCK);
+        }
+    }
+#elif defined(LINUX)
+    (void) flags;
+
+    /* get filesystem info */
+    struct statfs aFileStatFs;
+    if (statfs(path.getStr(), &aFileStatFs) < 0)
+    {
+        int e = errno;
+        SAL_INFO("sal.file", "statfs(" << path << "): " << UnixErrnoString(e));
+    }
+    else
+    {
+        SAL_INFO("sal.file", "statfs(" << path << "): OK");
+
+        // We avoid locking if on a Linux CIFS mount otherwise this
+        // fill fail later on when opening the file for reading
+        // during backup creation at save time (even though this is a
+        // write lock and not a read lock).
+        // Fixes the following bug:
+        // https://bugs.documentfoundation.org/show_bug.cgi?id=55004
+        switch (aFileStatFs.f_type) {
+        case SMB_SUPER_MAGIC:
+        case CIFS_SUPER_MAGIC:
+        case SMB2_SUPER_MAGIC:
+            *uFlags |= osl_File_OpenFlag_NoLock;
+            break;
+        default:
+            break;
         }
     }
 #else
     (void) path;
+    (void) flags;
+    (void) uFlags;
 #endif
-
-    return flags;
 }
 
 static bool osl_file_queryLocking(sal_uInt32 uFlags)
@@ -981,7 +1021,7 @@ oslFileError openFilePath(const OString& filePath, 
oslFileHandle* pHandle,
     }
     else
     {
-        flags = osl_file_adjustLockFlags (filePath, flags);
+        osl_file_adjustLockFlags (filePath, &flags, &uFlags);
     }
 
     // O_EXCL can be set only when O_CREAT is set

Reply via email to