diff options
author | Amir Goldstein <amir73il@gmail.com> | 2023-04-27 12:39:09 +0200 |
---|---|---|
committer | Amir Goldstein <amir73il@gmail.com> | 2023-06-19 13:01:14 +0200 |
commit | 42dd69ae1af42cf72d167e63a039b8c63653eb7f (patch) | |
tree | da3f8b549fc66bfbf52747724869f7d9a2da28bb /fs/overlayfs/copy_up.c | |
parent | ovl: prepare for lazy lookup of lowerdata inode (diff) | |
download | linux-42dd69ae1af42cf72d167e63a039b8c63653eb7f.tar.xz linux-42dd69ae1af42cf72d167e63a039b8c63653eb7f.zip |
ovl: implement lazy lookup of lowerdata in data-only layers
Defer lookup of lowerdata in the data-only layers to first data access
or before copy up.
We perform lowerdata lookup before copy up even if copy up is metadata
only copy up. We can further optimize this lookup later if needed.
We do best effort lazy lookup of lowerdata for d_real_inode(), because
this interface does not expect errors. The only current in-tree caller
of d_real_inode() is trace_uprobe and this caller is likely going to be
followed reading from the file, before placing uprobes on offset within
the file, so lowerdata should be available when setting the uprobe.
Tested-by: kernel test robot <oliver.sang@intel.com>
Reviewed-by: Alexander Larsson <alexl@redhat.com>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/overlayfs/copy_up.c')
-rw-r--r-- | fs/overlayfs/copy_up.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index 95dce240ba17..568f743a5584 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -1073,6 +1073,15 @@ static int ovl_copy_up_flags(struct dentry *dentry, int flags) if (WARN_ON(disconnected && d_is_dir(dentry))) return -EIO; + /* + * We may not need lowerdata if we are only doing metacopy up, but it is + * not very important to optimize this case, so do lazy lowerdata lookup + * before any copy up, so we can do it before taking ovl_inode_lock(). + */ + err = ovl_maybe_lookup_lowerdata(dentry); + if (err) + return err; + old_cred = ovl_override_creds(dentry->d_sb); while (!err) { struct dentry *next; |