SQLite

Check-in [a480a8845f]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment: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)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: a480a8845fb3b49967de0790b30e6250c824b9be
User & Date: drh 2008-07-30 17:28:04.000
Context
2008-07-31
01:34
Improved retry logic for winDelete() when in "pending delete" state. (CVS 5505) (check-in: 03a7973477 user: shane tags: trunk)
2008-07-30
17:28
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) (check-in: a480a8845f user: drh tags: trunk)
15:27
In the unix OS implementation, replace inode hash tables with linked lists. (CVS 5503) (check-in: db4022db64 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/os_unix.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** 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 $
*/
#include "sqliteInt.h"
#if SQLITE_OS_UNIX              /* This file is used on unix only */

/*
** If SQLITE_ENABLE_LOCKING_STYLE is defined, then several different 
** locking implementations are provided:







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains code that is specific to Unix systems.
**
** $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 */

/*
** If SQLITE_ENABLE_LOCKING_STYLE is defined, then several different 
** locking implementations are provided:
669
670
671
672
673
674
675


















676
677
678
679
680
681
682
  rc = fstat(fd, &statbuf);
  if( rc!=0 ){
#ifdef EOVERFLOW
    if( errno==EOVERFLOW ) return SQLITE_NOLFS;
#endif
    return SQLITE_IOERR;
  }



















  memset(&key1, 0, sizeof(key1));
  key1.dev = statbuf.st_dev;
  key1.ino = statbuf.st_ino;
#if SQLITE_THREADSAFE
  if( threadsOverrideEachOthersLocks<0 ){
    testThreadLockingBehavior(fd);







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
  rc = fstat(fd, &statbuf);
  if( rc!=0 ){
#ifdef EOVERFLOW
    if( errno==EOVERFLOW ) return SQLITE_NOLFS;
#endif
    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;
#if SQLITE_THREADSAFE
  if( threadsOverrideEachOthersLocks<0 ){
    testThreadLockingBehavior(fd);
1088
1089
1090
1091
1092
1093
1094










1095
1096
1097
1098
1099
1100
1101
  assert( id );
  rc = fstat(((unixFile*)id)->h, &buf);
  SimulateIOError( rc=1 );
  if( rc!=0 ){
    return SQLITE_IOERR_FSTAT;
  }
  *pSize = buf.st_size;










  return SQLITE_OK;
}

/*
** This routine checks if there is a RESERVED lock held on the specified
** file by this or any other process. If such a lock is held, return
** non-zero.  If the file is unlocked or holds only SHARED locks, then







>
>
>
>
>
>
>
>
>
>







1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
  assert( id );
  rc = fstat(((unixFile*)id)->h, &buf);
  SimulateIOError( rc=1 );
  if( rc!=0 ){
    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;
}

/*
** This routine checks if there is a RESERVED lock held on the specified
** file by this or any other process. If such a lock is held, return
** non-zero.  If the file is unlocked or holds only SHARED locks, then
Changes to test/incrvacuum.test.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37



38
39
40
41
42
43
44
45
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the incremental vacuum feature.
#
# 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 $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If this build of the library does not support auto-vacuum, omit this
# whole file.
ifcapable {!autovacuum || !pragma} {
  finish_test
  return
}

#---------------------------------------------------------------------
# Test the pragma on an empty database.
#
do_test incrvacuum-1.1 {
  execsql {
    pragma auto_vacuum;
  }
} $sqlite_options(default_autovacuum)
do_test incrvacuum-1.2.0 {



  expr {[file size test.db] > 0}
} {0}
do_test incrvacuum-1.2 {
  # This command will create the database.
  execsql {
    pragma auto_vacuum = 'full';
    pragma auto_vacuum;
  }







|




















>
>
>
|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the incremental vacuum feature.
#
# Note: There are also some tests for incremental vacuum and IO 
# errors in incrvacuum_ioerr.test.
#
# $Id: incrvacuum.test,v 1.19 2008/07/30 17:28:04 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If this build of the library does not support auto-vacuum, omit this
# whole file.
ifcapable {!autovacuum || !pragma} {
  finish_test
  return
}

#---------------------------------------------------------------------
# Test the pragma on an empty database.
#
do_test incrvacuum-1.1 {
  execsql {
    pragma auto_vacuum;
  }
} $sqlite_options(default_autovacuum)
do_test incrvacuum-1.2.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.
  execsql {
    pragma auto_vacuum = 'full';
    pragma auto_vacuum;
  }
685
686
687
688
689
690
691



692
693
694
695
696
697
698
699
db2 close
db close
file delete -force test.db test.db-journal
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}
} {0}
do_test incrvacuum-13.2 {
  set ::STMT [sqlite3_prepare $::DB {PRAGMA auto_vacuum = 2} -1 DUMMY]
  execsql {
    PRAGMA auto_vacuum = none;
    PRAGMA default_cache_size = 1024;
    PRAGMA auto_vacuum;







>
>
>
|







688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
db2 close
db close
file delete -force test.db test.db-journal
sqlite3 db test.db  ;  set ::DB [sqlite3_connection_pointer db]
sqlite3 db2 test.db

do_test incrvacuum-13.1 {
  # 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]
  execsql {
    PRAGMA auto_vacuum = none;
    PRAGMA default_cache_size = 1024;
    PRAGMA auto_vacuum;
Changes to test/io.test.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
#
# The focus of this file is testing some specific characteristics of the 
# 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 $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

db close
sqlite3_simulate_device
sqlite3 db test.db -vfs devsym







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
#
# The focus of this file is testing some specific characteristics of the 
# 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.17 2008/07/30 17:28:04 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

db close
sqlite3_simulate_device
sqlite3 db test.db -vfs devsym
371
372
373
374
375
376
377


378
379
380
381
382
383
384
385
  do_test io-3.1 {
    db close
    file delete -force test.db test.db-journal
    sqlite3 db test.db -vfs devsym
    db eval {
      PRAGMA auto_vacuum=OFF;
    }


    file size test.db
  } {0}
  do_test io-3.2 {
    execsql { CREATE TABLE abc(a, b) }
    nSync
    execsql {
      PRAGMA cache_size = 10;
      BEGIN;







>
>
|







371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
  do_test io-3.1 {
    db close
    file delete -force test.db test.db-journal
    sqlite3 db test.db -vfs devsym
    db eval {
      PRAGMA auto_vacuum=OFF;
    }
    # 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) }
    nSync
    execsql {
      PRAGMA cache_size = 10;
      BEGIN;