fsioctl.c: make generic_block_fiemap() signal-tolerant
authorDmitry Monakhov <dmonakhov@openvz.org>
Tue, 10 Feb 2015 22:09:29 +0000 (14:09 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 10 Feb 2015 22:30:30 +0000 (14:30 -0800)
__generic_block_fiemap may spin very long time for large sparse files.

Without this patch an unprivileged user may abuse system resources simply
by spawning a vast number of unkilable busyloops (works on ext2/ext3):

  truncate --size 1T test
  for ((i=0;i<1024;i++))
  do
         filefrag test > /dev/null &
  done

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Cc: Theodore Ts'o <tytso@mit.edu>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Michael Kerrisk <mtk.manpages@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Documentation/filesystems/fiemap.txt
fs/ioctl.c

index 1b805a0..f6d9c99 100644 (file)
@@ -196,7 +196,8 @@ struct fiemap_extent_info {
 };
 
 It is intended that the file system should not need to access any of this
-structure directly.
+structure directly. Filesystem handlers should be tolerant to signals and return
+EINTR once fatal signal received.
 
 
 Flag checking should be done at the beginning of the ->fiemap callback via the
index 214c3c1..5d01d26 100644 (file)
@@ -379,6 +379,11 @@ int __generic_block_fiemap(struct inode *inode,
                                past_eof = true;
                }
                cond_resched();
+               if (fatal_signal_pending(current)) {
+                       ret = -EINTR;
+                       break;
+               }
+
        } while (1);
 
        /* If ret is 1 then we just hit the end of the extent array */