Loading mm/iov_iter.c +28 −76 Original line number Diff line number Diff line Loading @@ -70,6 +70,33 @@ } \ } #define iterate_and_advance(i, n, v, I, B) { \ size_t skip = i->iov_offset; \ if (unlikely(i->type & ITER_BVEC)) { \ const struct bio_vec *bvec; \ struct bio_vec v; \ iterate_bvec(i, n, v, bvec, skip, (B)) \ if (skip == bvec->bv_len) { \ bvec++; \ skip = 0; \ } \ i->nr_segs -= bvec - i->bvec; \ i->bvec = bvec; \ } else { \ const struct iovec *iov; \ struct iovec v; \ iterate_iovec(i, n, v, iov, skip, (I)) \ if (skip == iov->iov_len) { \ iov++; \ skip = 0; \ } \ i->nr_segs -= iov - i->iov; \ i->iov = iov; \ } \ i->count -= n; \ i->iov_offset = skip; \ } static size_t copy_to_iter_iovec(void *from, size_t bytes, struct iov_iter *i) { size_t skip, copy, left, wanted; Loading Loading @@ -366,42 +393,6 @@ static size_t zero_iovec(size_t bytes, struct iov_iter *i) return wanted - bytes; } static void advance_iovec(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->iov = iov; i->iov_offset = base; i->nr_segs = nr_segs; } } /* * Fault in the first iovec of the given iov_iter, to a maximum length * of bytes. Returns 0 on success, or non-zero if the memory could not be Loading Loading @@ -685,42 +676,6 @@ static size_t zero_bvec(size_t bytes, struct iov_iter *i) return wanted - bytes; } static void advance_bvec(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 bio_vec *bvec = i->bvec; 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 && !bvec->bv_len)) { int copy; copy = min(bytes, bvec->bv_len - base); BUG_ON(!i->count || i->count < copy); i->count -= copy; bytes -= copy; base += copy; if (bvec->bv_len == base) { bvec++; nr_segs--; base = 0; } } i->bvec = bvec; i->iov_offset = base; i->nr_segs = nr_segs; } } static ssize_t get_pages_bvec(struct iov_iter *i, struct page **pages, size_t maxsize, unsigned maxpages, size_t *start) Loading Loading @@ -849,10 +804,7 @@ EXPORT_SYMBOL(iov_iter_copy_from_user_atomic); void iov_iter_advance(struct iov_iter *i, size_t size) { if (i->type & ITER_BVEC) advance_bvec(i, size); else advance_iovec(i, size); iterate_and_advance(i, size, v, 0, 0) } EXPORT_SYMBOL(iov_iter_advance); Loading Loading
mm/iov_iter.c +28 −76 Original line number Diff line number Diff line Loading @@ -70,6 +70,33 @@ } \ } #define iterate_and_advance(i, n, v, I, B) { \ size_t skip = i->iov_offset; \ if (unlikely(i->type & ITER_BVEC)) { \ const struct bio_vec *bvec; \ struct bio_vec v; \ iterate_bvec(i, n, v, bvec, skip, (B)) \ if (skip == bvec->bv_len) { \ bvec++; \ skip = 0; \ } \ i->nr_segs -= bvec - i->bvec; \ i->bvec = bvec; \ } else { \ const struct iovec *iov; \ struct iovec v; \ iterate_iovec(i, n, v, iov, skip, (I)) \ if (skip == iov->iov_len) { \ iov++; \ skip = 0; \ } \ i->nr_segs -= iov - i->iov; \ i->iov = iov; \ } \ i->count -= n; \ i->iov_offset = skip; \ } static size_t copy_to_iter_iovec(void *from, size_t bytes, struct iov_iter *i) { size_t skip, copy, left, wanted; Loading Loading @@ -366,42 +393,6 @@ static size_t zero_iovec(size_t bytes, struct iov_iter *i) return wanted - bytes; } static void advance_iovec(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->iov = iov; i->iov_offset = base; i->nr_segs = nr_segs; } } /* * Fault in the first iovec of the given iov_iter, to a maximum length * of bytes. Returns 0 on success, or non-zero if the memory could not be Loading Loading @@ -685,42 +676,6 @@ static size_t zero_bvec(size_t bytes, struct iov_iter *i) return wanted - bytes; } static void advance_bvec(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 bio_vec *bvec = i->bvec; 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 && !bvec->bv_len)) { int copy; copy = min(bytes, bvec->bv_len - base); BUG_ON(!i->count || i->count < copy); i->count -= copy; bytes -= copy; base += copy; if (bvec->bv_len == base) { bvec++; nr_segs--; base = 0; } } i->bvec = bvec; i->iov_offset = base; i->nr_segs = nr_segs; } } static ssize_t get_pages_bvec(struct iov_iter *i, struct page **pages, size_t maxsize, unsigned maxpages, size_t *start) Loading Loading @@ -849,10 +804,7 @@ EXPORT_SYMBOL(iov_iter_copy_from_user_atomic); void iov_iter_advance(struct iov_iter *i, size_t size) { if (i->type & ITER_BVEC) advance_bvec(i, size); else advance_iovec(i, size); iterate_and_advance(i, size, v, 0, 0) } EXPORT_SYMBOL(iov_iter_advance); Loading