From: Martin Wilck <[email protected]> Replace the line-by-line reading in lookup_wwid() with mmap() and a simple loop over the in-memory structures.
Signed-off-by: Martin Wilck <[email protected]> --- libmultipath/wwids.c | 71 ++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c index c193b97..42455de 100644 --- a/libmultipath/wwids.c +++ b/libmultipath/wwids.c @@ -4,8 +4,10 @@ #include <string.h> #include <limits.h> #include <stdio.h> +#include <stdbool.h> #include <sys/types.h> #include <sys/stat.h> +#include <sys/mman.h> #include <fcntl.h> #include "util.h" @@ -24,41 +26,44 @@ * Copyright (c) 2010 Benjamin Marzinski, Redhat */ -static int -lookup_wwid(FILE *f, const char *wwid) { - int c; - char buf[LINE_MAX]; - int count; +struct mem_map { + char *addr; + ssize_t len; +}; - while ((c = fgetc(f)) != EOF){ - if (c != '/') { - if (fgets(buf, LINE_MAX, f) == NULL) - return 0; - else - continue; - } - count = 0; - while ((c = fgetc(f)) != '/') { - if (c == EOF) - return 0; - if (count >= WWID_SIZE - 1) - goto next; - if (wwid[count] == '\0') - goto next; - if (c != wwid[count++]) - goto next; - } - if (wwid[count] == '\0') - return 1; -next: - if (fgets(buf, LINE_MAX, f) == NULL) - return 0; - } - return 0; +static void cleanup_mmap(struct mem_map *mm) +{ + if (mm->addr) + munmap(mm->addr, mm->len); } -static int -write_out_wwid(int fd, const char *wwid) { +static bool lookup_wwid(int fd, const char *wwid) +{ + struct mem_map mm __attribute__((cleanup(cleanup_mmap))) = { .addr = 0 }; + struct stat stb; + ssize_t wlen; + const char *line; + + if (fstat(fd, &stb) != 0) + return false; + + mm.len = stb.st_size; + mm.addr = mmap(NULL, stb.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (!mm.addr) + return false; + + wlen = strlen(wwid); + for (line = mm.addr; line >= mm.addr && line < mm.addr + mm.len; + line = memchr(line, '\n', mm.addr + mm.len - line) + 1) + if (line[0] == '/' && (line - mm.addr + 2 + wlen <= mm.len) && + line[wlen + 1] == '/' && !strncmp(wwid, line + 1, wlen)) + return true; + + return false; +} + +static int write_out_wwid(int fd, const char *wwid) +{ int ret; off_t offset; char buf[WWID_SIZE + 3]; @@ -245,7 +250,7 @@ int check_wwids_file(const char *wwid, int write_wwid) close(fd); return -1; } - found = lookup_wwid(f, wwid); + found = lookup_wwid(fd, wwid); if (found) { ret = 0; goto out; -- 2.55.0
