erofs: allow readdir() to be interrupted
authorChao Yu <chao@kernel.org>
Thu, 10 Jul 2025 07:36:18 +0000 (15:36 +0800)
committerGao Xiang <hsiangkao@linux.alibaba.com>
Thu, 10 Jul 2025 09:08:27 +0000 (17:08 +0800)
In a quick slow device, readdir() may loop for long time in large
directory, let's give a chance to allow it to be interrupted by
userspace.

Signed-off-by: Chao Yu <chao@kernel.org>
Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Link: https://lore.kernel.org/r/20250710073619.4083422-1-chao@kernel.org
[ Gao Xiang: move cond_resched() to the end of the while loop. ]
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
fs/erofs/dir.c

index 2fae209d0274031d69ab15538fd7308c9ec6047b..3e4b38bec0aa49cf70cd952646a5ea8938dd4323 100644 (file)
@@ -58,6 +58,11 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx)
                struct erofs_dirent *de;
                unsigned int nameoff, maxsize;
 
+               if (fatal_signal_pending(current)) {
+                       err = -ERESTARTSYS;
+                       break;
+               }
+
                de = erofs_bread(&buf, dbstart, true);
                if (IS_ERR(de)) {
                        erofs_err(sb, "failed to readdir of logical block %llu of nid %llu",
@@ -88,6 +93,7 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx)
                        break;
                ctx->pos = dbstart + maxsize;
                ofs = 0;
+               cond_resched();
        }
        erofs_put_metabuf(&buf);
        if (EROFS_I(dir)->dot_omitted && ctx->pos == dir->i_size) {