diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2014-10-28 18:27:28 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-10-28 18:27:28 -0400 |
commit | d45f00ae43e63eff1b3d79df20610ae1ef645ebd (patch) | |
tree | 49b273720e044e74116a2d98668a11aac49a3214 /fs/overlayfs | |
parent | 54ef6df3f3f1353d99c80c437259d317b2cd1cbd (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.c | 3 |
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)) { |