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/. */
11 #include "mozilla/net/IOActivityMonitor.h"
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
;
25 // Base class. Must be first
29 // This points to the underlying sqlite3_file
30 sqlite3_file pReal
[1];
33 int BaseClose(sqlite3_file
* pFile
) {
34 BaseFile
* p
= (BaseFile
*)pFile
;
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
);
48 int BaseWrite(sqlite3_file
* pFile
, const void* zBuf
, int iAmt
,
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
);
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.
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;
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
;
152 p
->location
= new char[7 + strlen(zName
) + 1];
153 strcpy(p
->location
, "file://");
154 strcpy(p
->location
+ 7, zName
);
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
);
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
;
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
) {
207 # define EXPECTED_VFS "win32"
208 # define EXPECTED_VFS_EXCL "win32"
210 # define EXPECTED_VFS "unix"
211 # define EXPECTED_VFS_EXCL "unix-excl"
214 if (sqlite3_vfs_find(GetVFSName(exclusive
))) {
219 sqlite3_vfs
* origVfs
;
221 // Use the non-exclusive VFS.
222 origVfs
= sqlite3_vfs_find(nullptr);
223 found
= origVfs
&& origVfs
->zName
&& !strcmp(origVfs
->zName
, EXPECTED_VFS
);
225 origVfs
= sqlite3_vfs_find(EXPECTED_VFS_EXCL
);
226 found
= (origVfs
!= 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
235 MOZ_ASSERT(origVfs
->iVersion
== kLastKnowVfsVersion
);
238 kLastKnowVfsVersion
, /* iVersion */
239 origVfs
->szOsFile
+ static_cast<int>(sizeof(BaseFile
)), /* szOsFile */
240 origVfs
->mxPathname
, /* mxPathname */
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