public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
To: libc-alpha@sourceware.org, Florian Weimer <fweimer@redhat.com>
Cc: Dave Flogeras <dflogeras2@gmail.com>,
	James Clarke <jrtc27@debian.org>,
	John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Subject: [PATCH v3 1/7] linux: Do not skip entries with zero d_ino values [BZ #12165]
Date: Wed, 21 Oct 2020 11:15:36 -0300	[thread overview]
Message-ID: <20201021141542.2003377-2-adhemerval.zanella@linaro.org> (raw)
In-Reply-To: <20201021141542.2003377-1-adhemerval.zanella@linaro.org>

According to Linux commit 2adc376c55194 (vfs: avoid creation of inode
number 0 in get_next_ino) Linux did not treat d_ino == 0 as a special
case (it is a valid inode number).

This patch fixes readdir{64} by not ignoring entried with d_ino being
0.

Checked on x86_64-linux-gnu and i686-linux-gnu.
---
 sysdeps/unix/sysv/linux/readdir.c   | 59 +++++++++++------------------
 sysdeps/unix/sysv/linux/readdir64.c | 59 +++++++++++------------------
 2 files changed, 44 insertions(+), 74 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/readdir.c b/sysdeps/unix/sysv/linux/readdir.c
index ca2a8964e9..1a9820e475 100644
--- a/sysdeps/unix/sysv/linux/readdir.c
+++ b/sysdeps/unix/sysv/linux/readdir.c
@@ -25,51 +25,36 @@
 struct dirent *
 __readdir_unlocked (DIR *dirp)
 {
-  struct dirent *dp;
-  int saved_errno = errno;
+  const int saved_errno = errno;
 
-  do
+  if (dirp->offset >= dirp->size)
     {
-      size_t reclen;
-
-      if (dirp->offset >= dirp->size)
+      /* We've emptied out our buffer.  Refill it.  */
+      ssize_t bytes = __getdents (dirp->fd, dirp->data, dirp->allocation);
+      if (bytes <= 0)
 	{
-	  /* We've emptied out our buffer.  Refill it.  */
-
-	  size_t maxread = dirp->allocation;
-	  ssize_t bytes;
-
-	  bytes = __getdents (dirp->fd, dirp->data, maxread);
-	  if (bytes <= 0)
-	    {
-	      /* On some systems getdents fails with ENOENT when the
-		 open directory has been rmdir'd already.  POSIX.1
-		 requires that we treat this condition like normal EOF.  */
-	      if (bytes < 0 && errno == ENOENT)
-		bytes = 0;
-
-	      /* Don't modifiy errno when reaching EOF.  */
-	      if (bytes == 0)
-		__set_errno (saved_errno);
-	      dp = NULL;
-	      break;
-	    }
-	  dirp->size = (size_t) bytes;
-
-	  /* Reset the offset into the buffer.  */
-	  dirp->offset = 0;
+	  /* On some systems getdents fails with ENOENT when the
+	     open directory has been rmdir'd already.  POSIX.1
+	     requires that we treat this condition like normal EOF.  */
+	  if (bytes < 0 && errno == ENOENT)
+	    bytes = 0;
+
+	  /* Don't modifiy errno when reaching EOF.  */
+	  if (bytes == 0)
+	    __set_errno (saved_errno);
+	  return NULL;
 	}
+      dirp->size = bytes;
 
-      dp = (struct dirent *) &dirp->data[dirp->offset];
-
-      reclen = dp->d_reclen;
+      /* Reset the offset into the buffer.  */
+      dirp->offset = 0;
+    }
 
-      dirp->offset += reclen;
+  struct dirent *dp = (struct dirent *) &dirp->data[dirp->offset];
 
-      dirp->filepos = dp->d_off;
+  dirp->offset += dp->d_reclen;
 
-      /* Skip deleted files.  */
-    } while (dp->d_ino == 0);
+  dirp->filepos = dp->d_off;
 
   return dp;
 }
