File: Fix-backup-copy-creation-for-files-on-mounted-samba-shares.diff

package info (click to toggle)
libreoffice 4%3A7.4.7-1%2Bdeb12u9
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 3,601,024 kB
  • sloc: cpp: 4,235,177; xml: 385,692; java: 273,650; python: 72,159; ansic: 36,750; perl: 31,520; javascript: 18,215; sh: 11,445; yacc: 10,839; makefile: 9,490; cs: 6,703; objc: 1,969; lex: 1,885; asm: 1,047; awk: 1,018; pascal: 940; php: 79; csh: 20; sed: 5
file content (128 lines) | stat: -rw-r--r-- 4,205 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
From 63efbc8ad8aae12b54e649c1495d1233c1a9b33f Mon Sep 17 00:00:00 2001
From: Kevin Ottens <kevin.ottens@enioka.com>
Date: Fri, 2 Feb 2024 15:39:36 +0100
Subject: 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.bergmann@allotropia.de>
---
 sal/osl/unx/file.cxx | 54 +++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 47 insertions(+), 7 deletions(-)

diff --git a/sal/osl/unx/file.cxx b/sal/osl/unx/file.cxx
index 5acfe2803189..03d685a997e9 100644
--- a/sal/osl/unx/file.cxx
+++ b/sal/osl/unx/file.cxx
@@ -64,6 +64,14 @@
 #include <android/asset_manager.h>
 #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
-- 
cgit v1.2.3