[Devel] [PATCH rh7 2/2] fs: use original vfsmount for touch_atime
Maxim Patlasov
mpatlasov at virtuozzo.com
Tue Sep 13 17:55:44 PDT 2016
In case of overlayfs, vfs_open is called recursively filling filp->f_path
with pointers to real dentry and vfsmount (upper or lower). Hence, touch_atime
has no access to mnt_flags of original (overlayfs) vfsmount. The patch fixes
the problem by saving original path to a new field of struct file.
The patch to be reverted when RHEL picks up 4bacc9c92 from mainline:
> Make file->f_path always point to the overlay dentry so that the path in
> /proc/pid/fd is correct and to ensure that label-based LSMs have access to the
> overlay as well as the underlay (path-based LSMs probably don't need it).
Picking it now is premature because it introduced a lot of bugs (outside overlay)
and the chances are high to overlook some related fixes in mainline.
https://jira.sw.ru/browse/PSBM-51009
Signed-off-by: Maxim Patlasov <mpatlasov at virtuozzo.com>
---
fs/open.c | 3 +++
include/linux/fs.h | 4 +++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/fs/open.c b/fs/open.c
index bc60c05..8c066b1 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -894,6 +894,9 @@ int vfs_open(const struct path *path, struct file *filp,
struct inode *inode = path->dentry->d_inode;
iop_dentry_open_t dentry_open = get_dentry_open_iop(inode);
+ if (!filp->f_original_path.mnt)
+ filp->f_original_path = *path;
+
if (dentry_open)
return dentry_open(path->dentry, filp, cred);
else {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index f1c3d5b..7b84d49 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -961,6 +961,7 @@ struct file {
struct rcu_head fu_rcuhead;
} f_u;
struct path f_path;
+ struct path f_original_path;
#define f_dentry f_path.dentry
struct inode *f_inode; /* cached value */
const struct file_operations *f_op;
@@ -2095,7 +2096,8 @@ extern void touch_atime(struct path *);
static inline void file_accessed(struct file *file)
{
if (!(file->f_flags & O_NOATIME))
- touch_atime(&file->f_path);
+ touch_atime(file->f_original_path.mnt ?
+ &file->f_original_path : &file->f_path);
}
int sync_inode(struct inode *inode, struct writeback_control *wbc);
More information about the Devel
mailing list