summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '9999/0006-linux-Do-not-skip-entries-with-zero-d_ino-values-BZ-.patch')
-rw-r--r--9999/0006-linux-Do-not-skip-entries-with-zero-d_ino-values-BZ-.patch182
1 files changed, 182 insertions, 0 deletions
diff --git a/9999/0006-linux-Do-not-skip-entries-with-zero-d_ino-values-BZ-.patch b/9999/0006-linux-Do-not-skip-entries-with-zero-d_ino-values-BZ-.patch
new file mode 100644
index 0000000..eae612d
--- /dev/null
+++ b/9999/0006-linux-Do-not-skip-entries-with-zero-d_ino-values-BZ-.patch
@@ -0,0 +1,182 @@
+From 2a131fefbe72a749fe28b426a37b499bf7255cdf Mon Sep 17 00:00:00 2001
+From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date: Tue, 20 Oct 2020 12:18:56 -0300
+Subject: [PATCH 06/14] linux: Do not skip entries with zero d_ino values [BZ
+ #12165]
+
+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 c31f349639..7743f50071 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 e876d84b02..d990a36e4e 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.35.1
+