1 | /* |
2 | This file is part of the KDE project. |
3 | |
4 | SPDX-FileCopyrightText: 2010 Michael Pyne <mpyne@kde.org> |
5 | |
6 | SPDX-License-Identifier: LGPL-2.0-only |
7 | */ |
8 | |
9 | #ifndef KSHAREDDATACACHE_P_H |
10 | #define KSHAREDDATACACHE_P_H |
11 | |
12 | #include "kcoreaddons_debug.h" |
13 | |
14 | #include <cerrno> |
15 | #include <fcntl.h> |
16 | #include <unistd.h> // for _POSIX_ADVISORY_INFO |
17 | |
18 | // posix_fallocate is used to ensure that the file used for the cache is |
19 | // actually fully committed to disk before attempting to use the file. |
20 | #if defined(_POSIX_ADVISORY_INFO) && ((_POSIX_ADVISORY_INFO == 0) || (_POSIX_ADVISORY_INFO >= 200112L)) |
21 | #define KSDC_POSIX_FALLOCATE_SUPPORTED 1 |
22 | #endif |
23 | #ifdef Q_OS_OSX |
24 | #include "posix_fallocate_mac.h" |
25 | #define KSDC_POSIX_FALLOCATE_SUPPORTED 1 |
26 | #endif |
27 | |
28 | static bool ensureFileAllocated(int fd, size_t fileSize) |
29 | { |
30 | #ifdef KSDC_POSIX_FALLOCATE_SUPPORTED |
31 | int result; |
32 | while ((result = ::posix_fallocate(fd: fd, offset: 0, len: fileSize)) == EINTR) { |
33 | ; |
34 | } |
35 | |
36 | if (result != 0) { |
37 | if (result == ENOSPC) { |
38 | qCCritical(KCOREADDONS_DEBUG) << "No space left on device. Check filesystem free space at your XDG_CACHE_HOME!" ; |
39 | } |
40 | qCCritical(KCOREADDONS_DEBUG) << "The operating system is unable to promise" << fileSize |
41 | << "bytes for mapped cache, " |
42 | "abandoning the cache for crash-safety." ; |
43 | return false; |
44 | } |
45 | |
46 | return true; |
47 | #else |
48 | |
49 | #ifdef __GNUC__ |
50 | #warning \ |
51 | "This system does not seem to support posix_fallocate, which is needed to ensure KSharedDataCache's underlying files are fully committed to disk to avoid crashes with low disk space." |
52 | #endif |
53 | qCWarning(KCOREADDONS_DEBUG) << "This system misses support for posix_fallocate()" |
54 | " -- ensure this partition has room for at least" |
55 | << fileSize << "bytes." ; |
56 | |
57 | // TODO: It's possible to emulate the functionality, but doing so |
58 | // overwrites the data in the file so we don't do this. If you were to add |
59 | // this emulation, you must ensure it only happens on initial creation of a |
60 | // new file and not just mapping an existing cache. |
61 | |
62 | return true; |
63 | #endif // KSDC_POSIX_FALLOCATE_SUPPORTED |
64 | } |
65 | |
66 | #endif /* KSHAREDDATACACHE_P_H */ |
67 | |