diff options
Diffstat (limited to 'fs/overlayfs')
-rw-r--r-- | fs/overlayfs/file.c | 9 | ||||
-rw-r--r-- | fs/overlayfs/inode.c | 3 | ||||
-rw-r--r-- | fs/overlayfs/super.c | 28 | ||||
-rw-r--r-- | fs/overlayfs/util.c | 4 |
4 files changed, 32 insertions, 12 deletions
diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index 8be4dc050d1e..ec3671ca140c 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -239,6 +239,7 @@ static void ovl_file_accessed(struct file *file) { struct inode *inode, *upperinode; struct timespec64 ctime, uctime; + struct timespec64 mtime, umtime; if (file->f_flags & O_NOATIME) return; @@ -251,9 +252,11 @@ static void ovl_file_accessed(struct file *file) ctime = inode_get_ctime(inode); uctime = inode_get_ctime(upperinode); - if ((!timespec64_equal(&inode->i_mtime, &upperinode->i_mtime) || - !timespec64_equal(&ctime, &uctime))) { - inode->i_mtime = upperinode->i_mtime; + mtime = inode_get_mtime(inode); + umtime = inode_get_mtime(upperinode); + if ((!timespec64_equal(&mtime, &umtime)) || + !timespec64_equal(&ctime, &uctime)) { + inode_set_mtime_to_ts(inode, inode_get_mtime(upperinode)); inode_set_ctime_to_ts(inode, uctime); } diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 83ef66644c21..b6e98a7d36ce 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -704,7 +704,8 @@ int ovl_update_time(struct inode *inode, int flags) if (upperpath.dentry) { touch_atime(&upperpath); - inode->i_atime = d_inode(upperpath.dentry)->i_atime; + inode_set_atime_to_ts(inode, + inode_get_atime(d_inode(upperpath.dentry))); } } return 0; diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 3fa2416264a4..6cd949c59fed 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -34,14 +34,22 @@ static struct dentry *ovl_d_real(struct dentry *dentry, struct dentry *real = NULL, *lower; int err; - /* It's an overlay file */ + /* + * vfs is only expected to call d_real() with NULL from d_real_inode() + * and with overlay inode from file_dentry() on an overlay file. + * + * TODO: remove @inode argument from d_real() API, remove code in this + * function that deals with non-NULL @inode and remove d_real() call + * from file_dentry(). + */ if (inode && d_inode(dentry) == inode) return dentry; + else if (inode) + goto bug; if (!d_is_reg(dentry)) { - if (!inode || inode == d_inode(dentry)) - return dentry; - goto bug; + /* d_real_inode() is only relevant for regular files */ + return dentry; } real = ovl_dentry_upper(dentry); @@ -487,13 +495,13 @@ static const struct xattr_handler ovl_other_xattr_handler = { .set = ovl_other_xattr_set, }; -static const struct xattr_handler *ovl_trusted_xattr_handlers[] = { +static const struct xattr_handler * const ovl_trusted_xattr_handlers[] = { &ovl_own_trusted_xattr_handler, &ovl_other_xattr_handler, NULL }; -static const struct xattr_handler *ovl_user_xattr_handlers[] = { +static const struct xattr_handler * const ovl_user_xattr_handlers[] = { &ovl_own_user_xattr_handler, &ovl_other_xattr_handler, NULL @@ -1488,8 +1496,16 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc) sb->s_xattr = ofs->config.userxattr ? ovl_user_xattr_handlers : ovl_trusted_xattr_handlers; sb->s_fs_info = ofs; +#ifdef CONFIG_FS_POSIX_ACL sb->s_flags |= SB_POSIXACL; +#endif sb->s_iflags |= SB_I_SKIP_SYNC | SB_I_IMA_UNVERIFIABLE_SIGNATURE; + /* + * Ensure that umask handling is done by the filesystems used + * for the the upper layer instead of overlayfs as that would + * lead to unexpected results. + */ + sb->s_iflags |= SB_I_NOUMASK; err = -ENOMEM; root_dentry = ovl_get_root(sb, ctx->upper.dentry, oe); diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 89e0d60d35b6..868afd8834c3 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -1409,8 +1409,8 @@ void ovl_copyattr(struct inode *inode) inode->i_uid = vfsuid_into_kuid(vfsuid); inode->i_gid = vfsgid_into_kgid(vfsgid); inode->i_mode = realinode->i_mode; - inode->i_atime = realinode->i_atime; - inode->i_mtime = realinode->i_mtime; + inode_set_atime_to_ts(inode, inode_get_atime(realinode)); + inode_set_mtime_to_ts(inode, inode_get_mtime(realinode)); inode_set_ctime_to_ts(inode, inode_get_ctime(realinode)); i_size_write(inode, i_size_read(realinode)); } |