Skip to contentSkip to conversation

btrfs: fix directory offsets for '.' and '..' entries

PATCH In review Grazvydas Ignotas 4 participants 5 messages Sep 11, 2011 – Sep 18, 2011 Btrfs file system

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 btrfs: fix directory offsets for '.' and '..' entries

Currently getdents syscall returns wrong offset for '.' directory entry, which confuses some programs like wine. This can be observed with an example program getdents(2) manpage:

$ ./a.out /testfs/
--------------- nread=96 ---------------
i-node#  file type  d_reclen  d_off   d_name
     256  directory    24          2  .
     256  directory    24          2  ..
     257  regular      24          3  a
     258  regular      24 2147483647  b

Fix this by passing correct offsets to filldir().

---
 fs/btrfs/inode.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)
fs/btrfs/inode.c +2 -3
index 0ccc743..5e7460b 100644
@@ -4125,7 +4125,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
 
 	/* special case for "." */
 	if (filp->f_pos == 0) {
-		over = filldir(dirent, ".", 1, 1, btrfs_ino(inode), DT_DIR);
+		over = filldir(dirent, ".", 1, 0, btrfs_ino(inode), DT_DIR);
 		if (over)
 			return 0;
 		filp->f_pos = 1;
@@ -4133,8 +4133,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
 	/* special case for .., just use the back ref */
 	if (filp->f_pos == 1) {
 		u64 pino = parent_ino(filp->f_path.dentry);
-		over = filldir(dirent, "..", 2,
-			       2, pino, DT_DIR);
+		over = filldir(dirent, "..", 2, 1, pino, DT_DIR);
 		if (over)
 			return 0;
 		filp->f_pos = 2;
Signature · 1 line
1.7.0.4
#1 lore raw
Quoted 3 lines · Grazvydas Ignotas

Currently getdents syscall returns wrong offset for '.' directory entry, which confuses some programs like wine. This can be observed with an example program getdents(2) manpage:

Can you submit a patch to add your testcase to xfstests?

#2 lore raw
Quoted 2 lines · On Mon, Sep 12, 2011 at 12:06 AM, Christoph Hellwig <[email protected]>= wrote:
Quoted 1 line · Grazvydas Ignotas

Currently getdents syscall returns wrong offset for '.' directory en=

try,

Quoted 4 lines
Quoted 2 lines

which confuses some programs like wine. This can be observed with an example program getdents(2) manpage:

Can you submit a patch to add your testcase to xfstests?

Sent, hopefully did it right.

--=20
Gra=C5=BEvydas
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" = in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#3 lore raw
In reply to Grazvydas Ignotas

The same patch has been posted about one month ago.

http://marc.info/?l=linux-btrfs&m=131363399500506&w=2

Thanks,
Tsutomu

Quoted 42 lines · Grazvydas Ignotas

Currently getdents syscall returns wrong offset for '.' directory entry, which confuses some programs like wine. This can be observed with an example program getdents(2) manpage:

$ ./a.out /testfs/
--------------- nread=96 ---------------
i-node#  file type  d_reclen  d_off   d_name
     256  directory    24          2  .
     256  directory    24          2  ..
     257  regular      24          3  a
     258  regular      24 2147483647  b

Fix this by passing correct offsets to filldir().

---
 fs/btrfs/inode.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)
fs/btrfs/inode.c +2 -3
index 0ccc743..5e7460b 100644
@@ -4125,7 +4125,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
 
 	/* special case for "." */
 	if (filp->f_pos == 0) {
-		over = filldir(dirent, ".", 1, 1, btrfs_ino(inode), DT_DIR);
+		over = filldir(dirent, ".", 1, 0, btrfs_ino(inode), DT_DIR);
 		if (over)
 			return 0;
 		filp->f_pos = 1;
@@ -4133,8 +4133,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
 	/* special case for .., just use the back ref */
 	if (filp->f_pos == 1) {
 		u64 pino = parent_ino(filp->f_path.dentry);
-		over = filldir(dirent, "..", 2,
-			       2, pino, DT_DIR);
+		over = filldir(dirent, "..", 2, 1, pino, DT_DIR);
 		if (over)
 			return 0;
 		filp->f_pos = 2;