summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog32
-rw-r--r--nscd/aicache.c36
-rw-r--r--nscd/connections.c35
-rw-r--r--nscd/grpcache.c30
-rw-r--r--nscd/hstcache.c30
-rw-r--r--nscd/initgrcache.c35
-rw-r--r--nscd/pwdcache.c30
-rw-r--r--sysdeps/generic/futimesat.c10
-rw-r--r--sysdeps/unix/sysv/linux/Makefile7
-rw-r--r--sysdeps/unix/sysv/linux/futimesat.c17
-rw-r--r--sysdeps/unix/sysv/linux/ia64/bits/shm.h6
-rw-r--r--sysdeps/unix/sysv/linux/kernel-features.h5
12 files changed, 251 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index e9a519ddac..24a6063c4b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2005-11-19 Jakub Jelinek <jakub@redhat.com>
+
+ * sysdeps/unix/sysv/linux/ia64/bits/shm.h (shmatt_t): New type.
+ (struct shmid_ds): Use it for shm_nattch field.
+
+2005-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ * sysdeps/unix/sysv/linux/futimesat.c (futimesat): If FILE is NULL,
+ set access and modification times of the file referenced by FD.
+ * sysdeps/generic/futimesat.c (futimesat): Don't return EINVAL if
+ FILE is NULL. Don't check FD if FILE is absolute path.
+
+2005-11-19 Ulrich Drepper <drepper@redhat.com>
+
+ * nscd/nscd_gethst_r.c (nscd_gethst_r): Avoid unnecesary read call
+ if there are no aliases.
+
+ * sysdeps/unix/sysv/linux/Makefile (CFLAGS-connections.c,
+ CFLAGS-pwdcache.c, CFLAGS-grpcache.c, CFLAGS-hstcache.c,
+ CFLAGS-aicache.c, CFLAGS-initgrcache.c): Add -DHAVE_SENDFILE.
+ * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_SENDFILE):
+ Define.
+ * nscd/pwdcache.c [HAVE_SENDFILE]: Include <sys/sendfile.h> and
+ <kernel-features.h>.
+ [HAVE_SENDFILE] (cache_addpw): Use sendfile to transmit positive
+ result.
+ * nscd/grpcache.c: Likewise.
+ * nscd/hstcache.c: Likewise.
+ * nscd/aicache.c: Likewise.
+ * nscd/initgrcache.c: Likewise.
+ * nscd/connectionc.c: Likewise.
+
2005-11-18 Andreas Schwab <schwab@suse.de>
* sysdeps/powerpc/powerpc32/fpu/s_lround.S: Remove useless alias.
diff --git a/nscd/aicache.c b/nscd/aicache.c
index 992c6ef023..9b8a4e50f2 100644
--- a/nscd/aicache.c
+++ b/nscd/aicache.c
@@ -26,8 +26,15 @@
#include <time.h>
#include <unistd.h>
#include <sys/mman.h>
-#include <dbg_log.h>
-#include <nscd.h>
+#ifdef HAVE_SENDFILE
+# include <sys/sendfile.h>
+#endif
+
+#include "dbg_log.h"
+#include "nscd.h"
+#ifdef HAVE_SENDFILE
+# include <kernel-features.h>
+#endif
typedef enum nss_status (*nss_gethostbyname3_r)
@@ -365,7 +372,30 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
wait. */
assert (fd != -1);
- writeall (fd, &dataset->resp, total);
+#ifdef HAVE_SENDFILE
+ if (__builtin_expect (db->mmap_used, 1))
+ {
+ assert (db->wr_fd != -1);
+ assert ((char *) &dataset->resp > (char *) db->data);
+ assert ((char *) &dataset->resp - (char *) db->head
+ + total
+ <= (sizeof (struct database_pers_head)
+ + db->head->module * sizeof (ref_t)
+ + db->head->data_size));
+ off_t off = (char *) &dataset->resp - (char *) db->head;
+ ssize_t written;
+ written = sendfile (fd, db->wr_fd, &off, total);
+# ifndef __ASSUME_SENDFILE
+ if (written == -1 && errno == ENOSYS)
+ goto use_write;
+# endif
+ }
+ else
+# ifndef __ASSUME_SENDFILE
+ use_write:
+# endif
+#endif
+ writeall (fd, &dataset->resp, total);
}
goto out;
diff --git a/nscd/connections.c b/nscd/connections.c
index 137cfb239a..0a1ca77836 100644
--- a/nscd/connections.c
+++ b/nscd/connections.c
@@ -39,6 +39,9 @@
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/poll.h>
+#ifdef HAVE_SENDFILE
+# include <sys/sendfile.h>
+#endif
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
@@ -46,6 +49,9 @@
#include "nscd.h"
#include "dbg_log.h"
#include "selinux.h"
+#ifdef HAVE_SENDFILE
+# include <kernel-features.h>
+#endif
/* Wrapper functions with error checking for standard functions. */
@@ -939,8 +945,33 @@ cannot handle old request version %d; current version is %d"),
if (cached != NULL)
{
/* Hurray it's in the cache. */
- if (writeall (fd, cached->data, cached->recsize)
- != cached->recsize
+ ssize_t nwritten;
+
+#ifdef HAVE_SENDFILE
+ if (db->mmap_used || !cached->notfound)
+ {
+ assert (db->wr_fd != -1);
+ assert ((char *) cached->data > (char *) db->data);
+ assert ((char *) cached->data - (char *) db->head
+ + cached->recsize
+ <= (sizeof (struct database_pers_head)
+ + db->head->module * sizeof (ref_t)
+ + db->head->data_size));
+ off_t off = (char *) cached->data - (char *) db->head;
+ nwritten = sendfile (fd, db->wr_fd, &off, cached->recsize);
+# ifndef __ASSUME_SENDFILE
+ if (nwritten == -1 && errno == ENOSYS)
+ goto use_write;
+# endif
+ }
+ else
+# ifndef __ASSUME_SENDFILE
+ use_write:
+# endif
+#endif
+ nwritten = writeall (fd, cached->data, cached->recsize);
+
+ if (nwritten != cached->recsize
&& __builtin_expect (debug_level, 0) > 0)
{
/* We have problems sending the result. */
diff --git a/nscd/grpcache.c b/nscd/grpcache.c
index 3f440e9701..fb043152c6 100644
--- a/nscd/grpcache.c
+++ b/nscd/grpcache.c
@@ -32,11 +32,17 @@
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
+#ifdef HAVE_SENDFILE
+# include <sys/sendfile.h>
+#endif
#include <sys/socket.h>
#include <stackinfo.h>
#include "nscd.h"
#include "dbg_log.h"
+#ifdef HAVE_SENDFILE
+# include <kernel-features.h>
+#endif
/* This is the standard reply in case the service is disabled. */
static const gr_response_header disabled =
@@ -294,7 +300,29 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
unnecessarily let the receiver wait. */
assert (fd != -1);
- written = writeall (fd, &dataset->resp, total);
+#ifdef HAVE_SENDFILE
+ if (__builtin_expect (db->mmap_used, 1))
+ {
+ assert (db->wr_fd != -1);
+ assert ((char *) &dataset->resp > (char *) db->data);
+ assert ((char *) &dataset->resp - (char *) db->head
+ + total
+ <= (sizeof (struct database_pers_head)
+ + db->head->module * sizeof (ref_t)
+ + db->head->data_size));
+ off_t off = (char *) &dataset->resp - (char *) db->head;
+ written = sendfile (fd, db->wr_fd, &off, total);
+# ifndef __ASSUME_SENDFILE
+ if (written == -1 && errno == ENOSYS)
+ goto use_write;
+# endif
+ }
+ else
+# ifndef __ASSUME_SENDFILE
+ use_write:
+# endif
+#endif
+ written = writeall (fd, &dataset->resp, total);
}
/* Add the record to the database. But only if it has not been
diff --git a/nscd/hstcache.c b/nscd/hstcache.c
index 29bce99819..29f14af66b 100644
--- a/nscd/hstcache.c
+++ b/nscd/hstcache.c
@@ -34,10 +34,16 @@
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <sys/mman.h>
+#ifdef HAVE_SENDFILE
+# include <sys/sendfile.h>
+#endif
#include <stackinfo.h>
#include "nscd.h"
#include "dbg_log.h"
+#ifdef HAVE_SENDFILE
+# include <kernel-features.h>
+#endif
/* This is the standard reply in case the service is disabled. */
@@ -328,7 +334,29 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
unnecessarily keep the receiver waiting. */
assert (fd != -1);
- written = writeall (fd, &dataset->resp, total);
+#ifdef HAVE_SENDFILE
+ if (__builtin_expect (db->mmap_used, 1))
+ {
+ assert (db->wr_fd != -1);
+ assert ((char *) &dataset->resp > (char *) db->data);
+ assert ((char *) &dataset->resp - (char *) db->head
+ + total
+ <= (sizeof (struct database_pers_head)
+ + db->head->module * sizeof (ref_t)
+ + db->head->data_size));
+ off_t off = (char *) &dataset->resp - (char *) db->head;
+ written = sendfile (fd, db->wr_fd, &off, total);
+# ifndef __ASSUME_SENDFILE
+ if (written == -1 && errno == ENOSYS)
+ goto use_write;
+# endif
+ }
+ else
+# ifndef __ASSUME_SENDFILE
+ use_write:
+# endif
+#endif
+ written = writeall (fd, &dataset->resp, total);
}
/* Add the record to the database. But only if it has not been
diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c
index bb6dee2b4e..eb03fc7a5d 100644
--- a/nscd/initgrcache.c
+++ b/nscd/initgrcache.c
@@ -26,8 +26,15 @@
#include <time.h>
#include <unistd.h>
#include <sys/mman.h>
-#include <dbg_log.h>
-#include <nscd.h>
+#ifdef HAVE_SENDFILE
+# include <sys/sendfile.h>
+#endif
+
+#include "dbg_log.h"
+#include "nscd.h"
+#ifdef HAVE_SENDFILE
+# include <kernel-features.h>
+#endif
#include "../nss/nsswitch.h"
@@ -344,7 +351,29 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
unnecessarily let the receiver wait. */
assert (fd != -1);
- written = writeall (fd, &dataset->resp, total);
+#ifdef HAVE_SENDFILE
+ if (__builtin_expect (db->mmap_used, 1))
+ {
+ assert (db->wr_fd != -1);
+ assert ((char *) &dataset->resp > (char *) db->data);
+ assert ((char *) &dataset->resp - (char *) db->head
+ + total
+ <= (sizeof (struct database_pers_head)
+ + db->head->module * sizeof (ref_t)
+ + db->head->data_size));
+ off_t off = (char *) &dataset->resp - (char *) db->head;
+ written = sendfile (fd, db->wr_fd, &off, total);
+# ifndef __ASSUME_SENDFILE
+ if (written == -1 && errno == ENOSYS)
+ goto use_write;
+# endif
+ }
+ else
+# ifndef __ASSUME_SENDFILE
+ use_write:
+# endif
+#endif
+ written = writeall (fd, &dataset->resp, total);
}
diff --git a/nscd/pwdcache.c b/nscd/pwdcache.c
index e4ed7e97ca..6f4b032d10 100644
--- a/nscd/pwdcache.c
+++ b/nscd/pwdcache.c
@@ -32,11 +32,17 @@
#include <time.h>
#include <unistd.h>
#include <sys/mman.h>
+#ifdef HAVE_SENDFILE
+# include <sys/sendfile.h>
+#endif
#include <sys/socket.h>
#include <stackinfo.h>
#include "nscd.h"
#include "dbg_log.h"
+#ifdef HAVE_SENDFILE
+# include <kernel-features.h>
+#endif
/* This is the standard reply in case the service is disabled. */
static const pw_response_header disabled =
@@ -289,7 +295,29 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
unnecessarily let the receiver wait. */
assert (fd != -1);
- written = writeall (fd, &dataset->resp, total);
+#ifdef HAVE_SENDFILE
+ if (__builtin_expect (db->mmap_used, 1))
+ {
+ assert (db->wr_fd != -1);
+ assert ((char *) &dataset->resp > (char *) db->data);
+ assert ((char *) &dataset->resp - (char *) db->head
+ + total
+ <= (sizeof (struct database_pers_head)
+ + db->head->module * sizeof (ref_t)
+ + db->head->data_size));
+ off_t off = (char *) &dataset->resp - (char *) db->head;
+ written = sendfile (fd, db->wr_fd, &off, total);
+# ifndef __ASSUME_SENDFILE
+ if (written == -1 && errno == ENOSYS)
+ goto use_write;
+# endif
+ }
+ else
+# ifndef __ASSUME_SENDFILE
+ use_write:
+# endif
+#endif
+ written = writeall (fd, &dataset->resp, total);
}
diff --git a/sysdeps/generic/futimesat.c b/sysdeps/generic/futimesat.c
index 33d170862a..74ccd876e6 100644
--- a/sysdeps/generic/futimesat.c
+++ b/sysdeps/generic/futimesat.c
@@ -30,18 +30,14 @@ futimesat (fd, file, tvp)
const char *file;
const struct timeval tvp[2];
{
- if (fd < 0 && fd != AT_FDCWD)
+ if (fd < 0
+ && (file == NULL
+ || (fd != AT_FDCWD && file[0] != '/')))
{
__set_errno (EBADF);
return -1;
}
- if (file == NULL)
- {
- __set_errno (EINVAL);
- return -1;
- }
-
__set_errno (ENOSYS);
return -1;
}
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index c5e1da03e9..b2bbbc0b28 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -152,6 +152,11 @@ CFLAGS-mq_receive.c += -fexceptions
endif
ifeq ($(subdir),nscd)
-CFLAGS-connections.c += -DHAVE_EPOLL
+CFLAGS-connections.c += -DHAVE_EPOLL -DHAVE_SENDFILE
+CFLAGS-pwdcache.c += -DHAVE_SENDFILE
+CFLAGS-grpcache.c += -DHAVE_SENDFILE
+CFLAGS-hstcache.c += -DHAVE_SENDFILE
+CFLAGS-aicache.c += -DHAVE_SENDFILE
+CFLAGS-initgrcache.c += -DHAVE_SENDFILE
CFLAGS-gai.c += -DNEED_NETLINK
endif
diff --git a/sysdeps/unix/sysv/linux/futimesat.c b/sysdeps/unix/sysv/linux/futimesat.c
index 7ab0477c5e..8a87cc442b 100644
--- a/sysdeps/unix/sysv/linux/futimesat.c
+++ b/sysdeps/unix/sysv/linux/futimesat.c
@@ -37,7 +37,22 @@ futimesat (fd, file, tvp)
{
char *buf = NULL;
- if (fd != AT_FDCWD && file[0] != '/')
+ if (file == NULL)
+ {
+ static const char procfd[] = "/proc/self/fd/%d";
+ /* Buffer for the path name we are going to use. It consists of
+ - the string /proc/self/fd/
+ - the file descriptor number.
+ The final NUL is included in the sizeof. A bit of overhead
+ due to the format elements compensates for possible negative
+ numbers. */
+ size_t buflen = sizeof (procfd) + sizeof (int) * 3;
+ buf = alloca (buflen);
+
+ __snprintf (buf, buflen, procfd, fd);
+ file = buf;
+ }
+ else if (fd != AT_FDCWD && file[0] != '/')
{
size_t filelen = strlen (file);
static const char procfd[] = "/proc/self/fd/%d/%s";
diff --git a/sysdeps/unix/sysv/linux/ia64/bits/shm.h b/sysdeps/unix/sysv/linux/ia64/bits/shm.h
index 7506e55867..7f38f2dd7b 100644
--- a/sysdeps/unix/sysv/linux/ia64/bits/shm.h
+++ b/sysdeps/unix/sysv/linux/ia64/bits/shm.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -38,6 +38,8 @@
/* Segment low boundary address multiple. */
#define SHMLBA (1024 * 1024)
+/* Type to count number of attaches. */
+typedef unsigned long int shmatt_t;
/* Data structure describing a set of semaphores. */
struct shmid_ds
@@ -49,7 +51,7 @@ struct shmid_ds
__time_t shm_ctime; /* time of last change by shmctl() */
__pid_t shm_cpid; /* pid of creator */
__pid_t shm_lpid; /* pid of last shmop */
- unsigned long int shm_nattch; /* number of current attaches */
+ shmatt_t shm_nattch; /* number of current attaches */
unsigned long int __unused1;
unsigned long int __unused2;
};
diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index 002cc46c79..44ac727820 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -84,6 +84,11 @@
# define __ASSUME_MSG_NOSIGNAL 1
#endif
+/* The sendfile syscall was introduced in 2.2.0. */
+#if __LINUX_KERNEL_VERSION >= 131584
+# define __ASSUME_SENDFILE 1
+#endif
+
/* On x86 another `getrlimit' syscall was added in 2.3.25. */
#if __LINUX_KERNEL_VERSION >= 131865 && defined __i386__
# define __ASSUME_NEW_GETRLIMIT_SYSCALL 1