Skip to content

Commit

Permalink
ovl: pass ofs to setattr operations
Browse files Browse the repository at this point in the history
Pass down struct ovl_fs to setattr operations so we can ultimately
retrieve the relevant upper mount and take the mount's idmapping into
account when creating new filesystem objects. This is needed to support
idmapped base layers with overlay.

Cc: <linux-unionfs@vger.kernel.org>
Tested-by: Giuseppe Scrivano <gscrivan@redhat.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
  • Loading branch information
Christian Brauner authored and Miklos Szeredi committed Apr 28, 2022
1 parent c67cf65 commit 5272eaf
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 10 deletions.
19 changes: 11 additions & 8 deletions fs/overlayfs/copy_up.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,8 @@ static int ovl_copy_up_data(struct ovl_fs *ofs, struct path *old,
return error;
}

static int ovl_set_size(struct dentry *upperdentry, struct kstat *stat)
static int ovl_set_size(struct ovl_fs *ofs,
struct dentry *upperdentry, struct kstat *stat)
{
struct iattr attr = {
.ia_valid = ATTR_SIZE,
Expand All @@ -302,7 +303,8 @@ static int ovl_set_size(struct dentry *upperdentry, struct kstat *stat)
return notify_change(&init_user_ns, upperdentry, &attr, NULL);
}

static int ovl_set_timestamps(struct dentry *upperdentry, struct kstat *stat)
static int ovl_set_timestamps(struct ovl_fs *ofs, struct dentry *upperdentry,
struct kstat *stat)
{
struct iattr attr = {
.ia_valid =
Expand All @@ -314,7 +316,8 @@ static int ovl_set_timestamps(struct dentry *upperdentry, struct kstat *stat)
return notify_change(&init_user_ns, upperdentry, &attr, NULL);
}

int ovl_set_attr(struct dentry *upperdentry, struct kstat *stat)
int ovl_set_attr(struct ovl_fs *ofs, struct dentry *upperdentry,
struct kstat *stat)
{
int err = 0;

Expand All @@ -334,7 +337,7 @@ int ovl_set_attr(struct dentry *upperdentry, struct kstat *stat)
err = notify_change(&init_user_ns, upperdentry, &attr, NULL);
}
if (!err)
ovl_set_timestamps(upperdentry, stat);
ovl_set_timestamps(ofs, upperdentry, stat);

return err;
}
Expand Down Expand Up @@ -541,7 +544,7 @@ static int ovl_link_up(struct ovl_copy_up_ctx *c)

if (!err) {
/* Restore timestamps on parent (best effort) */
ovl_set_timestamps(upperdir, &c->pstat);
ovl_set_timestamps(ofs, upperdir, &c->pstat);
ovl_dentry_set_upper_alias(c->dentry);
}
}
Expand Down Expand Up @@ -615,9 +618,9 @@ static int ovl_copy_up_inode(struct ovl_copy_up_ctx *c, struct dentry *temp)

inode_lock(temp->d_inode);
if (S_ISREG(c->stat.mode))
err = ovl_set_size(temp, &c->stat);
err = ovl_set_size(ofs, temp, &c->stat);
if (!err)
err = ovl_set_attr(temp, &c->stat);
err = ovl_set_attr(ofs, temp, &c->stat);
inode_unlock(temp->d_inode);

return err;
Expand Down Expand Up @@ -839,7 +842,7 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c)

/* Restore timestamps on parent (best effort) */
inode_lock(udir);
ovl_set_timestamps(c->destdir, &c->pstat);
ovl_set_timestamps(ofs, c->destdir, &c->pstat);
inode_unlock(udir);

ovl_dentry_set_upper_alias(c->dentry);
Expand Down
2 changes: 1 addition & 1 deletion fs/overlayfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry,
goto out_cleanup;

inode_lock(opaquedir->d_inode);
err = ovl_set_attr(opaquedir, &stat);
err = ovl_set_attr(ofs, opaquedir, &stat);
inode_unlock(opaquedir->d_inode);
if (err)
goto out_cleanup;
Expand Down
2 changes: 1 addition & 1 deletion fs/overlayfs/overlayfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ int ovl_copy_up_with_data(struct dentry *dentry);
int ovl_maybe_copy_up(struct dentry *dentry, int flags);
int ovl_copy_xattr(struct super_block *sb, struct dentry *old,
struct dentry *new);
int ovl_set_attr(struct dentry *upper, struct kstat *stat);
int ovl_set_attr(struct ovl_fs *ofs, struct dentry *upper, struct kstat *stat);
struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct dentry *real,
bool is_upper);
int ovl_set_origin(struct ovl_fs *ofs, struct dentry *lower,
Expand Down

0 comments on commit 5272eaf

Please sign in to comment.