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
|