summaryrefslogtreecommitdiffstats
path: root/xlators/performance/io-cache
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/performance/io-cache')
-rw-r--r--xlators/performance/io-cache/src/io-cache-messages.h41
-rw-r--r--xlators/performance/io-cache/src/io-cache.c292
-rw-r--r--xlators/performance/io-cache/src/io-cache.h45
-rw-r--r--xlators/performance/io-cache/src/ioc-inode.c14
-rw-r--r--xlators/performance/io-cache/src/ioc-mem-types.h2
-rw-r--r--xlators/performance/io-cache/src/page.c67
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);
}