diff options
Diffstat (limited to 'xlators/cluster/ec/src/ec-inode-write.c')
| -rw-r--r-- | xlators/cluster/ec/src/ec-inode-write.c | 61 | 
1 files changed, 48 insertions, 13 deletions
diff --git a/xlators/cluster/ec/src/ec-inode-write.c b/xlators/cluster/ec/src/ec-inode-write.c index 50d71082fad..4bd692dff57 100644 --- a/xlators/cluster/ec/src/ec-inode-write.c +++ b/xlators/cluster/ec/src/ec-inode-write.c @@ -1265,6 +1265,26 @@ int32_t ec_writev_merge_head(call_frame_t * frame, void * cookie,      return 0;  } +static int +ec_make_internal_fop_xdata (dict_t **xdata) +{ +    dict_t *dict = NULL; + +    dict = dict_new(); +    if (!dict) +       goto out; + +    if (dict_set_str (dict, GLUSTERFS_INTERNAL_FOP_KEY, "yes")) +       goto out; + +    *xdata = dict; +    return 0; +out: +    if (dict) +            dict_unref (dict); +    return -1; +} +  void ec_writev_start(ec_fop_data_t *fop)  {      ec_t *ec = fop->xl->private; @@ -1275,9 +1295,8 @@ void ec_writev_start(ec_fop_data_t *fop)      fd_t *fd;      size_t tail;      uint64_t current; -    uid_t uid; -    gid_t gid;      int32_t err = -ENOMEM; +    dict_t      *xdata = NULL;      /* This shouldn't fail because we have the inode locked. */      GF_ASSERT(ec_get_inode_size(fop, fop->fd->inode, ¤t)); @@ -1289,9 +1308,7 @@ void ec_writev_start(ec_fop_data_t *fop)          return;      } -    uid = fop->frame->root->uid;      fop->frame->root->uid = 0; -    gid = fop->frame->root->gid;      fop->frame->root->gid = 0;      ctx = ec_fd_get(fop->fd, fop->xl); @@ -1330,24 +1347,31 @@ void ec_writev_start(ec_fop_data_t *fop)      fop->buffers = iobref;      if (fop->head > 0) { +        if (ec_make_internal_fop_xdata (&xdata)) { +                err = -ENOMEM; +                goto out; +        }          ec_readv(fop->frame, fop->xl, -1, EC_MINIMUM_MIN, ec_writev_merge_head, -                 NULL, fd, ec->stripe_size, fop->offset, 0, NULL); +                 NULL, fd, ec->stripe_size, fop->offset, 0, xdata);      }      tail = fop->size - fop->user_size - fop->head;      if ((tail > 0) && ((fop->head == 0) || (fop->size > ec->stripe_size))) {          if (current > fop->offset + fop->head + fop->user_size) { +            if (ec_make_internal_fop_xdata (&xdata)) { +                    err = -ENOMEM; +                    goto out; +            }              ec_readv(fop->frame, fop->xl, -1, EC_MINIMUM_MIN,                       ec_writev_merge_tail, NULL, fd, ec->stripe_size, -                     fop->offset + fop->size - ec->stripe_size, 0, NULL); +                     fop->offset + fop->size - ec->stripe_size, 0, xdata);          } else {              memset(fop->vector[0].iov_base + fop->size - tail, 0, tail);          }      } -    fop->frame->root->uid = uid; -    fop->frame->root->gid = gid; -      fd_unref(fd); +    if (xdata) +            dict_unref (xdata);      return; @@ -1359,10 +1383,9 @@ out:          iobref_unref(iobref);      } -    fop->frame->root->uid = uid; -    fop->frame->root->gid = gid; -      fd_unref(fd); +    if (xdata) +            dict_unref (xdata);      ec_fop_set_error(fop, -err);  } @@ -1460,6 +1483,11 @@ int32_t ec_manager_writev(ec_fop_data_t *fop, int32_t state)              return EC_STATE_DELAYED_START;          case EC_STATE_DELAYED_START: +            /* Restore uid, gid if they were changed to do some partial +             * reads. */ +            fop->frame->root->uid = fop->uid; +            fop->frame->root->gid = fop->gid; +              ec_dispatch_all(fop);              return EC_STATE_PREPARE_ANSWER; @@ -1520,10 +1548,17 @@ int32_t ec_manager_writev(ec_fop_data_t *fop, int32_t state)              return EC_STATE_LOCK_REUSE; +        case -EC_STATE_DELAYED_START: +            /* We have failed while doing partial reads. We need to restore +             * original uid, gid. */ +            fop->frame->root->uid = fop->uid; +            fop->frame->root->gid = fop->gid; + +        /* Fall through */ +          case -EC_STATE_INIT:          case -EC_STATE_LOCK:          case -EC_STATE_DISPATCH: -        case -EC_STATE_DELAYED_START:          case -EC_STATE_PREPARE_ANSWER:          case -EC_STATE_REPORT:              GF_ASSERT(fop->error != 0);  | 
