mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
ovl: refactor ovl_iterate() and port to cred guard
factor out ovl_iterate_merged() and move some code into ovl_iterate_real() for easier use of the scoped ovl cred guard. Signed-off-by: Amir Goldstein <amir73il@gmail.com> Link: https://patch.msgid.link/20251117-work-ovl-cred-guard-v4-25-b31603935724@kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
parent
198d182288
commit
d25e4b739f
|
|
@ -832,36 +832,12 @@ static int ovl_iterate_real(struct file *file, struct dir_context *ctx)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ovl_iterate_merged(struct file *file, struct dir_context *ctx)
|
||||||
static int ovl_iterate(struct file *file, struct dir_context *ctx)
|
|
||||||
{
|
{
|
||||||
struct ovl_dir_file *od = file->private_data;
|
struct ovl_dir_file *od = file->private_data;
|
||||||
struct dentry *dentry = file->f_path.dentry;
|
struct dentry *dentry = file->f_path.dentry;
|
||||||
struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
|
|
||||||
struct ovl_cache_entry *p;
|
struct ovl_cache_entry *p;
|
||||||
const struct cred *old_cred;
|
int err = 0;
|
||||||
int err;
|
|
||||||
|
|
||||||
old_cred = ovl_override_creds(dentry->d_sb);
|
|
||||||
if (!ctx->pos)
|
|
||||||
ovl_dir_reset(file);
|
|
||||||
|
|
||||||
if (od->is_real) {
|
|
||||||
/*
|
|
||||||
* If parent is merge, then need to adjust d_ino for '..', if
|
|
||||||
* dir is impure then need to adjust d_ino for copied up
|
|
||||||
* entries.
|
|
||||||
*/
|
|
||||||
if (ovl_xino_bits(ofs) ||
|
|
||||||
(ovl_same_fs(ofs) &&
|
|
||||||
(ovl_is_impure_dir(file) ||
|
|
||||||
OVL_TYPE_MERGE(ovl_path_type(dentry->d_parent))))) {
|
|
||||||
err = ovl_iterate_real(file, ctx);
|
|
||||||
} else {
|
|
||||||
err = iterate_dir(od->realfile, ctx);
|
|
||||||
}
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!od->cache) {
|
if (!od->cache) {
|
||||||
struct ovl_dir_cache *cache;
|
struct ovl_dir_cache *cache;
|
||||||
|
|
@ -869,7 +845,7 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx)
|
||||||
cache = ovl_cache_get(dentry);
|
cache = ovl_cache_get(dentry);
|
||||||
err = PTR_ERR(cache);
|
err = PTR_ERR(cache);
|
||||||
if (IS_ERR(cache))
|
if (IS_ERR(cache))
|
||||||
goto out;
|
return err;
|
||||||
|
|
||||||
od->cache = cache;
|
od->cache = cache;
|
||||||
ovl_seek_cursor(od, ctx->pos);
|
ovl_seek_cursor(od, ctx->pos);
|
||||||
|
|
@ -881,7 +857,7 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx)
|
||||||
if (!p->ino || p->check_xwhiteout) {
|
if (!p->ino || p->check_xwhiteout) {
|
||||||
err = ovl_cache_update(&file->f_path, p, !p->ino);
|
err = ovl_cache_update(&file->f_path, p, !p->ino);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* ovl_cache_update() sets is_whiteout on stale entry */
|
/* ovl_cache_update() sets is_whiteout on stale entry */
|
||||||
|
|
@ -892,12 +868,50 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx)
|
||||||
od->cursor = p->l_node.next;
|
od->cursor = p->l_node.next;
|
||||||
ctx->pos++;
|
ctx->pos++;
|
||||||
}
|
}
|
||||||
err = 0;
|
|
||||||
out:
|
|
||||||
ovl_revert_creds(old_cred);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ovl_need_adjust_d_ino(struct file *file)
|
||||||
|
{
|
||||||
|
struct dentry *dentry = file->f_path.dentry;
|
||||||
|
struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
|
||||||
|
|
||||||
|
/* If parent is merge, then need to adjust d_ino for '..' */
|
||||||
|
if (ovl_xino_bits(ofs))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* Can't do consistent inode numbering */
|
||||||
|
if (!ovl_same_fs(ofs))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* If dir is impure then need to adjust d_ino for copied up entries */
|
||||||
|
if (ovl_is_impure_dir(file) ||
|
||||||
|
OVL_TYPE_MERGE(ovl_path_type(dentry->d_parent)))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* Pure: no need to adjust d_ino */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int ovl_iterate(struct file *file, struct dir_context *ctx)
|
||||||
|
{
|
||||||
|
struct ovl_dir_file *od = file->private_data;
|
||||||
|
|
||||||
|
if (!ctx->pos)
|
||||||
|
ovl_dir_reset(file);
|
||||||
|
|
||||||
|
with_ovl_creds(file_dentry(file)->d_sb) {
|
||||||
|
if (!od->is_real)
|
||||||
|
return ovl_iterate_merged(file, ctx);
|
||||||
|
|
||||||
|
if (ovl_need_adjust_d_ino(file))
|
||||||
|
return ovl_iterate_real(file, ctx);
|
||||||
|
|
||||||
|
return iterate_dir(od->realfile, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static loff_t ovl_dir_llseek(struct file *file, loff_t offset, int origin)
|
static loff_t ovl_dir_llseek(struct file *file, loff_t offset, int origin)
|
||||||
{
|
{
|
||||||
loff_t res;
|
loff_t res;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user