Commit 3e3271549670 ("vfs: get rid of old '->iterate' directory operation") added a wrapper around ovl_iterate() to lock the inode exclusive. Use the overlayfs private inode lock instead to provide exclusive locking. Add ovl_inode_lock()/_unlock() to ovl_iterate() and replace inode_lock/_unlock() with the ovl_ variant in ovl_dir_llseek() and ovl_dir_release(). This replacement is valid, because the inode lock was taken only to provide exclusion between these functions (for other files referring to the same inode). Signed-off-by: Miklos Szeredi <mszeredi@xxxxxxxxxx> --- fs/overlayfs/readdir.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c index b894a97f8ef8..edee9f86f469 100644 --- a/fs/overlayfs/readdir.c +++ b/fs/overlayfs/readdir.c @@ -758,6 +758,7 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx) if (!ctx->pos) ovl_dir_reset(file); + ovl_inode_lock(file_inode(file)); if (od->is_real) { /* * If parent is merge, then need to adjust d_ino for '..', if @@ -806,6 +807,7 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx) } err = 0; out: + ovl_inode_unlock(file_inode(file)); revert_creds(old_cred); return err; } @@ -815,7 +817,7 @@ static loff_t ovl_dir_llseek(struct file *file, loff_t offset, int origin) loff_t res; struct ovl_dir_file *od = file->private_data; - inode_lock(file_inode(file)); + ovl_inode_lock(file_inode(file)); if (!file->f_pos) ovl_dir_reset(file); @@ -845,7 +847,7 @@ static loff_t ovl_dir_llseek(struct file *file, loff_t offset, int origin) res = offset; } out_unlock: - inode_unlock(file_inode(file)); + ovl_inode_unlock(file_inode(file)); return res; } @@ -929,9 +931,9 @@ static int ovl_dir_release(struct inode *inode, struct file *file) struct ovl_dir_file *od = file->private_data; if (od->cache) { - inode_lock(inode); + ovl_inode_lock(inode); ovl_cache_put(od, inode); - inode_unlock(inode); + ovl_inode_unlock(inode); } fput(od->realfile); if (od->upperfile) @@ -966,11 +968,10 @@ static int ovl_dir_open(struct inode *inode, struct file *file) return 0; } -WRAP_DIR_ITER(ovl_iterate) // FIXME! const struct file_operations ovl_dir_operations = { .read = generic_read_dir, .open = ovl_dir_open, - .iterate_shared = shared_ovl_iterate, + .iterate_shared = ovl_iterate, .llseek = ovl_dir_llseek, .fsync = ovl_dir_fsync, .release = ovl_dir_release, -- 2.44.0