summaryrefslogtreecommitdiff
path: root/fs/overlayfs/super.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-09-13 09:11:44 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-13 09:11:44 -0700
commitc353f88f3de485a059e5c003721e2dc276d02fad (patch)
tree2a18b309dc3dcd250d6d2aeb51b61264cd8f9b2a /fs/overlayfs/super.c
parent6d8ef53e8b2fed8b0f91df0c6da7cc92747d934a (diff)
parent939ae4efd51c627da270af74ef069db5124cb5b0 (diff)
Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
Pull overlayfs updates from Miklos Szeredi: "This fixes d_ino correctness in readdir, which brings overlayfs on par with normal filesystems regarding inode number semantics, as long as all layers are on the same filesystem. There are also some bug fixes, one in particular (random ioctl's shouldn't be able to modify lower layers) that touches some vfs code, but of course no-op for non-overlay fs" * 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs: ovl: fix false positive ESTALE on lookup ovl: don't allow writing ioctl on lower layer ovl: fix relatime for directories vfs: add flags to d_real() ovl: cleanup d_real for negative ovl: constant d_ino for non-merge dirs ovl: constant d_ino across copy up ovl: fix readdir error value ovl: check snprintf return
Diffstat (limited to 'fs/overlayfs/super.c')
-rw-r--r--fs/overlayfs/super.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index d86e89f97201..cd49c0298ddf 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -70,20 +70,20 @@ static int ovl_check_append_only(struct inode *inode, int flag)
static struct dentry *ovl_d_real(struct dentry *dentry,
const struct inode *inode,
- unsigned int open_flags)
+ unsigned int open_flags, unsigned int flags)
{
struct dentry *real;
int err;
+ if (flags & D_REAL_UPPER)
+ return ovl_dentry_upper(dentry);
+
if (!d_is_reg(dentry)) {
if (!inode || inode == d_inode(dentry))
return dentry;
goto bug;
}
- if (d_is_negative(dentry))
- return dentry;
-
if (open_flags) {
err = ovl_open_maybe_copy_up(dentry, open_flags);
if (err)
@@ -105,7 +105,7 @@ static struct dentry *ovl_d_real(struct dentry *dentry,
goto bug;
/* Handle recursion */
- real = d_real(real, inode, open_flags);
+ real = d_real(real, inode, open_flags, 0);
if (!inode || inode == d_inode(real))
return real;
@@ -198,6 +198,7 @@ static void ovl_destroy_inode(struct inode *inode)
dput(oi->__upperdentry);
kfree(oi->redirect);
+ ovl_dir_cache_free(inode);
mutex_destroy(&oi->lock);
call_rcu(&inode->i_rcu, ovl_i_callback);