From: stephan Date: Sat, 22 Nov 2025 07:35:36 +0000 (+0000) Subject: Incremental work on kvvfs v2. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ec274603f19eb2cbf2f5c75d75c12162c41c0e11;p=thirdparty%2Fsqlite.git Incremental work on kvvfs v2. FossilOrigin-Name: 60d61cf383b63b25dcfbf8da9539aaec253b6618ec83403f6690b7a32c13363d --- diff --git a/ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js b/ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js index 05de2c40e5..8e907e3e36 100644 --- a/ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js +++ b/ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js @@ -47,6 +47,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ const warn = function(){ sqlite3.config.warn("kvvfs:", ...arguments); }; + const error = function(){ + sqlite3.config.error("kvvfs:", ...arguments); + }; /** Implementation of JS's Storage interface for use as backing store @@ -302,6 +305,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ const pVfs = new capi.sqlite3_vfs(kvvfsMethods.$pVfs); const pIoDb = new capi.sqlite3_io_methods(kvvfsMethods.$pIoDb); const pIoJrnl = new capi.sqlite3_io_methods(kvvfsMethods.$pIoJrnl); + const recordHandler = Object.create(null); /** Implementations for members of the object referred to by sqlite3__wasm_kvvfs_methods(). We swap out the native @@ -327,6 +331,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ astack = wasm.scopedAllocPush(); try{ const store = storageForZClass(zClass); + if( !store ) return -1; + if( 0 ){ + debug("xRcrdRead", nBuf, zClass, wasm.cstrToJs(zClass), + wasm.cstrToJs(zKey), store); + } const zXKey = keyForStorage(store, zClass, zKey); if(!zXKey) return -3/*OOM*/; const jV = store.s.getItem(wasm.cstrToJs(zXKey)); @@ -347,10 +356,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ wasm.heap8u().copyWithin( Number(zBuf), Number(zV), wasm.ptr.addn(zV, nBuf,- 1) ); - wasm.poke(wasm.ptr.add(zBuf, nBuf, -1), 0); + wasm.poke(wasm.ptr.add(zBuf, nBuf), 0); return nBuf - 1; }catch(e){ - sqlite3.config.error("kvrecordRead()",e); + error("kvrecordRead()",e); return -2; }finally{ pstack.restore(stack); @@ -370,7 +379,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ); return 0; }catch(e){ - sqlite3.config.error("kvrecordWrite()",e); + error("kvrecordWrite()",e); return capi.SQLITE_IOERR; }finally{ pstack.restore(stack); @@ -386,7 +395,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ store.s.removeItem(wasm.cstrToJs(zXKey)); return 0; }catch(e){ - sqlite3.config.error("kvrecordDelete()",e); + error("kvrecordDelete()",e); return capi.SQLITE_IOERR; }finally{ pstack.restore(stack); @@ -450,59 +459,75 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ return capi.SQLITE_ERROR; } }/*xOpen()*/, -//#if nope - xAccess:function(pProtoVfs, zPath, flags, pResOut){ - /* Triggering an abort() via xClose(), but we'll need a working - xAccess() if we want to use kvvfs as the default vfs. */ + + xDelete: function(pVfs, zName, iSyncFlag){ try{ - let drc = 0; - const jzName = wasm.cstrToJs(zPath); - const s = cache.jzClassToStorage[jzName]; - debug("xAccess", jzName, s); - if( s ){ - if( 0 && !jzName.endsWith("-journal") ){ - drc = 1; - }else{ - const zKey = jzName.endsWith("-journal") - ? cache.zKeyJrnl - : cache.zKeySz; - drc = sqlite3_kvvfs_methods.override.recordHandler - .xRcrdRead(zPath, zKey, wasm.ptr.null, 0); + if( 0 ){ + util.assert(zName, "null zName?"); + const jzName = wasm.cstrToJs(zName); + const s = cache.jzClassToStorage[jzName]; + debug("xDelete", jzName, s); + if( cache.rxJournalSuffix.test(jzName) ){ + recordHandler.xRcrdDelete(zName, cache.zKeyJrnl); } + return 0; } - wasm.poke32(pResOut, drc>0 ? 1 : 0); - return 0; + return originalMethods.vfs.xDelete(pVfs, zName, iSyncFlag); }catch(e){ - warn("xAccess",e); + warn("xDelete",e); return capi.SQLITE_ERROR; } - }/*xAccess*/, - xDelete: function(pVfs, zName, iSyncFlag){ + }, + + xAccess:function(pProtoVfs, zPath, flags, pResOut){ try{ - // Triggering an abort() via xClose() - util.assert(zName, "null zName?"); - const jzName = wasm.cstrToJs(zName); - const s = cache.jzClassToStorage[jzName]; - debug("xDelete", jzName, s); - if( s ){ - if( jzName.endsWith("-journal") ){ - const zKey = cache.zKeyJrnl; - util.assert(zKey, "Missing cache.zKeyJrnl"); - sqlite3_kvvfs_methods.override.recordHandler - .xRcrdDelete(zName, zKey); - }else{ - drc = 1; - delete cache.jzClassToStorage[jzName]; + if( 0 ){ + const jzName = wasm.cstrToJs(zPath); + const s = cache.jzClassToStorage[jzName]; + debug("xAccess", jzName, s); + let drc = 1; + wasm.poke32(pResOut, 0); + if( s ){ + /* This block is _somehow_ triggering an + abort() via xClose(). */ + if(0) debug("cache.zKeyJrnl...",wasm.cstrToJs(cache.zKeyJrnl), + wasm.cstrToJs(cache.zKeySz)); + drc = recordHandler.xRcrdRead( + zPath, + jzName.endsWith("-journal") + ? cache.zKeyJrnl + : cache.zKeySz, + wasm.ptr.null, 0 + ); + debug("xAccess", jzName, drc, pResOut); + if( drc>0 ){ + wasm.poke32( + pResOut, 1 + /* This poke is triggering an abort via xClose(). + If we poke 0 then no problem... except that + xAccess() doesn't report the truth. Same effect + if we move that to the native impl + os_kv.c:kvvfsAccess(). */ + ); + } } return 0; - }else{ - return originalMethods.vfs.xDelete(pVfs, zName, iSyncFlag); } + const rc = originalMethods.vfs.xAccess( + pProtoVfs, zPath, flags, pResOut + /* This one is only valid for local/session storage */ + ); + if( 0 && 0===rc ){ + debug("xAccess pResOut", wasm.peek32(pResOut)); + } + return rc; }catch(e){ - warn("xDelete",e); + error('xAccess',e); return capi.SQLITE_ERROR; } }, + +//#if nope xFullPathname: function(pVfs, zPath, nOut, zOut){}, xDlOpen: function(pVfs, zFilename){}, xSleep: function(pVfs,usec){}, @@ -544,8 +569,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ delete s.s; delete s.refc; } - h.f.dispose(); originalIoMethods(h.f).xClose(pFile); + h.f.dispose(); }else{ /* Can happen if xOpen fails */ } @@ -594,10 +619,13 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }/*sqlite3_kvvfs_methods.override*/; const ov = sqlite3_kvvfs_methods.override; - debug("pVfs and friends", pVfs, pIoDb, pIoJrnl); + debug("pVfs and friends", pVfs, pIoDb, pIoJrnl, + kvvfsMethods, capi.sqlite3_file.structInfo, + KVVfsFile.structInfo); try { for(const e of Object.entries(ov.recordHandler)){ // Overwrite kvvfsMethods's callbacks + recordHandler[e[0]] = e[1]; kvvfsMethods[kvvfsMethods.memberKey(e[0])] = wasm.installFunction(kvvfsMethods.memberSignature(e[0]), e[1]); } @@ -612,12 +640,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } for(const e of Object.entries(ov.ioDb)){ // Similar treatment for pVfs.$pIoDb a.k.a. pIoDb... - const k = e[0], f = e[1], km = pIoDb.memberKey(k), - member = pIoDb.structInfo.members[k] - || util.toss("Missing pIoDb.structInfo[",k,"]"); + const k = e[0], f = e[1], km = pIoDb.memberKey(k); originalMethods.ioDb[k] = wasm.functionEntry(pIoDb[km]) || util.toss("Missing native pIoDb[",km,"]"); - pIoDb[km] = wasm.installFunction(member.signature, f); + pIoDb[km] = wasm.installFunction(pIoDb.memberSignature(k), f); } for(const e of Object.entries(ov.ioJrnl)){ // Similar treatment for pVfs.$pIoJrnl a.k.a. pIoJrnl... @@ -628,8 +654,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ /* use pIoDb's copy */ pIoJrnl[km] = pIoDb[km] || util.toss("Missing copied pIoDb[",km,"]"); }else{ - const member = pIoJrnl.structInfo.members[k] - || util.toss("Missing pIoJrnl.structInfo[",k,"]"); pIoJrnl[km] = wasm.installFunction(pIoJrnl.memberSignature(k), f); } } diff --git a/manifest b/manifest index b47629356b..bce3dbeea0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Factor\sKVVfsFile::zName\sback\sout.\sRemove\sthe\sextraneous\spart\sof\sthe\sstorage\skeys\sfor\snon-local/non-session\sstorage. -D 2025-11-22T05:37:21.474 +C Incremental\swork\son\skvvfs\sv2. +D 2025-11-22T07:35:36.321 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -600,7 +600,7 @@ F ext/wasm/api/sqlite3-api-worker1.c-pp.js 1041dd645e8e821c082b628cd8d9acf70c667 F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 F ext/wasm/api/sqlite3-opfs-async-proxy.js 9654b565b346dc609b75d15337f20acfa7af7d9d558da1afeb9b6d8eaa404966 F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c8fb7f0630264e6c7fa0e57515d -F ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js a0835218719d0ec6bfc79ec29d44d2028ef98a7c1b1aeee75f4338f5d3eb337c +F ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js f6eeaeccd0a6e1fd3fe58dba8e09954a32f8f7097fae4c00e519d91a72c7be1d F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 26cb41d5a62f46a106b6371eb00fef02de3cdbfaa51338ba087a45f53028e0d0 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js aa330fa0e8ef35cbd92eb0d52e05fbaa07e61540c5cb164e693c82428ce1d763 F ext/wasm/api/sqlite3-vtab-helper.c-pp.js 9097074724172e31e56ce20ccd7482259cf72a76124213cbc9469d757676da86 @@ -717,7 +717,7 @@ F src/notify.c 57c2d1a2805d6dee32acd5d250d928ab94e02d76369ae057dee7d445fd64e878 F src/os.c 509452169d5ea739723e213b8e2481cf0e587f0e88579a912d200db5269f5f6d F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63 F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06 -F src/os_kv.c 59f41c1ac47f9d1f89d3c04eb08b7f91e14e903d2b44e10a29e803ee353553a1 +F src/os_kv.c f11812682d83d125fb25c34db44d3091e4171662e087080ad2067203cc0606aa F src/os_setup.h 8efc64eda6a6c2f221387eefc2e7e45fd5a3d5c8337a7a83519ba4fbd2957ae2 F src/os_unix.c 7945ede1e85b2d1b910e1b4af9ba342e964b1e30e79f4176480a60736445cb36 F src/os_win.c a89b501fc195085c7d6c9eec7f5bd782625e94bb2a96b000f4d009703df1083f @@ -2178,8 +2178,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3f9ff9873303c3900dd3cba6e922bfb8cdb1f595353b692796b62e3025013517 -R 3850965b51b022600461307bc9bfa402 +P d2bf96d68c6cb2ae68558722edb22192fb1dbbf08fefdb2fd0a4827688e082a8 +R edd2150137694760800c3d7cae9ac6f3 U stephan -Z 2898a867b93493236c621da268e3979f +Z 821185e1e7c2969ce068a864d05b8e47 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 28409835c2..3f7d6d560e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d2bf96d68c6cb2ae68558722edb22192fb1dbbf08fefdb2fd0a4827688e082a8 +60d61cf383b63b25dcfbf8da9539aaec253b6618ec83403f6690b7a32c13363d diff --git a/src/os_kv.c b/src/os_kv.c index 337cf1b0a9..feb3536f4c 100644 --- a/src/os_kv.c +++ b/src/os_kv.c @@ -918,6 +918,20 @@ static int kvvfsAccess( int *pResOut ){ SQLITE_KV_LOG(("xAccess(\"%s\")\n", zPath)); +#if 0 && defined(SQLITE_WASM) + /* + ** Bug somewhere: if this method sets *pResOut to non-0 then + ** xClose() is abort()ing via free(). The symptoms are the same + ** whether we set *pResOut from here or from JS. + */ + if( 0==sqlite3_strglob("*-journal", zPath) ){ + *pResOut = + sqlite3KvvfsMethods.xRcrdRead(zPath, "jrnl", 0, 0)>0; + }else{ + *pResOut = + sqlite3KvvfsMethods.xRcrdRead(zPath, "sz", 0, 0)>0; + } +#else if( strcmp(zPath, "local-journal")==0 ){ *pResOut = sqlite3KvvfsMethods.xRcrdRead("local", "jrnl", 0, 0)>0; @@ -937,6 +951,8 @@ static int kvvfsAccess( { *pResOut = 0; } + /*all current JS tests avoid triggering: assert( *pResOut == 0 ); */ +#endif SQLITE_KV_LOG(("xAccess returns %d\n",*pResOut)); return SQLITE_OK; }