diff options
Diffstat (limited to 'xlators/performance/io-cache')
| -rw-r--r-- | xlators/performance/io-cache/src/io-cache-messages.h | 41 | ||||
| -rw-r--r-- | xlators/performance/io-cache/src/io-cache.c | 292 | ||||
| -rw-r--r-- | xlators/performance/io-cache/src/io-cache.h | 45 | ||||
| -rw-r--r-- | xlators/performance/io-cache/src/ioc-inode.c | 14 | ||||
| -rw-r--r-- | xlators/performance/io-cache/src/ioc-mem-types.h | 2 | ||||
| -rw-r--r-- | xlators/performance/io-cache/src/page.c | 67 |
6 files changed, 267 insertions, 194 deletions
diff --git a/xlators/performance/io-cache/src/io-cache-messages.h b/xlators/performance/io-cache/src/io-cache-messages.h index 09c5439ca71..38ad0b14d0e 100644 --- a/xlators/performance/io-cache/src/io-cache-messages.h +++ b/xlators/performance/io-cache/src/io-cache-messages.h @@ -10,7 +10,7 @@ #ifndef _IO_CACHE_MESSAGES_H_ #define _IO_CACHE_MESSAGES_H_ -#include "glfs-message-id.h" +#include <glusterfs/glfs-message-id.h> /* To add new message IDs, append new identifiers at the end of the list. * @@ -27,6 +27,43 @@ GLFS_MSGID(IO_CACHE, IO_CACHE_MSG_ENFORCEMENT_FAILED, IO_CACHE_MSG_XLATOR_CHILD_MISCONFIGURED, IO_CACHE_MSG_NO_MEMORY, IO_CACHE_MSG_VOL_MISCONFIGURED, IO_CACHE_MSG_INODE_NULL, IO_CACHE_MSG_PAGE_WAIT_VALIDATE, IO_CACHE_MSG_STR_COVERSION_FAILED, - IO_CACHE_MSG_WASTED_COPY); + IO_CACHE_MSG_WASTED_COPY, IO_CACHE_MSG_SET_FD_FAILED, + IO_CACHE_MSG_TABLE_NULL, IO_CACHE_MSG_MEMORY_INIT_FAILED, + IO_CACHE_MSG_NO_CACHE_SIZE_OPT, IO_CACHE_MSG_NOT_RECONFIG_CACHE_SIZE, + IO_CACHE_MSG_CREATE_MEM_POOL_FAILED, + IO_CACHE_MSG_ALLOC_MEM_POOL_FAILED, IO_CACHE_MSG_NULL_PAGE_WAIT, + IO_CACHE_MSG_FRAME_NULL, IO_CACHE_MSG_PAGE_FAULT, + IO_CACHE_MSG_SERVE_READ_REQUEST, IO_CACHE_MSG_LOCAL_NULL, + IO_CACHE_MSG_DEFAULTING_TO_OLD); +#define IO_CACHE_MSG_NO_MEMORY_STR "out of memory" +#define IO_CACHE_MSG_ENFORCEMENT_FAILED_STR "inode context is NULL" +#define IO_CACHE_MSG_SET_FD_FAILED_STR "failed to set fd ctx" +#define IO_CACHE_MSG_TABLE_NULL_STR "table is NULL" +#define IO_CACHE_MSG_MEMORY_INIT_FAILED_STR "Memory accounting init failed" +#define IO_CACHE_MSG_NO_CACHE_SIZE_OPT_STR "could not get cache-size option" +#define IO_CACHE_MSG_INVALID_ARGUMENT_STR \ + "file size is greater than the max size" +#define IO_CACHE_MSG_NOT_RECONFIG_CACHE_SIZE_STR "Not reconfiguring cache-size" +#define IO_CACHE_MSG_XLATOR_CHILD_MISCONFIGURED_STR \ + "FATAL: io-cache not configured with exactly one child" +#define IO_CACHE_MSG_VOL_MISCONFIGURED_STR "dangling volume. check volfile" +#define IO_CACHE_MSG_CREATE_MEM_POOL_FAILED_STR \ + "failed to create local_t's memory pool" +#define IO_CACHE_MSG_ALLOC_MEM_POOL_FAILED_STR "Unable to allocate mem_pool" +#define IO_CACHE_MSG_STR_COVERSION_FAILED_STR \ + "asprintf failed while converting prt to str" +#define IO_CACHE_MSG_INODE_NULL_STR "ioc_inode is NULL" +#define IO_CACHE_MSG_PAGE_WAIT_VALIDATE_STR \ + "cache validate called without any page waiting to be validated" +#define IO_CACHE_MSG_NULL_PAGE_WAIT_STR "asked to wait on a NULL page" +#define IO_CACHE_MSG_WASTED_COPY_STR "wasted copy" +#define IO_CACHE_MSG_FRAME_NULL_STR "frame>root>rsp_refs is null" +#define IO_CACHE_MSG_PAGE_FAULT_STR "page fault on a NULL frame" +#define IO_CACHE_MSG_SERVE_READ_REQUEST_STR \ + "NULL page has been provided to serve read request" +#define IO_CACHE_MSG_LOCAL_NULL_STR "local is NULL" +#define IO_CACHE_MSG_DEFAULTING_TO_OLD_STR \ + "minimum size of file that can be cached is greater than maximum size. " \ + "Hence Defaulting to old value" #endif /* _IO_CACHE_MESSAGES_H_ */ diff --git a/xlators/performance/io-cache/src/io-cache.c b/xlators/performance/io-cache/src/io-cache.c index 6705128087e..9375d29c17f 100644 --- a/xlators/performance/io-cache/src/io-cache.c +++ b/xlators/performance/io-cache/src/io-cache.c @@ -9,13 +9,13 @@ */ #include <math.h> -#include "glusterfs.h" -#include "logging.h" -#include "dict.h" -#include "xlator.h" +#include <glusterfs/glusterfs.h> +#include <glusterfs/logging.h> +#include <glusterfs/dict.h> +#include <glusterfs/xlator.h> #include "io-cache.h" #include "ioc-mem-types.h" -#include "statedump.h" +#include <glusterfs/statedump.h> #include <assert.h> #include <sys/time.h> #include "io-cache-messages.h" @@ -78,23 +78,72 @@ ioc_get_inode (dict_t *dict, char *name) } */ -int32_t +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; + + 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; + } + + iov_range_copy(trav->vector, trav->count, page_offset, vector, + count, write_offset, page_end - page_offset); + } 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; +} + +static gf_boolean_t ioc_inode_need_revalidate(ioc_inode_t *ioc_inode) { - int8_t need_revalidate = 0; - struct timeval tv = { - 0, - }; ioc_table_t *table = NULL; + GF_ASSERT(ioc_inode); table = ioc_inode->table; + GF_ASSERT(table); - gettimeofday(&tv, NULL); - - if (time_elapsed(&tv, &ioc_inode->cache.tv) >= table->cache_timeout) - need_revalidate = 1; - - return need_revalidate; + return (gf_time() - ioc_inode->cache.last_revalidate >= + table->cache_timeout); } /* @@ -273,16 +322,14 @@ ioc_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) local = mem_get0(this->local_pool); if (local == NULL) { op_errno = ENOMEM; - gf_msg(this->name, GF_LOG_ERROR, 0, IO_CACHE_MSG_NO_MEMORY, - "out of memory"); + gf_smsg(this->name, GF_LOG_ERROR, 0, IO_CACHE_MSG_NO_MEMORY, NULL); goto unwind; } ret = loc_copy(&local->file_loc, loc); if (ret != 0) { op_errno = ENOMEM; - gf_msg(this->name, GF_LOG_ERROR, 0, IO_CACHE_MSG_NO_MEMORY, - "out of memory"); + gf_smsg(this->name, GF_LOG_ERROR, 0, IO_CACHE_MSG_NO_MEMORY, NULL); goto unwind; } @@ -328,14 +375,12 @@ ioc_forget(xlator_t *this, inode_t *inode) static int32_t ioc_invalidate(xlator_t *this, inode_t *inode) { - uint64_t ioc_addr = 0; - ioc_inode_t *ioc_inode = NULL; + uint64_t ioc_inode = 0; - inode_ctx_get(inode, this, (uint64_t *)&ioc_addr); - ioc_inode = (void *)(uintptr_t)ioc_addr; + inode_ctx_get(inode, this, &ioc_inode); if (ioc_inode) - ioc_inode_flush(ioc_inode); + ioc_inode_flush((ioc_inode_t *)(uintptr_t)ioc_inode); return 0; } @@ -360,9 +405,6 @@ ioc_cache_validate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, ioc_inode_t *ioc_inode = NULL; size_t destroy_size = 0; struct iatt *local_stbuf = NULL; - struct timeval tv = { - 0, - }; local = frame->local; ioc_inode = local->inode; @@ -400,10 +442,9 @@ ioc_cache_validate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, if (op_ret < 0) local_stbuf = NULL; - gettimeofday(&tv, NULL); ioc_inode_lock(ioc_inode); { - memcpy(&ioc_inode->cache.tv, &tv, sizeof(struct timeval)); + ioc_inode->cache.last_revalidate = gf_time(); } ioc_inode_unlock(ioc_inode); @@ -413,6 +454,7 @@ ioc_cache_validate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, * fd_ref on fd, safe to unref validate frame's private copy */ fd_unref(local->fd); + dict_unref(local->xattr_req); STACK_DESTROY(frame->root); @@ -439,8 +481,8 @@ ioc_wait_on_inode(ioc_inode_t *ioc_inode, ioc_page_t *page) if (!page_found) { waiter = GF_CALLOC(1, sizeof(ioc_waitq_t), gf_ioc_mt_ioc_waitq_t); if (waiter == NULL) { - gf_msg(ioc_inode->table->xl->name, GF_LOG_ERROR, ENOMEM, - IO_CACHE_MSG_NO_MEMORY, "out of memory"); + gf_smsg(ioc_inode->table->xl->name, GF_LOG_ERROR, ENOMEM, + IO_CACHE_MSG_NO_MEMORY, NULL); ret = -ENOMEM; goto out; } @@ -477,8 +519,8 @@ ioc_cache_validate(call_frame_t *frame, ioc_inode_t *ioc_inode, fd_t *fd, ret = -1; local->op_ret = -1; local->op_errno = ENOMEM; - gf_msg(ioc_inode->table->xl->name, GF_LOG_ERROR, 0, - IO_CACHE_MSG_NO_MEMORY, "out of memory"); + gf_smsg(ioc_inode->table->xl->name, GF_LOG_ERROR, 0, + IO_CACHE_MSG_NO_MEMORY, NULL); goto out; } @@ -488,17 +530,20 @@ ioc_cache_validate(call_frame_t *frame, ioc_inode_t *ioc_inode, fd_t *fd, local->op_ret = -1; local->op_errno = ENOMEM; mem_put(validate_local); - gf_msg(ioc_inode->table->xl->name, GF_LOG_ERROR, 0, - IO_CACHE_MSG_NO_MEMORY, "out of memory"); + gf_smsg(ioc_inode->table->xl->name, GF_LOG_ERROR, 0, + IO_CACHE_MSG_NO_MEMORY, NULL); goto out; } validate_local->fd = fd_ref(fd); validate_local->inode = ioc_inode; + if (local && local->xattr_req) + validate_local->xattr_req = dict_ref(local->xattr_req); validate_frame->local = validate_local; STACK_WIND(validate_frame, ioc_cache_validate_cbk, FIRST_CHILD(frame->this), - FIRST_CHILD(frame->this)->fops->fstat, fd, NULL); + FIRST_CHILD(frame->this)->fops->fstat, fd, + validate_local->xattr_req); out: return ret; @@ -568,9 +613,9 @@ ioc_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, // TODO: see why inode context is NULL and handle it. if (!ioc_inode) { - gf_msg(this->name, GF_LOG_ERROR, EINVAL, - IO_CACHE_MSG_ENFORCEMENT_FAILED, - "inode context is NULL (%s)", uuid_utoa(fd->inode->gfid)); + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, + IO_CACHE_MSG_ENFORCEMENT_FAILED, "inode-gfid=%s", + uuid_utoa(fd->inode->gfid), NULL); goto out; } @@ -662,9 +707,9 @@ ioc_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, (table->max_file_size < ioc_inode->ia_size))) { ret = fd_ctx_set(fd, this, 1); if (ret) - gf_msg(this->name, GF_LOG_WARNING, ENOMEM, - IO_CACHE_MSG_NO_MEMORY, "%s: failed to set fd ctx", - local->file_loc.path); + gf_smsg(this->name, GF_LOG_WARNING, ENOMEM, + IO_CACHE_MSG_SET_FD_FAILED, "path=%s", + local->file_loc.path, NULL); } } ioc_inode_unlock(ioc_inode); @@ -678,9 +723,9 @@ ioc_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, * as a whole */ ret = fd_ctx_set(fd, this, 1); if (ret) - gf_msg(this->name, GF_LOG_WARNING, ENOMEM, - IO_CACHE_MSG_NO_MEMORY, "%s: failed to set fd ctx", - local->file_loc.path); + gf_smsg(this->name, GF_LOG_WARNING, ENOMEM, + IO_CACHE_MSG_SET_FD_FAILED, "path=%s", + local->file_loc.path, NULL); } /* if weight == 0, we disable caching on it */ @@ -688,9 +733,9 @@ ioc_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, /* we allow a pattern-matched cache disable this way */ ret = fd_ctx_set(fd, this, 1); if (ret) - gf_msg(this->name, GF_LOG_WARNING, ENOMEM, - IO_CACHE_MSG_NO_MEMORY, "%s: failed to set fd ctx", - local->file_loc.path); + gf_smsg(this->name, GF_LOG_WARNING, ENOMEM, + IO_CACHE_MSG_SET_FD_FAILED, "path=%s", + local->file_loc.path, NULL); } } @@ -763,16 +808,14 @@ ioc_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, local = mem_get0(this->local_pool); if (local == NULL) { op_errno = ENOMEM; - gf_msg(this->name, GF_LOG_ERROR, 0, IO_CACHE_MSG_NO_MEMORY, - "out of memory"); + gf_smsg(this->name, GF_LOG_ERROR, 0, IO_CACHE_MSG_NO_MEMORY, NULL); goto unwind; } ret = loc_copy(&local->file_loc, loc); if (ret != 0) { op_errno = ENOMEM; - gf_msg(this->name, GF_LOG_ERROR, 0, IO_CACHE_MSG_NO_MEMORY, - "out of memory"); + gf_smsg(this->name, GF_LOG_ERROR, 0, IO_CACHE_MSG_NO_MEMORY, NULL); goto unwind; } @@ -810,8 +853,7 @@ ioc_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, local = mem_get0(this->local_pool); if (local == NULL) { - gf_msg(this->name, GF_LOG_ERROR, ENOMEM, IO_CACHE_MSG_NO_MEMORY, - "out of memory"); + gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, IO_CACHE_MSG_NO_MEMORY, NULL); STACK_UNWIND_STRICT(open, frame, -1, ENOMEM, NULL, NULL); return 0; } @@ -846,8 +888,7 @@ ioc_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, local = mem_get0(this->local_pool); if (local == NULL) { - gf_msg(this->name, GF_LOG_ERROR, ENOMEM, IO_CACHE_MSG_NO_MEMORY, - "out of memory"); + gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, IO_CACHE_MSG_NO_MEMORY, NULL); STACK_UNWIND_STRICT(create, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL, NULL); return 0; @@ -958,8 +999,8 @@ ioc_dispatch_requests(call_frame_t *frame, ioc_inode_t *ioc_inode, fd_t *fd, trav = __ioc_page_create(ioc_inode, trav_offset); fault = 1; if (!trav) { - gf_msg(frame->this->name, GF_LOG_CRITICAL, ENOMEM, - IO_CACHE_MSG_NO_MEMORY, "out of memory"); + gf_smsg(frame->this->name, GF_LOG_CRITICAL, ENOMEM, + IO_CACHE_MSG_NO_MEMORY, NULL); local->op_ret = -1; local->op_errno = ENOMEM; ioc_inode_unlock(ioc_inode); @@ -1095,8 +1136,8 @@ ioc_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, table = this->private; if (!table) { - gf_msg(this->name, GF_LOG_ERROR, EINVAL, - IO_CACHE_MSG_ENFORCEMENT_FAILED, "table is null"); + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, IO_CACHE_MSG_TABLE_NULL, + NULL); op_errno = EINVAL; goto out; } @@ -1127,8 +1168,7 @@ ioc_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, local = mem_get0(this->local_pool); if (local == NULL) { - gf_msg(this->name, GF_LOG_ERROR, ENOMEM, IO_CACHE_MSG_NO_MEMORY, - "out of memory"); + gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, IO_CACHE_MSG_NO_MEMORY, NULL); op_errno = ENOMEM; goto out; } @@ -1141,6 +1181,7 @@ ioc_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, local->offset = offset; local->size = size; local->inode = ioc_inode; + local->xattr_req = dict_ref(xdata); gf_msg_trace(this->name, 0, "NEW REQ (%p) offset " @@ -1183,13 +1224,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; } @@ -1214,8 +1264,7 @@ ioc_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, local = mem_get0(this->local_pool); if (local == NULL) { - gf_msg(this->name, GF_LOG_ERROR, ENOMEM, IO_CACHE_MSG_NO_MEMORY, - "out of memory"); + gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, IO_CACHE_MSG_NO_MEMORY, NULL); STACK_UNWIND_STRICT(writev, frame, -1, ENOMEM, NULL, NULL, NULL); return 0; @@ -1226,8 +1275,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, @@ -1342,9 +1395,6 @@ ioc_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, { ioc_inode_t *ioc_inode = NULL; uint64_t tmp_inode = 0; - struct timeval tv = { - 0, - }; inode_ctx_get(fd->inode, this, &tmp_inode); ioc_inode = (ioc_inode_t *)(long)tmp_inode; @@ -1355,10 +1405,9 @@ ioc_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, return 0; } - gettimeofday(&tv, NULL); ioc_inode_lock(ioc_inode); { - memcpy(&ioc_inode->cache.tv, &tv, sizeof(struct timeval)); + ioc_inode->cache.last_revalidate = gf_time(); } ioc_inode_unlock(ioc_inode); @@ -1563,8 +1612,8 @@ mem_acct_init(xlator_t *this) ret = xlator_mem_acct_init(this, gf_ioc_mt_end + 1); if (ret != 0) { - gf_msg(this->name, GF_LOG_ERROR, ENOMEM, IO_CACHE_MSG_NO_MEMORY, - "Memory accounting init failed"); + gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, + IO_CACHE_MSG_MEMORY_INIT_FAILED, NULL); return ret; } @@ -1583,9 +1632,8 @@ check_cache_size_ok(xlator_t *this, uint64_t cache_size) opt = xlator_volume_option_get(this, "cache-size"); if (!opt) { ret = _gf_false; - gf_msg(this->name, GF_LOG_ERROR, EINVAL, - IO_CACHE_MSG_ENFORCEMENT_FAILED, - "could not get cache-size option"); + gf_smsg(this->name, GF_LOG_ERROR, EINVAL, + IO_CACHE_MSG_NO_CACHE_SIZE_OPT, NULL); goto out; } @@ -1599,10 +1647,9 @@ check_cache_size_ok(xlator_t *this, uint64_t cache_size) if (cache_size > max_cache_size) { ret = _gf_false; - gf_msg(this->name, GF_LOG_ERROR, 0, IO_CACHE_MSG_INVALID_ARGUMENT, - "Cache size %" PRIu64 - " is greater than the max size of %" PRIu64, - cache_size, max_cache_size); + gf_smsg(this->name, GF_LOG_ERROR, 0, IO_CACHE_MSG_INVALID_ARGUMENT, + "Cache-size=%" PRIu64, cache_size, "max-size=%" PRIu64, + max_cache_size, NULL); goto out; } out: @@ -1652,13 +1699,9 @@ reconfigure(xlator_t *this, dict_t *options) if ((table->max_file_size <= UINT64_MAX) && (table->min_file_size > table->max_file_size)) { - gf_msg(this->name, GF_LOG_ERROR, 0, IO_CACHE_MSG_INVALID_ARGUMENT, - "minimum size (%" PRIu64 - ") of a file that can be cached is " - "greater than maximum size (%" PRIu64 - "). " - "Hence Defaulting to old value", - table->min_file_size, table->max_file_size); + gf_smsg(this->name, GF_LOG_ERROR, 0, IO_CACHE_MSG_DEFAULTING_TO_OLD, + "minimum-size=%" PRIu64, table->min_file_size, + "maximum-size=%" PRIu64, table->max_file_size, NULL); goto unlock; } @@ -1666,8 +1709,8 @@ reconfigure(xlator_t *this, dict_t *options) unlock); if (!check_cache_size_ok(this, cache_size_new)) { ret = -1; - gf_msg(this->name, GF_LOG_ERROR, 0, IO_CACHE_MSG_INVALID_ARGUMENT, - "Not reconfiguring cache-size"); + gf_smsg(this->name, GF_LOG_ERROR, 0, + IO_CACHE_MSG_NOT_RECONFIG_CACHE_SIZE, NULL); goto unlock; } table->cache_size = cache_size_new; @@ -1699,22 +1742,19 @@ init(xlator_t *this) xl_options = this->options; if (!this->children || this->children->next) { - gf_msg(this->name, GF_LOG_ERROR, 0, - IO_CACHE_MSG_XLATOR_CHILD_MISCONFIGURED, - "FATAL: io-cache not configured with exactly " - "one child"); + gf_smsg(this->name, GF_LOG_ERROR, 0, + IO_CACHE_MSG_XLATOR_CHILD_MISCONFIGURED, NULL); goto out; } if (!this->parents) { - gf_msg(this->name, GF_LOG_WARNING, 0, IO_CACHE_MSG_VOL_MISCONFIGURED, - "dangling volume. check volfile "); + gf_smsg(this->name, GF_LOG_WARNING, 0, IO_CACHE_MSG_VOL_MISCONFIGURED, + NULL); } table = (void *)GF_CALLOC(1, sizeof(*table), gf_ioc_mt_ioc_table_t); if (table == NULL) { - gf_msg(this->name, GF_LOG_ERROR, ENOMEM, IO_CACHE_MSG_NO_MEMORY, - "out of memory"); + gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, IO_CACHE_MSG_NO_MEMORY, NULL); goto out; } @@ -1756,11 +1796,9 @@ init(xlator_t *this) if ((table->max_file_size <= UINT64_MAX) && (table->min_file_size > table->max_file_size)) { - gf_msg("io-cache", GF_LOG_ERROR, 0, IO_CACHE_MSG_INVALID_ARGUMENT, - "minimum size (%" PRIu64 - ") of a file that can be cached is " - "greater than maximum size (%" PRIu64 ")", - table->min_file_size, table->max_file_size); + gf_smsg("io-cache", GF_LOG_ERROR, 0, IO_CACHE_MSG_INVALID_ARGUMENT, + "minimum-size=%" PRIu64, table->min_file_size, + "maximum-size=%" PRIu64, table->max_file_size, NULL); goto out; } @@ -1776,8 +1814,8 @@ init(xlator_t *this) this->local_pool = mem_pool_new(ioc_local_t, 64); if (!this->local_pool) { ret = -1; - gf_msg(this->name, GF_LOG_ERROR, ENOMEM, IO_CACHE_MSG_NO_MEMORY, - "failed to create local_t's memory pool"); + gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, + IO_CACHE_MSG_CREATE_MEM_POOL_FAILED, NULL); goto out; } @@ -1789,8 +1827,8 @@ init(xlator_t *this) table->mem_pool = mem_pool_new(rbthash_entry_t, num_pages); if (!table->mem_pool) { - gf_msg(this->name, GF_LOG_ERROR, ENOMEM, IO_CACHE_MSG_NO_MEMORY, - "Unable to allocate mem_pool"); + gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, + IO_CACHE_MSG_ALLOC_MEM_POOL_FAILED, NULL); goto out; } @@ -1893,7 +1931,7 @@ __ioc_cache_dump(ioc_inode_t *ioc_inode, char *prefix) char key[GF_DUMP_MAX_BUF_LEN] = { 0, }; - char timestr[256] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; @@ -1903,11 +1941,9 @@ __ioc_cache_dump(ioc_inode_t *ioc_inode, char *prefix) table = ioc_inode->table; - if (ioc_inode->cache.tv.tv_sec) { - gf_time_fmt(timestr, sizeof timestr, ioc_inode->cache.tv.tv_sec, + if (ioc_inode->cache.last_revalidate) { + gf_time_fmt(timestr, sizeof timestr, ioc_inode->cache.last_revalidate, gf_timefmt_FT); - snprintf(timestr + strlen(timestr), sizeof timestr - strlen(timestr), - ".%" GF_PRI_SUSECONDS, ioc_inode->cache.tv.tv_usec); gf_proc_dump_write("last-cache-validation-time", "%s", timestr); } @@ -2016,9 +2052,9 @@ ioc_priv_dump(xlator_t *this) if (ret) goto out; { - gf_proc_dump_write("page_size", "%ld", priv->page_size); - gf_proc_dump_write("cache_size", "%ld", priv->cache_size); - gf_proc_dump_write("cache_used", "%ld", priv->cache_used); + gf_proc_dump_write("page_size", "%" PRIu64, priv->page_size); + gf_proc_dump_write("cache_size", "%" PRIu64, priv->cache_size); + gf_proc_dump_write("cache_used", "%" PRIu64, priv->cache_used); gf_proc_dump_write("inode_count", "%u", priv->inode_count); gf_proc_dump_write("cache_timeout", "%u", priv->cache_timeout); gf_proc_dump_write("min-file-size", "%" PRIu64, priv->min_file_size); @@ -2121,6 +2157,14 @@ struct xlator_cbks cbks = { }; struct volume_options options[] = { + { + .key = {"io-cache"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", + .description = "enable/disable io-cache", + .op_version = {GD_OP_VERSION_6_0}, + .flags = OPT_FLAG_SETTABLE, + }, {.key = {"priority"}, .type = GF_OPTION_TYPE_PRIORITY_LIST, .default_value = "", @@ -2171,3 +2215,17 @@ struct volume_options options[] = { .description = "Enable/Disable io cache translator"}, {.key = {NULL}}, }; + +xlator_api_t xlator_api = { + .init = init, + .fini = fini, + .reconfigure = reconfigure, + .mem_acct_init = mem_acct_init, + .op_version = {1}, /* Present from the initial version */ + .dumpops = &dumpops, + .fops = &fops, + .cbks = &cbks, + .options = options, + .identifier = "io-cache", + .category = GF_MAINTAINED, +}; diff --git a/xlators/performance/io-cache/src/io-cache.h b/xlators/performance/io-cache/src/io-cache.h index cc66fcea714..14923c75edc 100644 --- a/xlators/performance/io-cache/src/io-cache.h +++ b/xlators/performance/io-cache/src/io-cache.h @@ -12,16 +12,12 @@ #define __IO_CACHE_H #include <sys/types.h> -#include "compat-errno.h" - -#include "glusterfs.h" -#include "logging.h" -#include "dict.h" -#include "xlator.h" -#include "common-utils.h" -#include "call-stub.h" -#include "rbthash.h" -#include "hashfn.h" +#include <glusterfs/compat-errno.h> + +#include <glusterfs/glusterfs.h> +#include <glusterfs/dict.h> +#include <glusterfs/call-stub.h> +#include <glusterfs/rbthash.h> #include <sys/time.h> #include <fnmatch.h> #include "io-cache-messages.h" @@ -91,6 +87,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; }; @@ -119,15 +117,13 @@ struct ioc_page { struct ioc_cache { rbthash_table_t *page_table; struct list_head page_lru; - time_t mtime; /* - * seconds component of file mtime - */ - time_t mtime_nsec; /* - * nanosecond component of file mtime - */ - struct timeval tv; /* - * time-stamp at last re-validate - */ + time_t mtime; /* + * seconds component of file mtime + */ + time_t mtime_nsec; /* + * nanosecond component of file mtime + */ + time_t last_revalidate; /* timestamp at last re-validate */ }; struct ioc_inode { @@ -272,17 +268,6 @@ ioc_frame_fill(ioc_page_t *page, call_frame_t *frame, off_t offset, size_t size, pthread_mutex_unlock(&page->page_lock); \ } while (0) -static inline uint64_t -time_elapsed(struct timeval *now, struct timeval *then) -{ - uint64_t sec = now->tv_sec - then->tv_sec; - - if (sec) - return sec; - - return 0; -} - ioc_inode_t * ioc_inode_search(ioc_table_t *table, inode_t *inode); diff --git a/xlators/performance/io-cache/src/ioc-inode.c b/xlators/performance/io-cache/src/ioc-inode.c index a26e6d35adb..97767d85285 100644 --- a/xlators/performance/io-cache/src/ioc-inode.c +++ b/xlators/performance/io-cache/src/ioc-inode.c @@ -46,8 +46,8 @@ ptr_to_str(void *ptr) ret = gf_asprintf(&str, "%p", ptr); if (-1 == ret) { - gf_msg("io-cache", GF_LOG_WARNING, 0, IO_CACHE_MSG_STR_COVERSION_FAILED, - "asprintf failed while converting ptr to str"); + gf_smsg("io-cache", GF_LOG_WARNING, 0, + IO_CACHE_MSG_STR_COVERSION_FAILED, NULL); str = NULL; goto out; } @@ -75,8 +75,8 @@ ioc_inode_wakeup(call_frame_t *frame, ioc_inode_t *ioc_inode, if (ioc_inode == NULL) { local->op_ret = -1; local->op_errno = EINVAL; - gf_msg(frame->this->name, GF_LOG_WARNING, 0, IO_CACHE_MSG_INODE_NULL, - "ioc_inode is NULL"); + gf_smsg(frame->this->name, GF_LOG_WARNING, 0, IO_CACHE_MSG_INODE_NULL, + NULL); goto out; } @@ -89,10 +89,8 @@ ioc_inode_wakeup(call_frame_t *frame, ioc_inode_t *ioc_inode, { waiter = ioc_inode->waitq; if (!waiter) { - gf_msg(frame->this->name, GF_LOG_WARNING, 0, - IO_CACHE_MSG_PAGE_WAIT_VALIDATE, - "cache validate called without any " - "page waiting to be validated"); + gf_smsg(frame->this->name, GF_LOG_WARNING, 0, + IO_CACHE_MSG_PAGE_WAIT_VALIDATE, NULL); ioc_inode_unlock(ioc_inode); goto out; diff --git a/xlators/performance/io-cache/src/ioc-mem-types.h b/xlators/performance/io-cache/src/ioc-mem-types.h index 3271840bb43..20c9a12021e 100644 --- a/xlators/performance/io-cache/src/ioc-mem-types.h +++ b/xlators/performance/io-cache/src/ioc-mem-types.h @@ -11,7 +11,7 @@ #ifndef __IOC_MT_H__ #define __IOC_MT_H__ -#include "mem-types.h" +#include <glusterfs/mem-types.h> enum gf_ioc_mem_types_ { gf_ioc_mt_iovec = gf_common_mt_end + 1, diff --git a/xlators/performance/io-cache/src/page.c b/xlators/performance/io-cache/src/page.c index d2cbe2499a4..84b1ae6cb20 100644 --- a/xlators/performance/io-cache/src/page.c +++ b/xlators/performance/io-cache/src/page.c @@ -8,10 +8,10 @@ cases as published by the Free Software Foundation. */ -#include "glusterfs.h" -#include "logging.h" -#include "dict.h" -#include "xlator.h" +#include <glusterfs/glusterfs.h> +#include <glusterfs/logging.h> +#include <glusterfs/dict.h> +#include <glusterfs/xlator.h> #include "io-cache.h" #include "ioc-mem-types.h" #include <assert.h> @@ -307,8 +307,8 @@ __ioc_wait_on_page(ioc_page_t *page, call_frame_t *frame, off_t offset, if (page == NULL) { local->op_ret = -1; local->op_errno = ENOMEM; - gf_msg(frame->this->name, GF_LOG_WARNING, 0, IO_CACHE_MSG_NO_MEMORY, - "asked to wait on a NULL page"); + gf_smsg(frame->this->name, GF_LOG_WARNING, 0, + IO_CACHE_MSG_NULL_PAGE_WAIT, NULL); goto out; } @@ -413,9 +413,6 @@ ioc_fault_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, ioc_waitq_t *waitq = NULL; size_t iobref_page_size = 0; char zero_filled = 0; - struct timeval tv = { - 0, - }; GF_ASSERT(frame); @@ -431,7 +428,6 @@ ioc_fault_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, zero_filled = ((op_ret >= 0) && (stbuf->ia_mtime == 0)); - gettimeofday(&tv, NULL); ioc_inode_lock(ioc_inode); { if (op_ret == -1 || @@ -448,7 +444,7 @@ ioc_fault_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, ioc_inode->cache.mtime_nsec = stbuf->ia_mtime_nsec; } - memcpy(&ioc_inode->cache.tv, &tv, sizeof(struct timeval)); + ioc_inode->cache.last_revalidate = gf_time(); if (op_ret < 0) { /* error, readv returned -1 */ @@ -461,12 +457,10 @@ ioc_fault_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, if (!page) { /* page was flushed */ /* some serious bug ? */ - gf_msg(frame->this->name, GF_LOG_WARNING, 0, - IO_CACHE_MSG_WASTED_COPY, - "wasted copy: %" PRId64 "[+%" PRId64 - "] " - "ioc_inode=%p", - offset, table->page_size, ioc_inode); + gf_smsg(frame->this->name, GF_LOG_WARNING, 0, + IO_CACHE_MSG_WASTED_COPY, "offset=%" PRId64, offset, + "page-size=%" PRId64, table->page_size, "ioc_inode=%p", + ioc_inode, NULL); } else { if (page->vector) { iobref_unref(page->iobref); @@ -490,9 +484,8 @@ ioc_fault_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, } else { /* TODO: we have got a response to * our request and no data */ - gf_msg(frame->this->name, GF_LOG_CRITICAL, ENOMEM, - IO_CACHE_MSG_NO_MEMORY, - "frame>root>rsp_refs is null"); + gf_smsg(frame->this->name, GF_LOG_CRITICAL, ENOMEM, + IO_CACHE_MSG_FRAME_NULL, NULL); } /* if(frame->root->rsp_refs) */ /* page->size should indicate exactly how @@ -546,6 +539,8 @@ unlock: pthread_mutex_destroy(&local->local_lock); fd_unref(local->fd); + if (local->xattr_req) + dict_unref(local->xattr_req); STACK_DESTROY(frame->root); return 0; @@ -567,6 +562,7 @@ ioc_page_fault(ioc_inode_t *ioc_inode, call_frame_t *frame, fd_t *fd, ioc_table_t *table = NULL; call_frame_t *fault_frame = NULL; ioc_local_t *fault_local = NULL; + ioc_local_t *local = NULL; int32_t op_ret = -1, op_errno = -1; ioc_waitq_t *waitq = NULL; ioc_page_t *page = NULL; @@ -575,8 +571,8 @@ ioc_page_fault(ioc_inode_t *ioc_inode, call_frame_t *frame, fd_t *fd, if (frame == NULL) { op_ret = -1; op_errno = EINVAL; - gf_msg("io-cache", GF_LOG_WARNING, EINVAL, - IO_CACHE_MSG_ENFORCEMENT_FAILED, "page fault on a NULL frame"); + gf_smsg("io-cache", GF_LOG_WARNING, EINVAL, IO_CACHE_MSG_PAGE_FAULT, + NULL); goto err; } @@ -588,6 +584,7 @@ ioc_page_fault(ioc_inode_t *ioc_inode, call_frame_t *frame, fd_t *fd, goto err; } + local = frame->local; fault_local = mem_get0(THIS->local_pool); if (fault_local == NULL) { op_ret = -1; @@ -609,6 +606,9 @@ ioc_page_fault(ioc_inode_t *ioc_inode, call_frame_t *frame, fd_t *fd, fault_local->pending_size = table->page_size; fault_local->inode = ioc_inode; + if (local && local->xattr_req) + fault_local->xattr_req = dict_ref(local->xattr_req); + gf_msg_trace(frame->this->name, 0, "stack winding page fault for offset = %" PRId64 " with " @@ -617,7 +617,7 @@ ioc_page_fault(ioc_inode_t *ioc_inode, call_frame_t *frame, fd_t *fd, STACK_WIND(fault_frame, ioc_fault_cbk, FIRST_CHILD(fault_frame->this), FIRST_CHILD(fault_frame->this)->fops->readv, fd, - table->page_size, offset, 0, NULL); + table->page_size, offset, 0, fault_local->xattr_req); return; err: @@ -655,9 +655,8 @@ __ioc_frame_fill(ioc_page_t *page, call_frame_t *frame, off_t offset, GF_VALIDATE_OR_GOTO(frame->this->name, local, out); if (page == NULL) { - gf_msg(frame->this->name, GF_LOG_WARNING, 0, - IO_CACHE_MSG_ENFORCEMENT_FAILED, - "NULL page has been provided to serve read request"); + gf_smsg(frame->this->name, GF_LOG_WARNING, 0, + IO_CACHE_MSG_SERVE_READ_REQUEST, NULL); local->op_ret = -1; local->op_errno = EINVAL; goto out; @@ -720,11 +719,8 @@ __ioc_frame_fill(ioc_page_t *page, call_frame_t *frame, off_t offset, new->size = copy_size; new->iobref = iobref_ref(page->iobref); new->count = iov_subset(page->vector, page->count, src_offset, - src_offset + copy_size, NULL); - - new->vector = GF_CALLOC(new->count, sizeof(struct iovec), - gf_ioc_mt_iovec); - if (new->vector == NULL) { + copy_size, &new->vector, 0); + if (new->count < 0) { local->op_ret = -1; local->op_errno = ENOMEM; @@ -733,9 +729,6 @@ __ioc_frame_fill(ioc_page_t *page, call_frame_t *frame, off_t offset, goto out; } - new->count = iov_subset(page->vector, page->count, src_offset, - src_offset + copy_size, new->vector); - /* add the ioc_fill to fill_list for this frame */ if (list_empty(&local->fill_list)) { /* if list is empty, then this is the first @@ -798,8 +791,8 @@ ioc_frame_unwind(call_frame_t *frame) local = frame->local; if (local == NULL) { - gf_msg(frame->this->name, GF_LOG_WARNING, ENOMEM, - IO_CACHE_MSG_NO_MEMORY, "local is NULL"); + gf_smsg(frame->this->name, GF_LOG_WARNING, ENOMEM, + IO_CACHE_MSG_LOCAL_NULL, NULL); op_ret = -1; op_errno = ENOMEM; goto unwind; @@ -878,6 +871,8 @@ unwind: } if (local) { + if (local->xattr_req) + dict_unref(local->xattr_req); pthread_mutex_destroy(&local->local_lock); mem_put(local); } |
