If it makes sense to copy up only metadata during copy up, do it. This is done for regular files which are not opened for WRITE and have origin being saved. Right now ->metacopy is set to 0 always. Last patch in the series will remove the hard coded statement and enable metacopy feature. Currently ovl_set_origin() returns success even if specified xattr could not be set due to -EOPNOTSUPP returned by upper. IOW, ovl_set_origin() operation is optional and copy up operation continues. With metadata copy up, ovl_set_origin() can't be optional. We need to know if origin could be set or not. If it could not be set, then either disable metacopy or abort copy up operation. I have take then later approach and disable metacopy for this inode. Normally we should not run into this path as metacopy will not be enabled if upper does not support xattr. This check is done during mount. This path can only hit if checks during mount pass but at some point of time later upper still returns -EOPNOTSUPP. So its a saftey mechanism to handle that unexpected -EOPNOTSUPP. Reviewed-by: Amir Goldstein <amir73il@xxxxxxxxx> Signed-off-by: Vivek Goyal <vgoyal@xxxxxxxxxx> --- fs/overlayfs/copy_up.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index 98403b1d40c2..45e396a0fd6a 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -232,6 +232,26 @@ int ovl_set_attr(struct dentry *upperdentry, struct kstat *stat) return err; } +static bool ovl_need_meta_copy_up(struct dentry *dentry, umode_t mode, + int flags) +{ + struct ovl_fs *ofs = dentry->d_sb->s_fs_info; + + /* TODO: Will enable metacopy in last patch of series */ + return false; + + if (!ofs->config.metacopy) + return false; + + if (!S_ISREG(mode)) + return false; + + if (flags && ((OPEN_FMODE(flags) & FMODE_WRITE) || (flags & O_TRUNC))) + return false; + + return true; +} + struct ovl_fh *ovl_encode_fh(struct dentry *real, bool is_upper) { struct ovl_fh *fh; @@ -416,6 +436,7 @@ struct ovl_copy_up_ctx { bool tmpfile; bool origin; bool indexed; + bool metacopy; }; static int ovl_link_up(struct ovl_copy_up_ctx *c) @@ -553,7 +574,7 @@ static int ovl_copy_up_inode(struct ovl_copy_up_ctx *c, struct dentry *temp) return err; } - if (S_ISREG(c->stat.mode)) { + if (S_ISREG(c->stat.mode) && !c->metacopy) { struct path upperpath; ovl_path_upper(c->dentry, &upperpath); @@ -729,6 +750,8 @@ static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry, if (err) return err; + ctx.metacopy = ovl_need_meta_copy_up(dentry, ctx.stat.mode, flags); + if (parent) { ovl_path_upper(parent, &parentpath); ctx.destdir = parentpath.dentry; -- 2.13.6 -- To unsubscribe from this list: send the line "unsubscribe linux-unionfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html