From 43d3e6bd9210fc5900734206ed9478067b3f8003 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sat, 13 Oct 2007 18:14:58 +0000 Subject: [PATCH] * nscd/nscd_getgr_r.c (nscd_getgr_r): Optimize a bit: use simpler read mechanism when there are no group members and avoid no-op read syscall in this case. --- ChangeLog | 4 +++ nscd/nscd_getgr_r.c | 102 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 63 insertions(+), 43 deletions(-) diff --git a/ChangeLog b/ChangeLog index b0400a1c02..13bf1dc9f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2007-10-13 Ulrich Drepper + * nscd/nscd_getgr_r.c (nscd_getgr_r): Optimize a bit: use simpler + read mechanism when there are no group members and avoid no-op + read syscall in this case. + [BZ #3242] * nscd/nscd_helper.c (wait_on_socket): Take timeout as parameter. (__readall): If reading failed due to EAGAIN error wait a bit diff --git a/nscd/nscd_getgr_r.c b/nscd/nscd_getgr_r.c index fc036f2888..543ee17703 100644 --- a/nscd/nscd_getgr_r.c +++ b/nscd/nscd_getgr_r.c @@ -190,26 +190,37 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type, /* Read the length information, group name, and password. */ if (gr_name == NULL) { - /* Allocate array to store lengths. */ - if (lensize == 0) + /* Handle a simple, usual case: no group members. */ + if (__builtin_expect (gr_resp.gr_mem_cnt == 0, 1)) { - lensize = gr_resp.gr_mem_cnt * sizeof (uint32_t); - len = (uint32_t *) alloca (lensize); + size_t n = gr_resp.gr_name_len + gr_resp.gr_passwd_len; + if (__builtin_expect (__readall (sock, resultbuf->gr_name, n) + != (ssize_t) n, 0)) + goto out_close; + } + else + { + /* Allocate array to store lengths. */ + if (lensize == 0) + { + lensize = gr_resp.gr_mem_cnt * sizeof (uint32_t); + len = (uint32_t *) alloca (lensize); + } + else if (gr_resp.gr_mem_cnt * sizeof (uint32_t) > lensize) + len = extend_alloca (len, lensize, + gr_resp.gr_mem_cnt * sizeof (uint32_t)); + + vec[0].iov_base = (void *) len; + vec[0].iov_len = gr_resp.gr_mem_cnt * sizeof (uint32_t); + vec[1].iov_base = resultbuf->gr_name; + vec[1].iov_len = gr_resp.gr_name_len + gr_resp.gr_passwd_len; + total_len = vec[0].iov_len + vec[1].iov_len; + + /* Get this data. */ + size_t n = __readvall (sock, vec, 2); + if (__builtin_expect (n != total_len, 0)) + goto out_close; } - else if (gr_resp.gr_mem_cnt * sizeof (uint32_t) > lensize) - len = extend_alloca (len, lensize, - gr_resp.gr_mem_cnt * sizeof (uint32_t)); - - vec[0].iov_base = (void *) len; - vec[0].iov_len = gr_resp.gr_mem_cnt * sizeof (uint32_t); - vec[1].iov_base = resultbuf->gr_name; - vec[1].iov_len = gr_resp.gr_name_len + gr_resp.gr_passwd_len; - total_len = vec[0].iov_len + vec[1].iov_len; - - /* Get this data. */ - size_t n = __readvall (sock, vec, 2); - if (__builtin_expect (n != total_len, 0)) - goto out_close; } else /* We already have the data. Just copy the group name and @@ -251,37 +262,42 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type, } retval = 0; - if (gr_name == NULL) + + /* If there are no group members TOTAL_LEN is zero. */ + if (total_len > 0) { - size_t n = __readall (sock, resultbuf->gr_mem[0], total_len); - if (__builtin_expect (n != total_len, 0)) + if (gr_name == NULL) { - /* The `errno' to some value != ERANGE. */ - __set_errno (ENOENT); - retval = ENOENT; + size_t n = __readall (sock, resultbuf->gr_mem[0], total_len); + if (__builtin_expect (n != total_len, 0)) + { + /* The `errno' to some value != ERANGE. */ + __set_errno (ENOENT); + retval = ENOENT; + } + else + *result = resultbuf; } else - *result = resultbuf; - } - else - { - /* Copy the group member names. */ - memcpy (resultbuf->gr_mem[0], gr_name + gr_name_len, total_len); - - /* Try to detect corrupt databases. */ - if (resultbuf->gr_name[gr_name_len - 1] != '\0' - || resultbuf->gr_passwd[gr_resp.gr_passwd_len - 1] != '\0' - || ({for (cnt = 0; cnt < gr_resp.gr_mem_cnt; ++cnt) - if (resultbuf->gr_mem[cnt][len[cnt] - 1] != '\0') - break; - cnt < gr_resp.gr_mem_cnt; })) { - /* We cannot use the database. */ - retval = mapped->head->gc_cycle != gc_cycle ? -2 : -1; - goto out_close; + /* Copy the group member names. */ + memcpy (resultbuf->gr_mem[0], gr_name + gr_name_len, total_len); + + /* Try to detect corrupt databases. */ + if (resultbuf->gr_name[gr_name_len - 1] != '\0' + || resultbuf->gr_passwd[gr_resp.gr_passwd_len - 1] != '\0' + || ({for (cnt = 0; cnt < gr_resp.gr_mem_cnt; ++cnt) + if (resultbuf->gr_mem[cnt][len[cnt] - 1] != '\0') + break; + cnt < gr_resp.gr_mem_cnt; })) + { + /* We cannot use the database. */ + retval = mapped->head->gc_cycle != gc_cycle ? -2 : -1; + goto out_close; + } + + *result = resultbuf; } - - *result = resultbuf; } } else -- 2.11.4.GIT