[sheepdog] [PATCH 1/2] object cache: use flock instead of fcntl for locking
Liu Yuan
namei.unix at gmail.com
Mon Jun 4 04:41:59 CEST 2012
From: Liu Yuan <tailai.ly at taobao.com>
To quote manual:
"record locks are automatically released when the process terminates or if
it closes any file descriptor referring to a file on which locks are held"
This means fcntl lock doesn't support locking across FD even in the same process
space.
Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
sheep/object_cache.c | 49 ++++++++++++++-----------------------------------
1 file changed, 14 insertions(+), 35 deletions(-)
diff --git a/sheep/object_cache.c b/sheep/object_cache.c
index e091930..533769c 100644
--- a/sheep/object_cache.c
+++ b/sheep/object_cache.c
@@ -304,7 +304,6 @@ 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);
@@ -320,24 +319,18 @@ static int write_cache_object(uint32_t vid, uint32_t idx, void *buf, size_t coun
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");
+ if (flock(fd, LOCK_EX) < 0) {
ret = SD_RES_EIO;
+ eprintf("%m\n");
goto out_close;
}
size = xpwrite(fd, buf, count, offset);
-
- fl.l_type = F_UNLCK;
- if (fcntl(fd, F_SETLK, &fl) < 0) {
+ if (flock(fd, LOCK_UN) < 0) {
ret = SD_RES_EIO;
eprintf("%m\n");
goto out_close;
}
+
if (size != count) {
eprintf("size %zu, count:%zu, offset %zu %m\n",
size, count, offset);
@@ -355,7 +348,6 @@ 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);
@@ -371,21 +363,13 @@ static int read_cache_object(uint32_t vid, uint32_t idx, void *buf, size_t count
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");
+ if (flock(fd, LOCK_SH) < 0) {
ret = SD_RES_EIO;
+ eprintf("%m\n");
goto out_close;
}
-
size = xpread(fd, buf, count, offset);
-
- fl.l_type = F_UNLCK;
- if (fcntl(fd, F_SETLK, &fl) < 0) {
+ if (flock(fd, LOCK_UN) < 0) {
ret = SD_RES_EIO;
eprintf("%m\n");
goto out_close;
@@ -439,7 +423,6 @@ static int create_cache_object(struct object_cache *oc, uint32_t idx, void *buff
{
int flags = def_open_flags | O_CREAT | O_EXCL, fd, ret = SD_RES_SUCCESS;
struct strbuf buf;
- struct flock fl;
strbuf_init(&buf, PATH_MAX);
strbuf_addstr(&buf, cache_dir);
@@ -451,27 +434,23 @@ static int create_cache_object(struct object_cache *oc, uint32_t idx, void *buff
dprintf("%08"PRIx32" already created\n", idx);
goto out;
}
+ dprintf("%m\n");
ret = SD_RES_EIO;
goto out;
}
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0; /* 0 means EOF */
- fl.l_pid = getpid();
- if (fcntl(fd, F_SETLKW, &fl) < 0) {
- eprintf("%m\n");
+
+ if (flock(fd, LOCK_EX) < 0) {
ret = SD_RES_EIO;
+ eprintf("%m\n");
goto out_close;
}
ret = xpwrite(fd, buffer, buf_size, 0);
-
- fl.l_type = F_UNLCK;
- if (fcntl(fd, F_SETLK, &fl) < 0) {
+ if (flock(fd, LOCK_UN) < 0) {
ret = SD_RES_EIO;
eprintf("%m\n");
goto out_close;
}
+
if (ret != buf_size) {
ret = SD_RES_EIO;
eprintf("failed, vid %"PRIx32", idx %"PRIx32"\n", oc->vid, idx);
@@ -526,7 +505,7 @@ static int object_cache_pull(struct vnode_info *vnodes, struct object_cache *oc,
ret = forward_read_obj_req(&read_req);
if (ret == SD_RES_SUCCESS) {
- dprintf("oid %"PRIx64"pulled successfully\n", oid);
+ dprintf("oid %"PRIx64" pulled successfully\n", oid);
ret = create_cache_object(oc, idx, buf, data_length);
}
free(buf);
--
1.7.10.2
More information about the sheepdog
mailing list