1*e7952263Sdan 2*e7952263SdanSQLite's OS layer contains the following definitions used in F2FS related 3*e7952263Sdancalls: 4*e7952263Sdan 5*e7952263Sdan#define F2FS_IOCTL_MAGIC 0xf5 6*e7952263Sdan#define F2FS_IOC_START_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 1) 7*e7952263Sdan#define F2FS_IOC_COMMIT_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 2) 8*e7952263Sdan#define F2FS_IOC_START_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 3) 9*e7952263Sdan#define F2FS_IOC_ABORT_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 5) 10*e7952263Sdan#define F2FS_IOC_GET_FEATURES _IOR(F2FS_IOCTL_MAGIC, 12, u32) 11*e7952263Sdan#define F2FS_FEATURE_ATOMIC_WRITE 0x0004 12*e7952263Sdan 13*e7952263SdanAfter opening a database file on Linux (including Android), SQLite determines 14*e7952263Sdanwhether or not a file supports F2FS atomic commits as follows: 15*e7952263Sdan 16*e7952263Sdan u32 flags = 0; 17*e7952263Sdan rc = ioctl(fd, F2FS_IOC_GET_FEATURES, &flags); 18*e7952263Sdan if( rc==0 && (flags & F2FS_FEATURE_ATOMIC_WRITE) ){ 19*e7952263Sdan /* File supports F2FS atomic commits */ 20*e7952263Sdan }else{ 21*e7952263Sdan /* File does NOT support F2FS atomic commits */ 22*e7952263Sdan } 23*e7952263Sdan 24*e7952263Sdanwhere "fd" is the file-descriptor open on the database file. 25*e7952263Sdan 26*e7952263SdanUsually, when writing to a database file that supports atomic commits, SQLite 27*e7952263Sdanaccumulates the entire transaction in heap memory, deferring all writes to the 28*e7952263Sdandb file until the transaction is committed. 29*e7952263Sdan 30*e7952263SdanWhen it is time to commit a transaction on a file that supports atomic 31*e7952263Sdancommits, SQLite does: 32*e7952263Sdan 33*e7952263Sdan /* Take an F_WRLCK lock on the database file. This prevents any other 34*e7952263Sdan ** SQLite clients from reading or writing the file until the lock 35*e7952263Sdan ** is released. */ 36*e7952263Sdan rc = fcntl(fd, F_SETLK, ...); 37*e7952263Sdan if( rc!=0 ) goto failed; 38*e7952263Sdan 39*e7952263Sdan rc = ioctl(fd, F2FS_IOC_START_ATOMIC_WRITE); 40*e7952263Sdan if( rc!=0 ) goto fallback_to_legacy_journal_commit; 41*e7952263Sdan 42*e7952263Sdan foreach (dirty page){ 43*e7952263Sdan rc = write(fd, ...dirty page...); 44*e7952263Sdan if( rc!=0 ){ 45*e7952263Sdan ioctl(fd, F2FS_IOC_ABORT_VOLATILE_WRITE); 46*e7952263Sdan goto fallback_to_legacy_journal_commit; 47*e7952263Sdan } 48*e7952263Sdan } 49*e7952263Sdan 50*e7952263Sdan rc = ioctl(fd, F2FS_IOC_COMMIT_ATOMIC_WRITE); 51*e7952263Sdan if( rc!=0 ){ 52*e7952263Sdan ioctl(fd, F2FS_IOC_ABORT_VOLATILE_WRITE); 53*e7952263Sdan goto fallback_to_legacy_journal_commit; 54*e7952263Sdan } 55*e7952263Sdan 56*e7952263Sdan /* If we get there, the transaction has been successfully 57*e7952263Sdan ** committed to persistent storage. The following call 58*e7952263Sdan ** relinquishes the F_WRLCK lock. */ 59*e7952263Sdan fcntl(fd, F_SETLK, ...); 60*e7952263Sdan 61*e7952263SdanAssumptions: 62*e7952263Sdan 63*e7952263Sdan1. After either of the F2FS_IOC_ABORT_VOLATILE_WRITE calls return, 64*e7952263Sdan the database file is in the state that it was in before 65*e7952263Sdan F2FS_IOC_START_ATOMIC_WRITE was invoked. Even if the ioctl() 66*e7952263Sdan fails - we're ignoring the return code. 67*e7952263Sdan 68*e7952263Sdan This is true regardless of the type of error that occurred in 69*e7952263Sdan ioctl() or write(). 70*e7952263Sdan 71*e7952263Sdan2. If the system fails before the F2FS_IOC_COMMIT_ATOMIC_WRITE is 72*e7952263Sdan completed, then following a reboot the database file is in the 73*e7952263Sdan state that it was in before F2FS_IOC_START_ATOMIC_WRITE was invoked. 74*e7952263Sdan Or, if the write was commited right before the system failed, in a 75*e7952263Sdan state indicating that all write() calls were successfully committed 76*e7952263Sdan to persistent storage before the failure occurred. 77*e7952263Sdan 78*e7952263Sdan3. If the process crashes before the F2FS_IOC_COMMIT_ATOMIC_WRITE is 79*e7952263Sdan completed then the file is automatically restored to the state that 80*e7952263Sdan it was in before F2FS_IOC_START_ATOMIC_WRITE was called. This occurs 81*e7952263Sdan before the posix advisory lock is automatically dropped - there is 82*e7952263Sdan no chance that another client will be able to read the file in a 83*e7952263Sdan half-committed state before the rollback operation occurs. 84*e7952263Sdan 85*e7952263Sdan 86*e7952263Sdan 87*e7952263Sdan 88