Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

vfs: add whiteout support

Whiteout isn't actually a new file type, but is represented as a char
device (Linus's idea) with 0/0 device number.

This has several advantages compared to introducing a new whiteout file
type:

- no userspace API changes (e.g. trivial to make backups of upper layer
filesystem, without losing whiteouts)

- no fs image format changes (you can boot an old kernel/fsck without
whiteout support and things won't break)

- implementation is trivial

Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>

+25
+14
fs/namei.c
··· 4346 4346 return sys_renameat2(AT_FDCWD, oldname, AT_FDCWD, newname, 0); 4347 4347 } 4348 4348 4349 + int vfs_whiteout(struct inode *dir, struct dentry *dentry) 4350 + { 4351 + int error = may_create(dir, dentry); 4352 + if (error) 4353 + return error; 4354 + 4355 + if (!dir->i_op->mknod) 4356 + return -EPERM; 4357 + 4358 + return dir->i_op->mknod(dir, dentry, 4359 + S_IFCHR | WHITEOUT_MODE, WHITEOUT_DEV); 4360 + } 4361 + EXPORT_SYMBOL(vfs_whiteout); 4362 + 4349 4363 int readlink_copy(char __user *buffer, int buflen, const char *link) 4350 4364 { 4351 4365 int len = PTR_ERR(link);
+11
include/linux/fs.h
··· 223 223 #define ATTR_TIMES_SET (1 << 16) 224 224 225 225 /* 226 + * Whiteout is represented by a char device. The following constants define the 227 + * mode and device number to use. 228 + */ 229 + #define WHITEOUT_MODE 0 230 + #define WHITEOUT_DEV 0 231 + 232 + /* 226 233 * This is the Inode Attributes structure, used for notify_change(). It 227 234 * uses the above definitions as flags, to know which values have changed. 228 235 * Also, in this manner, a Filesystem can look at only the values it cares ··· 1405 1398 extern int vfs_rmdir(struct inode *, struct dentry *); 1406 1399 extern int vfs_unlink(struct inode *, struct dentry *, struct inode **); 1407 1400 extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct inode **, unsigned int); 1401 + extern int vfs_whiteout(struct inode *, struct dentry *); 1408 1402 1409 1403 /* 1410 1404 * VFS dentry helper functions. ··· 1635 1627 #define IS_IMA(inode) ((inode)->i_flags & S_IMA) 1636 1628 #define IS_AUTOMOUNT(inode) ((inode)->i_flags & S_AUTOMOUNT) 1637 1629 #define IS_NOSEC(inode) ((inode)->i_flags & S_NOSEC) 1630 + 1631 + #define IS_WHITEOUT(inode) (S_ISCHR(inode->i_mode) && \ 1632 + (inode)->i_rdev == WHITEOUT_DEV) 1638 1633 1639 1634 /* 1640 1635 * Inode state bits. Protected by inode->i_lock