lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 29 Apr 2008 19:04:40 +0530
From:	bsn.0007@...il.com
To:	libc-alpha@...rceware.org
Cc:	Jan Blunck <jblunck@...e.de>, Erez Zadok <ezk@...sunysb.edu>,
	linux-kernel@...r.kernel.org, linux-fsdevel@...r.kernel.org,
	viro@...iv.linux.org.uk, Christoph Hellwig <hch@....de>,
	Ulrich Drepper <drepper@...hat.com>,
	Mingming Cao <cmm@...ibm.com>,
	Dave Hansen <haveblue@...ibm.com>,
	Trond Myklebust <trond.myklebust@....uio.no>,
	bharata@...ux.vnet.ibm.com, David Woodhouse <dwmw2@...radead.org>
Subject: [RFC PATCH 2/2] Union Mount: glibc seekdir support

seekdir support for union mounted directory.

seekdir, telldir and rewinddir  now work on the dirent cache maintained
by readdir.

Signed-off-by: Nagabhushan B S <bsn.0007@...il.com>
---
 sysdeps/unix/dirstream.h                 |    9 +++++++--
 sysdeps/unix/readdir.c                   |   21 ++++++++++++++++++---
 sysdeps/unix/rewinddir.c                 |   16 ++++++++++++----
 sysdeps/unix/seekdir.c                   |   26 ++++++++++++++++++++++----
 sysdeps/unix/sysv/linux/i386/readdir64.c |    2 ++
 sysdeps/unix/telldir.c                   |    5 ++++-
 6 files changed, 65 insertions(+), 14 deletions(-)

--- a/sysdeps/unix/dirstream.h
+++ b/sysdeps/unix/dirstream.h
@@ -19,11 +19,15 @@
 #ifndef _UNION_DIR_CACHE
 #define _UNION_DIR_CACHE    1
 
-#include <limits.h>
+#include <dirent.h>
+
+#ifndef CACHE_DIRENT_TYPE
+#define CACHE_DIRENT_TYPE struct dirent
+#endif
 
 struct union_dir_cache
 {
-  char fname[NAME_MAX];
+  CACHE_DIRENT_TYPE dp;
   struct union_dir_cache *next;
   struct union_dir_cache *prev;
 };
@@ -66,6 +70,7 @@ struct __dirstream
     struct union_dir_cache *head;
     struct union_dir_cache *current;
     unsigned char union_dir_status;
+    off_t union_dir_pos;
 
     /* Directory block.  */
     char data[0] __attribute__ ((aligned (__alignof__ (void*))));
--- a/sysdeps/unix/readdir.c
+++ b/sysdeps/unix/readdir.c
@@ -48,6 +48,21 @@ __READDIR (DIR *dirp)
   __libc_lock_lock (dirp->lock);
 #endif
 
+  /* If union mounted directory, check if we can return dirent from cache */
+  if (dirp->head && dirp->current->next)
+    {
+      dirp->current = dirp->current->next;
+      while (dirp->current && dirp->current->dp.d_type == DT_WHT)
+        dirp->current = dirp->current->next;
+
+      if (dirp->current) {
+        dirp->union_dir_pos = dirp->current->dp.d_off;
+#ifndef NOT_IN_libc
+        __libc_lock_unlock (dirp->lock);
+#endif
+        return &dirp->current->dp;
+      }
+    }
   do
     {
       size_t reclen;
@@ -135,7 +150,7 @@ __READDIR (DIR *dirp)
               temp = dirp->head;
               while (temp)
                 {
-                  if (!strcmp (temp->fname, dp->d_name))
+                  if (!strcmp (temp->dp.d_name, dp->d_name))
                     {
                       isdup = 1;
                       break;
@@ -168,8 +183,8 @@ __READDIR (DIR *dirp)
               dirp->current = dirp->current->next;
             }
 
-          strcpy(dirp->current->fname, dp->d_name);
-
+          memcpy(&dirp->current->dp, dp, sizeof(DIRENT_TYPE));
+          dirp->current->dp.d_off = ++dirp->union_dir_pos;
         }
 	dirp->union_dir_status &= ~DIR_FIRST_DIRENT;
 
--- a/sysdeps/unix/rewinddir.c
+++ b/sysdeps/unix/rewinddir.c
@@ -29,9 +29,17 @@ rewinddir (dirp)
      DIR *dirp;
 {
   __libc_lock_lock (dirp->lock);
-  (void) __lseek (dirp->fd, (off_t) 0, SEEK_SET);
-  dirp->filepos = 0;
-  dirp->offset = 0;
-  dirp->size = 0;
+  if (dirp->head)
+    {
+      dirp->current = dirp->head;
+      dirp->union_dir_pos = dirp->current->dp.d_off;
+    }
+  else
+    {
+      (void) __lseek (dirp->fd, (off_t) 0, SEEK_SET);
+      dirp->filepos = 0;
+      dirp->offset = 0;
+      dirp->size = 0;
+    }
   __libc_lock_unlock (dirp->lock);
 }
--- a/sysdeps/unix/seekdir.c
+++ b/sysdeps/unix/seekdir.c
@@ -30,9 +30,27 @@ seekdir (dirp, pos)
      long int pos;
 {
   __libc_lock_lock (dirp->lock);
-  (void) __lseek (dirp->fd, pos, SEEK_SET);
-  dirp->size = 0;
-  dirp->offset = 0;
-  dirp->filepos = pos;
+  if (dirp->head) /* union mounted directory */
+    {
+      if (pos == 0)
+        dirp->current = dirp->head;
+      else
+        {
+          dirp->current = dirp->head;
+          while (dirp->current->next && pos != 1)
+            {
+              dirp->current = dirp->current->next;
+              pos--;
+            }
+        }
+      dirp->union_dir_pos = dirp->current->dp.d_off;
+    }
+  else
+    {
+      (void) __lseek (dirp->fd, pos, SEEK_SET);
+      dirp->size = 0;
+      dirp->offset = 0;
+      dirp->filepos = pos;
+    }
   __libc_lock_unlock (dirp->lock);
 }
--- a/sysdeps/unix/sysv/linux/i386/readdir64.c
+++ b/sysdeps/unix/sysv/linux/i386/readdir64.c
@@ -16,6 +16,7 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#define CACHE_DIRENT_TYPE struct dirent64
 #define __READDIR __readdir64
 #define __GETDENTS __getdents64
 #define DIRENT_TYPE struct dirent64
@@ -34,6 +35,7 @@ versioned_symbol (libc, __readdir64, rea
 
 #include <sysdeps/unix/sysv/linux/i386/olddirent.h>
 
+#define CACHE_DIRENT_TYPE struct __old_dirent64
 #define __READDIR attribute_compat_text_section __old_readdir64
 #define __GETDENTS __old_getdents64
 #define DIRENT_TYPE struct __old_dirent64
--- a/sysdeps/unix/telldir.c
+++ b/sysdeps/unix/telldir.c
@@ -24,5 +24,8 @@
 long int
 telldir (DIR *dirp)
 {
-  return dirp->filepos;
+  if (dirp->head)          /* union mounted directory  */
+    return dirp->union_dir_pos;
+  else
+    return dirp->filepos;
 }
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