len -= cur_len;
                dev_offset += cur_len;
-               bvec_iter_advance(bip->bip_vec, &bip->bip_iter, cur_len);
+               if (!bvec_iter_advance(bip->bip_vec, &bip->bip_iter, cur_len))
+                       return -EIO;
        }
 
        return err;
 
 
                len -= cur_len;
                meta_nsoff += cur_len;
-               bvec_iter_advance(bip->bip_vec, &bip->bip_iter, cur_len);
+               if (!bvec_iter_advance(bip->bip_vec, &bip->bip_iter, cur_len))
+                       return -EIO;
        }
 
        return ret;
 
 
        if (bio_no_advance_iter(bio))
                iter->bi_size -= bytes;
-       else
+       else {
                bvec_iter_advance(bio->bi_io_vec, iter, bytes);
+               /* TODO: It is reasonable to complete bio with error here. */
+       }
 }
 
 #define __bio_for_each_segment(bvl, bio, iter, start)                  \
 
 
 #include <linux/kernel.h>
 #include <linux/bug.h>
+#include <linux/errno.h>
 
 /*
  * was unsigned short, but we might as well be ready for > 64kB I/O pages
        .bv_offset      = bvec_iter_offset((bvec), (iter)),     \
 })
 
-static inline void bvec_iter_advance(const struct bio_vec *bv,
-                                    struct bvec_iter *iter,
-                                    unsigned bytes)
+static inline bool bvec_iter_advance(const struct bio_vec *bv,
+               struct bvec_iter *iter, unsigned bytes)
 {
-       WARN_ONCE(bytes > iter->bi_size,
-                 "Attempted to advance past end of bvec iter\n");
+       if (WARN_ONCE(bytes > iter->bi_size,
+                    "Attempted to advance past end of bvec iter\n")) {
+               iter->bi_size = 0;
+               return false;
+       }
 
        while (bytes) {
                unsigned iter_len = bvec_iter_len(bv, *iter);
                        iter->bi_idx++;
                }
        }
+       return true;
 }
 
 #define for_each_bvec(bvl, bio_vec, iter, start)                       \