@@ -193,7 +193,7 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter,
193
193
struct file * file = iocb -> ki_filp ;
194
194
struct block_device * bdev = I_BDEV (bdev_file_inode (file ));
195
195
unsigned blkbits = blksize_bits (bdev_logical_block_size (bdev ));
196
- struct bio_vec inline_vecs [DIO_INLINE_BIO_VECS ], * bvec ;
196
+ struct bio_vec inline_vecs [DIO_INLINE_BIO_VECS ], * vecs , * bvec ;
197
197
loff_t pos = iocb -> ki_pos ;
198
198
bool should_dirty = false;
199
199
struct bio bio ;
@@ -204,9 +204,17 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter,
204
204
if ((pos | iov_iter_alignment (iter )) & ((1 << blkbits ) - 1 ))
205
205
return - EINVAL ;
206
206
207
+ if (nr_pages <= DIO_INLINE_BIO_VECS )
208
+ vecs = inline_vecs ;
209
+ else {
210
+ vecs = kmalloc (nr_pages * sizeof (struct bio_vec ), GFP_KERNEL );
211
+ if (!vecs )
212
+ return - ENOMEM ;
213
+ }
214
+
207
215
bio_init (& bio );
208
216
bio .bi_max_vecs = nr_pages ;
209
- bio .bi_io_vec = inline_vecs ;
217
+ bio .bi_io_vec = vecs ;
210
218
bio .bi_bdev = bdev ;
211
219
bio .bi_iter .bi_sector = pos >> blkbits ;
212
220
bio .bi_private = current ;
@@ -243,6 +251,9 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter,
243
251
put_page (bvec -> bv_page );
244
252
}
245
253
254
+ if (vecs != inline_vecs )
255
+ kfree (vecs );
256
+
246
257
if (unlikely (bio .bi_error ))
247
258
return bio .bi_error ;
248
259
iocb -> ki_pos += ret ;
@@ -256,10 +267,10 @@ blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
256
267
struct inode * inode = bdev_file_inode (file );
257
268
int nr_pages ;
258
269
259
- nr_pages = iov_iter_npages (iter , BIO_MAX_PAGES );
270
+ nr_pages = iov_iter_npages (iter , BIO_MAX_PAGES + 1 );
260
271
if (!nr_pages )
261
272
return 0 ;
262
- if (is_sync_kiocb (iocb ) && nr_pages <= DIO_INLINE_BIO_VECS )
273
+ if (is_sync_kiocb (iocb ) && nr_pages <= BIO_MAX_PAGES )
263
274
return __blkdev_direct_IO_simple (iocb , iter , nr_pages );
264
275
return __blockdev_direct_IO (iocb , inode , I_BDEV (inode ), iter ,
265
276
blkdev_get_block , NULL , NULL ,
0 commit comments