From af1ab7266edf91216e27484c505c78401f092e13 Mon Sep 17 00:00:00 2001 From: Krutika Dhananjay Date: Tue, 7 Jun 2016 16:27:34 +0530 Subject: libglusterfs: Implement API that provides page-aligned iobufs Backport of: http://review.gluster.org/14672 One of the consumers of a page aligned buffer would be posix's readv fop on O_DIRECT fds. Today the way it works is by getting a page-aligned buffer through calloc, pread()ing into this buffer and then copying its contents into a newly created iobuf's ptr. This results in an extra memcpy() which can be avoided if we could implement an api that would return an iobuf whose ptr is page-aligned. That way the iobuf->ptr can be directly passed to sys_pread() as a parameter by posix translator. Change-Id: Ie44c300dc773fef8e1669d609987d47dbd340ac2 BUG: 1351024 Signed-off-by: Krutika Dhananjay Reviewed-on: http://review.gluster.org/14826 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Zhou Zhengping Reviewed-by: Pranith Kumar Karampuri --- libglusterfs/src/iobuf.c | 35 +++++++++++++++++++++++++++++++++++ libglusterfs/src/iobuf.h | 4 ++++ 2 files changed, 39 insertions(+) (limited to 'libglusterfs') diff --git a/libglusterfs/src/iobuf.c b/libglusterfs/src/iobuf.c index a4d36691cd0..b2df0dc9a3a 100644 --- a/libglusterfs/src/iobuf.c +++ b/libglusterfs/src/iobuf.c @@ -678,6 +678,36 @@ unlock: return iobuf; } +struct iobuf * +iobuf_get_page_aligned (struct iobuf_pool *iobuf_pool, size_t page_size, + size_t align_size) +{ + size_t req_size = 0; + struct iobuf *iobuf = NULL; + + req_size = page_size; + + if (req_size == 0) { + req_size = iobuf_pool->default_page_size; + } + + iobuf = iobuf_get2 (iobuf_pool, req_size + align_size); + /* If std allocation was used, then free_ptr will be non-NULL. In this + * case, we do not want to modify the original free_ptr. + * On the other hand, if the buf was gotten through the available + * arenas, then we use iobuf->free_ptr to store the original + * pointer to the offset into the mmap'd block of memory and in turn + * reuse iobuf->ptr to hold the page-aligned address. And finally, in + * iobuf_put(), we copy iobuf->free_ptr into iobuf->ptr - back to where + * it was originally when __iobuf_get() returned this iobuf. + */ + if (!iobuf->free_ptr) + iobuf->free_ptr = iobuf->ptr; + iobuf->ptr = GF_ALIGN_BUF (iobuf->ptr, align_size); + + return iobuf; +} + struct iobuf * iobuf_get (struct iobuf_pool *iobuf_pool) { @@ -745,6 +775,11 @@ __iobuf_put (struct iobuf *iobuf, struct iobuf_arena *iobuf_arena) list_del_init (&iobuf->list); iobuf_arena->active_cnt--; + if (iobuf->free_ptr) { + iobuf->ptr = iobuf->free_ptr; + iobuf->free_ptr = NULL; + } + list_add (&iobuf->list, &iobuf_arena->passive.list); iobuf_arena->passive_cnt++; diff --git a/libglusterfs/src/iobuf.h b/libglusterfs/src/iobuf.h index 7e5cfe37a28..1578ceb84dd 100644 --- a/libglusterfs/src/iobuf.h +++ b/libglusterfs/src/iobuf.h @@ -169,4 +169,8 @@ void iobuf_stats_dump (struct iobuf_pool *iobuf_pool); struct iobuf * iobuf_get2 (struct iobuf_pool *iobuf_pool, size_t page_size); + +struct iobuf * +iobuf_get_page_aligned (struct iobuf_pool *iobuf_pool, size_t page_size, + size_t align_size); #endif /* !_IOBUF_H_ */ -- cgit