1*4882a593Smuzhiyundm_bow (backup on write) 2*4882a593Smuzhiyun======================== 3*4882a593Smuzhiyun 4*4882a593Smuzhiyundm_bow is a device mapper driver that uses the free space on a device to back up 5*4882a593Smuzhiyundata that is overwritten. The changes can then be committed by a simple state 6*4882a593Smuzhiyunchange, or rolled back by removing the dm_bow device and running a command line 7*4882a593Smuzhiyunutility over the underlying device. 8*4882a593Smuzhiyun 9*4882a593Smuzhiyundm_bow has three states, set by writing ‘1’ or ‘2’ to /sys/block/dm-?/bow/state. 10*4882a593SmuzhiyunIt is only possible to go from state 0 (initial state) to state 1, and then from 11*4882a593Smuzhiyunstate 1 to state 2. 12*4882a593Smuzhiyun 13*4882a593SmuzhiyunState 0: dm_bow collects all trims to the device and assumes that these mark 14*4882a593Smuzhiyunfree space on the overlying file system that can be safely used. Typically the 15*4882a593Smuzhiyunmount code would create the dm_bow device, mount the file system, call the 16*4882a593SmuzhiyunFITRIM ioctl on the file system then switch to state 1. These trims are not 17*4882a593Smuzhiyunpropagated to the underlying device. 18*4882a593Smuzhiyun 19*4882a593SmuzhiyunState 1: All writes to the device cause the underlying data to be backed up to 20*4882a593Smuzhiyunthe free (trimmed) area as needed in such a way as they can be restored. 21*4882a593SmuzhiyunHowever, the writes, with one exception, then happen exactly as they would 22*4882a593Smuzhiyunwithout dm_bow, so the device is always in a good final state. The exception is 23*4882a593Smuzhiyunthat sector 0 is used to keep a log of the latest changes, both to indicate that 24*4882a593Smuzhiyunwe are in this state and to allow rollback. See below for all details. If there 25*4882a593Smuzhiyunisn't enough free space, writes are failed with -ENOSPC. 26*4882a593Smuzhiyun 27*4882a593SmuzhiyunState 2: The transition to state 2 triggers replacing the special sector 0 with 28*4882a593Smuzhiyunthe normal sector 0, and the freeing of all state information. dm_bow then 29*4882a593Smuzhiyunbecomes a pass-through driver, allowing the device to continue to be used with 30*4882a593Smuzhiyunminimal performance impact. 31*4882a593Smuzhiyun 32*4882a593SmuzhiyunUsage 33*4882a593Smuzhiyun===== 34*4882a593Smuzhiyundm-bow takes one command line parameter, the name of the underlying device. 35*4882a593Smuzhiyun 36*4882a593Smuzhiyundm-bow will typically be used in the following way. dm-bow will be loaded with a 37*4882a593Smuzhiyunsuitable underlying device and the resultant device will be mounted. A file 38*4882a593Smuzhiyunsystem trim will be issued via the FITRIM ioctl, then the device will be 39*4882a593Smuzhiyunswitched to state 1. The file system will now be used as normal. At some point, 40*4882a593Smuzhiyunthe changes can either be committed by switching to state 2, or rolled back by 41*4882a593Smuzhiyununmounting the file system, removing the dm-bow device and running the command 42*4882a593Smuzhiyunline utility. Note that rebooting the device will be equivalent to unmounting 43*4882a593Smuzhiyunand removing, but the command line utility must still be run 44*4882a593Smuzhiyun 45*4882a593SmuzhiyunDetails of operation in state 1 46*4882a593Smuzhiyun=============================== 47*4882a593Smuzhiyun 48*4882a593Smuzhiyundm_bow maintains a type for all sectors. A sector can be any of: 49*4882a593Smuzhiyun 50*4882a593SmuzhiyunSECTOR0 51*4882a593SmuzhiyunSECTOR0_CURRENT 52*4882a593SmuzhiyunUNCHANGED 53*4882a593SmuzhiyunFREE 54*4882a593SmuzhiyunCHANGED 55*4882a593SmuzhiyunBACKUP 56*4882a593Smuzhiyun 57*4882a593SmuzhiyunSECTOR0 is the first sector on the device, and is used to hold the log of 58*4882a593Smuzhiyunchanges. This is the one exception. 59*4882a593Smuzhiyun 60*4882a593SmuzhiyunSECTOR0_CURRENT is a sector picked from the FREE sectors, and is where reads and 61*4882a593Smuzhiyunwrites from the true sector zero are redirected to. Note that like any backup 62*4882a593Smuzhiyunsector, if the sector is written to directly, it must be moved again. 63*4882a593Smuzhiyun 64*4882a593SmuzhiyunUNCHANGED means that the sector has not been changed since we entered state 1. 65*4882a593SmuzhiyunThus if it is written to or trimmed, the contents must first be backed up. 66*4882a593Smuzhiyun 67*4882a593SmuzhiyunFREE means that the sector was trimmed in state 0 and has not yet been written 68*4882a593Smuzhiyunto or used for backup. On being written to, a FREE sector is changed to CHANGED. 69*4882a593Smuzhiyun 70*4882a593SmuzhiyunCHANGED means that the sector has been modified, and can be further modified 71*4882a593Smuzhiyunwithout further backup. 72*4882a593Smuzhiyun 73*4882a593SmuzhiyunBACKUP means that this is a free sector being used as a backup. On being written 74*4882a593Smuzhiyunto, the contents must first be backed up again. 75*4882a593Smuzhiyun 76*4882a593SmuzhiyunAll backup operations are logged to the first sector. The log sector has the 77*4882a593Smuzhiyunformat: 78*4882a593Smuzhiyun-------------------------------------------------------- 79*4882a593Smuzhiyun| Magic | Count | Sequence | Log entry | Log entry | … 80*4882a593Smuzhiyun-------------------------------------------------------- 81*4882a593Smuzhiyun 82*4882a593SmuzhiyunMagic is a magic number. Count is the number of log entries. Sequence is 0 83*4882a593Smuzhiyuninitially. A log entry is 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun----------------------------------- 86*4882a593Smuzhiyun| Source | Dest | Size | Checksum | 87*4882a593Smuzhiyun----------------------------------- 88*4882a593Smuzhiyun 89*4882a593SmuzhiyunWhen SECTOR0 is full, the log sector is backed up and another empty log sector 90*4882a593Smuzhiyuncreated with sequence number one higher. The first entry in any log entry with 91*4882a593Smuzhiyunsequence > 0 therefore must be the log of the backing up of the previous log 92*4882a593Smuzhiyunsector. Note that sequence is not strictly needed, but is a useful sanity check 93*4882a593Smuzhiyunand potentially limits the time spent trying to restore a corrupted snapshot. 94*4882a593Smuzhiyun 95*4882a593SmuzhiyunOn entering state 1, dm_bow has a list of free sectors. All other sectors are 96*4882a593Smuzhiyununchanged. Sector0_current is selected from the free sectors and the contents of 97*4882a593Smuzhiyunsector 0 are copied there. The sector 0 is backed up, which triggers the first 98*4882a593Smuzhiyunlog entry to be written. 99*4882a593Smuzhiyun 100