summaryrefslogtreecommitdiffstats
path: root/fs/overlayfs/util.c
diff options
context:
space:
mode:
authorVivek Goyal <vgoyal@redhat.com>2018-05-11 17:49:30 +0200
committerMiklos Szeredi <mszeredi@redhat.com>2018-07-20 09:56:10 +0200
commit67d756c27ac4f4576dee313579724bd8711bc75e (patch)
tree899a2a39cfd62193e07e0876790f54b7e327720f /fs/overlayfs/util.c
parentovl: Add helper ovl_dentry_lowerdata() to get lower data dentry (diff)
downloadlinux-67d756c27ac4f4576dee313579724bd8711bc75e.tar.xz
linux-67d756c27ac4f4576dee313579724bd8711bc75e.zip
ovl: Fix ovl_getattr() to get number of blocks from lower
If an inode has been copied up metadata only, then we need to query the number of blocks from lower and fill up the stat->st_blocks. We need to be careful about races where we are doing stat on one cpu and data copy up is taking place on other cpu. We want to return stat->st_blocks either from lower or stable upper and not something in between. Hence, ovl_has_upperdata() is called first to figure out whether block reporting will take place from lower or upper. We now support metacopy dentries in middle layer. That means number of blocks reporting needs to come from lowest data dentry and this could be different from lower dentry. Hence we end up making a separate vfs_getxattr() call for metacopy dentries to get number of blocks. Signed-off-by: Vivek Goyal <vgoyal@redhat.com> Reviewed-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/overlayfs/util.c')
-rw-r--r--fs/overlayfs/util.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index 7c7b95d5da1f..4f9c2ecee74c 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -825,3 +825,19 @@ out:
pr_warn_ratelimited("overlayfs: failed to get metacopy (%i)\n", res);
return res;
}
+
+bool ovl_is_metacopy_dentry(struct dentry *dentry)
+{
+ struct ovl_entry *oe = dentry->d_fsdata;
+
+ if (!d_is_reg(dentry))
+ return false;
+
+ if (ovl_dentry_upper(dentry)) {
+ if (!ovl_has_upperdata(d_inode(dentry)))
+ return true;
+ return false;
+ }
+
+ return (oe->numlower > 1);
+}