diff options
author | Kent Overstreet <koverstreet@google.com> | 2013-03-22 13:24:17 -0700 |
---|---|---|
committer | Kent Overstreet <koverstreet@google.com> | 2013-03-22 13:24:17 -0700 |
commit | 46b21eec593b4042577c5fcdc6c2238d3913d51d (patch) | |
tree | ee4c8a27a438971025dfc659029e14dba3088018 | |
parent | cda4afa7accbcacb76ad3773b3cd01747b791fa6 (diff) |
add offset to iov_iteriov
-rw-r--r-- | fs/iov-iter.c | 46 | ||||
-rw-r--r-- | include/linux/fs.h | 4 |
2 files changed, 21 insertions, 29 deletions
diff --git a/fs/iov-iter.c b/fs/iov-iter.c index 6cecab49b7ca..edc5d1ce535f 100644 --- a/fs/iov-iter.c +++ b/fs/iov-iter.c @@ -180,35 +180,25 @@ void iov_iter_advance(struct iov_iter *i, size_t bytes) { BUG_ON(i->count < bytes); - if (likely(i->nr_segs == 1)) { - i->iov_offset += bytes; - i->count -= bytes; - } else { - const struct iovec *iov = i->iov; - size_t base = i->iov_offset; - unsigned long nr_segs = i->nr_segs; - - /* - * The !iov->iov_len check ensures we skip over unlikely - * zero-length segments (without overruning the iovec). - */ - while (bytes || unlikely(i->count && !iov->iov_len)) { - int copy; - - copy = min(bytes, iov->iov_len - base); - BUG_ON(!i->count || i->count < copy); - i->count -= copy; - bytes -= copy; - base += copy; - if (iov->iov_len == base) { - iov++; - nr_segs--; - base = 0; - } + i->count -= bytes; + i->offset += bytes; + + while (bytes) { + size_t len; + + BUG_ON(!i->nr_segs); + + len = i->iov->iov_len - i->iov_offset; + + if (bytes < len) { + i->iov_offset += bytes; + bytes = 0; + } else { + bytes -= len; + i->iov++; + i->nr_segs--; + i->iov_offset = 0; } - i->iov = iov; - i->iov_offset = base; - i->nr_segs = nr_segs; } } EXPORT_SYMBOL(iov_iter_advance); diff --git a/include/linux/fs.h b/include/linux/fs.h index e5ea8b38da14..3fc25679467e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -293,6 +293,7 @@ struct iov_iter { unsigned long nr_segs; size_t iov_offset; size_t count; + loff_t offset; }; size_t __iov_iter_copy_to_user_atomic(struct page *page, @@ -311,12 +312,13 @@ size_t iov_iter_single_seg_count(const struct iov_iter *i); static inline void iov_iter_init(struct iov_iter *i, const struct iovec *iov, unsigned long nr_segs, - size_t count) + size_t count, loff_t offset) { i->iov = iov; i->nr_segs = nr_segs; i->iov_offset = 0; i->count = count; + i->offset = offset; } static inline size_t iov_iter_count(struct iov_iter *i) |