ovl: use ovl_lookup_upper() wrapper
Introduce ovl_lookup_upper() as a simple wrapper around lookup_one(). Make it clear in the helper's name that this only operates on the upper layer. The wrapper will take upper layer's idmapping into account when checking permission in lookup_one(). 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>
This commit is contained in:
parent
a15506eac9
commit
22f289ce1f
@ -486,7 +486,7 @@ static int ovl_create_index(struct dentry *dentry, struct dentry *origin,
|
|||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
index = lookup_one_len(name.name, indexdir, name.len);
|
index = ovl_lookup_upper(ofs, name.name, indexdir, name.len);
|
||||||
if (IS_ERR(index)) {
|
if (IS_ERR(index)) {
|
||||||
err = PTR_ERR(index);
|
err = PTR_ERR(index);
|
||||||
} else {
|
} else {
|
||||||
@ -535,8 +535,8 @@ static int ovl_link_up(struct ovl_copy_up_ctx *c)
|
|||||||
return err;
|
return err;
|
||||||
|
|
||||||
inode_lock_nested(udir, I_MUTEX_PARENT);
|
inode_lock_nested(udir, I_MUTEX_PARENT);
|
||||||
upper = lookup_one_len(c->dentry->d_name.name, upperdir,
|
upper = ovl_lookup_upper(ofs, c->dentry->d_name.name, upperdir,
|
||||||
c->dentry->d_name.len);
|
c->dentry->d_name.len);
|
||||||
err = PTR_ERR(upper);
|
err = PTR_ERR(upper);
|
||||||
if (!IS_ERR(upper)) {
|
if (!IS_ERR(upper)) {
|
||||||
err = ovl_do_link(ofs, ovl_dentry_upper(c->dentry), udir, upper);
|
err = ovl_do_link(ofs, ovl_dentry_upper(c->dentry), udir, upper);
|
||||||
@ -699,7 +699,8 @@ static int ovl_copy_up_workdir(struct ovl_copy_up_ctx *c)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
upper = lookup_one_len(c->destname.name, c->destdir, c->destname.len);
|
upper = ovl_lookup_upper(ofs, c->destname.name, c->destdir,
|
||||||
|
c->destname.len);
|
||||||
err = PTR_ERR(upper);
|
err = PTR_ERR(upper);
|
||||||
if (IS_ERR(upper))
|
if (IS_ERR(upper))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -751,7 +752,8 @@ static int ovl_copy_up_tmpfile(struct ovl_copy_up_ctx *c)
|
|||||||
|
|
||||||
inode_lock_nested(udir, I_MUTEX_PARENT);
|
inode_lock_nested(udir, I_MUTEX_PARENT);
|
||||||
|
|
||||||
upper = lookup_one_len(c->destname.name, c->destdir, c->destname.len);
|
upper = ovl_lookup_upper(ofs, c->destname.name, c->destdir,
|
||||||
|
c->destname.len);
|
||||||
err = PTR_ERR(upper);
|
err = PTR_ERR(upper);
|
||||||
if (!IS_ERR(upper)) {
|
if (!IS_ERR(upper)) {
|
||||||
err = ovl_do_link(ofs, temp, udir, upper);
|
err = ovl_do_link(ofs, temp, udir, upper);
|
||||||
|
@ -51,7 +51,7 @@ struct dentry *ovl_lookup_temp(struct ovl_fs *ofs, struct dentry *workdir)
|
|||||||
/* counter is allowed to wrap, since temp dentries are ephemeral */
|
/* counter is allowed to wrap, since temp dentries are ephemeral */
|
||||||
snprintf(name, sizeof(name), "#%x", atomic_inc_return(&temp_id));
|
snprintf(name, sizeof(name), "#%x", atomic_inc_return(&temp_id));
|
||||||
|
|
||||||
temp = lookup_one_len(name, workdir, strlen(name));
|
temp = ovl_lookup_upper(ofs, name, workdir, strlen(name));
|
||||||
if (!IS_ERR(temp) && temp->d_inode) {
|
if (!IS_ERR(temp) && temp->d_inode) {
|
||||||
pr_err("workdir/%s already exists\n", name);
|
pr_err("workdir/%s already exists\n", name);
|
||||||
dput(temp);
|
dput(temp);
|
||||||
@ -155,8 +155,8 @@ int ovl_mkdir_real(struct ovl_fs *ofs, struct inode *dir,
|
|||||||
* to it unhashed and negative. If that happens, try to
|
* to it unhashed and negative. If that happens, try to
|
||||||
* lookup a new hashed and positive dentry.
|
* lookup a new hashed and positive dentry.
|
||||||
*/
|
*/
|
||||||
d = lookup_one_len(dentry->d_name.name, dentry->d_parent,
|
d = ovl_lookup_upper(ofs, dentry->d_name.name, dentry->d_parent,
|
||||||
dentry->d_name.len);
|
dentry->d_name.len);
|
||||||
if (IS_ERR(d)) {
|
if (IS_ERR(d)) {
|
||||||
pr_warn("failed lookup after mkdir (%pd2, err=%i).\n",
|
pr_warn("failed lookup after mkdir (%pd2, err=%i).\n",
|
||||||
dentry, err);
|
dentry, err);
|
||||||
@ -333,9 +333,8 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode,
|
|||||||
|
|
||||||
inode_lock_nested(udir, I_MUTEX_PARENT);
|
inode_lock_nested(udir, I_MUTEX_PARENT);
|
||||||
newdentry = ovl_create_real(ofs, udir,
|
newdentry = ovl_create_real(ofs, udir,
|
||||||
lookup_one_len(dentry->d_name.name,
|
ovl_lookup_upper(ofs, dentry->d_name.name,
|
||||||
upperdir,
|
upperdir, dentry->d_name.len),
|
||||||
dentry->d_name.len),
|
|
||||||
attr);
|
attr);
|
||||||
err = PTR_ERR(newdentry);
|
err = PTR_ERR(newdentry);
|
||||||
if (IS_ERR(newdentry))
|
if (IS_ERR(newdentry))
|
||||||
@ -488,8 +487,8 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode,
|
|||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
upper = lookup_one_len(dentry->d_name.name, upperdir,
|
upper = ovl_lookup_upper(ofs, dentry->d_name.name, upperdir,
|
||||||
dentry->d_name.len);
|
dentry->d_name.len);
|
||||||
err = PTR_ERR(upper);
|
err = PTR_ERR(upper);
|
||||||
if (IS_ERR(upper))
|
if (IS_ERR(upper))
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
@ -771,8 +770,8 @@ static int ovl_remove_and_whiteout(struct dentry *dentry,
|
|||||||
if (err)
|
if (err)
|
||||||
goto out_dput;
|
goto out_dput;
|
||||||
|
|
||||||
upper = lookup_one_len(dentry->d_name.name, upperdir,
|
upper = ovl_lookup_upper(ofs, dentry->d_name.name, upperdir,
|
||||||
dentry->d_name.len);
|
dentry->d_name.len);
|
||||||
err = PTR_ERR(upper);
|
err = PTR_ERR(upper);
|
||||||
if (IS_ERR(upper))
|
if (IS_ERR(upper))
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
@ -819,8 +818,8 @@ static int ovl_remove_upper(struct dentry *dentry, bool is_dir,
|
|||||||
}
|
}
|
||||||
|
|
||||||
inode_lock_nested(dir, I_MUTEX_PARENT);
|
inode_lock_nested(dir, I_MUTEX_PARENT);
|
||||||
upper = lookup_one_len(dentry->d_name.name, upperdir,
|
upper = ovl_lookup_upper(ofs, dentry->d_name.name, upperdir,
|
||||||
dentry->d_name.len);
|
dentry->d_name.len);
|
||||||
err = PTR_ERR(upper);
|
err = PTR_ERR(upper);
|
||||||
if (IS_ERR(upper))
|
if (IS_ERR(upper))
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
@ -1195,8 +1194,8 @@ static int ovl_rename(struct user_namespace *mnt_userns, struct inode *olddir,
|
|||||||
|
|
||||||
trap = lock_rename(new_upperdir, old_upperdir);
|
trap = lock_rename(new_upperdir, old_upperdir);
|
||||||
|
|
||||||
olddentry = lookup_one_len(old->d_name.name, old_upperdir,
|
olddentry = ovl_lookup_upper(ofs, old->d_name.name, old_upperdir,
|
||||||
old->d_name.len);
|
old->d_name.len);
|
||||||
err = PTR_ERR(olddentry);
|
err = PTR_ERR(olddentry);
|
||||||
if (IS_ERR(olddentry))
|
if (IS_ERR(olddentry))
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
@ -1205,8 +1204,8 @@ static int ovl_rename(struct user_namespace *mnt_userns, struct inode *olddir,
|
|||||||
if (!ovl_matches_upper(old, olddentry))
|
if (!ovl_matches_upper(old, olddentry))
|
||||||
goto out_dput_old;
|
goto out_dput_old;
|
||||||
|
|
||||||
newdentry = lookup_one_len(new->d_name.name, new_upperdir,
|
newdentry = ovl_lookup_upper(ofs, new->d_name.name, new_upperdir,
|
||||||
new->d_name.len);
|
new->d_name.len);
|
||||||
err = PTR_ERR(newdentry);
|
err = PTR_ERR(newdentry);
|
||||||
if (IS_ERR(newdentry))
|
if (IS_ERR(newdentry))
|
||||||
goto out_dput_old;
|
goto out_dput_old;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/uuid.h>
|
#include <linux/uuid.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
#include <linux/namei.h>
|
||||||
#include "ovl_entry.h"
|
#include "ovl_entry.h"
|
||||||
|
|
||||||
#undef pr_fmt
|
#undef pr_fmt
|
||||||
@ -310,6 +311,13 @@ static inline struct dentry *ovl_do_tmpfile(struct ovl_fs *ofs,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline struct dentry *ovl_lookup_upper(struct ovl_fs *ofs,
|
||||||
|
const char *name,
|
||||||
|
struct dentry *base, int len)
|
||||||
|
{
|
||||||
|
return lookup_one(ovl_upper_mnt_userns(ofs), name, base, len);
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool ovl_open_flags_need_copy_up(int flags)
|
static inline bool ovl_open_flags_need_copy_up(int flags)
|
||||||
{
|
{
|
||||||
if (!flags)
|
if (!flags)
|
||||||
|
@ -1013,7 +1013,7 @@ void ovl_cleanup_whiteouts(struct ovl_fs *ofs, struct dentry *upper,
|
|||||||
if (WARN_ON(!p->is_whiteout || !p->is_upper))
|
if (WARN_ON(!p->is_whiteout || !p->is_upper))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
dentry = lookup_one_len(p->name, upper, p->len);
|
dentry = ovl_lookup_upper(ofs, p->name, upper, p->len);
|
||||||
if (IS_ERR(dentry)) {
|
if (IS_ERR(dentry)) {
|
||||||
pr_err("lookup '%s/%.*s' failed (%i)\n",
|
pr_err("lookup '%s/%.*s' failed (%i)\n",
|
||||||
upper->d_name.name, p->len, p->name,
|
upper->d_name.name, p->len, p->name,
|
||||||
@ -1113,7 +1113,7 @@ static int ovl_workdir_cleanup_recurse(struct ovl_fs *ofs, struct path *path,
|
|||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dentry = lookup_one_len(p->name, path->dentry, p->len);
|
dentry = ovl_lookup_upper(ofs, p->name, path->dentry, p->len);
|
||||||
if (IS_ERR(dentry))
|
if (IS_ERR(dentry))
|
||||||
continue;
|
continue;
|
||||||
if (dentry->d_inode)
|
if (dentry->d_inode)
|
||||||
@ -1181,7 +1181,7 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs)
|
|||||||
if (p->len == 2 && p->name[1] == '.')
|
if (p->len == 2 && p->name[1] == '.')
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
index = lookup_one_len(p->name, indexdir, p->len);
|
index = ovl_lookup_upper(ofs, p->name, indexdir, p->len);
|
||||||
if (IS_ERR(index)) {
|
if (IS_ERR(index)) {
|
||||||
err = PTR_ERR(index);
|
err = PTR_ERR(index);
|
||||||
index = NULL;
|
index = NULL;
|
||||||
|
@ -761,7 +761,7 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs,
|
|||||||
|
|
||||||
inode_lock_nested(dir, I_MUTEX_PARENT);
|
inode_lock_nested(dir, I_MUTEX_PARENT);
|
||||||
retry:
|
retry:
|
||||||
work = lookup_one_len(name, ofs->workbasedir, strlen(name));
|
work = ovl_lookup_upper(ofs, name, ofs->workbasedir, strlen(name));
|
||||||
|
|
||||||
if (!IS_ERR(work)) {
|
if (!IS_ERR(work)) {
|
||||||
struct iattr attr = {
|
struct iattr attr = {
|
||||||
@ -1289,7 +1289,7 @@ static int ovl_check_rename_whiteout(struct ovl_fs *ofs)
|
|||||||
goto cleanup_temp;
|
goto cleanup_temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
whiteout = lookup_one_len(name.name.name, workdir, name.name.len);
|
whiteout = ovl_lookup_upper(ofs, name.name.name, workdir, name.name.len);
|
||||||
err = PTR_ERR(whiteout);
|
err = PTR_ERR(whiteout);
|
||||||
if (IS_ERR(whiteout))
|
if (IS_ERR(whiteout))
|
||||||
goto cleanup_temp;
|
goto cleanup_temp;
|
||||||
@ -1321,7 +1321,7 @@ static struct dentry *ovl_lookup_or_create(struct ovl_fs *ofs,
|
|||||||
struct dentry *child;
|
struct dentry *child;
|
||||||
|
|
||||||
inode_lock_nested(parent->d_inode, I_MUTEX_PARENT);
|
inode_lock_nested(parent->d_inode, I_MUTEX_PARENT);
|
||||||
child = lookup_one_len(name, parent, len);
|
child = ovl_lookup_upper(ofs, name, parent, len);
|
||||||
if (!IS_ERR(child) && !child->d_inode)
|
if (!IS_ERR(child) && !child->d_inode)
|
||||||
child = ovl_create_real(ofs, parent->d_inode, child,
|
child = ovl_create_real(ofs, parent->d_inode, child,
|
||||||
OVL_CATTR(mode));
|
OVL_CATTR(mode));
|
||||||
|
@ -838,7 +838,7 @@ static void ovl_cleanup_index(struct dentry *dentry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inode_lock_nested(dir, I_MUTEX_PARENT);
|
inode_lock_nested(dir, I_MUTEX_PARENT);
|
||||||
index = lookup_one_len(name.name, indexdir, name.len);
|
index = ovl_lookup_upper(ofs, name.name, indexdir, name.len);
|
||||||
err = PTR_ERR(index);
|
err = PTR_ERR(index);
|
||||||
if (IS_ERR(index)) {
|
if (IS_ERR(index)) {
|
||||||
index = NULL;
|
index = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user