[sheepdog] [PATCH 7/9] sheep: handle no space error of object I/Os

MORITA Kazutaka morita.kazutaka at lab.ntt.co.jp
Mon Sep 17 01:00:00 CEST 2012


This handles no space error of object I/Os.  Handling this error when
writing a config or epoch logs is left for future work.

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 sheep/farm/farm.c   |   41 ---------------------------
 sheep/plain_store.c |   77 ++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 61 insertions(+), 57 deletions(-)

diff --git a/sheep/farm/farm.c b/sheep/farm/farm.c
index 86d9fb3..683c1ed 100644
--- a/sheep/farm/farm.c
+++ b/sheep/farm/farm.c
@@ -71,47 +71,6 @@ err:
 	return ret;
 }
 
-static int write_last_sector(int fd, uint32_t length)
-{
-	const int size = SECTOR_SIZE;
-	char *buf;
-	int ret;
-	off_t off = length - size;
-
-	buf = valloc(size);
-	if (!buf) {
-		eprintf("failed to allocate memory\n");
-		return SD_RES_NO_MEM;
-	}
-	memset(buf, 0, size);
-
-	ret = xpwrite(fd, buf, size, off);
-	if (ret != size)
-		ret = SD_RES_EIO;
-	else
-		ret = SD_RES_SUCCESS;
-	free(buf);
-
-	return ret;
-}
-
-/*
- * Preallocate the whole object to get a better filesystem layout.
- */
-int prealloc(int fd, uint32_t size)
-{
-	int ret = fallocate(fd, 0, 0, size);
-	if (ret < 0) {
-		if (errno != ENOSYS && errno != EOPNOTSUPP) {
-			dprintf("%m\n");
-			ret = SD_RES_SYSTEM_ERROR;
-		} else
-			ret = write_last_sector(fd, size);
-	} else
-		ret = SD_RES_SUCCESS;
-	return ret;
-}
-
 static int get_trunk_sha1(uint32_t epoch, unsigned char *outsha1)
 {
 	int i, nr_logs = -1, ret = -1;
diff --git a/sheep/plain_store.c b/sheep/plain_store.c
index de38a1f..cb2776c 100644
--- a/sheep/plain_store.c
+++ b/sheep/plain_store.c
@@ -109,18 +109,22 @@ static int err_to_sderr(uint64_t oid, int err)
 {
 	struct stat s;
 
-	if (err != ENOENT) {
+	switch (err) {
+	case ENOENT:
+		if (stat(obj_path, &s) < 0) {
+			eprintf("corrupted\n");
+			return SD_RES_EIO;
+		}
+		dprintf("object %016" PRIx64 " not found locally\n", oid);
+		return SD_RES_NO_OBJ;
+	case ENOSPC:
+		/* TODO: stop automatic recovery */
+		eprintf("diskfull, oid=%"PRIx64"\n", oid);
+		return SD_RES_NO_SPACE;
+	default:
 		eprintf("oid=%"PRIx64", %m\n", oid);
 		return SD_RES_EIO;
 	}
-
-	if (stat(obj_path, &s) < 0) {
-		eprintf("corrupted\n");
-		return SD_RES_EIO;
-	}
-
-	dprintf("object %016" PRIx64 " not found locally\n", oid);
-	return SD_RES_NO_OBJ;
 }
 
 int default_write(uint64_t oid, struct siocb *iocb)
@@ -146,7 +150,7 @@ int default_write(uint64_t oid, struct siocb *iocb)
 		eprintf("failed to write object %"PRIx64", path=%s, offset=%"
 			PRId64", size=%"PRId32", result=%zd, %m\n", oid, path,
 			iocb->offset, iocb->length, size);
-		ret = SD_RES_EIO;
+		ret = err_to_sderr(oid, errno);
 		goto out;
 	}
 out:
@@ -242,7 +246,7 @@ static int default_read_from_path(uint64_t oid, char *path,
 		eprintf("failed to read object %"PRIx64", path=%s, offset=%"
 			PRId64", size=%"PRId32", result=%zd, %m\n", oid, path,
 			iocb->offset, iocb->length, size);
-		ret = SD_RES_EIO;
+		ret = err_to_sderr(oid, errno);
 	}
 
 	close(fd);
@@ -270,11 +274,52 @@ int default_read(uint64_t oid, struct siocb *iocb)
 	return ret;
 }
 
+static int write_last_sector(int fd, uint32_t length)
+{
+	const int size = SECTOR_SIZE;
+	char *buf;
+	int ret;
+	off_t off = length - size;
+
+	buf = valloc(size);
+	if (!buf) {
+		eprintf("failed to allocate memory\n");
+		return SD_RES_NO_MEM;
+	}
+	memset(buf, 0, size);
+
+	ret = xpwrite(fd, buf, size, off);
+	if (ret != size)
+		ret = err_to_sderr(0, errno); /* FIXME: set oid */
+	else
+		ret = SD_RES_SUCCESS;
+	free(buf);
+
+	return ret;
+}
+
+/*
+ * Preallocate the whole object to get a better filesystem layout.
+ */
+int prealloc(int fd, uint32_t size)
+{
+	int ret = fallocate(fd, 0, 0, size);
+	if (ret < 0) {
+		if (errno != ENOSYS && errno != EOPNOTSUPP) {
+			dprintf("%m\n");
+			ret = SD_RES_SYSTEM_ERROR;
+		} else
+			ret = write_last_sector(fd, size);
+	} else
+		ret = SD_RES_SUCCESS;
+	return ret;
+}
+
 int default_create_and_write(uint64_t oid, struct siocb *iocb)
 {
 	char path[PATH_MAX], tmp_path[PATH_MAX];
 	int flags = get_open_flags(oid, true);
-	int ret = SD_RES_EIO, fd;
+	int ret, fd;
 	uint32_t len = iocb->length;
 
 	get_obj_path(oid, path);
@@ -292,7 +337,7 @@ int default_create_and_write(uint64_t oid, struct siocb *iocb)
 			return SD_RES_SUCCESS;
 
 		eprintf("failed to open %s: %m\n", tmp_path);
-		return SD_RES_EIO;
+		return err_to_sderr(oid, errno);
 	}
 
 	if (iocb->offset != 0 || iocb->length != get_objsize(oid)) {
@@ -304,14 +349,14 @@ int default_create_and_write(uint64_t oid, struct siocb *iocb)
 	ret = xwrite(fd, iocb->buf, len);
 	if (ret != len) {
 		eprintf("failed to write object. %m\n");
-		ret = SD_RES_EIO;
+		ret = err_to_sderr(oid, errno);
 		goto out;
 	}
 
 	ret = rename(tmp_path, path);
 	if (ret < 0) {
 		eprintf("failed to rename %s to %s: %m\n", tmp_path, path);
-		ret = SD_RES_EIO;
+		ret = err_to_sderr(oid, errno);
 		goto out;
 	}
 	dprintf("%"PRIx64"\n", oid);
@@ -334,7 +379,7 @@ int default_link(uint64_t oid, struct siocb *iocb, uint32_t tgt_epoch)
 	if (link(stale_path, path) < 0) {
 		eprintf("failed to link from %s to %s, %m\n", stale_path,
 			path);
-		return SD_RES_EIO;
+		return err_to_sderr(oid, errno);
 	}
 
 	return SD_RES_SUCCESS;
-- 
1.7.2.5




More information about the sheepdog mailing list