From: Liu Yuan <tailai.ly at taobao.com> These are trivial helper wrappers around standard IO functions and interger hash function. "stolen" from git and Linux kernel. Signed-off-by: Liu Yuan <tailai.ly at taobao.com> --- update: - use lower bits in FNV hash value for integer hashing. include/sheepdog_proto.h | 7 ++ include/util.h | 14 +++ sheep/util.c | 214 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 235 insertions(+), 0 deletions(-) create mode 100644 sheep/util.c diff --git a/include/sheepdog_proto.h b/include/sheepdog_proto.h index 65aeef3..198ccdc 100644 --- a/include/sheepdog_proto.h +++ b/include/sheepdog_proto.h @@ -216,6 +216,13 @@ static inline uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval) return hval; } +static inline uint64_t hash_64(uint64_t val, unsigned int bits) +{ + uint64_t hash = fnv_64a_buf(&val, sizeof(uint64_t), FNV1A_64_INIT); + + return hash & ((1 << bits) - 1); +} + static inline int is_data_obj_writeable(struct sheepdog_inode *inode, int idx) { return inode->vdi_id == inode->data_vdi_id[idx]; diff --git a/include/util.h b/include/util.h index 2dccd16..725c8f8 100644 --- a/include/util.h +++ b/include/util.h @@ -2,6 +2,8 @@ #define __UTIL_H__ #include <string.h> +#include <limits.h> +#include <stdint.h> #include "bitops.h" @@ -53,4 +55,16 @@ static inline void *zalloc(size_t size) return calloc(1, size); } +typedef void (*try_to_free_t)(size_t); +extern try_to_free_t set_try_to_free_routine(try_to_free_t); + +extern void *xmalloc(size_t size); +extern void *xzalloc(size_t size); +extern void *xrealloc(void *ptr, size_t size); +extern void *xcalloc(size_t nmemb, size_t size); +extern ssize_t xread(int fd, void *buf, size_t len); +extern ssize_t xwrite(int fd, const void *buf, size_t len); +extern ssize_t xpread(int fd, void *buf, size_t count, off_t offset); +extern ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset); + #endif diff --git a/sheep/util.c b/sheep/util.c new file mode 100644 index 0000000..5a314ba --- /dev/null +++ b/sheep/util.c @@ -0,0 +1,214 @@ +/* + * Taken and modfied from git by Liu Yuan <namei.unix at gmail.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> + +#include "util.h" +#include "logger.h" + +static void do_nothing(size_t size) +{ +} + +static void (*try_to_free_routine)(size_t size) = do_nothing; + +try_to_free_t set_try_to_free_routine(try_to_free_t routine) +{ + try_to_free_t old = try_to_free_routine; + if (!routine) + routine = do_nothing; + try_to_free_routine = routine; + return old; +} + +void *xmalloc(size_t size) +{ + void *ret = malloc(size); + if (!ret && !size) + ret = malloc(1); + if (!ret) { + try_to_free_routine(size); + ret = malloc(size); + if (!ret && !size) + ret = malloc(1); + if (!ret) + panic("Out of memory"); + } + return ret; +} + +void *xzalloc(size_t size) +{ + void *ret; + ret = xmalloc(size); + memset(ret, 0, size); + return ret; +} + +void *xrealloc(void *ptr, size_t size) +{ + void *ret = realloc(ptr, size); + if (!ret && !size) + ret = realloc(ptr, 1); + if (!ret) { + try_to_free_routine(size); + ret = realloc(ptr, size); + if (!ret && !size) + ret = realloc(ptr, 1); + if (!ret) + panic("Out of memory"); + } + return ret; +} + +void *xcalloc(size_t nmemb, size_t size) +{ + void *ret = calloc(nmemb, size); + if (!ret && (!nmemb || !size)) + ret = calloc(1, 1); + if (!ret) { + try_to_free_routine(nmemb * size); + ret = calloc(nmemb, size); + if (!ret && (!nmemb || !size)) + ret = calloc(1, 1); + if (!ret) + panic("Out of memory"); + } + return ret; +} + +static ssize_t _read(int fd, void *buf, size_t len) +{ + ssize_t nr; + while (1) { + nr = read(fd, buf, len); + if ((nr < 0) && (errno == EAGAIN || errno == EINTR)) + continue; + return nr; + } +} + +static ssize_t _write(int fd, const void *buf, size_t len) +{ + ssize_t nr; + while (1) { + nr = write(fd, buf, len); + if ((nr < 0) && (errno == EAGAIN || errno == EINTR)) + continue; + return nr; + } +} + +ssize_t xread(int fd, void *buf, size_t count) +{ + char *p = buf; + ssize_t total = 0; + + while (count > 0) { + ssize_t loaded = _read(fd, p, count); + if (loaded < 0) + return -1; + if (loaded == 0) + return total; + count -= loaded; + p += loaded; + total += loaded; + } + + return total; +} + +ssize_t xwrite(int fd, const void *buf, size_t count) +{ + const char *p = buf; + ssize_t total = 0; + + while (count > 0) { + ssize_t written = _write(fd, p, count); + if (written < 0) + return -1; + if (!written) { + errno = ENOSPC; + return -1; + } + count -= written; + p += written; + total += written; + } + + return total; +} + +static ssize_t _pread(int fd, void *buf, size_t len, off_t offset) +{ + ssize_t nr; + while (1) { + nr = pread(fd, buf, len, offset); + if ((nr < 0) && (errno == EAGAIN || errno == EINTR)) + continue; + return nr; + } +} + +static ssize_t _pwrite(int fd, const void *buf, size_t len, off_t offset) +{ + ssize_t nr; + while (1) { + nr = pwrite(fd, buf, len, offset); + if ((nr < 0) && (errno == EAGAIN || errno == EINTR)) + continue; + return nr; + } +} + +ssize_t xpread(int fd, void *buf, size_t count, off_t offset) +{ + char *p = buf; + ssize_t total = 0; + + while (count > 0) { + ssize_t loaded = _pread(fd, p, count, offset); + if (loaded < 0) + return -1; + if (loaded == 0) + return total; + count -= loaded; + p += loaded; + total += loaded; + offset += loaded; + } + + return total; +} + +ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset) +{ + const char *p = buf; + ssize_t total = 0; + + while (count > 0) { + ssize_t written = _pwrite(fd, p, count, offset); + if (written < 0) + return -1; + if (!written) { + errno = ENOSPC; + return -1; + } + count -= written; + p += written; + total += written; + offset += written; + } + + return total; +} -- 1.7.6.1 |