aboutsummaryrefslogtreecommitdiffstats
path: root/fs/overlayfs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-10-28 18:27:28 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2014-10-28 18:27:28 -0400
commitd45f00ae43e63eff1b3d79df20610ae1ef645ebd (patch)
tree49b273720e044e74116a2d98668a11aac49a3214 /fs/overlayfs
parent54ef6df3f3f1353d99c80c437259d317b2cd1cbd (diff)
overlayfs: barriers for opening upper-layer directory
make sure that a) all stores done by opening struct file don't leak past storing the reference in od->upperfile b) the lockless side has read dependency barrier Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/overlayfs')
-rw-r--r--fs/overlayfs/readdir.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
index 910553f37aca..8c8ce9d87ba3 100644
--- a/fs/overlayfs/readdir.c
+++ b/fs/overlayfs/readdir.c
@@ -454,12 +454,13 @@ static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end,
454 if (!od->is_upper && ovl_path_type(dentry) == OVL_PATH_MERGE) { 454 if (!od->is_upper && ovl_path_type(dentry) == OVL_PATH_MERGE) {
455 struct inode *inode = file_inode(file); 455 struct inode *inode = file_inode(file);
456 456
457 realfile = od->upperfile; 457 realfile =lockless_dereference(od->upperfile);
458 if (!realfile) { 458 if (!realfile) {
459 struct path upperpath; 459 struct path upperpath;
460 460
461 ovl_path_upper(dentry, &upperpath); 461 ovl_path_upper(dentry, &upperpath);
462 realfile = ovl_path_open(&upperpath, O_RDONLY); 462 realfile = ovl_path_open(&upperpath, O_RDONLY);
463 smp_mb__before_spinlock();
463 mutex_lock(&inode->i_mutex); 464 mutex_lock(&inode->i_mutex);
464 if (!od->upperfile) { 465 if (!od->upperfile) {
465 if (IS_ERR(realfile)) { 466 if (IS_ERR(realfile)) {