no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / storage / BaseVFS.cpp
blobf6090bf008fd6d49398b111135cbc24e8c636b07
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "BaseVFS.h"
9 #include <string.h>
10 #include "sqlite3.h"
11 #include "mozilla/net/IOActivityMonitor.h"
13 namespace {
15 // The last VFS version for which this file has been updated.
16 constexpr int kLastKnowVfsVersion = 3;
18 // The last io_methods version for which this file has been updated.
19 constexpr int kLastKnownIOMethodsVersion = 3;
21 using namespace mozilla;
22 using namespace mozilla::net;
24 struct BaseFile {
25 // Base class. Must be first
26 sqlite3_file base;
27 // The filename
28 char* location;
29 // This points to the underlying sqlite3_file
30 sqlite3_file pReal[1];
33 int BaseClose(sqlite3_file* pFile) {
34 BaseFile* p = (BaseFile*)pFile;
35 delete[] p->location;
36 return p->pReal->pMethods->xClose(p->pReal);
39 int BaseRead(sqlite3_file* pFile, void* zBuf, int iAmt, sqlite_int64 iOfst) {
40 BaseFile* p = (BaseFile*)pFile;
41 int rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
42 if (rc == SQLITE_OK && IOActivityMonitor::IsActive()) {
43 IOActivityMonitor::Read(nsDependentCString(p->location), iAmt);
45 return rc;
48 int BaseWrite(sqlite3_file* pFile, const void* zBuf, int iAmt,
49 sqlite_int64 iOfst) {
50 BaseFile* p = (BaseFile*)pFile;
51 int rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
52 if (rc == SQLITE_OK && IOActivityMonitor::IsActive()) {
53 IOActivityMonitor::Write(nsDependentCString(p->location), iAmt);
55 return rc;
58 int BaseTruncate(sqlite3_file* pFile, sqlite_int64 size) {
59 BaseFile* p = (BaseFile*)pFile;
60 return p->pReal->pMethods->xTruncate(p->pReal, size);
63 int BaseSync(sqlite3_file* pFile, int flags) {
64 BaseFile* p = (BaseFile*)pFile;
65 return p->pReal->pMethods->xSync(p->pReal, flags);
68 int BaseFileSize(sqlite3_file* pFile, sqlite_int64* pSize) {
69 BaseFile* p = (BaseFile*)pFile;
70 return p->pReal->pMethods->xFileSize(p->pReal, pSize);
73 int BaseLock(sqlite3_file* pFile, int eLock) {
74 BaseFile* p = (BaseFile*)pFile;
75 return p->pReal->pMethods->xLock(p->pReal, eLock);
78 int BaseUnlock(sqlite3_file* pFile, int eLock) {
79 BaseFile* p = (BaseFile*)pFile;
80 return p->pReal->pMethods->xUnlock(p->pReal, eLock);
83 int BaseCheckReservedLock(sqlite3_file* pFile, int* pResOut) {
84 BaseFile* p = (BaseFile*)pFile;
85 return p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut);
88 int BaseFileControl(sqlite3_file* pFile, int op, void* pArg) {
89 #if defined(MOZ_SQLITE_PERSIST_AUXILIARY_FILES)
90 // Persist auxiliary files (-shm and -wal) on disk, because creating and
91 // deleting them may be expensive on slow storage.
92 // Only do this when there is a journal size limit, so the journal is
93 // truncated instead of deleted on shutdown, that feels safer if the user
94 // moves a database file around without its auxiliary files.
95 MOZ_ASSERT(
96 ::sqlite3_compileoption_used("DEFAULT_JOURNAL_SIZE_LIMIT"),
97 "A journal size limit ensures the journal is truncated on shutdown");
98 if (op == SQLITE_FCNTL_PERSIST_WAL) {
99 *static_cast<int*>(pArg) = 1;
100 return SQLITE_OK;
102 #endif
103 BaseFile* p = (BaseFile*)pFile;
104 return p->pReal->pMethods->xFileControl(p->pReal, op, pArg);
107 int BaseSectorSize(sqlite3_file* pFile) {
108 BaseFile* p = (BaseFile*)pFile;
109 return p->pReal->pMethods->xSectorSize(p->pReal);
112 int BaseDeviceCharacteristics(sqlite3_file* pFile) {
113 BaseFile* p = (BaseFile*)pFile;
114 return p->pReal->pMethods->xDeviceCharacteristics(p->pReal);
117 int BaseShmMap(sqlite3_file* pFile, int iPg, int pgsz, int bExtend,
118 void volatile** pp) {
119 BaseFile* p = (BaseFile*)pFile;
120 return p->pReal->pMethods->xShmMap(p->pReal, iPg, pgsz, bExtend, pp);
123 int BaseShmLock(sqlite3_file* pFile, int offset, int n, int flags) {
124 BaseFile* p = (BaseFile*)pFile;
125 return p->pReal->pMethods->xShmLock(p->pReal, offset, n, flags);
128 void BaseShmBarrier(sqlite3_file* pFile) {
129 BaseFile* p = (BaseFile*)pFile;
130 return p->pReal->pMethods->xShmBarrier(p->pReal);
133 int BaseShmUnmap(sqlite3_file* pFile, int deleteFlag) {
134 BaseFile* p = (BaseFile*)pFile;
135 return p->pReal->pMethods->xShmUnmap(p->pReal, deleteFlag);
138 int BaseFetch(sqlite3_file* pFile, sqlite3_int64 iOfst, int iAmt, void** pp) {
139 BaseFile* p = (BaseFile*)pFile;
140 return p->pReal->pMethods->xFetch(p->pReal, iOfst, iAmt, pp);
143 int BaseUnfetch(sqlite3_file* pFile, sqlite3_int64 iOfst, void* pPage) {
144 BaseFile* p = (BaseFile*)pFile;
145 return p->pReal->pMethods->xUnfetch(p->pReal, iOfst, pPage);
148 int BaseOpen(sqlite3_vfs* vfs, const char* zName, sqlite3_file* pFile,
149 int flags, int* pOutFlags) {
150 BaseFile* p = (BaseFile*)pFile;
151 if (zName) {
152 p->location = new char[7 + strlen(zName) + 1];
153 strcpy(p->location, "file://");
154 strcpy(p->location + 7, zName);
155 } else {
156 p->location = new char[8];
157 strcpy(p->location, "file://");
160 sqlite3_vfs* origVfs = (sqlite3_vfs*)(vfs->pAppData);
161 int rc = origVfs->xOpen(origVfs, zName, p->pReal, flags, pOutFlags);
162 if (rc) {
163 return rc;
165 if (p->pReal->pMethods) {
166 // If the io_methods version is higher than the last known one, you should
167 // update this VFS adding appropriate IO methods for any methods added in
168 // the version change.
169 MOZ_ASSERT(p->pReal->pMethods->iVersion == kLastKnownIOMethodsVersion);
170 static const sqlite3_io_methods IOmethods = {
171 kLastKnownIOMethodsVersion, /* iVersion */
172 BaseClose, /* xClose */
173 BaseRead, /* xRead */
174 BaseWrite, /* xWrite */
175 BaseTruncate, /* xTruncate */
176 BaseSync, /* xSync */
177 BaseFileSize, /* xFileSize */
178 BaseLock, /* xLock */
179 BaseUnlock, /* xUnlock */
180 BaseCheckReservedLock, /* xCheckReservedLock */
181 BaseFileControl, /* xFileControl */
182 BaseSectorSize, /* xSectorSize */
183 BaseDeviceCharacteristics, /* xDeviceCharacteristics */
184 BaseShmMap, /* xShmMap */
185 BaseShmLock, /* xShmLock */
186 BaseShmBarrier, /* xShmBarrier */
187 BaseShmUnmap, /* xShmUnmap */
188 BaseFetch, /* xFetch */
189 BaseUnfetch /* xUnfetch */
191 pFile->pMethods = &IOmethods;
194 return SQLITE_OK;
197 } // namespace
199 namespace mozilla::storage::basevfs {
201 const char* GetVFSName(bool exclusive) {
202 return exclusive ? "base-vfs-excl" : "base-vfs";
205 UniquePtr<sqlite3_vfs> ConstructVFS(bool exclusive) {
206 #if defined(XP_WIN)
207 # define EXPECTED_VFS "win32"
208 # define EXPECTED_VFS_EXCL "win32"
209 #else
210 # define EXPECTED_VFS "unix"
211 # define EXPECTED_VFS_EXCL "unix-excl"
212 #endif
214 if (sqlite3_vfs_find(GetVFSName(exclusive))) {
215 return nullptr;
218 bool found;
219 sqlite3_vfs* origVfs;
220 if (!exclusive) {
221 // Use the non-exclusive VFS.
222 origVfs = sqlite3_vfs_find(nullptr);
223 found = origVfs && origVfs->zName && !strcmp(origVfs->zName, EXPECTED_VFS);
224 } else {
225 origVfs = sqlite3_vfs_find(EXPECTED_VFS_EXCL);
226 found = (origVfs != nullptr);
228 if (!found) {
229 return nullptr;
232 // If the VFS version is higher than the last known one, you should update
233 // this VFS adding appropriate methods for any methods added in the version
234 // change.
235 MOZ_ASSERT(origVfs->iVersion == kLastKnowVfsVersion);
237 sqlite3_vfs vfs = {
238 kLastKnowVfsVersion, /* iVersion */
239 origVfs->szOsFile + static_cast<int>(sizeof(BaseFile)), /* szOsFile */
240 origVfs->mxPathname, /* mxPathname */
241 nullptr, /* pNext */
242 GetVFSName(exclusive), /* zName */
243 origVfs, /* pAppData */
244 BaseOpen, /* xOpen */
245 origVfs->xDelete, /* xDelete */
246 origVfs->xAccess, /* xAccess */
247 origVfs->xFullPathname, /* xFullPathname */
248 origVfs->xDlOpen, /* xDlOpen */
249 origVfs->xDlError, /* xDlError */
250 origVfs->xDlSym, /* xDlSym */
251 origVfs->xDlClose, /* xDlClose */
252 origVfs->xRandomness, /* xRandomness */
253 origVfs->xSleep, /* xSleep */
254 origVfs->xCurrentTime, /* xCurrentTime */
255 origVfs->xGetLastError, /* xGetLastError */
256 origVfs->xCurrentTimeInt64, /* xCurrentTimeInt64 */
257 origVfs->xSetSystemCall, /* xSetSystemCall */
258 origVfs->xGetSystemCall, /* xGetSystemCall */
259 origVfs->xNextSystemCall /* xNextSystemCall */
262 return MakeUnique<sqlite3_vfs>(vfs);
265 } // namespace mozilla::storage::basevfs