Skip to content

Commit

Permalink
ovl: mark parent impure and restore timestamp on ovl_link_up()
Browse files Browse the repository at this point in the history
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
  • Loading branch information
Amir Goldstein authored and Miklos Szeredi committed Jul 4, 2017
1 parent 9412812 commit f4439de
Showing 1 changed file with 33 additions and 24 deletions.
57 changes: 33 additions & 24 deletions fs/overlayfs/copy_up.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,48 +316,57 @@ static int ovl_set_origin(struct dentry *dentry, struct dentry *lower,
return err;
}

static int ovl_link_up(struct dentry *parent, struct dentry *dentry)
struct ovl_copy_up_ctx {
struct dentry *parent;
struct dentry *dentry;
struct path lowerpath;
struct kstat stat;
struct kstat pstat;
const char *link;
struct dentry *destdir;
struct qstr destname;
struct dentry *workdir;
bool tmpfile;
bool origin;
};

static int ovl_link_up(struct ovl_copy_up_ctx *c)
{
int err;
struct dentry *upper;
struct dentry *upperdir = ovl_dentry_upper(parent);
struct dentry *upperdir = ovl_dentry_upper(c->parent);
struct inode *udir = d_inode(upperdir);

err = ovl_set_nlink_lower(dentry);
/* Mark parent "impure" because it may now contain non-pure upper */
err = ovl_set_impure(c->parent, upperdir);
if (err)
return err;

err = ovl_set_nlink_lower(c->dentry);
if (err)
return err;

inode_lock_nested(udir, I_MUTEX_PARENT);
upper = lookup_one_len(dentry->d_name.name, upperdir,
dentry->d_name.len);
upper = lookup_one_len(c->dentry->d_name.name, upperdir,
c->dentry->d_name.len);
err = PTR_ERR(upper);
if (!IS_ERR(upper)) {
err = ovl_do_link(ovl_dentry_upper(dentry), udir, upper, true);
err = ovl_do_link(ovl_dentry_upper(c->dentry), udir, upper,
true);
dput(upper);

if (!err)
ovl_dentry_set_upper_alias(dentry);
if (!err) {
/* Restore timestamps on parent (best effort) */
ovl_set_timestamps(upperdir, &c->pstat);
ovl_dentry_set_upper_alias(c->dentry);
}
}
inode_unlock(udir);
ovl_set_nlink_upper(dentry);
ovl_set_nlink_upper(c->dentry);

return err;
}

struct ovl_copy_up_ctx {
struct dentry *parent;
struct dentry *dentry;
struct path lowerpath;
struct kstat stat;
struct kstat pstat;
const char *link;
struct dentry *destdir;
struct qstr destname;
struct dentry *workdir;
bool tmpfile;
bool origin;
};

static int ovl_install_temp(struct ovl_copy_up_ctx *c, struct dentry *temp,
struct dentry **newdentry)
{
Expand Down Expand Up @@ -629,7 +638,7 @@ static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
if (!ovl_dentry_upper(dentry))
err = ovl_do_copy_up(&ctx);
if (!err && !ovl_dentry_has_upper_alias(dentry))
err = ovl_link_up(parent, dentry);
err = ovl_link_up(&ctx);
ovl_copy_up_end(dentry);
}
do_delayed_call(&done);
Expand Down

0 comments on commit f4439de

Please sign in to comment.