BTRFS – NODATACOW and Reflink Copies and snapshots
How NODATACOW affects Snapshots and Reflink copyies: Although you can take a snapshot when NODATACOW is present on a file, you cannot take Reflink copies, it will fail.
Reflink copy is like a hardlink, but it copies the extent refrences, changes to a file will change the source file with a hardlink, but with reflink copies changing the target doesnt change the source (it only adds the new blocks/changes to the filesystem)
# cp -r –reflink=always /data/file /data/file1
# cp -r –reflink=always /data/FOLDER /data/DESTINATION
NOTE: even if “file” was originally 1TB the copy would be instant, just like making a hardlink. I can then make 100gigs worth of changes to file1, and both file and file1 remain unique and thier own, but their shared data is only stored once – its like block level deduplication in a way.
Reflink Copies on NODATACOW items (doesnt work as NODATACOW removes COW on a file and Reflink needs COW on that file) Reflink copies do not work on FILES that have NODATACOW on. They will work on FOLDERS as the FOLDERS dont really do anything with the NODATACOW attribute besides pass it on to new or empty files (and recursively to other folders as well). However if a few files have NODATACOW inside the file, and few have COW, the COW ones copy without problem, the NODATACOW present the error “Invalid Argument”
How to set Chattr
# chattr +C file
– Set NODATACOW on a file, doesnt work unless file is empty
# chattr +C folder
– Sets +C on the folder, only NEW files will get affected by it (new files will get NODATACOW, new folders will also get +C on them thus new files in those folders will get NODATACOW on as well)
# chattr -R +C folder
– Sets +C on the folders and subfolders, and any empty files. None empty files remain without +C.
Copying Moving rules – TO NODATACOW folder (has +C)
– Moving COW (doesnt have +C) file into NODATACOW (has +C) folder, COW stays on.
– Copying COW file into NODATACOW folder, COW turns off.
Copying Moving rules – TO COW folder (doesnt have +C)
– Copying COW file (has +C) Copying to NODATACOW, removes NODATACOW leaving COW (doesnt have +C)
– Moving COW file (has +C) Copying to NODATACOW, leaves NODATACOW (has +C) – preserves NODATACOW
Summary of copying/moving: Moving preserves state of original, copying attains attribute of parent older
NODATACOW on: means the +C attribute is set and lsattr sees it as —————C somefilename
NODATACOW off: means +C attribute is not set (or could not set), and lsattr sees it as —————- somefilename
# lsattr Snodatacow/ | grep empty
# cp –reflink=always Snodatacow/emptyfile file1
cp: failed to clone
file1' from Snodatacow/emptyfile’: Invalid argument
If I reflink copied a folder that has some files with NODATACOW on and some with it off, the ones with NODATACOW will fail with Invalid argument error, the ones with NODATACOW off will work. Folders with NODATACOW on will work (as folders having NODATACOW doesnt really mean anything besides future files and empty files have got C+ set)
NoDATACow only has implications on files. However NoDATACow can be places as an attribute on a folder, it just means any NEW file in the folder will have NoDATACow. Also setting +C on a file that already exists (that has data) does NOT set the NODATACOW attribute – if the file was empty (0byte size) then the NODATACOW attribute would set, however placing +C on a folder and then creating a new file in there makes that new file have NODATACOW.
What CHATTR +C does, it sets NODATACOW, here is the man page reading for it – here are the rules for it:
A file with the ‘C’ attribute set will not be subject to copy-on-write updates. This flag is only supported on file systems which perform copy-on-write. (Note: For btrfs, the ‘C’ flag should be set on new or empty files.
If it is set on a file which already has data blocks, it is undefined when the blocks assigned to the file will be fully stable. If the ‘C’ flag is set on a directory, it will have no effect on the directory, but new files
created in that directory will the No_COW attribute.)
Summary of Rules of CHATTR +C:
1. Cant set on file with data (it sets but does nothing, lsattr will show you that it didnt apply)
2. Can set on a file that is empty (0byte size). lsattr will show the C attribute
3. Can set on folder, any new file in the folder will be made with NODATACOW (that means copies as well – but not moves).
– Copying files into the folder, they will have C attribute
– Moving files into the folder, they will not have the C attribute
– Making a new file/Writing new file, that file will have C attribute
– Making new folder, that folder will inherit the C attribute, and all of its subfolder/subfiles will follow the rules above
– In short: Setting NODATACOW on a folder, means future writes/new files in that folder will have NODATACOW on – also empty files will have NODATACOW on. Exisiting files with data stay with NODATACOW off setting. Exisisting folder change to NODATACOW on (and rules apply recursively)
TIP: Make the folder that you need NODATACOW on, before you place files in there.
TIP WITH VMs: So if you want your VMDKs/VM files to be NODATACOW. Make a folder with NODATACOW and copy the vm files to it (if files are already there, OR you move VM files into it – the C+ attribute will not work). Or make a new folder with NODATACOW (the folder will be empty with the C+ attribute on) then make the VM inside of it.