SQLite

Check-in [93e792ffa8]
Login

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

Overview
Comment:Add assert() statements to os_unix.c which fire if there is a read or write for the locking region of a database file. (CVS 6270)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 93e792ffa88ba2e8422d041f36b70d9b2e220da2
User & Date: drh 2009-02-09 17:34:07.000
Context
2009-02-09
18:55
Fix a problem in backup.c causing OsTruncate() to be called with an argument larger than the current file-size. (CVS 6271) (check-in: b34bde80c7 user: danielk1977 tags: trunk)
17:34
Add assert() statements to os_unix.c which fire if there is a read or write for the locking region of a database file. (CVS 6270) (check-in: 93e792ffa8 user: drh tags: trunk)
13:19
Better error message when DISTINCT is used on an aggregate function that takes two or more arguments. Ticket #3641. (CVS 6269) (check-in: e20bf38466 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/os_unix.c.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**   *  Definitions of sqlite3_io_methods objects for all locking
**      methods plus "finder" functions for each locking method.
**   *  sqlite3_vfs method implementations.
**   *  Locking primitives for the proxy uber-locking-method. (MacOSX only)
**   *  Definitions of sqlite3_vfs objects for all locking methods
**      plus implementations of sqlite3_os_init() and sqlite3_os_end().
**
** $Id: os_unix.c,v 1.240 2009/02/09 05:32:32 danielk1977 Exp $
*/
#include "sqliteInt.h"
#if SQLITE_OS_UNIX              /* This file is used on unix only */

/*
** There are various methods for file locking used for concurrency
** control:







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**   *  Definitions of sqlite3_io_methods objects for all locking
**      methods plus "finder" functions for each locking method.
**   *  sqlite3_vfs method implementations.
**   *  Locking primitives for the proxy uber-locking-method. (MacOSX only)
**   *  Definitions of sqlite3_vfs objects for all locking methods
**      plus implementations of sqlite3_os_init() and sqlite3_os_end().
**
** $Id: os_unix.c,v 1.241 2009/02/09 17:34:07 drh Exp $
*/
#include "sqliteInt.h"
#if SQLITE_OS_UNIX              /* This file is used on unix only */

/*
** There are various methods for file locking used for concurrency
** control:
179
180
181
182
183
184
185

186

187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204





205
206
207
208
209
210
211
  struct unixOpenCnt *pOpen;       /* Info about all open fd's on this inode */
  struct unixLockInfo *pLock;      /* Info about locks on this inode */
  int h;                           /* The file descriptor */
  int dirfd;                       /* File descriptor for the directory */
  unsigned char locktype;          /* The type of lock held on this fd */
  int lastErrno;                   /* The unix errno from the last I/O error */
  void *lockingContext;            /* Locking style specific state */

  int openFlags;                   /* The flags specified at open */

#if SQLITE_THREADSAFE && defined(__linux__)
  pthread_t tid;                   /* The thread that "owns" this unixFile */
#endif
#if OS_VXWORKS
  int isDelete;                    /* Delete on close if true */
  struct vxworksFileId *pId;       /* Unique file ID */
#endif
#ifndef NDEBUG
  /* The next group of variables are used to track whether or not the
  ** transaction counter in bytes 24-27 of database files are updated
  ** whenever any part of the database changes.  An assertion fault will
  ** occur if a file is updated without also updating the transaction
  ** counter.  This test is made to avoid new problems similar to the
  ** one described by ticket #3584. 
  */
  unsigned char transCntrChng;   /* True if the transaction counter changed */
  unsigned char dbUpdate;        /* True if any part of database file changed */
  unsigned char inNormalWrite;   /* True if in a normal write operation */





#endif
#ifdef SQLITE_TEST
  /* In test mode, increase the size of this structure a bit so that 
  ** it is larger than the struct CrashFile defined in test6.c.
  */
  char aPadding[32];
#endif







>
|
>


















>
>
>
>
>







179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
  struct unixOpenCnt *pOpen;       /* Info about all open fd's on this inode */
  struct unixLockInfo *pLock;      /* Info about locks on this inode */
  int h;                           /* The file descriptor */
  int dirfd;                       /* File descriptor for the directory */
  unsigned char locktype;          /* The type of lock held on this fd */
  int lastErrno;                   /* The unix errno from the last I/O error */
  void *lockingContext;            /* Locking style specific state */
#if SQLITE_ENABLE_LOCKING_STYLE
  int openFlags;                   /* The flags specified at open() */
#endif
#if SQLITE_THREADSAFE && defined(__linux__)
  pthread_t tid;                   /* The thread that "owns" this unixFile */
