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