mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
cbdf35bcb8
commit
787fb6bc96
14
fs/namei.c
14
fs/namei.c
|
@ -4346,6 +4346,20 @@ SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newna
|
|||
return sys_renameat2(AT_FDCWD, oldname, AT_FDCWD, newname, 0);
|
||||
}
|
||||
|
||||
int vfs_whiteout(struct inode *dir, struct dentry *dentry)
|
||||
{
|
||||
int error = may_create(dir, dentry);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (!dir->i_op->mknod)
|
||||
return -EPERM;
|
||||
|
||||
return dir->i_op->mknod(dir, dentry,
|
||||
S_IFCHR | WHITEOUT_MODE, WHITEOUT_DEV);
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_whiteout);
|
||||
|
||||
int readlink_copy(char __user *buffer, int buflen, const char *link)
|
||||
{
|
||||
int len = PTR_ERR(link);
|
||||
|
|
|
@ -222,6 +222,13 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
|
|||
#define ATTR_OPEN (1 << 15) /* Truncating from open(O_TRUNC) */
|
||||
#define ATTR_TIMES_SET (1 << 16)
|
||||
|
||||
/*
|
||||
* Whiteout is represented by a char device. The following constants define the
|
||||
* mode and device number to use.
|
||||
*/
|
||||
#define WHITEOUT_MODE 0
|
||||
#define WHITEOUT_DEV 0
|
||||
|
||||
/*
|
||||
* This is the Inode Attributes structure, used for notify_change(). It
|
||||
* 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
|
|||
extern int vfs_rmdir(struct inode *, struct dentry *);
|
||||
extern int vfs_unlink(struct inode *, struct dentry *, struct inode **);
|
||||
extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct inode **, unsigned int);
|
||||
extern int vfs_whiteout(struct inode *, struct dentry *);
|
||||
|
||||
/*
|
||||
* VFS dentry helper functions.
|
||||
|
@ -1628,6 +1636,9 @@ struct super_operations {
|
|||
#define IS_AUTOMOUNT(inode) ((inode)->i_flags & S_AUTOMOUNT)
|
||||
#define IS_NOSEC(inode) ((inode)->i_flags & S_NOSEC)
|
||||
|
||||
#define IS_WHITEOUT(inode) (S_ISCHR(inode->i_mode) && \
|
||||
(inode)->i_rdev == WHITEOUT_DEV)
|
||||
|
||||
/*
|
||||
* Inode state bits. Protected by inode->i_lock
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue