* Supports only read-only opens. The "file name" has to be in the form of * '@ ', where file descriptor is usable by the cache manager. */
| 216 | * '@<file descriptor>', where file descriptor is usable by the cache manager. |
| 217 | */ |
| 218 | static int VfsRdOnlyOpen(sqlite3_vfs *vfs, |
| 219 | const char *zName, |
| 220 | sqlite3_file *pFile, |
| 221 | int flags, |
| 222 | int *pOutFlags) { |
| 223 | static const sqlite3_io_methods io_methods = {1, // iVersion |
| 224 | VfsRdOnlyClose, |
| 225 | VfsRdOnlyRead, |
| 226 | VfsRdOnlyWrite, |
| 227 | VfsRdOnlyTruncate, |
| 228 | VfsRdOnlySync, |
| 229 | VfsRdOnlyFileSize, |
| 230 | VfsRdOnlyLock, |
| 231 | VfsRdOnlyUnlock, |
| 232 | VfsRdOnlyCheckReservedLock, |
| 233 | VfsRdOnlyFileControl, |
| 234 | VfsRdOnlySectorSize, |
| 235 | VfsRdOnlyDeviceCharacteristics}; |
| 236 | |
| 237 | VfsRdOnlyFile *p = reinterpret_cast<VfsRdOnlyFile *>(pFile); |
| 238 | CacheManager *cache_mgr = reinterpret_cast<VfsRdOnly *>(vfs->pAppData) |
| 239 | ->cache_mgr; |
| 240 | // Prevent xClose from being called in case of errors |
| 241 | p->base.pMethods = NULL; |
| 242 | |
| 243 | if (flags & SQLITE_OPEN_READWRITE) |
| 244 | return SQLITE_IOERR; |
| 245 | if (flags & SQLITE_OPEN_DELETEONCLOSE) |
| 246 | return SQLITE_IOERR; |
| 247 | if (flags & SQLITE_OPEN_EXCLUSIVE) |
| 248 | return SQLITE_IOERR; |
| 249 | |
| 250 | assert(zName && (zName[0] == '@')); |
| 251 | p->fd = String2Int64(string(&zName[1])); |
| 252 | if (p->fd < 0) |
| 253 | return SQLITE_IOERR; |
| 254 | const int64_t size = cache_mgr->GetSize(p->fd); |
| 255 | if (size < 0) { |
| 256 | cache_mgr->Close(p->fd); |
| 257 | p->fd = -1; |
| 258 | return SQLITE_IOERR_FSTAT; |
| 259 | } |
| 260 | if (cache_mgr->Readahead(p->fd) != 0) { |
| 261 | cache_mgr->Close(p->fd); |
| 262 | p->fd = -1; |
| 263 | return SQLITE_IOERR; |
| 264 | } |
| 265 | p->size = static_cast<uint64_t>(size); |
| 266 | if (pOutFlags) |
| 267 | *pOutFlags = flags; |
| 268 | p->vfs_rdonly = reinterpret_cast<VfsRdOnly *>(vfs->pAppData); |
| 269 | p->base.pMethods = &io_methods; |
| 270 | perf::Inc(p->vfs_rdonly->no_open); |
| 271 | LogCvmfs(kLogSql, kLogDebug, "open sqlite3 catalog on fd %d, size %" PRIu64, |
| 272 | p->fd, p->size); |
| 273 | return SQLITE_OK; |
| 274 | } |
| 275 |