Here is just a few illustrations (with some text) for chapter about snapshot and snapshot-origin device mapper's targets from RedHat's Logical Volume Manager Administration Guide. Also, here i make some assumptions about how this works, which seems logical, but unproved since i don't check LVM's sources.
When you create snapshot with lvm, four Device Mapper devices will be used: 1. Create snapshot device ('snapshot' target). 2. Create Copy-On-Write (COW) device (usually, 'linear' target) for snapshot (created at 1). All data blocks changed in snapshot will be written to this device instead of the snapshot origin. Also, all data blocks changed in original device will backed up here (see below). 3. Recreate original device (snapshot origin) using new table with 'snapshot-origin' target and using old device number. 4. Create new device using old original device's table (usually, 'linear') and use this device as origin for snapshot (created at 1) and COW device for new original device (created at 3). Details explained below on example. There was LV 'shilvana_sys/usr' with dm table root@shilvana:~# dmsetup table | grep usr shilvana_sys-usr: 0 20971520 linear 8:3 264 and corresponding device root@shilvana:~# ls -lL /dev/mapper/shilvana_sys-usr brw-rw---- 1 root disk 254, 7 Aug 3 20:18 /dev/mapper/shilvana_sys-usr And now i create snapshot 'snap_usr' of 'shilvana_sys/usr' root@shilvana:~# lvcreate -v -L 100M --snapshot -n usr_snap /dev/shilvana_sys/usr and here is how tables and devices will look now root@shilvana:~# dmsetup table | grep usr shilvana_sys-usr-real: 0 20971520 linear 8:3 264 shilvana_sys-usr_snap-cow: 0 204800 linear 8:3 99614984 shilvana_sys-usr: 0 20971520 snapshot-origin 254:8 shilvana_sys-usr_snap: 0 20971520 snapshot 254:8 254:9 P 8 root@shilvana:~# ls -lL /dev/mapper/shilvana_sys-usr* brw-rw---- 1 root disk 254, 7 Aug 3 20:20 /dev/mapper/shilvana_sys-usr brw-rw---- 1 root disk 254, 8 Aug 3 20:20 /dev/mapper/shilvana_sys-usr-real brw-rw---- 1 root disk 254, 6 Aug 3 20:20 /dev/mapper/shilvana_sys-usr_snap brw-rw---- 1 root disk 254, 9 Aug 3 20:20 /dev/mapper/shilvana_sys-usr_snap-cow How it works? From now on (until snaphsot 'usr_snap' will be removed) both 'usr' and 'usr_snap' will behave like snapshots. Device 'usr-real' is snapshot's origin (it uses original (linear) mapping of old 'usr') and at the same time it is COW (Copy-on-Write) device for new 'usr'. Device 'usr_snap-cow' is COW device for 'usr_snap'. Normally, to use two snapshots we need five devices: snapshot's origin (must be unchanged), snap-1, COW device for snap-1, snap-2 and COW device for snap-2. But here we have only four: origin is at the same time COW device for one of the snapshots ('usr'). Hence, 'usr-real' as COW for 'usr' will work as usual (when we write to 'usr', data block will be written to 'usr-real'), but COW 'usr_snap-cow' will be used in two situations: - when data is written to 'usr_snap' (normal usage), changed data block will be written to 'usr_snap-cow' instead of to origin ('usr-real'); - when data is written to 'usr' and hence to 'usr-real', _original_ data block will be backed up from 'usr-real' to 'usr_snap-cow' in order to preserve it for 'usr_snap' (if this data block is not already changed in 'usr_snap', and, hence, already written to 'usr_snap-cow'); And here is some pictures. Before snapshot creation. 0 20971520 254:7 |... usr ..........| (linear) | | | 8:3 ..................................................... ----->| 264 After snapshot creation. 0 20971520 (254:6) |... usr-snap .....| (snapshot) | | | | 0 20971520 0 204800 (254:8) |... usr-real .....| (254:9) |.. usr_snap-cow ..| (linear) | | | | | | 8:3 .........................|.. other LVs ...........|.. free space ....|..... (PV) ----->| 264 ------------------------------------------------>| 99614984 | | | | (254:7) |... usr ..........| (snapshot-origin) | | 0 20971520 Note, that space for snapshot's COW device 'usr_snap-cow' allocated from free space in VG's Physical Volumes. Read unchanged block from 'usr' and 'usr_snap' respectively: (original block) (original block) ^ ^ | (read) | (read) | | usr usr_snap ^ ^ | | usr-real usr-real ^ ^ | | PV PV (original block) (original block) Change block in usr (write): (changed block) | | (write) v usr | v usr-real ---(save original)---> usr_snap-cow | | v v PV PV (changed block) (original block) Read block changed in usr (but not changed in 'usr_snap'): (changed block) (original block) ^ ^ | (read) | (read) | | usr usr_snap ^ ^ | | usr-real usr_snap-cow ^ ^ | | PV PV (changed block) (original block) Change block in usr_snap (write): (changed block) | | (write) v usr usr_snap | v usr-real usr_snap-cow | v PV PV (original block) (changed block) Read block changed in usr_snap (but not changed in 'usr'): (original block) (changed block) ^ ^ | (read) | (read) | | usr usr_snap ^ ^ | | usr-real usr_snap-cow ^ ^ | | PV PV (original block) (changed block)