Filesystems
Even after a hard disk has been conceptually divided into partitions or logical volumes, it is still not ready to hold files.
Journaling
Pithy
Journaling is basically git for file systems, but you write your diff before actually making the change. That way if something goes wrong during the write it can be reverted.
Old filesystems could be corrupted easily if power was interrupted in the middle of a write operation because the disk blocks could have inconsistent data structures. fsck was used at boot to check filesystems for this and automatically patch it.
Modern filesystems (1990+ IBM) include a feature called journaling that averts the possibility of this type of corruption.
With journaling, when a filesystem operation occurs, the required steps are:
- Write to the journal what you’re going to change.
- Once the journal update is complete, a “commit record” is written to mark the end of the entry.
- Only then is the normal filesystem modified.
If a crash occurs during the update, the filesystem can later replay the journal log to reconstruct a perfectly consistent filesystem.
In most cases, only metadata changes are journaled. The actual data to be stored is written directly to the filesystem. Some filesystems can use the journal for data too, but at a significant performance cost.
Linux ext3 (1999) was the first mainstream open-source journaling implementation.
Traditional filesystems
“Traditional” File systems in order of creation:
1980sUnix File SystemUFS- still default in FreeBSD1993Second extended filesystemext2- Linux default for a while1994Extents filesystemXFS- fast, can’t shirnk paritiions.. - default for Redhat and CentOS1999ext3- adds journaling2008ext4- small update, raises file limits, better performance - default on debian and ubuntu
Filesystem terminology
An inode (“index node”) is a record describing one file: its metadata (owner, permissions, size, timestamps) and where its data blocks live on disk. Notably it does not contain the filename — a directory entry is just a name pointing at an inode.
The superblock describes the filesystem itself: block size, where the inode tables are, block usage, and so on. Since losing it would be catastrophic, copies are kept at several locations on disk.
The kernel caches disk blocks, so a write an application thinks is done may not actually be on disk yet.
Filesystem formatting
mkfs.fstype [-L label] [other options] device # General format
mkfs.ext4 -L home /dev/sdb1 # ExampleThe -L option to both mkfs and newfs sets a volume label for the filesystem such as “spare,” “home,” or “extra.” It’s best practice to set a label. Labeling the filesystem frees you from having to track the device on which it’s been installed.
fsck
fsck - filesystem consistency check
Because of block buffering and the fact that disk drives are not really transactional devices, filesystem data structures can potentially become self-inconsistent.
The original fsck scheme worked surprisingly well, but because it involved reading all the data on a disk, it could take hours on a large drive. Now, filesystem journals let fsck pinpoint the activity that was occurring at the time of a failure. fsck can simply rewind the filesystem to the last known consistent state.
Disks are normally fscked automatically at boot time if they are listed in the system’s /etc/fstab file
You can run fsck by hand to perform an in-depth examination more akin to the original fsck procedure, but be aware of the time required.
lost+found (at the root of each filesystem) is where fsck deposits orphaned files whose parent directory can’t be determined. It has space preallocated so fsck doesn’t need to allocate anything on an unstable filesystem. Don’t delete it (mklost+found can re-create it). Since the name given to a file is recorded only in the file’s parent directory, names for orphan files are not available and so the files placed in lost+found are named with their inode numbers
mount / umount
mount- attaches a filesystem to the file tree: an existing directory (the mount point) becomes the root of the new filesystemumount- detaches it. Fails if the filesystem is busy, i.e. a process has a file open or its current directory there
fuser -c /mountpoint # print PIDs of processes using the filesystem
# or use the following flag to lazily umount it once all open files have been closed
umount -lZFS and Btrfs
Question
Why would I use either of these over something like
ext4?
Answer
- ext4: Single disk, no RAID, simple
- ZFS: Built-in RAID, checksums (catches corruption), snapshots, SSD cache but needs 2GB+ RAM, hardware locked-down
- Btrfs: Built-in RAID, snapshots, flexible storage (add/remove disks live), less RAM
Question
What are some usecases to think about using
ZFSorbtrfs?
Answer
ZFS:
- NAS/production storage (corruption risk is real)
- Snapshot-heavy backups
btrfs:- Server storage that grows/shrinks often
Everything else just use
ext4(+mdif you require raid)
ZFS came first but was locked to OpenSolaris, Canoncial said screw it and added to Ubuntu and didn’t get sued.
Copy-on-Write (CoW)
One key feature to both of these is CoW. Instead of overwriting a block in place:
- write to a new vacant block
- Then update its parent pointer