summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/overlayfs/dir.c2
-rw-r--r--fs/overlayfs/inode.c24
-rw-r--r--fs/overlayfs/overlayfs.h2
-rw-r--r--fs/overlayfs/super.c7
4 files changed, 16 insertions, 19 deletions
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index 617b616ab03b..4ef0d539b097 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -537,7 +537,7 @@ static int ovl_create_object(struct dentry *dentry, int mode, dev_t rdev,
goto out;
err = -ENOMEM;
- inode = ovl_new_inode(dentry->d_sb, mode);
+ inode = ovl_new_inode(dentry->d_sb, mode, rdev);
if (!inode)
goto out_drop_write;
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);
}
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index e218e741cb99..95d0d86c2d54 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -195,7 +195,7 @@ int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags);
int ovl_update_time(struct inode *inode, struct timespec *ts, int flags);
bool ovl_is_private_xattr(const char *name);
-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 *ovl_get_inode(struct super_block *sb, struct inode *realinode);
static inline void ovl_copyattr(struct inode *from, struct inode *to)
{
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 0e100856c7b8..e296312005cc 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -304,7 +304,7 @@ static struct dentry *ovl_d_real(struct dentry *dentry,
{
struct dentry *real;
- if (d_is_dir(dentry)) {
+ if (!d_is_reg(dentry)) {
if (!inode || inode == d_inode(dentry))
return dentry;
goto bug;
@@ -575,7 +575,8 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
if (upperdentry && !d_is_dir(upperdentry)) {
inode = ovl_get_inode(dentry->d_sb, realinode);
} else {
- inode = ovl_new_inode(dentry->d_sb, realinode->i_mode);
+ inode = ovl_new_inode(dentry->d_sb, realinode->i_mode,
+ realinode->i_rdev);
if (inode)
ovl_inode_init(inode, realinode, !!upperdentry);
}
@@ -1324,7 +1325,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
sb->s_fs_info = ufs;
sb->s_flags |= MS_POSIXACL | MS_NOREMOTELOCK;
- root_dentry = d_make_root(ovl_new_inode(sb, S_IFDIR));
+ root_dentry = d_make_root(ovl_new_inode(sb, S_IFDIR, 0));
if (!root_dentry)
goto out_free_oe;