journal.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /*
  2. ** 2007 August 22
  3. **
  4. ** The author disclaims copyright to this source code. In place of
  5. ** a legal notice, here is a blessing:
  6. **
  7. ** May you do good and not evil.
  8. ** May you find forgiveness for yourself and forgive others.
  9. ** May you share freely, never taking more than you give.
  10. **
  11. *************************************************************************
  12. **
  13. ** @(#) $Id: journal.c,v 1.7 2007/09/06 13:49:37 drh Exp $
  14. */
  15. #ifdef SQLITE_ENABLE_ATOMIC_WRITE
  16. /*
  17. ** This file implements a special kind of sqlite3_file object used
  18. ** by SQLite to create journal files if the atomic-write optimization
  19. ** is enabled.
  20. **
  21. ** The distinctive characteristic of this sqlite3_file is that the
  22. ** actual on disk file is created lazily. When the file is created,
  23. ** the caller specifies a buffer size for an in-memory buffer to
  24. ** be used to service read() and write() requests. The actual file
  25. ** on disk is not created or populated until either:
  26. **
  27. ** 1) The in-memory representation grows too large for the allocated
  28. ** buffer, or
  29. ** 2) The xSync() method is called.
  30. */
  31. #include "sqliteInt.h"
  32. /*
  33. ** A JournalFile object is a subclass of sqlite3_file used by
  34. ** as an open file handle for journal files.
  35. */
  36. struct JournalFile {
  37. sqlite3_io_methods *pMethod; /* I/O methods on journal files */
  38. int nBuf; /* Size of zBuf[] in bytes */
  39. char *zBuf; /* Space to buffer journal writes */
  40. int iSize; /* Amount of zBuf[] currently used */
  41. int flags; /* xOpen flags */
  42. sqlite3_vfs *pVfs; /* The "real" underlying VFS */
  43. sqlite3_file *pReal; /* The "real" underlying file descriptor */
  44. const char *zJournal; /* Name of the journal file */
  45. };
  46. typedef struct JournalFile JournalFile;
  47. /*
  48. ** If it does not already exists, create and populate the on-disk file
  49. ** for JournalFile p.
  50. */
  51. static int createFile(JournalFile *p){
  52. int rc = SQLITE_OK;
  53. if( !p->pReal ){
  54. sqlite3_file *pReal = (sqlite3_file *)&p[1];
  55. rc = sqlite3OsOpen(p->pVfs, p->zJournal, pReal, p->flags, 0);
  56. if( rc==SQLITE_OK ){
  57. p->pReal = pReal;
  58. if( p->iSize>0 ){
  59. assert(p->iSize<=p->nBuf);
  60. rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0);
  61. }
  62. }
  63. }
  64. return rc;
  65. }
  66. /*
  67. ** Close the file.
  68. */
  69. static int jrnlClose(sqlite3_file *pJfd){
  70. JournalFile *p = (JournalFile *)pJfd;
  71. if( p->pReal ){
  72. sqlite3OsClose(p->pReal);
  73. }
  74. sqlite3_free(p->zBuf);
  75. return SQLITE_OK;
  76. }
  77. /*
  78. ** Read data from the file.
  79. */
  80. static int jrnlRead(
  81. sqlite3_file *pJfd, /* The journal file from which to read */
  82. void *zBuf, /* Put the results here */
  83. int iAmt, /* Number of bytes to read */
  84. sqlite_int64 iOfst /* Begin reading at this offset */
  85. ){
  86. int rc = SQLITE_OK;
  87. JournalFile *p = (JournalFile *)pJfd;
  88. if( p->pReal ){
  89. rc = sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
  90. }else{
  91. assert( iAmt+iOfst<=p->iSize );
  92. memcpy(zBuf, &p->zBuf[iOfst], iAmt);
  93. }
  94. return rc;
  95. }
  96. /*
  97. ** Write data to the file.
  98. */
  99. static int jrnlWrite(
  100. sqlite3_file *pJfd, /* The journal file into which to write */
  101. const void *zBuf, /* Take data to be written from here */
  102. int iAmt, /* Number of bytes to write */
  103. sqlite_int64 iOfst /* Begin writing at this offset into the file */
  104. ){
  105. int rc = SQLITE_OK;
  106. JournalFile *p = (JournalFile *)pJfd;
  107. if( !p->pReal && (iOfst+iAmt)>p->nBuf ){
  108. rc = createFile(p);
  109. }
  110. if( rc==SQLITE_OK ){
  111. if( p->pReal ){
  112. rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
  113. }else{
  114. memcpy(&p->zBuf[iOfst], zBuf, iAmt);
  115. if( p->iSize<(iOfst+iAmt) ){
  116. p->iSize = (iOfst+iAmt);
  117. }
  118. }
  119. }
  120. return rc;
  121. }
  122. /*
  123. ** Truncate the file.
  124. */
  125. static int jrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
  126. int rc = SQLITE_OK;
  127. JournalFile *p = (JournalFile *)pJfd;
  128. if( p->pReal ){
  129. rc = sqlite3OsTruncate(p->pReal, size);
  130. }else if( size<p->iSize ){
  131. p->iSize = size;
  132. }
  133. return rc;
  134. }
  135. /*
  136. ** Sync the file.
  137. */
  138. static int jrnlSync(sqlite3_file *pJfd, int flags){
  139. int rc;
  140. JournalFile *p = (JournalFile *)pJfd;
  141. rc = createFile(p);
  142. if( rc==SQLITE_OK ){
  143. rc = sqlite3OsSync(p->pReal, flags);
  144. }
  145. return rc;
  146. }
  147. /*
  148. ** Query the size of the file in bytes.
  149. */
  150. static int jrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){
  151. int rc = SQLITE_OK;
  152. JournalFile *p = (JournalFile *)pJfd;
  153. if( p->pReal ){
  154. rc = sqlite3OsFileSize(p->pReal, pSize);
  155. }else{
  156. *pSize = (sqlite_int64) p->iSize;
  157. }
  158. return rc;
  159. }
  160. /*
  161. ** Table of methods for JournalFile sqlite3_file object.
  162. */
  163. static struct sqlite3_io_methods JournalFileMethods = {
  164. 1, /* iVersion */
  165. jrnlClose, /* xClose */
  166. jrnlRead, /* xRead */
  167. jrnlWrite, /* xWrite */
  168. jrnlTruncate, /* xTruncate */
  169. jrnlSync, /* xSync */
  170. jrnlFileSize, /* xFileSize */
  171. 0, /* xLock */
  172. 0, /* xUnlock */
  173. 0, /* xCheckReservedLock */
  174. 0, /* xFileControl */
  175. 0, /* xSectorSize */
  176. 0 /* xDeviceCharacteristics */
  177. };
  178. /*
  179. ** Open a journal file.
  180. */
  181. int sqlite3JournalOpen(
  182. sqlite3_vfs *pVfs, /* The VFS to use for actual file I/O */
  183. const char *zName, /* Name of the journal file */
  184. sqlite3_file *pJfd, /* Preallocated, blank file handle */
  185. int flags, /* Opening flags */
  186. int nBuf /* Bytes buffered before opening the file */
  187. ){
  188. JournalFile *p = (JournalFile *)pJfd;
  189. memset(p, 0, sqlite3JournalSize(pVfs));
  190. if( nBuf>0 ){
  191. p->zBuf = sqlite3MallocZero(nBuf);
  192. if( !p->zBuf ){
  193. return SQLITE_NOMEM;
  194. }
  195. }else{
  196. return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0);
  197. }
  198. p->pMethod = &JournalFileMethods;
  199. p->nBuf = nBuf;
  200. p->flags = flags;
  201. p->zJournal = zName;
  202. p->pVfs = pVfs;
  203. return SQLITE_OK;
  204. }
  205. /*
  206. ** If the argument p points to a JournalFile structure, and the underlying
  207. ** file has not yet been created, create it now.
  208. */
  209. int sqlite3JournalCreate(sqlite3_file *p){
  210. if( p->pMethods!=&JournalFileMethods ){
  211. return SQLITE_OK;
  212. }
  213. return createFile((JournalFile *)p);
  214. }
  215. /*
  216. ** Return the number of bytes required to store a JournalFile that uses vfs
  217. ** pVfs to create the underlying on-disk files.
  218. */
  219. int sqlite3JournalSize(sqlite3_vfs *pVfs){
  220. return (pVfs->szOsFile+sizeof(JournalFile));
  221. }
  222. #endif