cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

xfs_bio_io.c (1274B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (c) 2019 Christoph Hellwig.
      4 */
      5#include "xfs.h"
      6
      7static inline unsigned int bio_max_vecs(unsigned int count)
      8{
      9	return bio_max_segs(howmany(count, PAGE_SIZE));
     10}
     11
     12int
     13xfs_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(bdev, bio_max_vecs(left), op | REQ_META | REQ_SYNC,
     30			GFP_KERNEL);
     31	bio->bi_iter.bi_sector = sector;
     32
     33	do {
     34		struct page	*page = kmem_to_page(data);
     35		unsigned int	off = offset_in_page(data);
     36		unsigned int	len = min_t(unsigned, left, PAGE_SIZE - off);
     37
     38		while (bio_add_page(bio, page, len, off) != len) {
     39			struct bio	*prev = bio;
     40
     41			bio = bio_alloc(prev->bi_bdev, bio_max_vecs(left),
     42					prev->bi_opf, GFP_KERNEL);
     43			bio->bi_iter.bi_sector = bio_end_sector(prev);
     44			bio_chain(prev, bio);
     45
     46			submit_bio(prev);
     47		}
     48
     49		data += len;
     50		left -= len;
     51	} while (left > 0);
     52
     53	error = submit_bio_wait(bio);
     54	bio_put(bio);
     55
     56	if (is_vmalloc && op == REQ_OP_READ)
     57		invalidate_kernel_vmap_range(data, count);
     58	return error;
     59}