Skip to content

Commit 787fb6b

Browse files
author
Miklos Szeredi
committed
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 <[email protected]>
1 parent cbdf35b commit 787fb6b

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

fs/namei.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4346,6 +4346,20 @@ SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newna
43464346
return sys_renameat2(AT_FDCWD, oldname, AT_FDCWD, newname, 0);
43474347
}
43484348

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+
43494363
int readlink_copy(char __user *buffer, int buflen, const char *link)
43504364
{
43514365
int len = PTR_ERR(link);

include/linux/fs.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,13 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
222222
#define ATTR_OPEN (1 << 15) /* Truncating from open(O_TRUNC) */
223223
#define ATTR_TIMES_SET (1 << 16)
224224

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+
225232
/*
226233
* This is the Inode Attributes structure, used for notify_change(). It
227234
* uses the above definitions as flags, to know which values have changed.
@@ -1398,6 +1405,7 @@ extern int vfs_link(struct dentry *, struct inode *, struct dentry *, struct ino
13981405
extern int vfs_rmdir(struct inode *, struct dentry *);
13991406
extern int vfs_unlink(struct inode *, struct dentry *, struct inode **);
14001407
extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct inode **, unsigned int);
1408+
extern int vfs_whiteout(struct inode *, struct dentry *);
14011409

14021410
/*
14031411
* VFS dentry helper functions.
@@ -1628,6 +1636,9 @@ struct super_operations {
16281636
#define IS_AUTOMOUNT(inode) ((inode)->i_flags & S_AUTOMOUNT)
16291637
#define IS_NOSEC(inode) ((inode)->i_flags & S_NOSEC)
16301638

1639+
#define IS_WHITEOUT(inode) (S_ISCHR(inode->i_mode) && \
1640+
(inode)->i_rdev == WHITEOUT_DEV)
1641+
16311642
/*
16321643
* Inode state bits. Protected by inode->i_lock
16331644
*

0 commit comments

Comments
 (0)