[sheepdog] [PATCH] object cache: use read/write lock

Liu Yuan namei.unix at gmail.com
Fri May 25 10:37:08 CEST 2012


From: Liu Yuan <tailai.ly at taobao.com>

This allow concurrent read access to the same object, which is crucial to cloned
VMs which shared one base in the same node.

Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
 include/util.h       |   11 -----------
 sheep/object_cache.c |   52 ++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 42 insertions(+), 21 deletions(-)

diff --git a/include/util.h b/include/util.h
index 0747ba4..eafd9ca 100644
--- a/include/util.h
+++ b/include/util.h
@@ -60,17 +60,6 @@ static inline void *zalloc(size_t size)
 	return calloc(1, size);
 }
 
-static inline int xlockf(int fd, int cmd, off_t offset, off_t len)
-{
-	if (lseek(fd, offset, SEEK_SET) < 0) {
-		eprintf("%m\n");
-		return -1;
-	}
-
-	return lockf(fd, cmd, len);
-}
-
-
 typedef void (*try_to_free_t)(size_t);
 extern try_to_free_t set_try_to_free_routine(try_to_free_t);
 
diff --git a/sheep/object_cache.c b/sheep/object_cache.c
index ce30c17..305f931 100644
--- a/sheep/object_cache.c
+++ b/sheep/object_cache.c
@@ -264,6 +264,7 @@ static int write_cache_object(uint32_t vid, uint32_t idx, void *buf, size_t coun
 	size_t size;
 	int fd, flags = def_open_flags, ret = SD_RES_SUCCESS;
 	struct strbuf p;
+	struct flock fl;
 
 	strbuf_init(&p, PATH_MAX);
 	strbuf_addstr(&p, cache_dir);
@@ -273,24 +274,38 @@ static int write_cache_object(uint32_t vid, uint32_t idx, void *buf, size_t coun
 		flags |= O_DIRECT;
 
 	fd = open(p.buf, flags, def_fmode);
-	if (xlockf(fd, F_LOCK, offset, count) < 0) {
-		ret = SD_RES_EIO;
+	if (fd < 0) {
 		eprintf("%m\n");
+		ret = SD_RES_EIO;
 		goto out;
 	}
+
+	fl.l_type = F_WRLCK;
+	fl.l_whence = SEEK_SET;
+	fl.l_start = offset;
+	fl.l_len = count;
+	fl.l_pid = getpid();
+	if (fcntl(fd, F_SETLKW, &fl) < 0) {
+		eprintf("%m\n");
+		ret = SD_RES_EIO;
+		goto out_close;
+	}
 	size = xpwrite(fd, buf, count, offset);
-	if (xlockf(fd, F_ULOCK, offset, count) < 0) {
+
+	fl.l_type = F_UNLCK;
+	if (fcntl(fd, F_SETLK, &fl) < 0) {
 		ret = SD_RES_EIO;
 		eprintf("%m\n");
-		goto out;
+		goto out_close;
 	}
 	if (size != count) {
 		eprintf("size %zu, count:%zu, offset %zu %m\n",
 			size, count, offset);
 		ret = SD_RES_EIO;
 	}
-out:
+out_close:
 	close(fd);
+out:
 	strbuf_release(&p);
 	return ret;
 }
@@ -300,6 +315,7 @@ static int read_cache_object(uint32_t vid, uint32_t idx, void *buf, size_t count
 	size_t size;
 	int fd, flags = def_open_flags, ret = SD_RES_SUCCESS;
 	struct strbuf p;
+	struct flock fl;
 
 	strbuf_init(&p, PATH_MAX);
 	strbuf_addstr(&p, cache_dir);
@@ -309,25 +325,41 @@ static int read_cache_object(uint32_t vid, uint32_t idx, void *buf, size_t count
 		flags |= O_DIRECT;
 
 	fd = open(p.buf, flags, def_fmode);
-	if (xlockf(fd, F_LOCK, offset, count) < 0) {
-		ret = SD_RES_EIO;
+	if (fd < 0) {
 		eprintf("%m\n");
+		ret = SD_RES_EIO;
 		goto out;
 	}
 
+	fl.l_type = F_RDLCK;
+	fl.l_whence = SEEK_SET;
+	fl.l_start = offset;
+	fl.l_len = count;
+	fl.l_pid = getpid();
+	if (fcntl(fd, F_SETLKW, &fl) < 0) {
+		eprintf("%m\n");
+		ret = SD_RES_EIO;
+		goto out_close;
+	}
+
 	size = xpread(fd, buf, count, offset);
-	if (xlockf(fd, F_ULOCK, offset, count) < 0) {
+
+	fl.l_type = F_UNLCK;
+	if (fcntl(fd, F_SETLK, &fl) < 0) {
 		ret = SD_RES_EIO;
 		eprintf("%m\n");
-		goto out;
+		goto out_close;
 	}
+
 	if (size != count) {
 		eprintf("size %zu, count:%zu, offset %zu %m\n",
 			size, count, offset);
 		ret = SD_RES_EIO;
 	}
-out:
+
+out_close:
 	close(fd);
+out:
 	strbuf_release(&p);
 	return ret;
 }
-- 
1.7.10.2




More information about the sheepdog mailing list