Prev: [PATCH 03/38] VFS: Add read-only users count to superblock
Next: [PATCH 00/38] VFS union mounts - Add MS_FALLTHRU
From: Valerie Aurora on 6 Aug 2010 18:50 From: Jan Blunck <jblunck(a)suse.de> If we mkdir() a directory on the top layer of a union, we don't want entries from a matching directory on the lower layer to "show through" suddenly. To prevent this, we set the opaque flag on a directory if there was previously a white-out with the same name. (If there is no white-out and the directory exists in a lower layer, then mkdir() will fail with EEXIST.) Signed-off-by: Jan Blunck <jblunck(a)suse.de> Signed-off-by: Valerie Aurora <vaurora(a)redhat.com> --- fs/namei.c | 11 ++++++++++- include/linux/fs.h | 5 +++++ 2 files changed, 15 insertions(+), 1 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 665d394..cd8b0d0 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2108,6 +2108,7 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename, int, mode, unsigned, dev) int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) { int error = may_create(dir, dentry); + int opaque = 0; if (error) return error; @@ -2120,9 +2121,17 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) if (error) return error; + if (d_is_whiteout(dentry)) + opaque = 1; + error = dir->i_op->mkdir(dir, dentry, mode); - if (!error) + if (!error) { fsnotify_mkdir(dir, dentry); + if (opaque) { + dentry->d_inode->i_flags |= S_OPAQUE; + mark_inode_dirty(dentry->d_inode); + } + } return error; } diff --git a/include/linux/fs.h b/include/linux/fs.h index 1f80897..1dbe156 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -236,6 +236,7 @@ struct inodes_stat_t { #define S_NOCMTIME 128 /* Do not update file c/mtime */ #define S_SWAPFILE 256 /* Do not truncate: swapon got its bmaps */ #define S_PRIVATE 512 /* Inode is fs-internal */ +#define S_OPAQUE 1024 /* Directory is opaque */ /* * Note that nosuid etc flags are inode-specific: setting some file-system @@ -270,6 +271,7 @@ struct inodes_stat_t { #define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME) #define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE) #define IS_PRIVATE(inode) ((inode)->i_flags & S_PRIVATE) +#define IS_OPAQUE(inode) ((inode)->i_flags & S_OPAQUE) /* the read-only stuff doesn't really belong here, but any other place is probably as bad and I don't want to create yet another include file. */ @@ -351,8 +353,11 @@ struct inodes_stat_t { #define FS_NOTAIL_FL 0x00008000 /* file tail should not be merged */ #define FS_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */ #define FS_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ +/* 0x00040000 is used by ext4 */ #define FS_EXTENT_FL 0x00080000 /* Extents */ #define FS_DIRECTIO_FL 0x00100000 /* Use direct i/o */ +/* 0x00200000 and 0x00400000 also used by ext4 */ +#define FS_OPAQUE_FL 0x00800000 /* Dir is opaque */ #define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */ #define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo(a)vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ |