filp->f_pos not correctly updated in proc_task_readdir
commit53a8705c08cf4a9ffe954c36ca2ca7b5ea8887d7
authorZhang Le <r0bertz@gentoo.org>
Mon, 16 Mar 2009 06:35:21 +0000 (16 14:35 +0800)
committerZhang Le <r0bertz@gentoo.org>
Mon, 16 Mar 2009 06:39:58 +0000 (16 14:39 +0800)
treee2050a1a4b53cbb7ecec02143ab72fe68e98fe32
parentf37116fec4c7a340d81646eae45ab9cb98e1711f
filp->f_pos not correctly updated in proc_task_readdir

filp->f_pos only get updated at the end of the function. Thus d_off of those
dirents who are in the middle will be 0, and this will cause a problem in
glibc's readdir implementation, specifically endless loop. Because when overflow
occurs, f_pos will be set to next dirent to read, however it will be 0, unless
the next one is the last one. So it will start over again and again.

There is a sample program in man 2 gendents. This is the output of the program
running on a multithread program's task dir before this patch is applied:

$ ./a.out /proc/3807/task
--------------- nread=128 ---------------
i-node#  file type  d_reclen  d_off   d_name
  506442  directory    16          1  .
  506441  directory    16          0  ..
  506443  directory    16          0  3807
  506444  directory    16          0  3809
  506445  directory    16          0  3812
  506446  directory    16          0  3861
  506447  directory    16          0  3862
  506448  directory    16          8  3863

This is the output after this patch is applied

$ ./a.out /proc/3807/task
--------------- nread=128 ---------------
i-node#  file type  d_reclen  d_off   d_name
  506442  directory    16          1  .
  506441  directory    16          2  ..
  506443  directory    16          3  3807
  506444  directory    16          4  3809
  506445  directory    16          5  3812
  506446  directory    16          6  3861
  506447  directory    16          7  3862
  506448  directory    16          8  3863

Signed-off-by: Zhang Le <r0bertz@gentoo.org>
fs/proc/base.c