Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <gthelen@google.com>
Cc: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

-10
-5
fs/ext4/dir.c
··· 150 150 while (ctx->pos < inode->i_size) { 151 151 struct ext4_map_blocks map; 152 152 153 - if (fatal_signal_pending(current)) { 154 - err = -ERESTARTSYS; 155 - goto errout; 156 - } 157 - cond_resched(); 158 153 map.m_lblk = ctx->pos >> EXT4_BLOCK_SIZE_BITS(sb); 159 154 map.m_len = 1; 160 155 err = ext4_map_blocks(NULL, inode, &map, 0);
-5
fs/ext4/namei.c
··· 1107 1107 } 1108 1108 1109 1109 while (1) { 1110 - if (signal_pending(current)) { 1111 - err = -ERESTARTSYS; 1112 - goto errout; 1113 - } 1114 - cond_resched(); 1115 1110 block = dx_get_block(frame->at); 1116 1111 ret = htree_dirblock_to_tree(dir_file, dir, block, &hinfo, 1117 1112 start_hash, start_minor_hash);