diff options
author | Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com> | 2011-09-18 10:20:46 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2011-09-18 10:20:46 -0400 |
commit | 3765fefaee2da83f10829fa64a74e6b7360350cb (patch) | |
tree | ed697e436832afdd33f57e9e07afdac29e1fbaaf /fs/btrfs | |
parent | d525e8ab022cb000e6e31a515ba8c3cf0d9c6130 (diff) |
btrfs: fix d_off in the first dirent
Since the d_off in the first dirent for "." (that originates from
the 4th argument "offset" of filldir() for the 2nd dirent for "..")
is wrongly assigned in btrfs_real_readdir(), telldir returns same
offset for different locations.
| # mkfs.btrfs /dev/sdb1
| # mount /dev/sdb1 fs0
| # cd fs0
| # touch file0 file1
| # ../test
| telldir: 0
| readdir: d_off = 2, d_name = "."
| telldir: 2
| readdir: d_off = 2, d_name = ".."
| telldir: 2
| readdir: d_off = 3, d_name = "file0"
| telldir: 3
| readdir: d_off = 2147483647, d_name = "file1"
| telldir: 2147483647
To fix this problem, pass filp->f_pos (which is loff_t) instead.
| # ../test
| telldir: 0
| readdir: d_off = 1, d_name = "."
| telldir: 1
| readdir: d_off = 2, d_name = ".."
| telldir: 2
| readdir: d_off = 3, d_name = "file0"
:
At the moment the "offset" for "." is unused because there is no
preceding dirent, however it is better to pass filp->f_pos to follow
grammatical usage.
Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/inode.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index b94c0da3b43f..ba951764b005 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -4117,7 +4117,8 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, | |||
4117 | 4117 | ||
4118 | /* special case for "." */ | 4118 | /* special case for "." */ |
4119 | if (filp->f_pos == 0) { | 4119 | if (filp->f_pos == 0) { |
4120 | over = filldir(dirent, ".", 1, 1, btrfs_ino(inode), DT_DIR); | 4120 | over = filldir(dirent, ".", 1, |
4121 | filp->f_pos, btrfs_ino(inode), DT_DIR); | ||
4121 | if (over) | 4122 | if (over) |
4122 | return 0; | 4123 | return 0; |
4123 | filp->f_pos = 1; | 4124 | filp->f_pos = 1; |
@@ -4126,7 +4127,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, | |||
4126 | if (filp->f_pos == 1) { | 4127 | if (filp->f_pos == 1) { |
4127 | u64 pino = parent_ino(filp->f_path.dentry); | 4128 | u64 pino = parent_ino(filp->f_path.dentry); |
4128 | over = filldir(dirent, "..", 2, | 4129 | over = filldir(dirent, "..", 2, |
4129 | 2, pino, DT_DIR); | 4130 | filp->f_pos, pino, DT_DIR); |
4130 | if (over) | 4131 | if (over) |
4131 | return 0; | 4132 | return 0; |
4132 | filp->f_pos = 2; | 4133 | filp->f_pos = 2; |