[sheepdog] [PATCH v2] sheep: check memory address alignment for direct IO

MORITA Kazutaka morita.kazutaka at lab.ntt.co.jp
Wed May 22 13:03:08 CEST 2013


Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---

v2:
 - move alignment check ingo get_open_flags()
 - add check for object cache IO

 sheep/object_cache.c |  8 ++++++--
 sheep/plain_store.c  | 14 ++++++++------
 sheep/sheep_priv.h   |  5 +++++
 3 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/sheep/object_cache.c b/sheep/object_cache.c
index 3aa7fd6..18f1198 100644
--- a/sheep/object_cache.c
+++ b/sheep/object_cache.c
@@ -288,8 +288,10 @@ static int read_cache_object_noupdate(uint32_t vid, uint32_t idx, void *buf,
 	snprintf(p, sizeof(p), "%s/%06"PRIx32"/%08"PRIx32, object_cache_dir,
 		 vid, idx);
 
-	if (sys->object_cache_directio && !idx_has_vdi_bit(idx))
+	if (sys->object_cache_directio && !idx_has_vdi_bit(idx)) {
+		assert(is_aligned_to_pagesize(buf));
 		flags |= O_DIRECT;
+	}
 
 	fd = open(p, flags, sd_def_fmode);
 	if (fd < 0) {
@@ -322,8 +324,10 @@ static int write_cache_object_noupdate(uint32_t vid, uint32_t idx, void *buf,
 
 	snprintf(p, sizeof(p), "%s/%06"PRIx32"/%08"PRIx32, object_cache_dir,
 		 vid, idx);
-	if (sys->object_cache_directio && !idx_has_vdi_bit(idx))
+	if (sys->object_cache_directio && !idx_has_vdi_bit(idx)) {
+		assert(is_aligned_to_pagesize(buf));
 		flags |= O_DIRECT;
+	}
 
 	fd = open(p, flags, sd_def_fmode);
 	if (fd < 0) {
diff --git a/sheep/plain_store.c b/sheep/plain_store.c
index b932d6a..33a3fd2 100644
--- a/sheep/plain_store.c
+++ b/sheep/plain_store.c
@@ -20,7 +20,7 @@
 #include "config.h"
 #include "sha1.h"
 
-static int get_open_flags(uint64_t oid, bool create)
+static int get_open_flags(uint64_t oid, bool create, void *buf)
 {
 	int flags = O_DSYNC | O_RDWR;
 
@@ -28,8 +28,10 @@ static int get_open_flags(uint64_t oid, bool create)
 		flags &= ~O_DSYNC;
 
 	/* We can not use DIO for inode object because it is not 512B aligned */
-	if (sys->backend_dio && is_data_obj(oid))
+	if (sys->backend_dio && is_data_obj(oid)) {
+		assert(is_aligned_to_pagesize(buf));
 		flags |= O_DIRECT;
+	}
 
 	if (create)
 		flags |= O_CREAT | O_EXCL;
@@ -92,7 +94,7 @@ static int err_to_sderr(char *path, uint64_t oid, int err)
 
 int default_write(uint64_t oid, const struct siocb *iocb)
 {
-	int flags = get_open_flags(oid, false), fd,
+	int flags = get_open_flags(oid, false, iocb->buf), fd,
 	    ret = SD_RES_SUCCESS;
 	char path[PATH_MAX];
 	ssize_t size;
@@ -173,8 +175,8 @@ int default_cleanup(void)
 static int init_vdi_state(uint64_t oid, char *wd)
 {
 	char path[PATH_MAX];
-	int fd, flags = get_open_flags(oid, false), ret;
 	struct sd_inode *inode = xzalloc(sizeof(*inode));
+	int fd, flags = get_open_flags(oid, false, inode), ret;
 
 	snprintf(path, sizeof(path), "%s/%016"PRIx64, wd, oid);
 
@@ -233,7 +235,7 @@ int default_init(void)
 static int default_read_from_path(uint64_t oid, char *path,
 				  const struct siocb *iocb)
 {
-	int flags = get_open_flags(oid, false), fd,
+	int flags = get_open_flags(oid, false, iocb->buf), fd,
 	    ret = SD_RES_SUCCESS;
 	ssize_t size;
 
@@ -294,7 +296,7 @@ int prealloc(int fd, uint32_t size)
 int default_create_and_write(uint64_t oid, const struct siocb *iocb)
 {
 	char path[PATH_MAX], tmp_path[PATH_MAX];
-	int flags = get_open_flags(oid, true);
+	int flags = get_open_flags(oid, true, iocb->buf);
 	int ret, fd;
 	uint32_t len = iocb->length;
 
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index d086aef..98c4197 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -212,6 +212,11 @@ static inline uint32_t sys_epoch(void)
 	return uatomic_read(&sys->epoch);
 }
 
+static inline bool is_aligned_to_pagesize(void *p)
+{
+	return ((uintptr_t)p & (getpagesize() - 1)) == 0;
+}
+
 int create_listen_port(char *bindaddr, int port);
 int init_unix_domain_socket(const char *dir);
 
-- 
1.8.1.3.566.gaa39828



More information about the sheepdog mailing list