root/fs/xfs/xfs_bio_io.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bio_max_vecs
  2. xfs_rw_bdev

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright (c) 2019 Christoph Hellwig.
   4  */
   5 #include "xfs.h"
   6 
   7 static inline unsigned int bio_max_vecs(unsigned int count)
   8 {
   9         return min_t(unsigned, howmany(count, PAGE_SIZE), BIO_MAX_PAGES);
  10 }
  11 
  12 int
  13 xfs_rw_bdev(
  14         struct block_device     *bdev,
  15         sector_t                sector,
  16         unsigned int            count,
  17         char                    *data,
  18         unsigned int            op)
  19 
  20 {
  21         unsigned int            is_vmalloc = is_vmalloc_addr(data);
  22         unsigned int            left = count;
  23         int                     error;
  24         struct bio              *bio;
  25 
  26         if (is_vmalloc && op == REQ_OP_WRITE)
  27                 flush_kernel_vmap_range(data, count);
  28 
  29         bio = bio_alloc(GFP_KERNEL, bio_max_vecs(left));
  30         bio_set_dev(bio, bdev);
  31         bio->bi_iter.bi_sector = sector;
  32         bio->bi_opf = op | REQ_META | REQ_SYNC;
  33 
  34         do {
  35                 struct page     *page = kmem_to_page(data);
  36                 unsigned int    off = offset_in_page(data);
  37                 unsigned int    len = min_t(unsigned, left, PAGE_SIZE - off);
  38 
  39                 while (bio_add_page(bio, page, len, off) != len) {
  40                         struct bio      *prev = bio;
  41 
  42                         bio = bio_alloc(GFP_KERNEL, bio_max_vecs(left));
  43                         bio_copy_dev(bio, prev);
  44                         bio->bi_iter.bi_sector = bio_end_sector(prev);
  45                         bio->bi_opf = prev->bi_opf;
  46                         bio_chain(prev, bio);
  47 
  48                         submit_bio(prev);
  49                 }
  50 
  51                 data += len;
  52                 left -= len;
  53         } while (left > 0);
  54 
  55         error = submit_bio_wait(bio);
  56         bio_put(bio);
  57 
  58         if (is_vmalloc && op == REQ_OP_READ)
  59                 invalidate_kernel_vmap_range(data, count);
  60         return error;
  61 }

/* [<][>][^][v][top][bottom][index][help] */