xref: /sqlite-3.40.0/doc/F2FS.txt (revision e7952263)
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