diff --git a/sysdeps/unix/sysv/linux/readdir64.c b/sysdeps/unix/sysv/linux/readdir64.c
index 1aa6e2664f..d35a4595f6 100644
--- a/sysdeps/unix/sysv/linux/readdir64.c
+++ b/sysdeps/unix/sysv/linux/readdir64.c
@@ -30,55 +30,40 @@
 struct dirent64 *
 __readdir64 (DIR *dirp)
 {
-  struct dirent64 *dp;
-  int saved_errno = errno;
+  const int saved_errno = errno;
 
 #if IS_IN (libc)
   __libc_lock_lock (dirp->lock);
 #endif
 
-  do
+  if (dirp->offset >= dirp->size)
     {
-      size_t reclen;
-
-      if (dirp->offset >= dirp->size)
+      /* We've emptied out our buffer.  Refill it.  */
+      ssize_t bytes = __getdents64 (dirp->fd, dirp->data, dirp->allocation);
+      if (bytes <= 0)
 	{
-	  /* We've emptied out our buffer.  Refill it.  */
-
-	  size_t maxread = dirp->allocation;
-	  ssize_t bytes;
-
-	  bytes = __getdents64 (dirp->fd, dirp->data, maxread);
-	  if (bytes <= 0)
-	    {
-	      /* On some systems getdents fails with ENOENT when the
-		 open directory has been rmdir'd already.  POSIX.1
-		 requires that we treat this condition like normal EOF.  */
-	      if (bytes < 0 && errno == ENOENT)
-		bytes = 0;
-
-	      /* Don't modifiy errno when reaching EOF.  */
-	      if (bytes == 0)
-		__set_errno (saved_errno);
-	      dp = NULL;
-	      break;
-	    }
-	  dirp->size = (size_t) bytes;
-
-	  /* Reset the offset into the buffer.  */
-	  dirp->offset = 0;
+	  /* On some systems getdents fails with ENOENT when the
+	     open directory has been rmdir'd already.  POSIX.1
+	     requires that we treat this condition like normal EOF.  */
+	  if (bytes < 0 && errno == ENOENT)
+	    bytes = 0;
+
+	  /* Don't modifiy errno when reaching EOF.  */
+	  if (bytes == 0)
+	    __set_errno (saved_errno);
+	  return NULL;
 	}
+      dirp->size = bytes;
 
-      dp = (struct dirent64 *) &dirp->data[dirp->offset];
-
-      reclen = dp->d_reclen;
+      /* Reset the offset into the buffer.  */
+      dirp->offset = 0;
+   }
 
-      dirp->offset += reclen;
+  struct dirent64 *dp = (struct dirent64 *) &dirp->data[dirp->offset];
 
-      dirp->filepos = dp->d_off;
+  dirp->offset += dp->d_reclen;
 
-      /* Skip deleted files.  */
-    } while (dp->d_ino == 0);
+  dirp->filepos = dp->d_off;
 
 #if IS_IN (libc)
   __libc_lock_unlock (dirp->lock);
-- 
2.25.1


  reply	other threads:[~2020-10-21 14:15 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-21 14:15 [PATCH v3 0/7] Fix getdents{64} regression on some FS Adhemerval Zanella
2020-10-21 14:15 ` Adhemerval Zanella [this message]
2020-10-21 14:15 ` [PATCH v3 2/7] linux: Use getdents64 on non-LFS readdir Adhemerval Zanella
2020-10-21 14:15 ` [PATCH v3 3/7] linux: Set internal DIR filepos as off64_t [BZ #23960, BZ #24050] Adhemerval Zanella
2020-10-21 14:15 ` [PATCH v3 4/7] linux: Add __readdir64_unlocked Adhemerval Zanella
2020-10-21 14:15 ` [PATCH v3 5/7] linux: Add __old_readdir64_unlocked Adhemerval Zanella
2020-10-21 14:15 ` [PATCH v3 6/7] linux: Use getdents64 on readdir64 compat implementation Adhemerval Zanella
2020-10-21 14:15 ` [PATCH v3 7/7] dirent: Deprecate getdirentries Adhemerval Zanella
2022-01-06 21:48   ` John Paul Adrian Glaubitz
2022-01-06 21:59     ` Sam James
2022-01-06 22:01       ` John Paul Adrian Glaubitz
2022-05-10 19:30       ` John Paul Adrian Glaubitz
2022-05-12 15:40         ` Adhemerval Zanella
2021-07-22  8:28 ` [PATCH v3 0/7] Fix getdents{64} regression on some FS John Paul Adrian Glaubitz
2021-08-19 16:07 ` John Paul Adrian Glaubitz
2021-08-19 16:19   ` Adhemerval Zanella
2021-08-19 16:50     ` John Paul Adrian Glaubitz
2021-08-19 16:52       ` Adhemerval Zanella
2021-08-19 17:02         ` John Paul Adrian Glaubitz
2021-08-19 17:15           ` Florian Weimer
2021-08-19 20:30             ` John Paul Adrian Glaubitz
2021-08-20 10:34               ` Dave Flogeras

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201021141542.2003377-2-adhemerval.zanella@linaro.org \
    --to=adhemerval.zanella@linaro.org \
    --cc=dflogeras2@gmail.com \
    --cc=fweimer@redhat.com \
    --cc=glaubitz@physik.fu-berlin.de \
    --cc=jrtc27@debian.org \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).