[sheepdog] [PATCH 4/5] farm: add a lock for read/write
Liu Yuan
namei.unix at gmail.com
Tue Jun 19 05:55:17 CEST 2012
From: Liu Yuan <tailai.ly at taobao.com>
We observed a race for this same object, which resule an EIO:
Jun 14 16:16:12 queue_request(387) 1
Jun 14 16:16:12 do_local_io(52) 1, ac1a3e00000000 , 1
Jun 14 16:16:12 listen_handler(805) accepted a new connection: 191
Jun 14 16:16:12 client_rx_handler(588) connection from: 10.232.134.8:42092
Jun 14 16:16:12 queue_request(387) 2
Jun 14 16:16:12 do_local_io(52) 2, ac1a3e00000000 , 1
Jun 14 16:16:12 do_io_request(111) failed: 2, ac1a3e00000000 , 1, 3
Jun 14 16:16:12 io_op_done(119) leaving sheepdog cluster
So let's be more denfensive now.
Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
sheep/farm/farm.c | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/sheep/farm/farm.c b/sheep/farm/farm.c
index 5351e59..bef821c 100644
--- a/sheep/farm/farm.c
+++ b/sheep/farm/farm.c
@@ -14,6 +14,7 @@
#include <dirent.h>
#include <pthread.h>
#include <linux/limits.h>
+#include <sys/file.h>
#include "farm.h"
#include "sheep_priv.h"
@@ -125,13 +126,29 @@ static int farm_write(uint64_t oid, struct siocb *iocb, int create)
if (fd < 0)
return err_to_sderr(oid, errno);
+ if (flock(fd, LOCK_EX) < 0) {
+ ret = SD_RES_EIO;
+ eprintf("%m\n");
+ goto out;
+ }
if (create && !(iocb->flags & SD_FLAG_CMD_COW)) {
ret = prealloc(fd, is_vdi_obj(oid) ?
SD_INODE_SIZE : SD_DATA_OBJ_SIZE);
- if (ret != SD_RES_SUCCESS)
+ if (ret != SD_RES_SUCCESS) {
+ if (flock(fd, LOCK_UN) < 0) {
+ ret = SD_RES_EIO;
+ eprintf("%m\n");
+ goto out;
+ }
goto out;
+ }
}
size = xpwrite(fd, iocb->buf, iocb->length, iocb->offset);
+ if (flock(fd, LOCK_UN) < 0) {
+ ret = SD_RES_EIO;
+ eprintf("%m\n");
+ goto out;
+ }
if (size != iocb->length) {
eprintf("%m\n");
ret = SD_RES_EIO;
@@ -451,7 +468,17 @@ static int farm_read(uint64_t oid, struct siocb *iocb)
if (fd < 0)
return err_to_sderr(oid, errno);
+ if (flock(fd, LOCK_SH) < 0) {
+ ret = SD_RES_EIO;
+ eprintf("%m\n");
+ goto out;
+ }
size = xpread(fd, iocb->buf, iocb->length, iocb->offset);
+ if (flock(fd, LOCK_UN) < 0) {
+ ret = SD_RES_EIO;
+ eprintf("%m\n");
+ goto out;
+ }
if (size != iocb->length) {
ret = SD_RES_EIO;
goto out;
--
1.7.10.2
More information about the sheepdog
mailing list