#endif
#if OS_VXWORKS
  int isDelete;                    /* Delete on close if true */
  struct vxworksFileId *pId;       /* Unique file ID */
#endif
#ifndef NDEBUG
  /* The next group of variables are used to track whether or not the
  ** transaction counter in bytes 24-27 of database files are updated
  ** whenever any part of the database changes.  An assertion fault will
  ** occur if a file is updated without also updating the transaction
  ** counter.  This test is made to avoid new problems similar to the
  ** one described by ticket #3584. 
  */
  unsigned char transCntrChng;   /* True if the transaction counter changed */
  unsigned char dbUpdate;        /* True if any part of database file changed */
  unsigned char inNormalWrite;   /* True if in a normal write operation */

  /* If true, that means we are dealing with a database file that has
  ** a range of locking bytes from PENDING_BYTE through PENDING_BYTE+511
  ** which should never be read or written.  Asserts() will verify this */
  unsigned char isLockable;      /* True if file might be locked */
#endif
#ifdef SQLITE_TEST
  /* In test mode, increase the size of this structure a bit so that 
  ** it is larger than the struct CrashFile defined in test6.c.
  */
  char aPadding[32];
#endif
2685
2686
2687
2688
2689
2690
2691






2692
2693
2694
2695
2696
2697
2698
  sqlite3_file *id, 
  void *pBuf, 
  int amt,
  sqlite3_int64 offset
){
  int got;
  assert( id );






  got = seekAndRead((unixFile*)id, offset, pBuf, amt);
  if( got==amt ){
    return SQLITE_OK;
  }else if( got<0 ){
    /* lastErrno set by seekAndRead */
    return SQLITE_IOERR_READ;
  }else{







>
>
>
>
>
>







2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
  sqlite3_file *id, 
  void *pBuf, 
  int amt,
  sqlite3_int64 offset
){
  int got;
  assert( id );

  /* Never read or write any of the bytes in the locking range */
  assert( ((unixFile*)id)->isLockable==0
          || offset>=PENDING_BYTE+512
          || offset+amt<=PENDING_BYTE );

  got = seekAndRead((unixFile*)id, offset, pBuf, amt);
  if( got==amt ){
    return SQLITE_OK;
  }else if( got<0 ){
    /* lastErrno set by seekAndRead */
    return SQLITE_IOERR_READ;
  }else{
2749
2750
2751
2752
2753
2754
2755





2756
2757
2758
2759
2760
2761
2762
  const void *pBuf, 
  int amt,
  sqlite3_int64 offset 
){
  int wrote = 0;
  assert( id );
  assert( amt>0 );






#ifndef NDEBUG
  /* If we are doing a normal write to a database file (as opposed to
  ** doing a hot-journal rollback or a write to some file other than a
  ** normal database file) then record the fact that the database
  ** has changed.  If the transaction counter is modified, record that
  ** fact too.







>
>
>
>
>







2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
  const void *pBuf, 
  int amt,
  sqlite3_int64 offset 
){
  int wrote = 0;
  assert( id );
  assert( amt>0 );

  /* Never read or write any of the bytes in the locking range */
  assert( ((unixFile*)id)->isLockable==0
          || offset>=PENDING_BYTE+512
          || offset+amt<=PENDING_BYTE );

#ifndef NDEBUG
  /* If we are doing a normal write to a database file (as opposed to
  ** doing a hot-journal rollback or a write to some file other than a
  ** normal database file) then record the fact that the database
  ** has changed.  If the transaction counter is modified, record that
  ** fact too.
3673
3674
3675
3676
3677
3678
3679






3680
3681
3682
3683
3684
3685
3686
  else{
    ((unixFile*)pFile)->openFlags = openFlags;
  }
#endif
  if( pOutFlags ){
    *pOutFlags = flags;
  }







  assert(fd!=0);
  if( isOpenDirectory ){
    rc = openDirectory(zPath, &dirfd);
    if( rc!=SQLITE_OK ){
      close(fd); /* silently leak if fail, already in error */
      return rc;







>
>
>
>
>
>







3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
  else{
    ((unixFile*)pFile)->openFlags = openFlags;
  }
#endif
  if( pOutFlags ){
    *pOutFlags = flags;
  }

#ifndef NDEBUG
  if( (flags & SQLITE_OPEN_MAIN_DB)!=0 ){
    ((unixFile*)pFile)->isLockable = 1;
  }
#endif

  assert(fd!=0);
  if( isOpenDirectory ){
    rc = openDirectory(zPath, &dirfd);
    if( rc!=SQLITE_OK ){
      close(fd); /* silently leak if fail, already in error */
      return rc;