Index: src/os.c ================================================================== --- src/os.c +++ src/os.c @@ -73,10 +73,13 @@ return id->pMethod->xLockState(id); } int sqlite3OsCheckReservedLock(OsFile *id){ return id->pMethod->xCheckReservedLock(id); } +int sqlite3OsSectorSize(OsFile *id){ + return id->pMethod->xSectorSize(id); +} #ifdef SQLITE_ENABLE_REDEF_IO /* ** A function to return a pointer to the virtual function table. ** This routine really does not accomplish very much since the Index: src/os.h ================================================================== --- src/os.h +++ src/os.h @@ -214,10 +214,11 @@ int (*xFileSize)(OsFile*, i64 *pSize); int (*xLock)(OsFile*, int); int (*xUnlock)(OsFile*, int); int (*xLockState)(OsFile *id); int (*xCheckReservedLock)(OsFile *id); + int (*xSectorSize)(OsFile *id); }; /* ** The OsFile object describes an open disk file in an OS-dependent way. ** The version of OsFile defined here is a generic version. Each OS @@ -344,10 +345,11 @@ int sqlite3OsDelete(const char*); int sqlite3OsFileExists(const char*); char *sqlite3OsFullPathname(const char*); int sqlite3OsIsDirWritable(char*); int sqlite3OsSyncDirectory(const char*); +int sqlite3OsSectorSize(OsFile *id); int sqlite3OsTempFileName(char*); int sqlite3OsRandomSeed(char*); int sqlite3OsSleep(int ms); int sqlite3OsCurrentTime(double*); void sqlite3OsEnterMutex(void); Index: src/os_common.h ================================================================== --- src/os_common.h +++ src/os_common.h @@ -188,5 +188,16 @@ free(p); } /* Never actually used, but needed for the linker */ int sqlite3GenericAllocationSize(void *p){ return 0; } #endif + +/* +** The default size of a disk sector +*/ +#ifndef PAGER_SECTOR_SIZE +# define PAGER_SECTOR_SIZE 512 +#endif +static int osGenericSectorSize(OsFile *id){ + return PAGER_SECTOR_SIZE; +} + Index: src/os_os2.c ================================================================== --- src/os_os2.c +++ src/os_os2.c @@ -749,10 +749,11 @@ os2FileSize, os2Lock, os2Unlock, os2LockState, os2CheckReservedLock, + osGenericSectorSize, }; /* ** Allocate memory for an OsFile. Initialize the new OsFile ** to the value given in pInit and return a pointer to the new Index: src/os_unix.c ================================================================== --- src/os_unix.c +++ src/os_unix.c @@ -2353,10 +2353,11 @@ unixFileSize, unixLock, unixUnlock, unixLockState, unixCheckReservedLock, + osGenericSectorSize, }; #ifdef SQLITE_ENABLE_LOCKING_STYLE /* ** This vector defines all the methods that can operate on an OsFile @@ -2375,10 +2376,11 @@ unixFileSize, afpUnixLock, afpUnixUnlock, unixLockState, afpUnixCheckReservedLock, + osGenericSectorSize, }; /* ** This vector defines all the methods that can operate on an OsFile ** for unix with flock() style file locking. @@ -2396,10 +2398,11 @@ unixFileSize, flockUnixLock, flockUnixUnlock, unixLockState, flockUnixCheckReservedLock, + osGenericSectorSize, }; /* ** This vector defines all the methods that can operate on an OsFile ** for unix with dotlock style file locking. @@ -2417,10 +2420,11 @@ unixFileSize, dotlockUnixLock, dotlockUnixUnlock, unixLockState, dotlockUnixCheckReservedLock, + osGenericSectorSize, }; /* ** This vector defines all the methods that can operate on an OsFile ** for unix with dotlock style file locking. @@ -2438,10 +2442,11 @@ unixFileSize, nolockUnixLock, nolockUnixUnlock, unixLockState, nolockUnixCheckReservedLock, + osGenericSectorSize, }; #endif /* SQLITE_ENABLE_LOCKING_STYLE */ /* Index: src/os_win.c ================================================================== --- src/os_win.c +++ src/os_win.c @@ -1471,10 +1471,11 @@ winFileSize, winLock, winUnlock, winLockState, winCheckReservedLock, + osGenericSectorSize, }; /* ** Allocate memory for an OsFile. Initialize the new OsFile ** to the value given in pInit and return a pointer to the new Index: src/pager.c ================================================================== --- src/pager.c +++ src/pager.c @@ -16,11 +16,11 @@ ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.288 2007/03/15 12:51:16 drh Exp $ +** @(#) $Id: pager.c,v 1.289 2007/03/19 05:54:49 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include "os.h" #include "pager.h" @@ -347,17 +347,10 @@ # define MEMDB 0 #else # define MEMDB pPager->memDb #endif -/* -** The default size of a disk sector -*/ -#ifndef PAGER_SECTOR_SIZE -# define PAGER_SECTOR_SIZE 512 -#endif - /* ** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is ** reserved for working around a windows/posix incompatibility). It is ** used in the journal to signify that the remainder of the journal file ** is devoted to storing a master journal name - there are no more pages to @@ -1392,11 +1385,11 @@ /* The Pager.sectorSize variable may have been updated while rolling ** back a journal created by a process with a different PAGER_SECTOR_SIZE ** value. Reset it to the correct value for this process. */ - pPager->sectorSize = PAGER_SECTOR_SIZE; + pPager->sectorSize = sqlite3OsSectorSize(pPager->fd); return rc; } /* ** Playback the statement journal. @@ -1736,11 +1729,14 @@ pPager->fullSync = (pPager->noSync?0:1); /* pPager->pFirst = 0; */ /* pPager->pFirstSynced = 0; */ /* pPager->pLast = 0; */ pPager->nExtra = FORCE_ALIGNMENT(nExtra); - pPager->sectorSize = PAGER_SECTOR_SIZE; + assert(fd||memDb); + if( !memDb ){ + pPager->sectorSize = sqlite3OsSectorSize(fd); + } /* pPager->pBusyHandler = 0; */ /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ *ppPager = pPager; #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT pPager->pNext = pTsd->pPager; Index: src/test6.c ================================================================== --- src/test6.c +++ src/test6.c @@ -475,10 +475,17 @@ #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) return sqlite3OsFileHandle(((crashFile*)id)->pBase); #endif return 0; } + +/* +** Return the simulated file-system sector size. +*/ +int crashSectorSize(OsFile *id){ + return BLOCKSIZE; +} /* ** This vector defines all the methods that can operate on an OsFile ** for the crash tester. */ @@ -495,10 +502,11 @@ crashFileSize, crashLock, crashUnlock, crashLockState, crashCheckReservedLock, + crashSectorSize, }; /* ** Initialise the os_test.c specific fields of pFile. Index: src/test_async.c ================================================================== --- src/test_async.c +++ src/test_async.c @@ -647,10 +647,17 @@ rc = (int)sqlite3HashFind(&async.aLock, pFile->zName, pFile->nName); pthread_mutex_unlock(&async.lockMutex); TRACE(("CHECK-LOCK %d (%s)\n", rc, pFile->zName)); return rc>SHARED_LOCK; } + +static int asyncSectorSize(OsFile *id){ + /* TODO: This is tricky to implement, as this backend might not have + ** an open file handle at this point. + */ + return 512; +} /* ** This is broken. But sqlite3OsLockState() is only used for testing anyway. */ static int asyncLockState(OsFile *id){ @@ -695,11 +702,12 @@ asyncFileHandle, asyncFileSize, asyncLock, asyncUnlock, asyncLockState, - asyncCheckReservedLock + asyncCheckReservedLock, + asyncSectorSize, }; if( openForWriting && SQLITE_ASYNC_TWO_FILEHANDLES ){ int dummy; rc = xOrigOpenReadWrite(zName, &pBaseWrite, &dummy); Index: test/crash2.test ================================================================== --- test/crash2.test +++ test/crash2.test @@ -14,11 +14,11 @@ # uses its rollback journal to recover intact (no database corruption) # from a power failure during the middle of a COMMIT. Even more # specifically, the tests in this file verify this functionality # for storage mediums with various sector sizes. # -# $Id: crash2.test,v 1.1 2007/03/17 10:28:05 danielk1977 Exp $ +# $Id: crash2.test,v 1.2 2007/03/19 05:54:50 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !crashtest {