From: Liu Yuan <[email protected]>

These are trivial helper wrappers around standard IO functions
and interger hash function. "stolen" from git and Linux kernel.

Signed-off-by: Liu Yuan <[email protected]>
---
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 <[email protected]>
+ *
+ * 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

-- 
sheepdog mailing list
[email protected]
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to