diff options
Diffstat (limited to 'xlators/cluster/afr/src')
| -rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 31 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-lk-common.c | 193 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-transaction.c | 8 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr.h | 8 | 
4 files changed, 182 insertions, 58 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 9803744a0ec..caf72459336 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -763,6 +763,7 @@ afr_local_transaction_cleanup (afr_local_t *local, xlator_t *this)          GF_FREE (local->transaction.child_errno);          GF_FREE (local->child_errno); +        GF_FREE (local->transaction.eager_lock);          GF_FREE (local->transaction.basename);          GF_FREE (local->transaction.new_basename); @@ -2020,6 +2021,22 @@ afr_fd_ctx_set (xlator_t *this, fd_t *fd)                          goto unlock;                  } +                fd_ctx->lock_piggyback = GF_CALLOC (sizeof (*fd_ctx->lock_piggyback), +                                                    priv->child_count, +                                                    gf_afr_mt_char); +                if (!fd_ctx->lock_piggyback) { +                        ret = -ENOMEM; +                        goto unlock; +                } + +                fd_ctx->lock_acquired = GF_CALLOC (sizeof (*fd_ctx->lock_acquired), +                                                    priv->child_count, +                                                    gf_afr_mt_char); +                if (!fd_ctx->lock_acquired) { +                        ret = -ENOMEM; +                        goto unlock; +                } +                  fd_ctx->up_count   = priv->up_count;                  fd_ctx->down_count = priv->down_count; @@ -2274,6 +2291,12 @@ afr_cleanup_fd_ctx (xlator_t *this, fd_t *fd)                          GF_FREE (paused_call);                  } +                if (fd_ctx->lock_piggyback) +                        GF_FREE (fd_ctx->lock_piggyback); + +                if (fd_ctx->lock_acquired) +                        GF_FREE (fd_ctx->lock_acquired); +                  GF_FREE (fd_ctx);          } @@ -3593,6 +3616,14 @@ afr_transaction_local_init (afr_local_t *local, xlator_t *this)          if (!local->child_errno)                  goto out; +        local->transaction.eager_lock = +                GF_CALLOC (sizeof (*local->transaction.eager_lock), +                           priv->child_count, +                           gf_afr_mt_int32_t); + +        if (!local->transaction.eager_lock) +                goto out; +          local->pending = GF_CALLOC (sizeof (*local->pending),                                      priv->child_count,                                      gf_afr_mt_int32_t); diff --git a/xlators/cluster/afr/src/afr-lk-common.c b/xlators/cluster/afr/src/afr-lk-common.c index 483d7250e43..c8dd8b635e6 100644 --- a/xlators/cluster/afr/src/afr-lk-common.c +++ b/xlators/cluster/afr/src/afr-lk-common.c @@ -567,7 +567,13 @@ afr_unlock_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                          local->loc.path, child_index, strerror (op_errno));          } +          int_lock->inode_locked_nodes[child_index] &= LOCKED_NO; + +        if (op_ret == 1) { +                local->transaction.eager_lock[child_index] = 0; +        } +          afr_unlock_common_cbk (frame, cookie, this, op_ret, op_errno);          return 0; @@ -581,8 +587,13 @@ afr_unlock_inodelk (call_frame_t *frame, xlator_t *this)          afr_local_t         *local    = NULL;          afr_private_t       *priv     = NULL;          struct gf_flock flock = {0,}; +        struct gf_flock full_flock = {0,}; +        struct gf_flock *flock_use = &flock;          int call_count = 0;          int i = 0; +        int piggyback = 0; +        afr_fd_ctx_t        *fd_ctx      = NULL; +          local    = frame->local;          int_lock = &local->internal_lock; @@ -592,9 +603,13 @@ afr_unlock_inodelk (call_frame_t *frame, xlator_t *this)          flock.l_len   = int_lock->lk_flock.l_len;          flock.l_type  = F_UNLCK; +          gf_log (this->name, GF_LOG_DEBUG, "attempting data unlock range %"PRIu64                  " %"PRIu64" by %"PRIu64, flock.l_start, flock.l_len,                  frame->root->lk_owner); + +        full_flock.l_type = F_UNLCK; +          call_count = afr_locked_nodes_count (int_lock->inode_locked_nodes,                                               priv->child_count); @@ -607,42 +622,69 @@ afr_unlock_inodelk (call_frame_t *frame, xlator_t *this)                  goto out;          } +        if (local->fd) +                fd_ctx = afr_fd_ctx_get (local->fd, this); +          for (i = 0; i < priv->child_count; i++) { -                if (int_lock->inode_locked_nodes[i] & LOCKED_YES) { -                        if (local->fd) { -                                afr_trace_inodelk_in (frame, AFR_INODELK_TRANSACTION, -                                                      AFR_UNLOCK_OP, &flock, F_SETLK, i); +                if ((int_lock->inode_locked_nodes[i] & LOCKED_YES) +                    != LOCKED_YES) +                        continue; -                                STACK_WIND_COOKIE (frame, afr_unlock_inodelk_cbk, -                                                   (void *) (long)i, -                                                   priv->children[i], -                                                   priv->children[i]->fops->finodelk, -                                                   this->name, local->fd, -                                                   F_SETLK, &flock); +                if (local->fd) { +                        if (!local->transaction.eager_lock[i]) { +                                goto wind; +                        } + +                        piggyback = 0; +                        flock_use = &full_flock; +                        LOCK (&local->fd->lock); +                        { +                                if (fd_ctx->lock_piggyback[i]) { +                                        fd_ctx->lock_piggyback[i]--; +                                        piggyback = 1; +                                } +                        } +                        UNLOCK (&local->fd->lock); + +                        if (piggyback) { +                                afr_unlock_inodelk_cbk (frame, (void *) (long) i, +                                                        this, 1, 0);                                  if (!--call_count)                                          break; +                                continue; +                        } + +                        fd_ctx->lock_acquired[i]--; +                wind: +                        afr_trace_inodelk_in (frame, AFR_INODELK_TRANSACTION, +                                              AFR_UNLOCK_OP, &flock, F_SETLK, i); -                        } else { -                                afr_trace_inodelk_in (frame, AFR_INODELK_TRANSACTION, -                                                      AFR_UNLOCK_OP, &flock, F_SETLK, i); +                        STACK_WIND_COOKIE (frame, afr_unlock_inodelk_cbk, +                                           (void *) (long)i, +                                           priv->children[i], +                                           priv->children[i]->fops->finodelk, +                                           this->name, local->fd, +                                           F_SETLK, &flock); -                                STACK_WIND_COOKIE (frame, afr_unlock_inodelk_cbk, -                                                   (void *) (long)i, -                                                   priv->children[i], -                                                   priv->children[i]->fops->inodelk, -                                                   this->name, &local->loc, -                                                   F_SETLK, &flock); +                        if (!--call_count) +                                break; -                                if (!--call_count) -                                        break; +                } else { +                        afr_trace_inodelk_in (frame, AFR_INODELK_TRANSACTION, +                                              AFR_UNLOCK_OP, &flock, F_SETLK, i); -                        } +                        STACK_WIND_COOKIE (frame, afr_unlock_inodelk_cbk, +                                           (void *) (long)i, +                                           priv->children[i], +                                           priv->children[i]->fops->inodelk, +                                           this->name, &local->loc, +                                           F_SETLK, &flock); +                        if (!--call_count) +                                break;                  } -          } -  out:          return 0;  } @@ -1288,7 +1330,11 @@ afr_nonblocking_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          afr_local_t         *local    = NULL;          int call_count  = 0;          int child_index = (long) cookie; +        afr_fd_ctx_t        *fd_ctx = NULL; +        afr_private_t       *priv     = NULL; + +        priv = this->private;          local    = frame->local;          int_lock = &local->internal_lock; @@ -1302,7 +1348,7 @@ afr_nonblocking_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          }          UNLOCK (&frame->lock); -        if (op_ret < 0 ) { +        if (op_ret < 0) {                  if (op_errno == ENOSYS) {                          /* return ENOTSUP */                          gf_log (this->name, GF_LOG_ERROR, @@ -1314,9 +1360,27 @@ afr_nonblocking_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                          int_lock->lock_op_errno      = op_errno;                          local->op_errno              = op_errno;                  } -        } else if (op_ret == 0) { -                int_lock->inode_locked_nodes[child_index] |= LOCKED_YES; +        } else { +                int_lock->inode_locked_nodes[child_index] +                        |= LOCKED_YES;                  int_lock->inodelk_lock_count++; + +                if (priv->eager_lock && local->fd) { +                        fd_ctx = afr_fd_ctx_get (local->fd, this); +                        local->transaction.eager_lock[child_index] = 1; +                        /* piggybacked */ + +                        if (op_ret == 1) { +                                /* piggybacked */ +                        } else if (op_ret == 0) { +                                /* lock acquired from server */ +                                LOCK (&local->fd->lock); +                                { +                                        fd_ctx->lock_acquired[child_index]++; +                                } +                                UNLOCK (&local->fd->lock); +                        } +                }          }          if (call_count == 0) { @@ -1355,6 +1419,9 @@ afr_nonblocking_inodelk (call_frame_t *frame, xlator_t *this)          int      i          = 0;          int      ret        = 0;          struct gf_flock flock = {0,}; +        struct gf_flock full_flock = {0,}; +        struct gf_flock *flock_use = &flock; +        int     piggyback = 0;          local    = frame->local;          int_lock = &local->internal_lock; @@ -1367,6 +1434,9 @@ afr_nonblocking_inodelk (call_frame_t *frame, xlator_t *this)          gf_log (this->name, GF_LOG_DEBUG, "attempting data lock range %"PRIu64                  " %"PRIu64" by %"PRIu64, flock.l_start, flock.l_len,                  frame->root->lk_owner); + +        full_flock.l_type = int_lock->lk_flock.l_type; +          initialize_inodelk_variables (frame, this);          if (local->fd) { @@ -1400,22 +1470,45 @@ afr_nonblocking_inodelk (call_frame_t *frame, xlator_t *this)                  /* Send non-blocking inodelk calls only on up children                     and where the fd has been opened */                  for (i = 0; i < priv->child_count; i++) { -                        if (local->child_up[i] && local->fd_open_on[i]) { -                                afr_trace_inodelk_in (frame, AFR_INODELK_NB_TRANSACTION, -                                                      AFR_LOCK_OP, &flock, F_SETLK, i); +                        if (!local->child_up[i] || !local->fd_open_on[i]) +                                continue; -                                STACK_WIND_COOKIE (frame, afr_nonblocking_inodelk_cbk, -                                                   (void *) (long) i, -                                                   priv->children[i], -                                                   priv->children[i]->fops->finodelk, -                                                   this->name, local->fd, -                                                   F_SETLK, &flock); +                        if (!priv->eager_lock) +                                goto wind; + +                        flock_use = &full_flock; +                        piggyback = 0; +                        LOCK (&local->fd->lock); +                        { +                                if (fd_ctx->lock_acquired[i]) { +                                        fd_ctx->lock_piggyback[i]++; +                                        piggyback = 1; +                                } +                        } +                        UNLOCK (&local->fd->lock); + +                        if (piggyback) { +                                /* (op_ret == 1) => indicate piggybacked lock */ +                                afr_nonblocking_inodelk_cbk (frame, (void *) (long) i, +                                                             this, 1, 0);                                  if (!--call_count)                                          break; - +                                continue;                          } +                wind: +                        afr_trace_inodelk_in (frame, AFR_INODELK_NB_TRANSACTION, +                                              AFR_LOCK_OP, flock_use, F_SETLK, i); +                        STACK_WIND_COOKIE (frame, afr_nonblocking_inodelk_cbk, +                                           (void *) (long) i, +                                           priv->children[i], +                                           priv->children[i]->fops->finodelk, +                                           this->name, local->fd, +                                           F_SETLK, flock_use); + +                        if (!--call_count) +                                break;                  }          } else {                  call_count = internal_lock_count (frame, this); @@ -1423,24 +1516,22 @@ afr_nonblocking_inodelk (call_frame_t *frame, xlator_t *this)                  int_lock->lk_expected_count = call_count;                  for (i = 0; i < priv->child_count; i++) { -                        if (local->child_up[i]) { -                                afr_trace_inodelk_in (frame, AFR_INODELK_NB_TRANSACTION, -                                                      AFR_LOCK_OP, &flock, F_SETLK, i); - -                                STACK_WIND_COOKIE (frame, afr_nonblocking_inodelk_cbk, -                                                   (void *) (long) i, -                                                   priv->children[i], -                                                   priv->children[i]->fops->inodelk, -                                                   this->name, &local->loc, -                                                   F_SETLK, &flock); +                        if (!local->child_up[i]) +                                continue; +                        afr_trace_inodelk_in (frame, AFR_INODELK_NB_TRANSACTION, +                                              AFR_LOCK_OP, &flock, F_SETLK, i); -                                if (!--call_count) -                                        break; +                        STACK_WIND_COOKIE (frame, afr_nonblocking_inodelk_cbk, +                                           (void *) (long) i, +                                           priv->children[i], +                                           priv->children[i]->fops->inodelk, +                                           this->name, &local->loc, +                                           F_SETLK, &flock); -                        } +                        if (!--call_count) +                                break;                  }          } -  out:          return ret;  } diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c index b40e171030f..795fec255d3 100644 --- a/xlators/cluster/afr/src/afr-transaction.c +++ b/xlators/cluster/afr/src/afr-transaction.c @@ -377,13 +377,6 @@ afr_changelog_post_op_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          child_index = (long) cookie; -        if (op_ret == 1) { -        } - -        if (op_ret == 0) { -                __mark_pre_op_undone_on_fd (frame, this, child_index); -        } -          LOCK (&frame->lock);          {                  call_count = --local->call_count; @@ -610,6 +603,7 @@ afr_changelog_post_op (call_frame_t *frame, xlator_t *this)                                  afr_changelog_post_op_cbk (frame, (void *)(long)i,                                                             this, 1, 0, xattr[i]);                          } else { +                                __mark_pre_op_undone_on_fd (frame, this, i);                                  STACK_WIND_COOKIE (frame,                                                     afr_changelog_post_op_cbk,                                                     (void *) (long) i, diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index 06e1a664e23..bd0a08842b2 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -130,6 +130,7 @@ typedef struct _afr_private {          pthread_mutex_t  mutex;          struct list_head saved_fds;   /* list of fds on which locks have succeeded */          gf_boolean_t     optimistic_change_log; +        gf_boolean_t     eager_lock;          char                   vol_uuid[UUID_SIZE + 1];          int32_t                *last_event; @@ -652,6 +653,8 @@ typedef struct _afr_local {          struct {                  off_t start, len; +                int *eager_lock; +                  char *basename;                  char *new_basename; @@ -701,6 +704,9 @@ typedef struct {          afr_fd_open_status_t *opened_on; /* which subvolumes the fd is open on */          unsigned int *pre_op_piggyback; +        unsigned int *lock_piggyback; +        unsigned int *lock_acquired; +          int flags;          int32_t wbflags;          uint64_t up_count;   /* number of CHILD_UPs this fd has seen */ @@ -985,4 +991,6 @@ int  afr_open_fd_fix (call_frame_t *frame, xlator_t *this, gf_boolean_t pause_fop);  int  afr_set_elem_count_get (unsigned char *elems, int child_count); +afr_fd_ctx_t * +afr_fd_ctx_get (fd_t *fd, xlator_t *this);  #endif /* __AFR_H__ */  | 
