From d50f22e6ae410fdcde573b6015b97dc1573bbb7e Mon Sep 17 00:00:00 2001 From: Raghavendra Gowdappa Date: Fri, 12 Oct 2018 10:03:31 +0530 Subject: performance/io-cache: update pages with write data Currently io-cache invalidate pages falling in the range of write. But instead it can update pages with same data so that reads can make use of the cache. credits: Xavi Hernandez Change-Id: I932bd3da97ddfd464187f3009b1013eb334f00a7 Signed-off-by: Raghavendra Gowdappa updates: bz#1659869 --- xlators/performance/io-cache/src/io-cache.c | 92 +++++++++++++++++++++++++++-- xlators/performance/io-cache/src/io-cache.h | 2 + 2 files changed, 90 insertions(+), 4 deletions(-) diff --git a/xlators/performance/io-cache/src/io-cache.c b/xlators/performance/io-cache/src/io-cache.c index 28b59973c7e..4757c1ccd27 100644 --- a/xlators/performance/io-cache/src/io-cache.c +++ b/xlators/performance/io-cache/src/io-cache.c @@ -78,6 +78,77 @@ ioc_get_inode (dict_t *dict, char *name) } */ +int +ioc_update_pages(call_frame_t *frame, ioc_inode_t *ioc_inode, + struct iovec *vector, int32_t count, int op_ret, off_t offset) +{ + size_t size = 0; + off_t rounded_offset = 0, rounded_end = 0, trav_offset = 0, + write_offset = 0; + off_t page_offset = 0, page_end = 0; + ioc_page_t *trav = NULL; + struct iovec pagevector = + { + 0, + }, + writevector = { + 0, + }; + int pvcount = 0, wvcount; + + size = iov_length(vector, count); + size = min(size, op_ret); + + rounded_offset = gf_floor(offset, ioc_inode->table->page_size); + rounded_end = gf_roof(offset + size, ioc_inode->table->page_size); + + trav_offset = rounded_offset; + ioc_inode_lock(ioc_inode); + { + while (trav_offset < rounded_end) { + trav = __ioc_page_get(ioc_inode, trav_offset); + if (trav && trav->ready) { + if (trav_offset == rounded_offset) + page_offset = offset - rounded_offset; + else + page_offset = 0; + + if ((trav_offset + ioc_inode->table->page_size) >= + rounded_end) { + page_end = trav->size - (rounded_end - (offset + size)); + } else { + page_end = trav->size; + } + + wvcount = iov_subset(vector, count, write_offset, + write_offset + (page_end - page_offset), + &writevector); + if (wvcount) { + pvcount = iov_subset(trav->vector, trav->count, page_offset, + page_end, &pagevector); + if (pvcount) { + iov_copy(&pagevector, pvcount, &writevector, wvcount); + } + } + } else if (trav) { + if (!trav->waitq) + ioc_inode->table->cache_used -= __ioc_page_destroy(trav); + } + + if (trav_offset == rounded_offset) + write_offset += (ioc_inode->table->page_size - + (offset - rounded_offset)); + else + write_offset += ioc_inode->table->page_size; + + trav_offset += ioc_inode->table->page_size; + } + } + ioc_inode_unlock(ioc_inode); + + return 0; +} + int32_t ioc_inode_need_revalidate(ioc_inode_t *ioc_inode) { @@ -1188,13 +1259,22 @@ ioc_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, uint64_t ioc_inode = 0; local = frame->local; + frame->local = NULL; inode_ctx_get(local->fd->inode, this, &ioc_inode); - if (ioc_inode) - ioc_inode_flush((ioc_inode_t *)(long)ioc_inode); + if (op_ret >= 0) { + ioc_update_pages(frame, (ioc_inode_t *)(long)ioc_inode, local->vector, + local->op_ret, op_ret, local->offset); + } STACK_UNWIND_STRICT(writev, frame, op_ret, op_errno, prebuf, postbuf, xdata); + if (local->iobref) { + iobref_unref(local->iobref); + GF_FREE(local->vector); + } + + mem_put(local); return 0; } @@ -1231,8 +1311,12 @@ ioc_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, frame->local = local; inode_ctx_get(fd->inode, this, &ioc_inode); - if (ioc_inode) - ioc_inode_flush((ioc_inode_t *)(long)ioc_inode); + if (ioc_inode) { + local->iobref = iobref_ref(iobref); + local->vector = iov_dup(vector, count); + local->op_ret = count; + local->offset = offset; + } STACK_WIND(frame, ioc_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, fd, vector, count, offset, diff --git a/xlators/performance/io-cache/src/io-cache.h b/xlators/performance/io-cache/src/io-cache.h index 088e06ea917..e99dfa455a2 100644 --- a/xlators/performance/io-cache/src/io-cache.h +++ b/xlators/performance/io-cache/src/io-cache.h @@ -91,6 +91,8 @@ struct ioc_local { struct ioc_waitq *waitq; void *stub; fd_t *fd; + struct iovec *vector; + struct iobref *iobref; int32_t need_xattr; dict_t *xattr_req; }; -- cgit