Loading fs/overlayfs/copy_up.c +33 −24 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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); Loading Loading
fs/overlayfs/copy_up.c +33 −24 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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); Loading