From: Miklos Szeredi <[email protected]>

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]>
---
 fs/namei.c         | 14 ++++++++++++++
 include/linux/fs.h | 11 +++++++++++
 2 files changed, 25 insertions(+)

diff --git a/fs/namei.c b/fs/namei.c
index 1039eef0e22c..413d7c138e95 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4323,6 +4323,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);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 9d821253379d..88ec7a2878bc 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -221,6 +221,13 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t 
offset,
 #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.
  * Also, in this manner, a Filesystem can look at only the values it cares
@@ -1387,6 +1394,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.
@@ -1611,6 +1619,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
  *
-- 
1.8.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to