diff options
-rw-r--r-- | drivers/nvdimm/blk.c | 3 | ||||
-rw-r--r-- | drivers/nvdimm/btt.c | 3 | ||||
-rw-r--r-- | include/linux/bio.h | 4 | ||||
-rw-r--r-- | include/linux/bvec.h | 14 |
4 files changed, 16 insertions, 8 deletions
diff --git a/drivers/nvdimm/blk.c b/drivers/nvdimm/blk.c index 1a578b2a437b..345acca576b3 100644 --- a/drivers/nvdimm/blk.c +++ b/drivers/nvdimm/blk.c | |||
@@ -106,7 +106,8 @@ static int nd_blk_rw_integrity(struct nd_namespace_blk *nsblk, | |||
106 | 106 | ||
107 | len -= cur_len; | 107 | len -= cur_len; |
108 | dev_offset += cur_len; | 108 | dev_offset += cur_len; |
109 | bvec_iter_advance(bip->bip_vec, &bip->bip_iter, cur_len); | 109 | if (!bvec_iter_advance(bip->bip_vec, &bip->bip_iter, cur_len)) |
110 | return -EIO; | ||
110 | } | 111 | } |
111 | 112 | ||
112 | return err; | 113 | return err; |
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c index b5caaee78bbf..d00c10f382f0 100644 --- a/drivers/nvdimm/btt.c +++ b/drivers/nvdimm/btt.c | |||
@@ -985,7 +985,8 @@ static int btt_rw_integrity(struct btt *btt, struct bio_integrity_payload *bip, | |||
985 | 985 | ||
986 | len -= cur_len; | 986 | len -= cur_len; |
987 | meta_nsoff += cur_len; | 987 | meta_nsoff += cur_len; |
988 | bvec_iter_advance(bip->bip_vec, &bip->bip_iter, cur_len); | 988 | if (!bvec_iter_advance(bip->bip_vec, &bip->bip_iter, cur_len)) |
989 | return -EIO; | ||
989 | } | 990 | } |
990 | 991 | ||
991 | return ret; | 992 | return ret; |
diff --git a/include/linux/bio.h b/include/linux/bio.h index b3b5f5a89a9c..d5e8689f86b8 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
@@ -167,8 +167,10 @@ static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter, | |||
167 | 167 | ||
168 | if (bio_no_advance_iter(bio)) | 168 | if (bio_no_advance_iter(bio)) |
169 | iter->bi_size -= bytes; | 169 | iter->bi_size -= bytes; |
170 | else | 170 | else { |
171 | bvec_iter_advance(bio->bi_io_vec, iter, bytes); | 171 | bvec_iter_advance(bio->bi_io_vec, iter, bytes); |
172 | /* TODO: It is reasonable to complete bio with error here. */ | ||
173 | } | ||
172 | } | 174 | } |
173 | 175 | ||
174 | #define __bio_for_each_segment(bvl, bio, iter, start) \ | 176 | #define __bio_for_each_segment(bvl, bio, iter, start) \ |
diff --git a/include/linux/bvec.h b/include/linux/bvec.h index 89b65b82d98f..de317b4c13c1 100644 --- a/include/linux/bvec.h +++ b/include/linux/bvec.h | |||
@@ -22,6 +22,7 @@ | |||
22 | 22 | ||
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/bug.h> | 24 | #include <linux/bug.h> |
25 | #include <linux/errno.h> | ||
25 | 26 | ||
26 | /* | 27 | /* |
27 | * was unsigned short, but we might as well be ready for > 64kB I/O pages | 28 | * was unsigned short, but we might as well be ready for > 64kB I/O pages |
@@ -66,12 +67,14 @@ struct bvec_iter { | |||
66 | .bv_offset = bvec_iter_offset((bvec), (iter)), \ | 67 | .bv_offset = bvec_iter_offset((bvec), (iter)), \ |
67 | }) | 68 | }) |
68 | 69 | ||
69 | static inline void bvec_iter_advance(const struct bio_vec *bv, | 70 | static inline bool bvec_iter_advance(const struct bio_vec *bv, |
70 | struct bvec_iter *iter, | 71 | struct bvec_iter *iter, unsigned bytes) |
71 | unsigned bytes) | ||
72 | { | 72 | { |
73 | WARN_ONCE(bytes > iter->bi_size, | 73 | if (WARN_ONCE(bytes > iter->bi_size, |
74 | "Attempted to advance past end of bvec iter\n"); | 74 | "Attempted to advance past end of bvec iter\n")) { |
75 | iter->bi_size = 0; | ||
76 | return false; | ||
77 | } | ||
75 | 78 | ||
76 | while (bytes) { | 79 | while (bytes) { |
77 | unsigned iter_len = bvec_iter_len(bv, *iter); | 80 | unsigned iter_len = bvec_iter_len(bv, *iter); |
@@ -86,6 +89,7 @@ static inline void bvec_iter_advance(const struct bio_vec *bv, | |||
86 | iter->bi_idx++; | 89 | iter->bi_idx++; |
87 | } | 90 | } |
88 | } | 91 | } |
92 | return true; | ||
89 | } | 93 | } |
90 | 94 | ||
91 | #define for_each_bvec(bvl, bio_vec, iter, start) \ | 95 | #define for_each_bvec(bvl, bio_vec, iter, start) \ |