From 576bb263450bbba6601a9f528d0cf601d97a13e6 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Mon, 4 Apr 2022 12:51:43 +0200 Subject: ovl: pass ofs to creation operations Pass down struct ovl_fs to all creation helpers 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: Tested-by: Giuseppe Scrivano Reviewed-by: Amir Goldstein Signed-off-by: Christian Brauner (Microsoft) Signed-off-by: Miklos Szeredi --- fs/overlayfs/super.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'fs/overlayfs/super.c') diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 7dd5dcdeeb65..307a36af7b4f 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -778,7 +778,7 @@ retry: goto out_unlock; retried = true; - err = ovl_workdir_cleanup(dir, mnt, work, 0); + err = ovl_workdir_cleanup(ofs, dir, mnt, work, 0); dput(work); if (err == -EINVAL) { work = ERR_PTR(err); @@ -787,7 +787,7 @@ retry: goto retry; } - err = ovl_mkdir_real(dir, &work, attr.ia_mode); + err = ovl_mkdir_real(ofs, dir, &work, attr.ia_mode); if (err) goto out_dput; @@ -1256,8 +1256,9 @@ out: * Returns 1 if RENAME_WHITEOUT is supported, 0 if not supported and * negative values if error is encountered. */ -static int ovl_check_rename_whiteout(struct dentry *workdir) +static int ovl_check_rename_whiteout(struct ovl_fs *ofs) { + struct dentry *workdir = ofs->workdir; struct inode *dir = d_inode(workdir); struct dentry *temp; struct dentry *dest; @@ -1267,12 +1268,12 @@ static int ovl_check_rename_whiteout(struct dentry *workdir) inode_lock_nested(dir, I_MUTEX_PARENT); - temp = ovl_create_temp(workdir, OVL_CATTR(S_IFREG | 0)); + temp = ovl_create_temp(ofs, workdir, OVL_CATTR(S_IFREG | 0)); err = PTR_ERR(temp); if (IS_ERR(temp)) goto out_unlock; - dest = ovl_lookup_temp(workdir); + dest = ovl_lookup_temp(ofs, workdir); err = PTR_ERR(dest); if (IS_ERR(dest)) { dput(temp); @@ -1281,7 +1282,7 @@ static int ovl_check_rename_whiteout(struct dentry *workdir) /* Name is inline and stable - using snapshot as a copy helper */ take_dentry_name_snapshot(&name, temp); - err = ovl_do_rename(dir, temp, dir, dest, RENAME_WHITEOUT); + err = ovl_do_rename(ofs, dir, temp, dir, dest, RENAME_WHITEOUT); if (err) { if (err == -EINVAL) err = 0; @@ -1297,11 +1298,11 @@ static int ovl_check_rename_whiteout(struct dentry *workdir) /* Best effort cleanup of whiteout and temp file */ if (err) - ovl_cleanup(dir, whiteout); + ovl_cleanup(ofs, dir, whiteout); dput(whiteout); cleanup_temp: - ovl_cleanup(dir, temp); + ovl_cleanup(ofs, dir, temp); release_dentry_name_snapshot(&name); dput(temp); dput(dest); @@ -1312,7 +1313,8 @@ out_unlock: return err; } -static struct dentry *ovl_lookup_or_create(struct dentry *parent, +static struct dentry *ovl_lookup_or_create(struct ovl_fs *ofs, + struct dentry *parent, const char *name, umode_t mode) { size_t len = strlen(name); @@ -1321,7 +1323,7 @@ static struct dentry *ovl_lookup_or_create(struct dentry *parent, inode_lock_nested(parent->d_inode, I_MUTEX_PARENT); child = lookup_one_len(name, parent, len); if (!IS_ERR(child) && !child->d_inode) - child = ovl_create_real(parent->d_inode, child, + child = ovl_create_real(ofs, parent->d_inode, child, OVL_CATTR(mode)); inode_unlock(parent->d_inode); dput(parent); @@ -1343,7 +1345,7 @@ static int ovl_create_volatile_dirty(struct ovl_fs *ofs) const char *const *name = volatile_path; for (ctr = ARRAY_SIZE(volatile_path); ctr; ctr--, name++) { - d = ovl_lookup_or_create(d, *name, ctr > 1 ? S_IFDIR : S_IFREG); + d = ovl_lookup_or_create(ofs, d, *name, ctr > 1 ? S_IFDIR : S_IFREG); if (IS_ERR(d)) return PTR_ERR(d); } @@ -1391,7 +1393,7 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs, pr_warn("upper fs needs to support d_type.\n"); /* Check if upper/work fs supports O_TMPFILE */ - temp = ovl_do_tmpfile(ofs->workdir, S_IFREG | 0); + temp = ovl_do_tmpfile(ofs, ofs->workdir, S_IFREG | 0); ofs->tmpfile = !IS_ERR(temp); if (ofs->tmpfile) dput(temp); @@ -1400,7 +1402,7 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs, /* Check if upper/work fs supports RENAME_WHITEOUT */ - err = ovl_check_rename_whiteout(ofs->workdir); + err = ovl_check_rename_whiteout(ofs); if (err < 0) goto out; -- cgit v1.2.3