about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2007-08-29 05:16:12 +0000
committerUlrich Drepper <drepper@redhat.com>2007-08-29 05:16:12 +0000
commit0adfcc05265f4297adb89a040acb52689f3be87c (patch)
tree8de8a4c6cec2a03aecb7d7227017018c58c213ea
parent3586b2b60b6d92ce3cc3d497e84ae1e5cfcf81e4 (diff)
downloadglibc-0adfcc05265f4297adb89a040acb52689f3be87c.tar.gz
glibc-0adfcc05265f4297adb89a040acb52689f3be87c.tar.xz
glibc-0adfcc05265f4297adb89a040acb52689f3be87c.zip
* nscd/nscd_helper.c (get_mapping): Avoid the pread call, just go
	ahead and map the file.  This should always be correct and we can
	catch problems later.
-rw-r--r--ChangeLog6
-rw-r--r--nscd/nscd_helper.c59
2 files changed, 35 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index 95a4b83558..a4f1dfb372 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-08-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* nscd/nscd_helper.c (get_mapping): Avoid the pread call, just go
+	ahead and map the file.  This should always be correct and we can
+	catch problems later.
+
 2007-08-28  Jakub Jelinek  <jakub@redhat.com>
 
 	* libio/bits/stdio2.h (__fread_chk, __fread_unlocked_chk): New
diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
index 50146a093e..780878d1bb 100644
--- a/nscd/nscd_helper.c
+++ b/nscd/nscd_helper.c
@@ -286,45 +286,44 @@ get_mapping (request_type type, const char *key,
       || __builtin_expect (st.st_size < sizeof (struct database_pers_head), 0))
     goto out_close;
 
-  struct database_pers_head head;
-  if (__builtin_expect (TEMP_FAILURE_RETRY (__pread (mapfd, &head,
-						     sizeof (head), 0))
-			!= sizeof (head), 0))
-    goto out_close;
-
-  if (__builtin_expect (head.version != DB_VERSION, 0)
-      || __builtin_expect (head.header_size != sizeof (head), 0)
-      /* This really should not happen but who knows, maybe the update
-	 thread got stuck.  */
-      || __builtin_expect (! head.nscd_certainly_running
-			   && head.timestamp + MAPPING_TIMEOUT < time (NULL),
-			   0))
-    goto out_close;
-
-  size_t size = (sizeof (head) + roundup (head.module * sizeof (ref_t), ALIGN)
-		 + head.data_size);
-
-  if (__builtin_expect (st.st_size < size, 0))
-    goto out_close;
-
   /* The file is large enough, map it now.  */
-  void *mapping = __mmap (NULL, size, PROT_READ, MAP_SHARED, mapfd, 0);
+  void *mapping = __mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, mapfd, 0);
   if (__builtin_expect (mapping != MAP_FAILED, 1))
     {
-      /* Allocate a record for the mapping.  */
-      struct mapped_database *newp = malloc (sizeof (*newp));
-      if (newp == NULL)
+      /* Check whether the database is correct and up-to-date.  */
+      struct database_pers_head *head = mapping;
+
+      if (__builtin_expect (head->version != DB_VERSION, 0)
+	  || __builtin_expect (head->header_size != sizeof (*head), 0)
+	  /* This really should not happen but who knows, maybe the update
+	     thread got stuck.  */
+	  || __builtin_expect (! head->nscd_certainly_running
+			       && (head->timestamp + MAPPING_TIMEOUT
+				   < time (NULL)), 0))
 	{
-	  /* Ugh, after all we went through the memory allocation failed.  */
-	  __munmap (mapping, size);
+	out_unmap:
+	  __munmap (mapping, st.st_size);
 	  goto out_close;
 	}
 
+      size_t size = (sizeof (*head) + roundup (head->module * sizeof (ref_t),
+					       ALIGN)
+		     + head->data_size);
+
+      if (__builtin_expect (st.st_size < size, 0))
+	goto out_unmap;
+
+      /* Allocate a record for the mapping.  */
+      struct mapped_database *newp = malloc (sizeof (*newp));
+      if (newp == NULL)
+	/* Ugh, after all we went through the memory allocation failed.  */
+	goto out_unmap;
+
       newp->head = mapping;
-      newp->data = ((char *) mapping + head.header_size
-		    + roundup (head.module * sizeof (ref_t), ALIGN));
+      newp->data = ((char *) mapping + head->header_size
+		    + roundup (head->module * sizeof (ref_t), ALIGN));
       newp->mapsize = size;
-      newp->datasize = head.data_size;
+      newp->datasize = head->data_size;
       /* Set counter to 1 to show it is usable.  */
       newp->counter = 1;