blob: 41650d98fa5d6b60f0ae93868f0c29d4be95f1d3 [file] [log] [blame]
drhed7c8552001-04-11 14:29:21 +00001/*
2** Copyright (c) 2001 D. Richard Hipp
3**
4** This program is free software; you can redistribute it and/or
5** modify it under the terms of the GNU General Public
6** License as published by the Free Software Foundation; either
7** version 2 of the License, or (at your option) any later version.
8**
9** This program is distributed in the hope that it will be useful,
10** but WITHOUT ANY WARRANTY; without even the implied warranty of
11** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12** General Public License for more details.
13**
14** You should have received a copy of the GNU General Public
15** License along with this library; if not, write to the
16** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17** Boston, MA 02111-1307, USA.
18**
19** Author contact information:
20** drh@hwaci.com
21** http://www.hwaci.com/drh/
22**
23*************************************************************************
24** This is the implementation of the page cache subsystem.
25**
26** The page cache is used to access a database file. The pager journals
27** all writes in order to support rollback. Locking is used to limit
28** access to one or more reader or on writer.
29**
drh69688d52001-04-14 16:38:23 +000030** @(#) $Id: pager.c,v 1.2 2001/04/14 16:38:23 drh Exp $
drhed7c8552001-04-11 14:29:21 +000031*/
32#include "pager.h"
33#include <fcntl.h>
34#include <sys/stat.h>
35#include <unistd.h>
36#include <assert.h>
37
38/*
39** The page cache as a whole is always in one of the following
40** states:
41**
42** SQLITE_UNLOCK The page cache is not currently reading or
43** writing the database file. There is no
44** data held in memory. This is the initial
45** state.
46**
47** SQLITE_READLOCK The page cache is reading the database.
48** Writing is not permitted. There can be
49** multiple readers accessing the same database
drh69688d52001-04-14 16:38:23 +000050** file at the same time.
drhed7c8552001-04-11 14:29:21 +000051**
52** SQLITE_WRITELOCK The page cache is writing the database.
53** Access is exclusive. No other processes or
54** threads can be reading or writing while one
55** process is writing.
56**
57** The page cache comes up in PCS_UNLOCK. The first time a
58** sqlite_page_get() occurs, the state transitions to PCS_READLOCK.
59** After all pages have been released using sqlite_page_unref(),
60** the state transitions back to PCS_UNLOCK. The first time
61** that sqlite_page_write() is called, the state transitions to
62** PCS_WRITELOCK. The sqlite_page_rollback() and sqlite_page_commit()
63** functions transition the state back to PCS_READLOCK.
64*/
65#define SQLITE_UNLOCK 0
66#define SQLITE_READLOCK 1
67#define SQLITE_WRITELOCK 2
68
69/*
70** Each in-memory image of a page begins with the following header.
71*/
72struct PgHdr {
73 Pager *pPager; /* The pager to which this page belongs */
74 Pgno pgno; /* The page number for this page */
drh69688d52001-04-14 16:38:23 +000075 PgHdr *pNextHash, *pPrevHash; /* Hash collision chain for PgHdr.pgno */
drhed7c8552001-04-11 14:29:21 +000076 int nRef; /* Number of users of this page */
77 PgHdr *pNext, *pPrev; /* Freelist of pages where nRef==0 */
78 char inJournal; /* TRUE if has been written to journal */
79 char dirty; /* TRUE if we need to write back changes */
drh69688d52001-04-14 16:38:23 +000080 /* SQLITE_PAGE_SIZE bytes of page data follow this header */
drhed7c8552001-04-11 14:29:21 +000081};
82
83/*
drh69688d52001-04-14 16:38:23 +000084** Convert a pointer to a PgHdr into a pointer to its data
85** and back again.
drhed7c8552001-04-11 14:29:21 +000086*/
87#define PGHDR_TO_DATA(P) ((void*)(&(P)[1]))
88#define DATA_TO_PGHDR(D) (&((PgHdr*)(D))[-1])
89
90/*
91** The number of page numbers that will fit on one page.
92*/
93#define SQLITE_INDEX_SIZE (SQLITE_PAGE_SIZE/sizeof(Pgno))
94
95/*
96** How big to make the hash table used for locating in-memory pages
97** by page number.
98*/
99#define N_PG_HASH 353
100
101/*
102** A open page cache is an instance of the following structure.
103*/
104struct Pager {
105 char *zFilename; /* Name of the database file */
106 char *zJournal; /* Name of the journal file */
107 int fd, jfd; /* File descriptors for database and journal */
108 int nRef; /* Sum of PgHdr.nRef */
109 int dbSize; /* Number of pages in the file */
drh69688d52001-04-14 16:38:23 +0000110 int origDbSize; /* dbSize before the current change */
drhed7c8552001-04-11 14:29:21 +0000111 int jSize; /* Number of pages in the journal */
drh69688d52001-04-14 16:38:23 +0000112 int nIdx; /* Number of entries in aIdx[] */
drhed7c8552001-04-11 14:29:21 +0000113 int nPage; /* Total number of in-memory pages */
114 int mxPage; /* Maximum number of pages to hold in cache */
drhed7c8552001-04-11 14:29:21 +0000115 char state; /* SQLITE_UNLOCK, _READLOCK or _WRITELOCK */
drh69688d52001-04-14 16:38:23 +0000116 char ioErr; /* True if an I/O error has occurred */
drhed7c8552001-04-11 14:29:21 +0000117 PgHdr *pFirst, *pLast; /* List of free pages */
118 PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number of PgHdr */
drh69688d52001-04-14 16:38:23 +0000119 Pgno aIdx[SQLITE_INDEX_SIZE]; /* Current journal index page */
drhed7c8552001-04-11 14:29:21 +0000120};
121
122/*
123** Hash a page number
124*/
125#define sqlite_pager_hash(PN) ((PN)%N_PG_HASH)
126
127/*
128** Attempt to acquire a read lock (if wrlock==0) or a write lock (if wrlock==1)
129** on the database file. Return 0 on success and non-zero if the lock
130** could not be acquired.
131*/
132static int sqlite_pager_lock(int fd, int wrlock){
133 struct flock lock;
134 lock.l_type = write_lock ? F_WRLCK : F_RDLCK;
135 return fcntl(fd, F_SETLK, &lock)!=0;
136}
137
138/*
139** Unlock the database file.
140*/
141static int sqlite_pager_unlock(fd){
142 struct flock lock;
143 lock.l_type = F_UNLCK;
144 return fcntl(fd, F_SETLK, &lock)!=0;
145}
146
147/*
148** Find a page in the hash table given its page number. Return
149** a pointer to the page or NULL if not found.
150*/
151static PgHdr *sqlite_pager_lookup(Pager *pPager, Pgno pgno){
152 PgHdr *p = pPager->aHash[pgno % N_PG_HASH];
153 while( p && p->pgno!=pgno ){
154 p = p->pNextHash;
155 }
156 return p;
157}
158
159/*
160** Unlock the database and clear the in-memory cache. This routine
161** sets the state of the pager back to what it was when it was first
162** opened. Any outstanding pages are invalidated and subsequent attempts
163** to access those pages will likely result in a coredump.
164*/
165static void sqlite_pager_reset(Pager *pPager){
166 PgHdr *pPg, *pNext;
167 for(pPg=pPager->pFirst; pPg; pPg=pNext){
168 pNext = pPg->pNext;
169 sqlite_free(pPg);
170 }
171 pPager->pFirst = 0;
172 pPager->pNext = 0;
173 memset(pPager->aHash, 0, sizeof(pPager->aHash));
174 pPager->nPage = 0;
175 if( pPager->state==SQLITE_WRITELOCK ){
176 sqlite_pager_rollback(pPager);
177 }
178 sqlite_pager_unlock(pPager->fd);
179 pPager->state = SQLITE_UNLOCK;
180 pPager->nRef = 0;
181}
182
183/*
184** When this routine is called, the pager has the journal file open and
185** a write lock on the database. This routine releases the database
186** write lock and acquires a read lock in its place. The journal file
187** is deleted and closed.
188**
189** We have to release the write lock before acquiring the read lock,
190** so there is a race condition where another process can get the lock
191** while we are not holding it. But, no other process should do this
192** because we are also holding a lock on the journal, and no process
193** should get a write lock on the database without first getting a lock
194** on the journal. So this routine should never fail. But it can fail
195** if another process is not playing by the rules. If it does fail,
196** all in-memory cache pages are invalidated and this routine returns
197** SQLITE_PROTOCOL. SQLITE_OK is returned on success.
198*/
199static int sqlite_pager_unwritelock(Pager *pPager){
200 int rc;
201 assert( pPager->state==SQLITE_WRITELOCK );
202 sqlite_pager_unlock(pPager->fd);
203 rc = sqlite_pager_lock(pPager->fd, 0);
204 unlink(pPager->zJournal);
205 close(pPager->jfd);
206 pPager->jfd = -1;
207 if( rc!=SQLITE_OK ){
208 pPager->state = SQLITE_UNLOCK;
209 sqlite_pager_reset(pPager);
210 rc = SQLITE_PROTOCOL;
211 }else{
212 pPager->state = SQLITE_READLOCK;
213 }
214 return rc;
215}
216
217
218/*
219** Playback the journal and thus restore the database file to
220** the state it was in before we started making changes.
221**
222** A journal consists of multiple segments. Every segment begins
223** with a single page containing SQLITE_INDEX_SIZE page numbers. This
224** first page is called the index. Most segments have SQLITE_INDEX_SIZE
225** additional pages after the index. The N-th page after the index
226** contains the contents of a page in the database file before that
227** page was changed. The N-th entry in the index tells which page
228** of the index file the data is for.
229**
230** The first segment of a journal is formatted slightly differently.
231** The first segment contains an index but only SQLITE_INDEX_SIZE-1
232** data pages. The first page number in the index is actually the
233** total number of pages in the original file. This number is used
234** to truncate the original database file back to its original size.
235** The second number in the index page is the page number for the
236** first data page. And so forth.
237**
238** We really need to playback the journal beginning at the end
239** and working backwards toward the beginning. That way changes
240** to the database are undone in the reverse order from the way they
241** were applied. This is important if the same page is changed
242** more than once. But many operating systems work more efficiently
243** if data is read forward instead of backwards. So for efficiency
244** we want to read the data in the forward direction.
245**
246** This routine starts with the last segment and works backwards
247** toward the first. Within each segment, however, data is read
248** in the forward direction for efficiency. Care is taken that
249** only the first appearance of each page is copied over to the
250** database file. If a page appears in the index more than once,
251** only the first occurrance is written. A hash table is used to
252** keep track of which pages have been written and which have not.
253*/
254static int sqlite_pager_playback(Pager *pPager){
255 int nSeg; /* Number of segments */
256 int i, j; /* Loop counters */
257 Pgno mxPg = 0; /* Size of the original file in pages */
258 struct stat statbuf; /* Used to size the journal */
259 Pgno aIndex[SQLITE_INDEX_SIZE]; /* The index page */
260 char aBuf[SQLITE_PAGE_SIZE]; /* Page transfer buffer */
261 Pgno aHash[SQLITE_INDEX_SIZE*2-1]; /* Hash table for pages read so far */
262 int rc;
263
264 /* Figure out how many segments are in the journal. Remember that
265 ** the first segment is one page shorter than the others and that
266 ** the last segment may be incomplete.
267 */
268 if( fstat(pPager->jfd; &statbuf)!=0 ){
269 return SQLITE_OK;
270 }
271 if( statbuf.st_size <= SQLITE_INDEX_SIZE*SQLITE_PAGE_SIZE ){
272 nSeg = 1;
273 }else{
274 int nPage = statbuf.st_size/SQLITE_PAGE_SIZE;
275 nPage -= SQLITE_INDEX_SIZE;
276 nSeg = 1 + nPage/(SQLITE_INDEX_SIZE+1);
277 }
278
279 /* Process segments beginning with the last and working backwards
280 ** to the first.
281 */
282 for(i=nSeg-1; i>=0; i--){
283 /* Seek to the beginning of the segment */
284 sqlite_pager_seekpage(pPager->jfd,
285 i>0 ? i*(SQLITE_INDEX_SIZE + 1) - 1 : 0,
286 SEEK_SET
287 );
288
289 /* Initialize the hash table used to avoid copying duplicate pages */
290 memset(aHash, 0, sizeof(aHash));
291
292 /* Read the index page */
293 sqlite_pager_readpage(pPager->jfd, aIndex);
294
295 /* Extract the original file size from the first index entry if this
296 ** is the first segment */
297 if( i==0 ){
298 mxPg = aIndex[0];
299 aIndex[0] = 0;
300 }
301
302 /* Process pages of this segment in forward order
303 */
304 for(j=0; j<SQLITE_INDEX_SIZE; j++){
305 Pgno pgno = aIndex[i];
306 void *pBuf;
307 PgHdr *pPg;
308
309 /* 0 means "no such page". Skip zero entries */
310 if( pgno==0 ) continue;
311
312 /* Check to see if pgno is in the hash table. Skip this
313 ** entry if it is.
314 */
315 h = pgno % (SQLITE_PAGE_SIZE-1);
316 while( aHash[h]!=0 && aHash[h]!=pgno ){
317 h++;
318 if( h>=SQLITE_PAGE_SIZE-1 ) h = 0;
319 }
320 if( aHash[h]==pgno ){
321 lseek(pPager->jfd, SQLITE_PAGE_SIZE, SEEK_CUR);
322 continue;
323 }
324 aHash[h] = pgno;
325
326 /* Playback the page. Update the in-memory copy of the page
327 ** at the same time, if there is one.
328 */
329 pPg = sqlite_pager_lookup(pPager, pgno);
330 if( pPg ){
331 pBuf = PGHDR_TO_DATA(pPg);
332 }else{
333 pBuf = aBuf;
334 }
335 sqlite_pager_readpage(pPager->jfd, pBuf);
336 sqlite_pager_seekpage(pPager->fd, pgno, SEEK_SET);
337 rc = sqlite_pager_writepage(pPager->fd, pBuf);
338 if( rc!=SQLITE_OK ) return rc;
339 }
340 }
341
342 /* Truncate the database back to its original size
343 */
344 if( mxPg>0 ){
345 ftrucate(pPager->fd, mxPg * SQLITE_PAGE_SIZE);
346 }
347 return SQLITE_OK;
348}
349
350/*
351** Create a new page cache and put a pointer to the page cache in *ppPager.
352** The file to be cached need not exist. The file is not opened until
353** the first call to sqlite_pager_get() and is only held open until the
354** last page is released using sqlite_pager_unref().
355*/
356int sqlite_pager_open(Pager **ppPager, const char *zFilename, int mxPage){
357 Pager *pPager;
358 int nameLen;
359 int fd;
360
361 fd = open(zFilename, O_RDWR, 0644);
362 if( fd<0 ){
363 return SQLITE_CANTOPEN;
364 }
365 nameLen = strlen(zFilename);
366 pPager = sqliteMalloc( sizeof(*pPager) + nameLen*2 + 30 );
367 if( pPager==0 ) return SQLITE_NOMEM;
368 pPager->zFilename = (char*)&pPager[1];
369 pPager->zJournal = &pPager->zFilename[nameLen+1];
370 strcpy(pPager->zFilename, zFilename);
371 strcpy(pPager->zJournal, zFilename);
372 strcpy(&pPager->zJournal[nameLen], "-journal");
373 pPager->fd = fd;
374 pPager->jfd = -1;
375 pPager->nRef = 0;
376 pPager->dbSize = -1;
377 pPager->nPage = 0;
378 pPager->mxPage = mxPage>10 ? mxPage : 10;
379 pPager->state = SQLITE_UNLOCK;
380 pPager->pFirst = 0;
381 pPager->pLast = 0;
382 memset(pPager->aHash, 0, sizeof(pPager->aHash));
383 *ppPager = pPager;
384 return SQLITE_OK;
385}
386
387/*
388** Return the total number of pages in the file opened by pPager.
389*/
390int sqlite_pager_pagecount(Pager *pPager){
391 int n;
392 struct stat statbuf;
393 if( pPager->dbSize>=0 ){
394 return pPager->dbSize;
395 }
396 if( fstat(pPager->fd, &statbuf)!=0 ){
397 n = 0;
398 }else{
399 n = statbuf.st_size/SQLITE_PAGE_SIZE;
400 }
401 if( pPager->state!=SQLITE_NOLOCK ){
402 pPager->dbSize = n;
403 }
404 return n;
405}
406
407/*
408** Shutdown the page cache. Free all memory and close all files.
409**
410** If a transaction was in progress when this routine is called, that
411** transaction is rolled back. All outstanding pages are invalidated
412** and their memory is freed. Any attempt to use a page associated
413** with this page cache after this function returns will likely
414** result in a coredump.
415*/
416int sqlite_pager_close(Pager *pPager){
417 int i;
418 PgHdr *pPg;
419 switch( pPager->state ){
420 case SQLITE_WRITELOCK: {
421 sqlite_pager_rollback(pPager);
422 sqlite_pager_unlock(pPager->fd);
423 break;
424 }
425 case SQLITE_READLOCK: {
426 sqlite_pager_unlock(pPager->fd);
427 break;
428 }
429 default: {
430 /* Do nothing */
431 break;
432 }
433 }
434 for(i=0; i<N_PG_HASH; i++){
435 PgHdr *pNext;
436 for(pPg=pPager->aHash[i]; pPg; pPg=pNext){
437 pNext = pPg->pNextHash;
438 sqliteFree(pPg);
439 }
440 }
441 if( pPager->fd>=0 ) close(pPager->fd);
442 assert( pPager->jfd<0 );
443 sqliteFree(pPager);
444 return SQLITE_OK;
445}
446
447/*
448** Return the page number for the given page data
449*/
450int sqlite_pager_pagenumber(void *pData){
451 PgHdr *p = DATA_TO_PGHDR(pData);
452 return p->pgno;
453}
454
455/*
456** Acquire a page
457*/
458int sqlite_pager_get(Pager *pPager, int pgno, void **ppPage){
459 PgHdr *pPg;
460
461 /* If this is the first page accessed, then get a read lock
462 ** on the database file.
463 */
464 if( pPager->nRef==0 ){
465 if( sqlite_pager_lock(pPager->fd, 0)!=0 ){
466 *ppPage = 0;
467 return SQLITE_BUSY;
468 }
469
470 /* If a journal file exists, try to play it back.
471 */
472 if( access(pPager->zJournal,0)==0 ){
473 int rc;
474
475 /* Open the journal for exclusive access. Return SQLITE_BUSY if
476 ** we cannot get exclusive access to the journal file
477 */
478 pPager->jfd = open(pPager->zJournal, O_RDONLY, 0);
479 if( pPager->jfd<0 || sqlite_pager_lock(pPager->jfd, 1)!=0 ){
480 if( pPager->jfd>=0 ){ close(pPager->jfd); pPager->jfd = -1; }
481 sqlite_pager_unlock(pPager->fd);
482 *ppPage = 0;
483 return SQLITE_BUSY;
484 }
485
486 /* Get a write lock on the database */
487 sqlite_pager_unlock(pPager->fd);
488 if( sqlite_pager_lock(pPager->fd, 1)!=0 ){
489 *ppPage = 0;
490 return SQLITE_PROTOCOL;
491 }
492
493 /* Playback and delete the journal. Drop the database write
494 ** lock and reacquire the read lock.
495 */
496 sqlite_pager_playback(pPager);
497 rc = sqlite_pager_unwritelock(pPager);
498 if( rc!=SQLITE_OK ){ return SQLITE_PROTOCOL; }
499 }
500 pPg = 0;
501 }else{
502 /* Search for page in cache */
503 pPg = sqlite_pager_lookup(pPager, pgno);
504 }
505 if( pPg==0 ){
506 int h;
507 if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 ){
508 /* Create a new page */
509 pPg = sqlite_malloc( sizeof(*pPg) + SQLITE_PAGE_SIZE );
510 pPg->pPager = pPager;
511 }else{
512 /* Recycle an older page */
513 pPg = pPager->pFirst;
514 if( pPg->dirty ){
515 int rc;
516 sqlite_pager_seekpage(pPager->fd, pPg->pgno, SEEK_SET);
517 rc = sqlite_pager_writepage(pPager->fd, PGHDR_TO_DATA(pPg));
518 if( rc!=SQLITE_OK ){
519 *ppPage = 0;
520 return rc;
521 }
522 }
523 pPager->pFirst = pPg->pNext;
524 if( pPager->pFirst ){
525 pPager->pFirst->pPrev = 0;
526 }else{
527 pPager->pLast = 0;
528 }
529 if( pPg->pNextHash ){
530 pPg->pNextHash->pPrevHash = pPg->pPrevHash;
531 }
532 if( pPg->pPrevHash ){
533 pPg->pPrevHash->pNextHash = pPg->pNextHash;
534 }else{
535 h = sqlite_pager_hash(pPg->pgno);
536 assert( pPager->aHash[h]==pPg );
537 pPager->aHash[h] = pPg->pNextHash;
538 }
539 }
540 pPg->pgno = pgno;
541 pPg->inJournal = 0;
542 pPg->dirty = 0;
543 pPg->nRef = 1;
544 h = sqlite_pager_hash(pgno);
545 pPg->pNextHash = pPager->aHash[h];
546 pPager->aHash[h] = pPg;
547 if( pPg->pNextHash ){
548 assert( pPg->pNextHash->pPrevHash==0 );
549 pPg->pNextHash->pPrevHash = pPg;
550 }
551 sqlite_pager_seekpage(pPager->fd, pgno, SEEK_SET);
552 sqlite_pager_readpage(pPager->fd, PGHDR_TO_DATA(pPg));
553 }else{
554 if( pPg->nRef==0 ){
555 if( pPg->pPrev ){
556 pPg->pPrev->pNext = pPg->pNext;
557 }else{
558 pPager->pFirst = pPg->pNext;
559 }
560 if( pPg->pNext ){
561 pPg->pNext->pPrev = pPg->pPrev;
562 }else{
563 pPager->pLast = pPg->pPrev;
564 }
565 }
566 pPg->nRef++;
567 }
568 *ppPage = PGHDR_TO_DATA(pPg);
569 return SQLITE_OK;
570}
571
572/*
573** Release a page.
574**
575** If the number of references to the page drop to zero, then the
576** page is added to the LRU list. When all references to all pages
577** are released, a rollback occurs, and the lock on the database is
578** removed.
579*/
580int sqlite_pager_unref(void *pData){
581 Pager *pPager;
582 PgHdr *pPg;
583 pPg = DATA_TO_PGHDR(pData);
584 assert( pPg->nRef>0 );
585 pPager = pPg->pPager;
586 pPg->nRef--;
587 if( pPg->nRef==0 ){
588 pPg->pNext = 0;
589 pPg->pPrev = pPager->pLast;
590 pPager->pLast = pPg;
591 if( pPg->pPrev ){
592 pPg->pPrev->pNext = pPg;
593 }else{
594 pPager->pFirst = pPg;
595 }
596 }
597 pPager->nRef--;
598 assert( pPager->nRef>=0 );
599 if( pPager->nRef==0 ){
600 sqlite_pager_reset(pPager);
601 }
602}
603
604/*
605** Mark a data page as writeable. The page is written into the journal
606** if it is not there already. This routine must be called before making
607** changes to a page.
608**
609** The first time this routine is called, the pager creates a new
610** journal and acquires a write lock on the database. If the write
611** lock could not be acquired, this routine returns SQLITE_BUSY. The
612** calling routine must check for that routine and be careful not to
613** change any page data until this routine returns SQLITE_OK.
614*/
615int sqlite_pager_write(void *pData){
drh69688d52001-04-14 16:38:23 +0000616 PgHdr *pPg = DATA_TO_PGHDR(pData);
617 Pager *pPager = pPg->pPager;
618 int rc;
619
620 if( pPg->inJournal ){ return SQLITE_OK; }
621 if( pPager->state==SQLITE_UNLOCK ){ return SQLITE_PROTOCOL; }
drhed7c8552001-04-11 14:29:21 +0000622 if( pPager->state==SQLITE_READLOCK ){
623 pPager->jfd = open(pPager->zJournal, O_RDWR|O_CREAT, 0644);
624 if( pPager->jfd<0 ){
625 return SQLITE_CANTOPEN;
626 }
627 if( sqlite_pager_lock(pPager->jfd, 1) ){
628 close(pPager->jfd);
629 pPager->jfd = -1;
630 return SQLITE_BUSY;
631 }
632 sqlite_pager_unlock(pPager->fd);
633 if( sqlite_pager_lock(pPager->fd, 1) ){
634 close(pPager->jfd);
635 pPager->jfd = -1;
636 pPager->state = SQLITE_UNLOCK;
637 sqlite_pager_reset(pPager);
638 return SQLITE_PROTOCOL;
639 }
640 pPager->state = SQLITE_WRITELOCK;
drh69688d52001-04-14 16:38:23 +0000641 pPager->jSize = 1;
642 pPager->aIdx[0] = pPager->dbSize;
643 pPager->origDbSize = pPager->dbSize;
644 pPager->nIdx = 1;
drhed7c8552001-04-11 14:29:21 +0000645 }
646 /* Write this page to the journal */
drh69688d52001-04-14 16:38:23 +0000647 assert( pPager->jfd>=0 );
648 if( pPg->pgno >= pPager->origDbSize ){
649 sqlite_pager_seekpage(pPager->fd, pPg->pgno, SEEK_SET);
650 rc = sqlite_pager_writepage(pPager->fd, pData);
651 pPg->inJournal = 1;
652 return rc;
653 }
654 pPager->aIdx[pPager->nIdx++] = pPg->pgno;
655 sqlite_pager_seekpage(pPager->jfd, pPager->jSize++, SEEK_SET);
656 rc = sqlite_pager_write(pPager->jfd, pData);
657 pPg->inJournal = 1;
658 if( pPager->nIdx==SQLITE_INDEX_SIZE ){
659 sqlite_pager_seekpage(pPager->jfd, pPager->idxPgno, SEEK_SET);
660 rc = sqlite_pager_writepage(pPager->jfd, &pPager->aIdx);
661 pPager->nIdx = 0;
662 pPager->jSize++;
663 }
664 return rc;
drhed7c8552001-04-11 14:29:21 +0000665}
666
667/*
668** Commit all changes to the database and release the write lock.
669*/
670int sqlite_pager_commit(Pager*){
671 int i, rc;
672 PgHdr *pPg;
673 assert( pPager->state==SQLITE_WRITELOCK );
674 assert( pPager->jfd>=0 );
drh69688d52001-04-14 16:38:23 +0000675 memset(&pPager->aIdx[&pPager->nIdx], 0,
676 (SQLITE_INDEX_SIZE - pPager->nIdx)*sizeof(Pgno));
677 sqlite_pager_seekpage(pPager->jfd, pPager->idxPgno, SEEK_SET);
678 rc = sqlite_pager_writepage(pPager->jfd, &pPager->aIdx);
drhed7c8552001-04-11 14:29:21 +0000679 if( fsync(pPager->jfd) ){
680 return SQLITE_IOERR;
681 }
682 for(i=0; i<N_PG_HASH; i++){
683 for(pPg=pPager->aHash[i]; pPg; pPg=pPg->pNextHash){
684 if( pPg->dirty==0 ) continue;
685 rc = sqlite_pager_seekpage(pPager->fd, pPg->pgno, SEEK_SET);
686 if( rc!=SQLITE_OK ) return rc;
687 rc = sqlite_pager_writePage(pPager->fd, PGHDR_TO_DATA(pPg));
688 if( rc!=SQLITE_OK ) return rc;
689 }
690 }
691 if( fsync(pPager->fd) ){
692 return SQLITE_IOERR;
693 }
694 rc = sqlite_pager_unwritelock(pPager);
695 return rc;
696}
697
698/*
699** Rollback all changes. The database falls back to read-only mode.
700** All in-memory cache pages revert to their original data contents.
701** The journal is deleted.
702*/
703int sqlite_pager_rollback(Pager *pPager){
704 int rc;
705 if( pPager->state!=SQLITE_WRITELOCK ) return SQLITE_OK;
drh69688d52001-04-14 16:38:23 +0000706 memset(&pPager->aIdx[&pPager->nIdx], 0,
707 (SQLITE_INDEX_SIZE - pPager->nIdx)*sizeof(Pgno));
708 sqlite_pager_seekpage(pPager->jfd, pPager->idxPgno, SEEK_SET);
709 rc = sqlite_pager_writepage(pPager->jfd, &pPager->aIdx);
drhed7c8552001-04-11 14:29:21 +0000710 rc = sqlite_pager_playback(pPager);
711 if( rc!=SQLITE_OK ){
712 rc = sqlite_pager_unwritelock(pPager);
713 }
714 return rc;
715};