diff options
| -rw-r--r-- | libglusterfs/src/glusterfs/common-utils.h | 228 | ||||
| -rw-r--r-- | xlators/features/quota/src/quota.c | 10 | ||||
| -rw-r--r-- | xlators/features/shard/src/shard.c | 10 | ||||
| -rw-r--r-- | xlators/performance/io-cache/src/io-cache.c | 20 | ||||
| -rw-r--r-- | xlators/performance/io-cache/src/page.c | 10 | ||||
| -rw-r--r-- | xlators/performance/read-ahead/src/page.c | 10 | ||||
| -rw-r--r-- | xlators/performance/write-behind/src/write-behind.c | 3 | 
7 files changed, 177 insertions, 114 deletions
diff --git a/libglusterfs/src/glusterfs/common-utils.h b/libglusterfs/src/glusterfs/common-utils.h index 56ea83c37d9..49ebdba2fc2 100644 --- a/libglusterfs/src/glusterfs/common-utils.h +++ b/libglusterfs/src/glusterfs/common-utils.h @@ -512,65 +512,193 @@ static inline struct iovec *  iov_dup(const struct iovec *vector, int count)  {      int bytecount = 0; -    int i;      struct iovec *newvec = NULL;      bytecount = (count * sizeof(struct iovec));      newvec = GF_MALLOC(bytecount, gf_common_mt_iovec); -    if (!newvec) -        return NULL; - -    for (i = 0; i < count; i++) { -        newvec[i].iov_len = vector[i].iov_len; -        newvec[i].iov_base = vector[i].iov_base; +    if (newvec != NULL) { +        memcpy(newvec, vector, bytecount);      }      return newvec;  } -static inline int -iov_subset(struct iovec *orig, int orig_count, off_t src_offset, -           off_t dst_offset, struct iovec *new) +typedef struct _iov_iter { +    const struct iovec *iovec; +    void *ptr; +    uint32_t len; +    uint32_t count; +} iov_iter_t; + +static inline bool +iov_iter_init(iov_iter_t *iter, const struct iovec *iovec, uint32_t count, +              uint32_t offset)  { -    int new_count = 0; -    int i; -    off_t offset = 0; -    size_t start_offset = 0; -    size_t end_offset = 0, origin_iov_len = 0; +    uint32_t len; -    for (i = 0; i < orig_count; i++) { -        origin_iov_len = orig[i].iov_len; +    while (count > 0) { +        count--; +        len = iovec->iov_len; +        if (offset < len) { +            iter->ptr = iovec->iov_base + offset; +            iter->len = len - offset; +            iter->iovec = iovec + 1; +            iter->count = count; -        if ((offset + orig[i].iov_len < src_offset) || (offset > dst_offset)) { -            goto not_subset; +            return true;          } +        offset -= len; +    } -        if (!new) { -            goto count_only; -        } +    memset(iter, 0, sizeof(*iter)); + +    return false; +} + +static inline bool +iov_iter_end(iov_iter_t *iter) +{ +    return iter->count == 0; +} + +static inline bool +iov_iter_next(iov_iter_t *iter, uint32_t size) +{ +    GF_ASSERT(size <= iter->len); + +    if (iter->len > size) { +        iter->len -= size; +        iter->ptr += size; + +        return true; +    } +    if (iter->count > 0) { +        iter->count--; +        iter->ptr = iter->iovec->iov_base; +        iter->len = iter->iovec->iov_len; +        iter->iovec++; + +        return true; +    } + +    memset(iter, 0, sizeof(*iter)); + +    return false; +} + +static inline uint32_t +iov_iter_copy(iov_iter_t *dst, iov_iter_t *src, uint32_t size) +{ +    uint32_t len; + +    len = src->len; +    if (len > dst->len) { +        len = dst->len; +    } +    if (len > size) { +        len = size; +    } +    memcpy(dst->ptr, src->ptr, len); -        start_offset = 0; -        end_offset = orig[i].iov_len; +    return len; +} -        if (src_offset >= offset) { -            start_offset = (src_offset - offset); +static inline uint32_t +iov_iter_to_iovec(iov_iter_t *iter, struct iovec *iovec, int32_t idx, +                  uint32_t size) +{ +    uint32_t len; + +    len = iter->len; +    if (len > size) { +        len = size; +    } +    iovec[idx].iov_base = iter->ptr; +    iovec[idx].iov_len = len; + +    return len; +} + +static inline int +iov_subset(struct iovec *src, int src_count, uint32_t start, uint32_t size, +           struct iovec **dst, int32_t dst_count) +{ +    struct iovec iovec[src_count]; +    iov_iter_t iter; +    uint32_t len; +    int32_t idx; + +    if ((size == 0) || !iov_iter_init(&iter, src, src_count, start)) { +        return 0; +    } + +    idx = 0; +    do { +        len = iov_iter_to_iovec(&iter, iovec, idx, size); +        idx++; +        size -= len; +    } while ((size > 0) && iov_iter_next(&iter, len)); + +    if (*dst == NULL) { +        *dst = iov_dup(iovec, idx); +        if (*dst == NULL) { +            return -1;          } +    } else if (idx > dst_count) { +        return -1; +    } else { +        memcpy(*dst, iovec, idx * sizeof(struct iovec)); +    } -        if (dst_offset <= (offset + orig[i].iov_len)) { -            end_offset = (dst_offset - offset); +    return idx; +} + +static inline int +iov_skip(struct iovec *iovec, uint32_t count, uint32_t size) +{ +    uint32_t len, idx; + +    idx = 0; +    while ((size > 0) && (idx < count)) { +        len = iovec[idx].iov_len; +        if (len > size) { +            iovec[idx].iov_len -= size; +            iovec[idx].iov_base += size; +            break;          } +        idx++; +        size -= len; +    } + +    if (idx > 0) { +        memmove(iovec, iovec + idx, (count - idx) * sizeof(struct iovec)); +    } -        new[new_count].iov_base = orig[i].iov_base + start_offset; -        new[new_count].iov_len = end_offset - start_offset; +    return count - idx; +} -    count_only: -        new_count++; +static inline size_t +iov_range_copy(const struct iovec *dst, uint32_t dst_count, uint32_t dst_offset, +               const struct iovec *src, uint32_t src_count, uint32_t src_offset, +               uint32_t size) +{ +    iov_iter_t src_iter, dst_iter; +    uint32_t len, total; -    not_subset: -        offset += origin_iov_len; +    if ((size == 0) || !iov_iter_init(&src_iter, src, src_count, src_offset) || +        !iov_iter_init(&dst_iter, dst, dst_count, dst_offset)) { +        return 0;      } -    return new_count; +    total = 0; +    do { +        len = iov_iter_copy(&dst_iter, &src_iter, size); +        total += len; +        size -= len; +    } while ((size > 0) && iov_iter_next(&src_iter, len) && +             iov_iter_next(&dst_iter, len)); + +    return total;  }  static inline void @@ -609,35 +737,7 @@ iov_load(const struct iovec *vector, int count, char *buf, int size)  static inline size_t  iov_copy(const struct iovec *dst, int dcnt, const struct iovec *src, int scnt)  { -    size_t ret = 0; -    size_t left = 0; -    size_t min_i = 0; -    int s_i = 0, s_ii = 0; -    int d_i = 0, d_ii = 0; - -    ret = min(iov_length(dst, dcnt), iov_length(src, scnt)); -    left = ret; - -    while (left) { -        min_i = min(dst[d_i].iov_len - d_ii, src[s_i].iov_len - s_ii); -        memcpy(dst[d_i].iov_base + d_ii, src[s_i].iov_base + s_ii, min_i); - -        d_ii += min_i; -        if (d_ii == dst[d_i].iov_len) { -            d_ii = 0; -            d_i++; -        } - -        s_ii += min_i; -        if (s_ii == src[s_i].iov_len) { -            s_ii = 0; -            s_i++; -        } - -        left -= min_i; -    } - -    return ret; +    return iov_range_copy(dst, dcnt, 0, src, scnt, 0, UINT32_MAX);  }  /* based on the amusing discussion @ https://rusty.ozlabs.org/?p=560 */ diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c index 1335386a197..c787028e7b3 100644 --- a/xlators/features/quota/src/quota.c +++ b/xlators/features/quota/src/quota.c @@ -1769,19 +1769,13 @@ quota_writev_helper(call_frame_t *frame, xlator_t *this, fd_t *fd,          if ((op_errno == EDQUOT) && (local->space_available > 0)) {              new_count = iov_subset(vector, count, 0, local->space_available, -                                   NULL); - -            new_vector = GF_CALLOC(new_count, sizeof(struct iovec), -                                   gf_common_mt_iovec); -            if (new_vector == NULL) { +                                   &new_vector, 0); +            if (new_count < 0) {                  local->op_ret = -1;                  local->op_errno = ENOMEM;                  goto unwind;              } -            new_count = iov_subset(vector, count, 0, local->space_available, -                                   new_vector); -              vector = new_vector;              count = new_count;          } else if (op_errno == ENOENT || op_errno == ESTALE) { diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c index b6908c39ef5..6e78e967214 100644 --- a/xlators/features/shard/src/shard.c +++ b/xlators/features/shard/src/shard.c @@ -5476,21 +5476,17 @@ shard_common_inode_write_do(call_frame_t *frame, xlator_t *this)          remaining_size -= shard_write_size;          if (local->fop == GF_FOP_WRITE) { +            vec = NULL;              count = iov_subset(local->vector, local->count, vec_offset, -                               vec_offset + shard_write_size, NULL); - -            vec = GF_CALLOC(count, sizeof(struct iovec), gf_shard_mt_iovec); -            if (!vec) { +                               shard_write_size, &vec, 0); +            if (count < 0) {                  local->op_ret = -1;                  local->op_errno = ENOMEM;                  wind_failed = _gf_true; -                GF_FREE(vec);                  shard_common_inode_write_do_cbk(frame, (void *)(long)0, this,                                                  -1, ENOMEM, NULL, NULL, NULL);                  goto next;              } -            count = iov_subset(local->vector, local->count, vec_offset, -                               vec_offset + shard_write_size, vec);          }          if (cur_block == 0) { diff --git a/xlators/performance/io-cache/src/io-cache.c b/xlators/performance/io-cache/src/io-cache.c index 95ba2e19b9e..711afdf700d 100644 --- a/xlators/performance/io-cache/src/io-cache.c +++ b/xlators/performance/io-cache/src/io-cache.c @@ -87,14 +87,6 @@ ioc_update_pages(call_frame_t *frame, ioc_inode_t *ioc_inode,            write_offset = 0;      off_t page_offset = 0, page_end = 0;      ioc_page_t *trav = NULL; -    struct iovec pagevector = -                     { -                         0, -                     }, -                 writevector = { -                     0, -                 }; -    int pvcount = 0, wvcount;      size = iov_length(vector, count);      size = min(size, op_ret); @@ -120,16 +112,8 @@ ioc_update_pages(call_frame_t *frame, ioc_inode_t *ioc_inode,                      page_end = trav->size;                  } -                wvcount = iov_subset(vector, count, write_offset, -                                     write_offset + (page_end - page_offset), -                                     &writevector); -                if (wvcount) { -                    pvcount = iov_subset(trav->vector, trav->count, page_offset, -                                         page_end, &pagevector); -                    if (pvcount) { -                        iov_copy(&pagevector, pvcount, &writevector, wvcount); -                    } -                } +                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); diff --git a/xlators/performance/io-cache/src/page.c b/xlators/performance/io-cache/src/page.c index 4a9679cf0ce..69b4fc0573f 100644 --- a/xlators/performance/io-cache/src/page.c +++ b/xlators/performance/io-cache/src/page.c @@ -727,11 +727,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; @@ -740,9 +737,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 diff --git a/xlators/performance/read-ahead/src/page.c b/xlators/performance/read-ahead/src/page.c index 344026352f9..8a58ad8bb7a 100644 --- a/xlators/performance/read-ahead/src/page.c +++ b/xlators/performance/read-ahead/src/page.c @@ -347,19 +347,15 @@ ra_frame_fill(ra_page_t *page, call_frame_t *frame)          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_ra_mt_iovec); -        if (new->vector == NULL) { +                                copy_size, &new->vector, 0); +        if (new->count < 0) {              local->op_ret = -1;              local->op_errno = ENOMEM; +            iobref_unref(new->iobref);              GF_FREE(new);              goto out;          } -        new->count = iov_subset(page->vector, page->count, src_offset, -                                src_offset + copy_size, new->vector); -          new->next = fill;          new->prev = new->next->prev;          new->next->prev = new; diff --git a/xlators/performance/write-behind/src/write-behind.c b/xlators/performance/write-behind/src/write-behind.c index 70e281a3c79..aade1c9c563 100644 --- a/xlators/performance/write-behind/src/write-behind.c +++ b/xlators/performance/write-behind/src/write-behind.c @@ -971,8 +971,7 @@ __wb_modify_write_request(wb_request_t *req, int synced_size)      vector = req->stub->args.vector;      count = req->stub->args.count; -    req->stub->args.count = iov_subset(vector, count, synced_size, -                                       iov_length(vector, count), vector); +    req->stub->args.count = iov_skip(vector, count, synced_size);  out:      return;  | 
