From: drh Date: Wed, 30 Jul 2008 17:28:04 +0000 (+0000) Subject: When opening a zero-size database on unix, write one byte into the file before X-Git-Tag: version-3.6.10~673 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5462624dc4a05fee06396f7f284db4d1a8d57e6b;p=thirdparty%2Fsqlite.git When opening a zero-size database on unix, write one byte into the file before interrogating the inode number. This works around issues with msdos filesystems mounted on OS-X. Ticket #3260. (CVS 5504) FossilOrigin-Name: a480a8845fb3b49967de0790b30e6250c824b9be --- diff --git a/manifest b/manifest index efd953eb30..f2e8880c8e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sunix\sOS\simplementation,\sreplace\sinode\shash\stables\swith\slinked\slists.\s(CVS\s5503) -D 2008-07-30T15:27:54 +C When\sopening\sa\szero-size\sdatabase\son\sunix,\swrite\sone\sbyte\sinto\sthe\sfile\sbefore\ninterrogating\sthe\sinode\snumber.\s\sThis\sworks\saround\sissues\swith\smsdos\nfilesystems\smounted\son\sOS-X.\s\sTicket\s#3260.\s(CVS\s5504) +D 2008-07-30T17:28:04 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in bbb62eecc851379aef5a48a1bf8787eb13e6ec06 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -133,7 +133,7 @@ F src/os.c 939ae7690a01d9401685ba124b4ba45fd4a7a2ad F src/os.h ef8abeb9afc694b82dbd169a91c9b7e26db3c892 F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60 F src/os_os2.c 676ed273b17bd260f905df81375c9f9950d85517 -F src/os_unix.c c778a6b7098f54ee2e4420150265ad3d26824c96 +F src/os_unix.c fe0dbc35bcd3de49e46b132abfc0f45d6dd6a864 F src/os_win.c 50ec783403b418ddc9e6e05d541c6027dfd41070 F src/pager.c a6ecad26297469a8a3d1fd7a7c3dc2d603955044 F src/pager.h 588c1ac195228b2da45c4e5f7ab6c2fd253d1751 @@ -355,7 +355,7 @@ F test/in3.test dc62b080ed79898121c61c91118b4d1e111f1438 F test/incrblob.test 4455fffd08b2f9418a9257e18b135d72273eff3e F test/incrblob2.test c82a780356bdf4d0c77f1adf0ea888248904fc07 F test/incrblob_err.test c577c91d4ed9e8336cdb188b15d6ee2a6fe9604e -F test/incrvacuum.test 1a2b0bddc76629afeb41e3d8ea3e4563982d16b9 +F test/incrvacuum.test 0684fbd7773eec45b911d46a6f8dc0f220b1223d F test/incrvacuum2.test 46ef65f377e3937cfd1ba66e818309dab46f590d F test/incrvacuum_ioerr.test 57d2f5777ab13fa03b87b262a4ea1bad5cfc0291 F test/index.test cbf301cdb2da43e4eac636c3400c2439af1834ad @@ -368,7 +368,7 @@ F test/insert4.test 6e382eaf7295a4463e6f29ea20fcd8e63d097eeb F test/insert5.test 509017213328147d3acdfa2c441bfd82362dda41 F test/interrupt.test 42e7cf98646fd9cb4a3b131a93ed3c50b9e149f1 F test/intpkey.test 537669fd535f62632ca64828e435b9e54e8d677f -F test/io.test 833a1746518ec3005aa7792f9bcb8f01923ff544 +F test/io.test 23c52939ebf90f00d9cbd819ced6daa9f21445fa F test/ioerr.test b42f249c9181b5864e53fdae38ef75475d71c66f F test/ioerr2.test 5598405c48842c6c0187daad9eb49eff2c54f80d F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd @@ -614,7 +614,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P da0e4bff30a77f72ae283406b547401c2ebb42c5 -R 4761a1459dbfe21d158c4e02d11ac727 +P db4022db64dc5864e6f1d0a20672183879ad43aa +R 46a59a75e0405426ca6be3fd6558aebe U drh -Z 2fbbc6538919439da5b60f94f6787348 +Z f2a23010508f2b32889d0e3805823d10 diff --git a/manifest.uuid b/manifest.uuid index 660828ab40..813079e027 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -db4022db64dc5864e6f1d0a20672183879ad43aa \ No newline at end of file +a480a8845fb3b49967de0790b30e6250c824b9be \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 48d2ff1769..4874a6437d 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -12,7 +12,7 @@ ** ** This file contains code that is specific to Unix systems. ** -** $Id: os_unix.c,v 1.194 2008/07/30 15:27:54 drh Exp $ +** $Id: os_unix.c,v 1.195 2008/07/30 17:28:04 drh Exp $ */ #include "sqliteInt.h" #if SQLITE_OS_UNIX /* This file is used on unix only */ @@ -674,6 +674,24 @@ static int findLockInfo( return SQLITE_IOERR; } + /* On OS X on an msdos filesystem, the inode number is reported + ** incorrectly for zero-size files. See ticket #3260. To work + ** around this problem (we consider it a bug in OS X, not SQLite) + ** we always increase the file size to 1 by writing a single byte + ** prior to accessing the inode number. The one byte written is + ** an ASCII 'S' character which also happens to be the first byte + ** in the header of every SQLite database. In this way, if there + ** is a race condition such that another thread has already populated + ** the first page of the database, no damage is done. + */ + if( statbuf.st_size==0 ){ + write(fd, "S", 1); + rc = fstat(fd, &statbuf); + if( rc!=0 ){ + return SQLITE_IOERR; + } + } + memset(&key1, 0, sizeof(key1)); key1.dev = statbuf.st_dev; key1.ino = statbuf.st_ino; @@ -1092,6 +1110,16 @@ static int unixFileSize(sqlite3_file *id, i64 *pSize){ return SQLITE_IOERR_FSTAT; } *pSize = buf.st_size; + + /* When opening a zero-size database, the findLockInfo() procedure + ** writes a single byte into that file in order to work around a bug + ** in the OS-X msdos filesystem. In order to avoid problems with upper + ** layers, we need to report this file size as zero even though it is + ** really 1. Ticket #3260. + */ + if( *pSize==1 ) *pSize = 0; + + return SQLITE_OK; } diff --git a/test/incrvacuum.test b/test/incrvacuum.test index aebe2178d6..04ea03d04c 100644 --- a/test/incrvacuum.test +++ b/test/incrvacuum.test @@ -14,7 +14,7 @@ # Note: There are also some tests for incremental vacuum and IO # errors in incrvacuum_ioerr.test. # -# $Id: incrvacuum.test,v 1.18 2008/01/21 16:22:46 drh Exp $ +# $Id: incrvacuum.test,v 1.19 2008/07/30 17:28:04 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -35,7 +35,10 @@ do_test incrvacuum-1.1 { } } $sqlite_options(default_autovacuum) do_test incrvacuum-1.2.0 { - expr {[file size test.db] > 0} + # File size is sometimes 1 instead of 0 due to the hack we put in + # to work around ticket #3260. Search for comments on #3260 in + # os_unix.c. + expr {[file size test.db] > 1} } {0} do_test incrvacuum-1.2 { # This command will create the database. @@ -689,7 +692,10 @@ sqlite3 db test.db ; set ::DB [sqlite3_connection_pointer db] sqlite3 db2 test.db do_test incrvacuum-13.1 { - expr {[file size test.db]>0} + # File size is sometimes 1 instead of 0 due to the hack we put in + # to work around ticket #3260. Search for comments on #3260 in + # os_unix.c. + expr {[file size test.db]>1} } {0} do_test incrvacuum-13.2 { set ::STMT [sqlite3_prepare $::DB {PRAGMA auto_vacuum = 2} -1 DUMMY] diff --git a/test/io.test b/test/io.test index b0a6063e7f..12c756acac 100644 --- a/test/io.test +++ b/test/io.test @@ -13,7 +13,7 @@ # IO traffic generated by SQLite (making sure SQLite is not writing out # more database pages than it has to, stuff like that). # -# $Id: io.test,v 1.16 2008/05/01 18:01:47 drh Exp $ +# $Id: io.test,v 1.17 2008/07/30 17:28:04 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -375,7 +375,9 @@ ifcapable pager_pragmas { db eval { PRAGMA auto_vacuum=OFF; } - file size test.db + # File size might be 1 due to the hack to work around ticket #3260. + # Search for #3260 in os_unix.c for additional information. + expr {[file size test.db]>1} } {0} do_test io-3.2 { execsql { CREATE TABLE abc(a, b) }