Loading lib/iov_iter.c +54 −34 Original line number Diff line number Diff line Loading @@ -1864,19 +1864,56 @@ size_t hash_and_copy_to_iter(const void *addr, size_t bytes, void *hashp, } EXPORT_SYMBOL(hash_and_copy_to_iter); int iov_iter_npages(const struct iov_iter *i, int maxpages) static int iov_npages(const struct iov_iter *i, int maxpages) { size_t size = i->count; size_t skip = i->iov_offset, size = i->count; const struct iovec *p; int npages = 0; if (!size) return 0; if (unlikely(iov_iter_is_discard(i))) return 0; for (p = i->iov; size; skip = 0, p++) { unsigned offs = offset_in_page(p->iov_base + skip); size_t len = min(p->iov_len - skip, size); if (unlikely(iov_iter_is_pipe(i))) { struct pipe_inode_info *pipe = i->pipe; if (len) { size -= len; npages += DIV_ROUND_UP(offs + len, PAGE_SIZE); if (unlikely(npages > maxpages)) return maxpages; } } return npages; } static int bvec_npages(const struct iov_iter *i, int maxpages) { size_t skip = i->iov_offset, size = i->count; const struct bio_vec *p; int npages = 0; for (p = i->bvec; size; skip = 0, p++) { unsigned offs = (p->bv_offset + skip) % PAGE_SIZE; size_t len = min(p->bv_len - skip, size); size -= len; npages += DIV_ROUND_UP(offs + len, PAGE_SIZE); if (unlikely(npages > maxpages)) return maxpages; } return npages; } int iov_iter_npages(const struct iov_iter *i, int maxpages) { if (unlikely(!i->count)) return 0; /* iovec and kvec have identical layouts */ if (likely(iter_is_iovec(i) || iov_iter_is_kvec(i))) return iov_npages(i, maxpages); if (iov_iter_is_bvec(i)) return bvec_npages(i, maxpages); if (iov_iter_is_pipe(i)) { unsigned int iter_head; int npages; size_t off; if (!sanity(i)) Loading @@ -1884,11 +1921,13 @@ int iov_iter_npages(const struct iov_iter *i, int maxpages) data_start(i, &iter_head, &off); /* some of this one + all after this one */ npages = pipe_space_for_user(iter_head, pipe->tail, pipe); if (npages >= maxpages) return maxpages; } else if (unlikely(iov_iter_is_xarray(i))) { npages = pipe_space_for_user(iter_head, i->pipe->tail, i->pipe); return min(npages, maxpages); } if (iov_iter_is_xarray(i)) { size_t size = i->count; unsigned offset; int npages; offset = (i->xarray_start + i->iov_offset) & ~PAGE_MASK; Loading @@ -1900,28 +1939,9 @@ int iov_iter_npages(const struct iov_iter *i, int maxpages) if (size) npages++; } if (npages >= maxpages) return maxpages; } else iterate_all_kinds(i, size, v, ({ unsigned long p = (unsigned long)v.iov_base; npages += DIV_ROUND_UP(p + v.iov_len, PAGE_SIZE) - p / PAGE_SIZE; if (npages >= maxpages) return maxpages; 0;}),({ npages++; if (npages >= maxpages) return maxpages; }),({ unsigned long p = (unsigned long)v.iov_base; npages += DIV_ROUND_UP(p + v.iov_len, PAGE_SIZE) - p / PAGE_SIZE; if (npages >= maxpages) return maxpages; }), 0 ) return npages; return min(npages, maxpages); } return 0; } EXPORT_SYMBOL(iov_iter_npages); Loading Loading
lib/iov_iter.c +54 −34 Original line number Diff line number Diff line Loading @@ -1864,19 +1864,56 @@ size_t hash_and_copy_to_iter(const void *addr, size_t bytes, void *hashp, } EXPORT_SYMBOL(hash_and_copy_to_iter); int iov_iter_npages(const struct iov_iter *i, int maxpages) static int iov_npages(const struct iov_iter *i, int maxpages) { size_t size = i->count; size_t skip = i->iov_offset, size = i->count; const struct iovec *p; int npages = 0; if (!size) return 0; if (unlikely(iov_iter_is_discard(i))) return 0; for (p = i->iov; size; skip = 0, p++) { unsigned offs = offset_in_page(p->iov_base + skip); size_t len = min(p->iov_len - skip, size); if (unlikely(iov_iter_is_pipe(i))) { struct pipe_inode_info *pipe = i->pipe; if (len) { size -= len; npages += DIV_ROUND_UP(offs + len, PAGE_SIZE); if (unlikely(npages > maxpages)) return maxpages; } } return npages; } static int bvec_npages(const struct iov_iter *i, int maxpages) { size_t skip = i->iov_offset, size = i->count; const struct bio_vec *p; int npages = 0; for (p = i->bvec; size; skip = 0, p++) { unsigned offs = (p->bv_offset + skip) % PAGE_SIZE; size_t len = min(p->bv_len - skip, size); size -= len; npages += DIV_ROUND_UP(offs + len, PAGE_SIZE); if (unlikely(npages > maxpages)) return maxpages; } return npages; } int iov_iter_npages(const struct iov_iter *i, int maxpages) { if (unlikely(!i->count)) return 0; /* iovec and kvec have identical layouts */ if (likely(iter_is_iovec(i) || iov_iter_is_kvec(i))) return iov_npages(i, maxpages); if (iov_iter_is_bvec(i)) return bvec_npages(i, maxpages); if (iov_iter_is_pipe(i)) { unsigned int iter_head; int npages; size_t off; if (!sanity(i)) Loading @@ -1884,11 +1921,13 @@ int iov_iter_npages(const struct iov_iter *i, int maxpages) data_start(i, &iter_head, &off); /* some of this one + all after this one */ npages = pipe_space_for_user(iter_head, pipe->tail, pipe); if (npages >= maxpages) return maxpages; } else if (unlikely(iov_iter_is_xarray(i))) { npages = pipe_space_for_user(iter_head, i->pipe->tail, i->pipe); return min(npages, maxpages); } if (iov_iter_is_xarray(i)) { size_t size = i->count; unsigned offset; int npages; offset = (i->xarray_start + i->iov_offset) & ~PAGE_MASK; Loading @@ -1900,28 +1939,9 @@ int iov_iter_npages(const struct iov_iter *i, int maxpages) if (size) npages++; } if (npages >= maxpages) return maxpages; } else iterate_all_kinds(i, size, v, ({ unsigned long p = (unsigned long)v.iov_base; npages += DIV_ROUND_UP(p + v.iov_len, PAGE_SIZE) - p / PAGE_SIZE; if (npages >= maxpages) return maxpages; 0;}),({ npages++; if (npages >= maxpages) return maxpages; }),({ unsigned long p = (unsigned long)v.iov_base; npages += DIV_ROUND_UP(p + v.iov_len, PAGE_SIZE) - p / PAGE_SIZE; if (npages >= maxpages) return maxpages; }), 0 ) return npages; return min(npages, maxpages); } return 0; } EXPORT_SYMBOL(iov_iter_npages); Loading