diff options
author | Miklos Szeredi <mszeredi@redhat.com> | 2016-12-16 13:02:55 +0300 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2016-12-16 13:02:55 +0300 |
commit | ca4c8a3a800039c2681d609c5b7491c1bd17c0a7 (patch) | |
tree | 9175862945696937768703f572078b5043bd0628 /fs/overlayfs/inode.c | |
parent | 6c02cb59e6fe1dfbe4352dbf089e7a16ef6bfac6 (diff) | |
download | linux-ca4c8a3a800039c2681d609c5b7491c1bd17c0a7.tar.xz |
ovl: treat special files like a regular fs
No sense in opening special files on the underlying layers, they work just
as well if opened on the overlay.
Side effect is that it's no longer possible to connect one side of a pipe
opened on overlayfs with the other side opened on the underlying layer.
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/overlayfs/inode.c')
-rw-r--r-- | fs/overlayfs/inode.c | 24 |
1 files changed, 10 insertions, 14 deletions
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index a572e38349f6..a10e948d24fa 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -333,7 +333,7 @@ static const struct inode_operations ovl_symlink_inode_operations = { .update_time = ovl_update_time, }; -static void ovl_fill_inode(struct inode *inode, umode_t mode) +static void ovl_fill_inode(struct inode *inode, umode_t mode, dev_t rdev) { inode->i_ino = get_next_ino(); inode->i_mode = mode; @@ -342,8 +342,11 @@ static void ovl_fill_inode(struct inode *inode, umode_t mode) inode->i_acl = inode->i_default_acl = ACL_DONT_CACHE; #endif - mode &= S_IFMT; - switch (mode) { + switch (mode & S_IFMT) { + case S_IFREG: + inode->i_op = &ovl_file_inode_operations; + break; + case S_IFDIR: inode->i_op = &ovl_dir_inode_operations; inode->i_fop = &ovl_dir_operations; @@ -354,26 +357,19 @@ static void ovl_fill_inode(struct inode *inode, umode_t mode) break; default: - WARN(1, "illegal file type: %i\n", mode); - /* Fall through */ - - case S_IFREG: - case S_IFSOCK: - case S_IFBLK: - case S_IFCHR: - case S_IFIFO: inode->i_op = &ovl_file_inode_operations; + init_special_inode(inode, mode, rdev); break; } } -struct inode *ovl_new_inode(struct super_block *sb, umode_t mode) +struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, dev_t rdev) { struct inode *inode; inode = new_inode(sb); if (inode) - ovl_fill_inode(inode, mode); + ovl_fill_inode(inode, mode, rdev); return inode; } @@ -397,7 +393,7 @@ struct inode *ovl_get_inode(struct super_block *sb, struct inode *realinode) inode = iget5_locked(sb, (unsigned long) realinode, ovl_inode_test, ovl_inode_set, realinode); if (inode && inode->i_state & I_NEW) { - ovl_fill_inode(inode, realinode->i_mode); + ovl_fill_inode(inode, realinode->i_mode, realinode->i_rdev); set_nlink(inode, realinode->i_nlink); unlock_new_inode(inode); } |