journal.c 7.1 KB

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