Skip to content

Commit f4439de

Browse files
amir73ilMiklos Szeredi
authored andcommitted
ovl: mark parent impure and restore timestamp on ovl_link_up()
Signed-off-by: Amir Goldstein <[email protected]>
1 parent 9412812 commit f4439de

File tree

1 file changed

+33
-24
lines changed

1 file changed

+33
-24
lines changed

fs/overlayfs/copy_up.c

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -316,48 +316,57 @@ static int ovl_set_origin(struct dentry *dentry, struct dentry *lower,
316316
return err;
317317
}
318318

319-
static int ovl_link_up(struct dentry *parent, struct dentry *dentry)
319+
struct ovl_copy_up_ctx {
320+
struct dentry *parent;
321+
struct dentry *dentry;
322+
struct path lowerpath;
323+
struct kstat stat;
324+
struct kstat pstat;
325+
const char *link;
326+
struct dentry *destdir;
327+
struct qstr destname;
328+
struct dentry *workdir;
329+
bool tmpfile;
330+
bool origin;
331+
};
332+
333+
static int ovl_link_up(struct ovl_copy_up_ctx *c)
320334
{
321335
int err;
322336
struct dentry *upper;
323-
struct dentry *upperdir = ovl_dentry_upper(parent);
337+
struct dentry *upperdir = ovl_dentry_upper(c->parent);
324338
struct inode *udir = d_inode(upperdir);
325339

326-
err = ovl_set_nlink_lower(dentry);
340+
/* Mark parent "impure" because it may now contain non-pure upper */
341+
err = ovl_set_impure(c->parent, upperdir);
342+
if (err)
343+
return err;
344+
345+
err = ovl_set_nlink_lower(c->dentry);
327346
if (err)
328347
return err;
329348

330349
inode_lock_nested(udir, I_MUTEX_PARENT);
331-
upper = lookup_one_len(dentry->d_name.name, upperdir,
332-
dentry->d_name.len);
350+
upper = lookup_one_len(c->dentry->d_name.name, upperdir,
351+
c->dentry->d_name.len);
333352
err = PTR_ERR(upper);
334353
if (!IS_ERR(upper)) {
335-
err = ovl_do_link(ovl_dentry_upper(dentry), udir, upper, true);
354+
err = ovl_do_link(ovl_dentry_upper(c->dentry), udir, upper,
355+
true);
336356
dput(upper);
337357

338-
if (!err)
339-
ovl_dentry_set_upper_alias(dentry);
358+
if (!err) {
359+
/* Restore timestamps on parent (best effort) */
360+
ovl_set_timestamps(upperdir, &c->pstat);
361+
ovl_dentry_set_upper_alias(c->dentry);
362+
}
340363
}
341364
inode_unlock(udir);
342-
ovl_set_nlink_upper(dentry);
365+
ovl_set_nlink_upper(c->dentry);
343366

344367
return err;
345368
}
346369

347-
struct ovl_copy_up_ctx {
348-
struct dentry *parent;
349-
struct dentry *dentry;
350-
struct path lowerpath;
351-
struct kstat stat;
352-
struct kstat pstat;
353-
const char *link;
354-
struct dentry *destdir;
355-
struct qstr destname;
356-
struct dentry *workdir;
357-
bool tmpfile;
358-
bool origin;
359-
};
360-
361370
static int ovl_install_temp(struct ovl_copy_up_ctx *c, struct dentry *temp,
362371
struct dentry **newdentry)
363372
{
@@ -629,7 +638,7 @@ static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
629638
if (!ovl_dentry_upper(dentry))
630639
err = ovl_do_copy_up(&ctx);
631640
if (!err && !ovl_dentry_has_upper_alias(dentry))
632-
err = ovl_link_up(parent, dentry);
641+
err = ovl_link_up(&ctx);
633642
ovl_copy_up_end(dentry);
634643
}
635644
do_delayed_call(&done);

0 commit comments

Comments
 (0)