rtthread_io_methods.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. static int _rtthread_io_read(sqlite3_file *file_id, void *pbuf, int cnt, sqlite3_int64 offset)
  2. {
  3. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  4. sqlite3_int64 new_offset;
  5. int r_cnt;
  6. assert(file_id);
  7. assert(offset >= 0);
  8. assert(cnt > 0);
  9. new_offset = lseek(file->fd, offset, SEEK_SET);
  10. if (new_offset != offset)
  11. {
  12. return SQLITE_IOERR_READ;
  13. }
  14. do {
  15. r_cnt = read(file->fd, pbuf, cnt);
  16. if (r_cnt == cnt)
  17. {
  18. break;
  19. }
  20. if (r_cnt < 0)
  21. {
  22. if (errno != EINTR)
  23. {
  24. return SQLITE_IOERR_READ;
  25. }
  26. r_cnt = 1;
  27. continue;
  28. }
  29. else if (r_cnt > 0)
  30. {
  31. cnt -= r_cnt;
  32. pbuf = (void*)(r_cnt + (char*)pbuf);
  33. }
  34. } while (r_cnt > 0);
  35. if (r_cnt != cnt)
  36. {
  37. memset(&((char*)pbuf)[r_cnt], 0, cnt - r_cnt);
  38. return SQLITE_IOERR_SHORT_READ;
  39. }
  40. return SQLITE_OK;
  41. }
  42. static int _rtthread_io_write(sqlite3_file* file_id, const void *pbuf, int cnt, sqlite3_int64 offset)
  43. {
  44. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  45. sqlite3_int64 new_offset;
  46. int w_cnt;
  47. assert(file_id);
  48. assert(cnt > 0);
  49. new_offset = lseek(file->fd, offset, SEEK_SET);
  50. if (new_offset != offset)
  51. {
  52. return SQLITE_IOERR_WRITE;
  53. }
  54. do {
  55. w_cnt = write(file->fd, pbuf, cnt);
  56. if (w_cnt == cnt)
  57. {
  58. break;
  59. }
  60. if (w_cnt < 0)
  61. {
  62. if (errno != EINTR)
  63. {
  64. return SQLITE_IOERR_WRITE;
  65. }
  66. w_cnt = 1;
  67. continue;
  68. }
  69. else if (w_cnt > 0)
  70. {
  71. cnt -= w_cnt;
  72. pbuf = (void*)(w_cnt + (char*)pbuf);
  73. }
  74. } while (w_cnt > 0);
  75. if (w_cnt != cnt)
  76. {
  77. return SQLITE_FULL;
  78. }
  79. return SQLITE_OK;
  80. }
  81. static int _rtthread_io_truncate(sqlite3_file* file_id, sqlite3_int64 size)
  82. {
  83. return SQLITE_IOERR_TRUNCATE;
  84. }
  85. static int _rtthread_io_sync(sqlite3_file* file_id, int flags)
  86. {
  87. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  88. assert((flags & 0x0F) == SQLITE_SYNC_NORMAL
  89. || (flags & 0x0F) == SQLITE_SYNC_FULL);
  90. fsync(file->fd);
  91. return SQLITE_OK;
  92. }
  93. static int _rtthread_io_file_size(sqlite3_file* file_id, sqlite3_int64 *psize)
  94. {
  95. int rc;
  96. struct stat buf;
  97. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  98. assert(file_id);
  99. rc = fstat(file->fd, &buf);
  100. if (rc != 0)
  101. {
  102. return SQLITE_IOERR_FSTAT;
  103. }
  104. *psize = buf.st_size;
  105. /* When opening a zero-size database, the findInodeInfo() procedure
  106. ** writes a single byte into that file in order to work around a bug
  107. ** in the OS-X msdos filesystem. In order to avoid problems with upper
  108. ** layers, we need to report this file size as zero even though it is
  109. ** really 1. Ticket #3260.
  110. */
  111. if (*psize == 1) *psize = 0;
  112. return SQLITE_OK;
  113. }
  114. /*
  115. ** This routine checks if there is a RESERVED lock held on the specified
  116. ** file by this or any other process. If such a lock is held, set *pResOut
  117. ** to a non-zero value otherwise *pResOut is set to zero. The return value
  118. ** is set to SQLITE_OK unless an I/O error occurs during lock checking.
  119. */
  120. static int _rtthread_io_check_reserved_lock(sqlite3_file *file_id, int *pResOut)
  121. {
  122. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  123. rt_sem_t psem = &file->sem;
  124. int reserved = 0;
  125. /* Check if a thread in this process holds such a lock */
  126. if (file->eFileLock > SHARED_LOCK)
  127. {
  128. reserved = 1;
  129. }
  130. /* Otherwise see if some other process holds it. */
  131. if (!reserved)
  132. {
  133. if (rt_sem_trytake(psem) != RT_EOK)
  134. {
  135. /* someone else has the lock when we are in NO_LOCK */
  136. reserved = (file->eFileLock < SHARED_LOCK);
  137. }
  138. else
  139. {
  140. /* we could have it if we want it */
  141. rt_sem_release(psem);
  142. }
  143. }
  144. *pResOut = reserved;
  145. return SQLITE_OK;
  146. }
  147. /*
  148. ** Lock the file with the lock specified by parameter eFileLock - one
  149. ** of the following:
  150. **
  151. ** (1) SHARED_LOCK
  152. ** (2) RESERVED_LOCK
  153. ** (3) PENDING_LOCK
  154. ** (4) EXCLUSIVE_LOCK
  155. **
  156. ** Sometimes when requesting one lock state, additional lock states
  157. ** are inserted in between. The locking might fail on one of the later
  158. ** transitions leaving the lock state different from what it started but
  159. ** still short of its goal. The following chart shows the allowed
  160. ** transitions and the inserted intermediate states:
  161. **
  162. ** UNLOCKED -> SHARED
  163. ** SHARED -> RESERVED
  164. ** SHARED -> (PENDING) -> EXCLUSIVE
  165. ** RESERVED -> (PENDING) -> EXCLUSIVE
  166. ** PENDING -> EXCLUSIVE
  167. **
  168. ** Semaphore locks only really support EXCLUSIVE locks. We track intermediate
  169. ** lock states in the sqlite3_file structure, but all locks SHARED or
  170. ** above are really EXCLUSIVE locks and exclude all other processes from
  171. ** access the file.
  172. **
  173. ** This routine will only increase a lock. Use the sqlite3OsUnlock()
  174. ** routine to lower a locking level.
  175. */
  176. static int _rtthread_io_lock(sqlite3_file *file_id, int eFileLock)
  177. {
  178. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  179. rt_sem_t psem = &file->sem;
  180. int rc = SQLITE_OK;
  181. /* if we already have a lock, it is exclusive.
  182. ** Just adjust level and punt on outta here. */
  183. if (file->eFileLock > NO_LOCK)
  184. {
  185. file->eFileLock = eFileLock;
  186. rc = SQLITE_OK;
  187. goto sem_end_lock;
  188. }
  189. /* lock semaphore now but bail out when already locked. */
  190. if (rt_sem_trytake(psem) != RT_EOK)
  191. {
  192. rc = SQLITE_BUSY;
  193. goto sem_end_lock;
  194. }
  195. /* got it, set the type and return ok */
  196. file->eFileLock = eFileLock;
  197. sem_end_lock:
  198. return rc;
  199. }
  200. /*
  201. ** Lower the locking level on file descriptor pFile to eFileLock. eFileLock
  202. ** must be either NO_LOCK or SHARED_LOCK.
  203. **
  204. ** If the locking level of the file descriptor is already at or below
  205. ** the requested locking level, this routine is a no-op.
  206. */
  207. static int _rtthread_io_unlock(sqlite3_file *file_id, int eFileLock)
  208. {
  209. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  210. rt_sem_t psem = &file->sem;
  211. assert(eFileLock <= SHARED_LOCK);
  212. /* no-op if possible */
  213. if (file->eFileLock == eFileLock)
  214. {
  215. return SQLITE_OK;
  216. }
  217. /* shared can just be set because we always have an exclusive */
  218. if (eFileLock == SHARED_LOCK)
  219. {
  220. file->eFileLock = SHARED_LOCK;
  221. return SQLITE_OK;
  222. }
  223. /* no, really unlock. */
  224. rt_sem_release(psem);
  225. file->eFileLock = NO_LOCK;
  226. return SQLITE_OK;
  227. }
  228. static int _rtthread_io_close(sqlite3_file *file_id)
  229. {
  230. int rc = 0;
  231. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  232. if (file->fd >= 0)
  233. {
  234. _rtthread_io_unlock(file_id, NO_LOCK);
  235. rc = close(file->fd);
  236. file->fd = -1;
  237. }
  238. return rc;
  239. }
  240. static int _rtthread_fcntl_size_hint(sqlite3_file *file_id, i64 nByte)
  241. {
  242. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  243. if (file->szChunk > 0)
  244. {
  245. i64 nSize; /* Required file size */
  246. struct stat buf; /* Used to hold return values of fstat() */
  247. if (fstat(file->fd, &buf))
  248. {
  249. return SQLITE_IOERR_FSTAT;
  250. }
  251. nSize = ((nByte + file->szChunk - 1) / file->szChunk) * file->szChunk;
  252. if (nSize > (i64)buf.st_size)
  253. {
  254. /* If the OS does not have posix_fallocate(), fake it. Write a
  255. ** single byte to the last byte in each block that falls entirely
  256. ** within the extended region. Then, if required, a single byte
  257. ** at offset (nSize-1), to set the size of the file correctly.
  258. ** This is a similar technique to that used by glibc on systems
  259. ** that do not have a real fallocate() call.
  260. */
  261. int nBlk = 512; /* File-system block size */
  262. int nWrite = 0; /* Number of bytes written by seekAndWrite */
  263. i64 iWrite; /* Next offset to write to */
  264. iWrite = (buf.st_size / nBlk) * nBlk + nBlk - 1;
  265. assert(iWrite >= buf.st_size);
  266. assert(((iWrite + 1) % nBlk) == 0);
  267. for (/*no-op*/; iWrite < nSize + nBlk - 1; iWrite += nBlk)
  268. {
  269. if (iWrite >= nSize)
  270. {
  271. iWrite = nSize - 1;
  272. }
  273. nWrite = _rtthread_io_write(file_id, "", 1, iWrite);
  274. if (nWrite != 1)
  275. {
  276. return SQLITE_IOERR_WRITE;
  277. }
  278. }
  279. }
  280. }
  281. return SQLITE_OK;
  282. }
  283. /*
  284. ** Information and control of an open file handle.
  285. */
  286. static int _rtthread_io_file_ctrl(sqlite3_file *file_id, int op, void *pArg)
  287. {
  288. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  289. switch( op )
  290. {
  291. case SQLITE_FCNTL_LOCKSTATE: {
  292. *(int*)pArg = file->eFileLock;
  293. return SQLITE_OK;
  294. }
  295. case SQLITE_LAST_ERRNO: {
  296. *(int*)pArg = 0;
  297. return SQLITE_OK;
  298. }
  299. case SQLITE_FCNTL_CHUNK_SIZE: {
  300. file->szChunk = *(int *)pArg;
  301. return SQLITE_OK;
  302. }
  303. case SQLITE_FCNTL_SIZE_HINT: {
  304. int rc;
  305. rc = _rtthread_fcntl_size_hint(file_id, *(i64 *)pArg);
  306. return rc;
  307. }
  308. case SQLITE_FCNTL_PERSIST_WAL: {
  309. return SQLITE_OK;
  310. }
  311. case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
  312. return SQLITE_OK;
  313. }
  314. case SQLITE_FCNTL_VFSNAME: {
  315. *(char**)pArg = sqlite3_mprintf("%s", file->pvfs->zName);
  316. return SQLITE_OK;
  317. }
  318. case SQLITE_FCNTL_TEMPFILENAME: {
  319. char *zTFile = sqlite3_malloc(file->pvfs->mxPathname );
  320. if( zTFile )
  321. {
  322. _rtthread_get_temp_name(file->pvfs->mxPathname, zTFile);
  323. *(char**)pArg = zTFile;
  324. }
  325. return SQLITE_OK;
  326. }
  327. }
  328. return SQLITE_NOTFOUND;
  329. }
  330. static int _rtthread_io_sector_size(sqlite3_file *file_id)
  331. {
  332. return SQLITE_DEFAULT_SECTOR_SIZE;
  333. }
  334. static int _rtthread_io_device_characteristics(sqlite3_file *file_id)
  335. {
  336. return 0;
  337. }
  338. /*
  339. ** If possible, return a pointer to a mapping of file fd starting at offset
  340. ** iOff. The mapping must be valid for at least nAmt bytes.
  341. **
  342. ** If such a pointer can be obtained, store it in *pp and return SQLITE_OK.
  343. ** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK.
  344. ** Finally, if an error does occur, return an SQLite error code. The final
  345. ** value of *pp is undefined in this case.
  346. **
  347. ** If this function does return a pointer, the caller must eventually
  348. ** release the reference by calling unixUnfetch().
  349. */
  350. static int _rtthread_io_fetch(sqlite3_file *file_id, i64 iOff, int nAmt, void **pp)
  351. {
  352. *pp = 0;
  353. return SQLITE_OK;
  354. }
  355. /*
  356. ** If the third argument is non-NULL, then this function releases a
  357. ** reference obtained by an earlier call to unixFetch(). The second
  358. ** argument passed to this function must be the same as the corresponding
  359. ** argument that was passed to the unixFetch() invocation.
  360. **
  361. ** Or, if the third argument is NULL, then this function is being called
  362. ** to inform the VFS layer that, according to POSIX, any existing mapping
  363. ** may now be invalid and should be unmapped.
  364. */
  365. static int _rtthread_io_unfetch(sqlite3_file *fd, i64 iOff, void *p)
  366. {
  367. return SQLITE_OK;
  368. }
  369. static const sqlite3_io_methods _rtthread_io_method = {
  370. 3,
  371. _rtthread_io_close,
  372. _rtthread_io_read,
  373. _rtthread_io_write,
  374. _rtthread_io_truncate,
  375. _rtthread_io_sync,
  376. _rtthread_io_file_size,
  377. _rtthread_io_lock,
  378. _rtthread_io_unlock,
  379. _rtthread_io_check_reserved_lock,
  380. _rtthread_io_file_ctrl,
  381. _rtthread_io_sector_size,
  382. _rtthread_io_device_characteristics,
  383. 0,
  384. 0,
  385. 0,
  386. 0,
  387. _rtthread_io_fetch,
  388. _rtthread_io_unfetch
  389. };