From: Linus Torvalds Date: Sun, 10 Apr 2016 23:52:24 +0000 (-0700) Subject: Revert "ext4: allow readdir()'s of large empty directories to be interrupted" X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=9f2394c9be47a754bae9e4b6d382bdd4d77d0a11;p=GitHub%2FLineageOS%2FG12%2Fandroid_kernel_amlogic_linux-4.9.git Revert "ext4: allow readdir()'s of large empty directories to be interrupted" This reverts commit 1028b55bafb7611dda1d8fed2aeca16a436b7dff. It's broken: it makes ext4 return an error at an invalid point, causing the readdir wrappers to write the the position of the last successful directory entry into the position field, which means that the next readdir will now return that last successful entry _again_. You can only return fatal errors (that terminate the readdir directory walk) from within the filesystem readdir functions, the "normal" errors (that happen when the readdir buffer fills up, for example) happen in the iterorator where we know the position of the actual failing entry. I do have a very different patch that does the "signal_pending()" handling inside the iterator function where it is allowable, but while that one passes all the sanity checks, I screwed up something like four times while emailing it out, so I'm not going to commit it today. So my track record is not good enough, and the stars will have to align better before that one gets committed. And it would be good to get some review too, of course, since celestial alignments are always an iffy debugging model. IOW, let's just revert the commit that caused the problem for now. Reported-by: Greg Thelen Cc: Theodore Ts'o Signed-off-by: Linus Torvalds --- diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index 4173bfe21114..561d7308b393 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c @@ -150,11 +150,6 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx) while (ctx->pos < inode->i_size) { struct ext4_map_blocks map; - if (fatal_signal_pending(current)) { - err = -ERESTARTSYS; - goto errout; - } - cond_resched(); map.m_lblk = ctx->pos >> EXT4_BLOCK_SIZE_BITS(sb); map.m_len = 1; err = ext4_map_blocks(NULL, inode, &map, 0); diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index db98f89f737f..48e4b8907826 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1107,11 +1107,6 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash, } while (1) { - if (signal_pending(current)) { - err = -ERESTARTSYS; - goto errout; - } - cond_resched(); block = dx_get_block(frame->at); ret = htree_dirblock_to_tree(dir_file, dir, block, &hinfo, start_hash, start_minor_hash);