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/. */
9 #include "mozilla/net/IOActivityMonitor.h"
13 // The last VFS version for which this file has been updated.
14 constexpr int kLastKnowVfsVersion
= 3;
16 // The last io_methods version for which this file has been updated.
17 constexpr int kLastKnownIOMethodsVersion
= 3;
19 using namespace mozilla
;
20 using namespace mozilla::net
;
23 // Base class. Must be first
27 // This points to the underlying sqlite3_file
28 sqlite3_file pReal
[1];
31 int BaseClose(sqlite3_file
* pFile
) {
32 BaseFile
* p
= (BaseFile
*)pFile
;
34 return p
->pReal
->pMethods
->xClose(p
->pReal
);
37 int BaseRead(sqlite3_file
* pFile
, void* zBuf
, int iAmt
, sqlite_int64 iOfst
) {
38 BaseFile
* p
= (BaseFile
*)pFile
;
39 int rc
= p
->pReal
->pMethods
->xRead(p
->pReal
, zBuf
, iAmt
, iOfst
);
40 if (rc
== SQLITE_OK
&& IOActivityMonitor::IsActive()) {
41 IOActivityMonitor::Read(nsDependentCString(p
->location
), iAmt
);
46 int BaseWrite(sqlite3_file
* pFile
, const void* zBuf
, int iAmt
,
48 BaseFile
* p
= (BaseFile
*)pFile
;
49 int rc
= p
->pReal
->pMethods
->xWrite(p
->pReal
, zBuf
, iAmt
, iOfst
);
50 if (rc
== SQLITE_OK
&& IOActivityMonitor::IsActive()) {
51 IOActivityMonitor::Write(nsDependentCString(p
->location
), iAmt
);
56 int BaseTruncate(sqlite3_file
* pFile
, sqlite_int64 size
) {
57 BaseFile
* p
= (BaseFile
*)pFile
;
58 return p
->pReal
->pMethods
->xTruncate(p
->pReal
, size
);
61 int BaseSync(sqlite3_file
* pFile
, int flags
) {
62 BaseFile
* p
= (BaseFile
*)pFile
;
63 return p
->pReal
->pMethods
->xSync(p
->pReal
, flags
);
66 int BaseFileSize(sqlite3_file
* pFile
, sqlite_int64
* pSize
) {
67 BaseFile
* p
= (BaseFile
*)pFile
;
68 return p
->pReal
->pMethods
->xFileSize(p
->pReal
, pSize
);
71 int BaseLock(sqlite3_file
* pFile
, int eLock
) {
72 BaseFile
* p
= (BaseFile
*)pFile
;
73 return p
->pReal
->pMethods
->xLock(p
->pReal
, eLock
);
76 int BaseUnlock(sqlite3_file
* pFile
, int eLock
) {
77 BaseFile
* p
= (BaseFile
*)pFile
;
78 return p
->pReal
->pMethods
->xUnlock(p
->pReal
, eLock
);
81 int BaseCheckReservedLock(sqlite3_file
* pFile
, int* pResOut
) {
82 BaseFile
* p
= (BaseFile
*)pFile
;
83 return p
->pReal
->pMethods
->xCheckReservedLock(p
->pReal
, pResOut
);
86 int BaseFileControl(sqlite3_file
* pFile
, int op
, void* pArg
) {
87 #if defined(MOZ_SQLITE_PERSIST_AUXILIARY_FILES)
88 // Persist auxiliary files (-shm and -wal) on disk, because creating and
89 // deleting them may be expensive on slow storage.
90 // Only do this when there is a journal size limit, so the journal is
91 // truncated instead of deleted on shutdown, that feels safer if the user
92 // moves a database file around without its auxiliary files.
94 ::sqlite3_compileoption_used("DEFAULT_JOURNAL_SIZE_LIMIT"),
95 "A journal size limit ensures the journal is truncated on shutdown");
96 if (op
== SQLITE_FCNTL_PERSIST_WAL
) {
97 *static_cast<int*>(pArg
) = 1;
101 BaseFile
* p
= (BaseFile
*)pFile
;
102 return p
->pReal
->pMethods
->xFileControl(p
->pReal
, op
, pArg
);
105 int BaseSectorSize(sqlite3_file
* pFile
) {
106 BaseFile
* p
= (BaseFile
*)pFile
;
107 return p
->pReal
->pMethods
->xSectorSize(p
->pReal
);
110 int BaseDeviceCharacteristics(sqlite3_file
* pFile
) {
111 BaseFile
* p
= (BaseFile
*)pFile
;
112 return p
->pReal
->pMethods
->xDeviceCharacteristics(p
->pReal
);
115 int BaseShmMap(sqlite3_file
* pFile
, int iPg
, int pgsz
, int bExtend
,
116 void volatile** pp
) {
117 BaseFile
* p
= (BaseFile
*)pFile
;
118 return p
->pReal
->pMethods
->xShmMap(p
->pReal
, iPg
, pgsz
, bExtend
, pp
);
121 int BaseShmLock(sqlite3_file
* pFile
, int offset
, int n
, int flags
) {
122 BaseFile
* p
= (BaseFile
*)pFile
;
123 return p
->pReal
->pMethods
->xShmLock(p
->pReal
, offset
, n
, flags
);
126 void BaseShmBarrier(sqlite3_file
* pFile
) {
127 BaseFile
* p
= (BaseFile
*)pFile
;
128 return p
->pReal
->pMethods
->xShmBarrier(p
->pReal
);
131 int BaseShmUnmap(sqlite3_file
* pFile
, int deleteFlag
) {
132 BaseFile
* p
= (BaseFile
*)pFile
;
133 return p
->pReal
->pMethods
->xShmUnmap(p
->pReal
, deleteFlag
);
136 int BaseFetch(sqlite3_file
* pFile
, sqlite3_int64 iOfst
, int iAmt
, void** pp
) {
137 BaseFile
* p
= (BaseFile
*)pFile
;
138 return p
->pReal
->pMethods
->xFetch(p
->pReal
, iOfst
, iAmt
, pp
);
141 int BaseUnfetch(sqlite3_file
* pFile
, sqlite3_int64 iOfst
, void* pPage
) {
142 BaseFile
* p
= (BaseFile
*)pFile
;
143 return p
->pReal
->pMethods
->xUnfetch(p
->pReal
, iOfst
, pPage
);
146 int BaseOpen(sqlite3_vfs
* vfs
, const char* zName
, sqlite3_file
* pFile
,
147 int flags
, int* pOutFlags
) {
148 BaseFile
* p
= (BaseFile
*)pFile
;
150 p
->location
= new char[7 + strlen(zName
) + 1];
151 strcpy(p
->location
, "file://");
152 strcpy(p
->location
+ 7, zName
);
154 p
->location
= new char[8];
155 strcpy(p
->location
, "file://");
158 sqlite3_vfs
* origVfs
= (sqlite3_vfs
*)(vfs
->pAppData
);
159 int rc
= origVfs
->xOpen(origVfs
, zName
, p
->pReal
, flags
, pOutFlags
);
163 if (p
->pReal
->pMethods
) {
164 // If the io_methods version is higher than the last known one, you should
165 // update this VFS adding appropriate IO methods for any methods added in
166 // the version change.
167 MOZ_ASSERT(p
->pReal
->pMethods
->iVersion
== kLastKnownIOMethodsVersion
);
168 static const sqlite3_io_methods IOmethods
= {
169 kLastKnownIOMethodsVersion
, /* iVersion */
170 BaseClose
, /* xClose */
171 BaseRead
, /* xRead */
172 BaseWrite
, /* xWrite */
173 BaseTruncate
, /* xTruncate */
174 BaseSync
, /* xSync */
175 BaseFileSize
, /* xFileSize */
176 BaseLock
, /* xLock */
177 BaseUnlock
, /* xUnlock */
178 BaseCheckReservedLock
, /* xCheckReservedLock */
179 BaseFileControl
, /* xFileControl */
180 BaseSectorSize
, /* xSectorSize */
181 BaseDeviceCharacteristics
, /* xDeviceCharacteristics */
182 BaseShmMap
, /* xShmMap */
183 BaseShmLock
, /* xShmLock */
184 BaseShmBarrier
, /* xShmBarrier */
185 BaseShmUnmap
, /* xShmUnmap */
186 BaseFetch
, /* xFetch */
187 BaseUnfetch
/* xUnfetch */
189 pFile
->pMethods
= &IOmethods
;
197 namespace mozilla::storage
{
199 const char* GetBaseVFSName(bool exclusive
) {
200 return exclusive
? "base-vfs-excl" : "base-vfs";
203 UniquePtr
<sqlite3_vfs
> ConstructBaseVFS(bool exclusive
) {
205 # define EXPECTED_VFS "win32"
206 # define EXPECTED_VFS_EXCL "win32"
208 # define EXPECTED_VFS "unix"
209 # define EXPECTED_VFS_EXCL "unix-excl"
212 if (sqlite3_vfs_find(GetBaseVFSName(exclusive
))) {
217 sqlite3_vfs
* origVfs
;
219 // Use the non-exclusive VFS.
220 origVfs
= sqlite3_vfs_find(nullptr);
221 found
= origVfs
&& origVfs
->zName
&& !strcmp(origVfs
->zName
, EXPECTED_VFS
);
223 origVfs
= sqlite3_vfs_find(EXPECTED_VFS_EXCL
);
224 found
= (origVfs
!= nullptr);
230 // If the VFS version is higher than the last known one, you should update
231 // this VFS adding appropriate methods for any methods added in the version
233 MOZ_ASSERT(origVfs
->iVersion
== kLastKnowVfsVersion
);
236 kLastKnowVfsVersion
, /* iVersion */
237 origVfs
->szOsFile
+ static_cast<int>(sizeof(BaseFile
)), /* szOsFile */
238 origVfs
->mxPathname
, /* mxPathname */
240 GetBaseVFSName(exclusive
), /* zName */
241 origVfs
, /* pAppData */
242 BaseOpen
, /* xOpen */
243 origVfs
->xDelete
, /* xDelete */
244 origVfs
->xAccess
, /* xAccess */
245 origVfs
->xFullPathname
, /* xFullPathname */
246 origVfs
->xDlOpen
, /* xDlOpen */
247 origVfs
->xDlError
, /* xDlError */
248 origVfs
->xDlSym
, /* xDlSym */
249 origVfs
->xDlClose
, /* xDlClose */
250 origVfs
->xRandomness
, /* xRandomness */
251 origVfs
->xSleep
, /* xSleep */
252 origVfs
->xCurrentTime
, /* xCurrentTime */
253 origVfs
->xGetLastError
, /* xGetLastError */
254 origVfs
->xCurrentTimeInt64
, /* xCurrentTimeInt64 */
255 origVfs
->xSetSystemCall
, /* xSetSystemCall */
256 origVfs
->xGetSystemCall
, /* xGetSystemCall */
257 origVfs
->xNextSystemCall
/* xNextSystemCall */
260 return MakeUnique
<sqlite3_vfs
>(vfs
);
263 } // namespace mozilla::storage