diff options
Diffstat (limited to 'xlators/performance')
-rw-r--r-- | xlators/performance/quick-read/src/quick-read.c | 275 | ||||
-rw-r--r-- | xlators/performance/quick-read/src/quick-read.h | 2 |
2 files changed, 233 insertions, 44 deletions
diff --git a/xlators/performance/quick-read/src/quick-read.c b/xlators/performance/quick-read/src/quick-read.c index d26742b0c5e..628c09fedb9 100644 --- a/xlators/performance/quick-read/src/quick-read.c +++ b/xlators/performance/quick-read/src/quick-read.c @@ -13,6 +13,56 @@ #include "statedump.h" #include "quick-read-messages.h" #include "upcall-utils.h" +#include "atomic.h" + +typedef struct qr_local { + inode_t *inode; + uint64_t incident_gen; + fd_t *fd; +} qr_local_t; + +void +qr_local_wipe (qr_local_t *local) +{ + if (!local) + goto out; + + if (local->inode) + inode_unref (local->inode); + + if (local->fd) + fd_unref (local->fd); + + GF_FREE (local); +out: + return; +} + +qr_local_t * +qr_local_get (xlator_t *this) +{ + qr_local_t *local = NULL; + qr_private_t *priv = this->private; + + local = GF_CALLOC (1, sizeof (*local), gf_common_mt_char); + if (!local) + goto out; + + local->incident_gen = GF_ATOMIC_INC (priv->generation); +out: + return local; +} + +#define QR_STACK_UNWIND(fop, frame, params ...) do { \ + qr_local_t *__local = NULL; \ + if (frame) { \ + __local = frame->local; \ + frame->local = NULL; \ + } \ + STACK_UNWIND_STRICT (fop, frame, params); \ + qr_local_wipe (__local); \ + } while (0) + qr_inode_t *qr_inode_ctx_get (xlator_t *this, inode_t *inode); @@ -103,7 +153,7 @@ qr_inode_ctx_get_or_new (xlator_t *this, inode_t *inode) ret = __qr_inode_ctx_set (this, inode, qr_inode); if (ret) { - __qr_inode_prune (this, &priv->table, qr_inode, ~0); + __qr_inode_prune (this, &priv->table, qr_inode, 0); GF_FREE (qr_inode); qr_inode = NULL; } @@ -192,7 +242,6 @@ qr_inode_set_priority (xlator_t *this, inode_t *inode, const char *path) /* To be called with priv->table.lock held */ void - __qr_inode_prune (xlator_t *this, qr_inode_table_t *table, qr_inode_t *qr_inode, uint64_t gen) { @@ -204,8 +253,7 @@ __qr_inode_prune (xlator_t *this, qr_inode_table_t *table, qr_inode_t *qr_inode, qr_inode->data = NULL; /* Set gen only with valid callers */ - if (gen != ~0) - qr_inode->gen = gen; + qr_inode->gen = gen; if (!list_empty (&qr_inode->lru)) { table->cache_used -= qr_inode->size; @@ -217,6 +265,7 @@ __qr_inode_prune (xlator_t *this, qr_inode_table_t *table, qr_inode_t *qr_inode, } memset (&qr_inode->buf, 0, sizeof (qr_inode->buf)); + qr_inode->invalidation_time = GF_ATOMIC_INC (priv->generation); } @@ -250,13 +299,17 @@ __qr_cache_prune (xlator_t *this, qr_inode_table_t *table, qr_conf_t *conf) qr_inode_t *next = NULL; int index = 0; size_t size_pruned = 0; + qr_private_t *priv = NULL; + + priv = this->private; for (index = 0; index < conf->max_pri; index++) { list_for_each_entry_safe (curr, next, &table->lru[index], lru) { size_pruned += curr->size; - __qr_inode_prune (this, table, curr, ~0); + __qr_inode_prune (this, table, curr, + GF_ATOMIC_INC (priv->generation)); if (table->cache_used < conf->cache_size) return; @@ -326,10 +379,14 @@ qr_content_update (xlator_t *this, qr_inode_t *qr_inode, void *data, if (gen && qr_inode->gen && (qr_inode->gen >= gen)) goto unlock; - qr_inode->gen = gen; + if ((qr_inode->data == NULL) && + (qr_inode->invalidation_time >= gen)) + goto unlock; + __qr_inode_prune (this, table, qr_inode, gen); qr_inode->data = data; + data = NULL; qr_inode->size = buf->ia_size; qr_inode->ia_mtime = buf->ia_mtime; @@ -346,6 +403,9 @@ qr_content_update (xlator_t *this, qr_inode_t *qr_inode, void *data, unlock: UNLOCK (&table->lock); + if (data) + GF_FREE (data); + qr_cache_prune (this); } @@ -399,6 +459,9 @@ __qr_content_refresh (xlator_t *this, qr_inode_t *qr_inode, struct iatt *buf, if (gen && qr_inode->gen && (qr_inode->gen >= gen)) goto done; + if ((qr_inode->data == NULL) && (qr_inode->invalidation_time >= gen)) + goto done; + qr_inode->gen = gen; if (qr_size_fits (conf, buf) && qr_time_equal (conf, qr_inode, buf)) { @@ -467,22 +530,23 @@ qr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, void *content = NULL; qr_inode_t *qr_inode = NULL; inode_t *inode = NULL; + qr_local_t *local = NULL; - inode = frame->local; - frame->local = NULL; + local = frame->local; + inode = local->inode; if (op_ret == -1) { - qr_inode_prune (this, inode, ~0); + qr_inode_prune (this, inode, local->incident_gen); goto out; } if (dict_get (xdata, GLUSTERFS_BAD_INODE)) { - qr_inode_prune (this, inode, frame->root->unique); + qr_inode_prune (this, inode, local->incident_gen); goto out; } if (dict_get (xdata, "sh-failed")) { - qr_inode_prune (this, inode, frame->root->unique); + qr_inode_prune (this, inode, local->incident_gen); goto out; } @@ -496,8 +560,9 @@ qr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, GF_FREE (content); goto out; } + qr_content_update (this, qr_inode, content, buf, - frame->root->unique); + local->incident_gen); } else { /* purge old content if necessary */ qr_inode = qr_inode_ctx_get (this, inode); @@ -505,14 +570,11 @@ qr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, /* usual path for large files */ goto out; - qr_content_refresh (this, qr_inode, buf, frame->root->unique); + qr_content_refresh (this, qr_inode, buf, local->incident_gen); } out: - if (inode) - inode_unref (inode); - - STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode_ret, - buf, xdata, postparent); + QR_STACK_UNWIND (lookup, frame, op_ret, op_errno, inode_ret, + buf, xdata, postparent); return 0; } @@ -520,14 +582,18 @@ out: int qr_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { - qr_private_t *priv = NULL; - qr_conf_t *conf = NULL; - qr_inode_t *qr_inode = NULL; - int ret = -1; - dict_t *new_xdata = NULL; + qr_private_t *priv = NULL; + qr_conf_t *conf = NULL; + qr_inode_t *qr_inode = NULL; + int ret = -1; + dict_t *new_xdata = NULL; + qr_local_t *local = NULL; priv = this->private; conf = &priv->conf; + local = qr_local_get (this); + local->inode = inode_ref (loc->inode); + frame->local = local; qr_inode = qr_inode_ctx_get (this, loc->inode); if (qr_inode && qr_inode->data) @@ -550,8 +616,6 @@ qr_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) "cannot set key in request dict (%s)", loc->path); wind: - frame->local = inode_ref (loc->inode); - STACK_WIND (frame, qr_lookup_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, loc, xdata); @@ -566,8 +630,11 @@ int qr_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, gf_dirent_t *entries, dict_t *xdata) { - gf_dirent_t *entry = NULL; - qr_inode_t *qr_inode = NULL; + gf_dirent_t *entry = NULL; + qr_inode_t *qr_inode = NULL; + qr_local_t *local = NULL; + + local = frame->local; if (op_ret <= 0) goto unwind; @@ -582,11 +649,11 @@ qr_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, continue; qr_content_refresh (this, qr_inode, &entry->d_stat, - frame->root->unique); + local->incident_gen); } unwind: - STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata); + QR_STACK_UNWIND (readdirp, frame, op_ret, op_errno, entries, xdata); return 0; } @@ -595,6 +662,11 @@ int qr_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset, dict_t *xdata) { + qr_local_t *local = NULL; + + local = qr_local_get (this); + frame->local = local; + STACK_WIND (frame, qr_readdirp_cbk, FIRST_CHILD (this), FIRST_CHILD (this)->fops->readdirp, fd, size, offset, xdata); @@ -698,77 +770,191 @@ wind: return 0; } +int32_t +qr_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *prebuf, + struct iatt *postbuf, dict_t *xdata) +{ + qr_local_t *local = NULL; + + local = frame->local; + + qr_inode_prune (this, local->fd->inode, local->incident_gen); + + QR_STACK_UNWIND (writev, frame, op_ret, op_errno, + prebuf, postbuf, xdata); + return 0; +} int qr_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *iov, int count, off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata) { - qr_inode_prune (this, fd->inode, frame->root->unique); + qr_local_t *local = NULL; - STACK_WIND (frame, default_writev_cbk, + local = qr_local_get (this); + local->fd = fd_ref (fd); + + frame->local = local; + + STACK_WIND (frame, qr_writev_cbk, FIRST_CHILD (this), FIRST_CHILD (this)->fops->writev, fd, iov, count, offset, flags, iobref, xdata); return 0; } +int32_t +qr_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *prebuf, + struct iatt *postbuf, dict_t *xdata) +{ + qr_local_t *local = NULL; + + local = frame->local; + qr_inode_prune (this, local->inode, local->incident_gen); + + QR_STACK_UNWIND (truncate, frame, op_ret, op_errno, + prebuf, postbuf, xdata); + return 0; +} + int qr_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata) { - qr_inode_prune (this, loc->inode, frame->root->unique); + qr_local_t *local = NULL; - STACK_WIND (frame, default_truncate_cbk, + local = qr_local_get (this); + local->inode = inode_ref (loc->inode); + frame->local = local; + + STACK_WIND (frame, qr_truncate_cbk, FIRST_CHILD (this), FIRST_CHILD (this)->fops->truncate, loc, offset, xdata); return 0; } +int32_t +qr_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *prebuf, + struct iatt *postbuf, dict_t *xdata) +{ + qr_local_t *local = NULL; + + local = frame->local; + qr_inode_prune (this, local->fd->inode, local->incident_gen); + + QR_STACK_UNWIND (ftruncate, frame, op_ret, op_errno, + prebuf, postbuf, xdata); + return 0; +} int qr_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata) { - qr_inode_prune (this, fd->inode, frame->root->unique); + qr_local_t *local = NULL; - STACK_WIND (frame, default_ftruncate_cbk, + local = qr_local_get (this); + local->fd = fd_ref (fd); + frame->local = local; + + STACK_WIND (frame, qr_ftruncate_cbk, FIRST_CHILD (this), FIRST_CHILD (this)->fops->ftruncate, fd, offset, xdata); return 0; } +int32_t +qr_fallocate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *pre, + struct iatt *post, dict_t *xdata) +{ + qr_local_t *local = NULL; + + local = frame->local; + qr_inode_prune (this, local->fd->inode, local->incident_gen); + + QR_STACK_UNWIND (fallocate, frame, op_ret, op_errno, + pre, post, xdata); + return 0; +} + static int qr_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd, int keep_size, off_t offset, size_t len, dict_t *xdata) { - qr_inode_prune (this, fd->inode, frame->root->unique); + qr_local_t *local = NULL; - STACK_WIND (frame, default_fallocate_cbk, + local = qr_local_get (this); + local->fd = fd_ref (fd); + frame->local = local; + + STACK_WIND (frame, qr_fallocate_cbk, FIRST_CHILD (this), FIRST_CHILD (this)->fops->fallocate, fd, keep_size, offset, len, xdata); return 0; } +int32_t +qr_discard_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *pre, + struct iatt *post, dict_t *xdata) +{ + qr_local_t *local = NULL; + + local = frame->local; + qr_inode_prune (this, local->fd->inode, local->incident_gen); + + QR_STACK_UNWIND (discard, frame, op_ret, op_errno, + pre, post, xdata); + return 0; +} + static int qr_discard (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, size_t len, dict_t *xdata) { - qr_inode_prune (this, fd->inode, frame->root->unique); + qr_local_t *local = NULL; - STACK_WIND (frame, default_discard_cbk, + local = qr_local_get (this); + local->fd = fd_ref (fd); + frame->local = local; + + STACK_WIND (frame, qr_discard_cbk, FIRST_CHILD (this), FIRST_CHILD (this)->fops->discard, fd, offset, len, xdata); return 0; } +int32_t +qr_zerofill_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *pre, + struct iatt *post, dict_t *xdata) +{ + qr_local_t *local = NULL; + + local = frame->local; + qr_inode_prune (this, local->fd->inode, local->incident_gen); + + QR_STACK_UNWIND (zerofill, frame, op_ret, op_errno, + pre, post, xdata); + return 0; +} + static int qr_zerofill (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, off_t len, dict_t *xdata) { - qr_inode_prune (this, fd->inode, frame->root->unique); + qr_local_t *local = NULL; - STACK_WIND (frame, default_zerofill_cbk, + local = qr_local_get (this); + local->fd = fd_ref (fd); + frame->local = local; + + STACK_WIND (frame, qr_zerofill_cbk, FIRST_CHILD (this), FIRST_CHILD (this)->fops->zerofill, fd, offset, len, xdata); return 0; @@ -790,13 +976,14 @@ int qr_forget (xlator_t *this, inode_t *inode) { qr_inode_t *qr_inode = NULL; + qr_private_t *priv = this->private; qr_inode = qr_inode_ctx_get (this, inode); if (!qr_inode) return 0; - qr_inode_prune (this, inode, ~0); + qr_inode_prune (this, inode, GF_ATOMIC_INC (priv->generation)); GF_FREE (qr_inode); @@ -1193,7 +1380,7 @@ qr_init (xlator_t *this) ret = 0; time (&priv->last_child_down); - + GF_ATOMIC_INIT (priv->generation, 0); this->private = priv; out: if ((ret == -1) && priv) { @@ -1285,7 +1472,7 @@ qr_invalidate (xlator_t *this, void *data) ret = -1; goto out; } - qr_inode_prune (this, inode, ~0); + qr_inode_prune (this, inode, GF_ATOMIC_INC (priv->generation)); } out: diff --git a/xlators/performance/quick-read/src/quick-read.h b/xlators/performance/quick-read/src/quick-read.h index 8ef0f9802b8..20f7307a9a7 100644 --- a/xlators/performance/quick-read/src/quick-read.h +++ b/xlators/performance/quick-read/src/quick-read.h @@ -42,6 +42,7 @@ struct qr_inode { struct timeval last_refresh; struct list_head lru; uint64_t gen; + uint64_t invalidation_time; }; typedef struct qr_inode qr_inode_t; @@ -84,6 +85,7 @@ struct qr_private { time_t last_child_down; gf_lock_t lock; struct qr_statistics qr_counter; + gf_atomic_t generation; }; typedef struct qr_private qr_private_t; |