diff options
| -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;  | 
