|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
310c69 |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
310c69 |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
310c69 |
* of the License, or (at your option) any later version.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
310c69 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
310c69 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
310c69 |
* GNU General Public License for more details.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
310c69 |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
310c69 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
310c69 |
* 02110-1301, USA.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/bio.h#6 $
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#ifndef BIO_H
|
|
Packit Service |
310c69 |
#define BIO_H
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include <linux/bio.h>
|
|
Packit Service |
310c69 |
#include <linux/blkdev.h>
|
|
Packit Service |
310c69 |
#include <linux/version.h>
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include "kernelTypes.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)
|
|
Packit Service |
310c69 |
#define USE_BI_ITER 1
|
|
Packit Service |
310c69 |
#endif
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Copy the bio data to a char array.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param bio The bio to copy the data from
|
|
Packit Service |
310c69 |
* @param dataPtr The local array to copy the data to
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void bioCopyDataIn(BIO *bio, char *dataPtr);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Copy a char array to the bio data.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param bio The bio to copy the data to
|
|
Packit Service |
310c69 |
* @param dataPtr The local array to copy the data from
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void bioCopyDataOut(BIO *bio, char *dataPtr);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set the bi_rw or equivalent field of a bio to a particular data
|
|
Packit Service |
310c69 |
* operation. Intended to be called only by setBioOperationRead() etc.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param bio The bio to modify
|
|
Packit Service |
310c69 |
* @param operation The operation to set it to
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void setBioOperation(BIO *bio, unsigned int operation);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static inline void setBioOperationRead(BIO *bio)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
setBioOperation(bio, READ);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static inline void setBioOperationWrite(BIO *bio)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
setBioOperation(bio, WRITE);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static inline void clearBioOperationAndFlags(BIO *bio)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
|
|
Packit Service |
310c69 |
bio->bi_opf = 0;
|
|
Packit Service |
310c69 |
#else
|
|
Packit Service |
310c69 |
bio->bi_rw = 0;
|
|
Packit Service |
310c69 |
#endif
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static inline void copyBioOperationAndFlags(BIO *to, BIO *from)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
|
|
Packit Service |
310c69 |
to->bi_opf = from->bi_opf;
|
|
Packit Service |
310c69 |
#else
|
|
Packit Service |
310c69 |
to->bi_rw = from->bi_rw;
|
|
Packit Service |
310c69 |
#endif
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static inline void setBioOperationFlag(BIO *bio, unsigned int flag)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
|
|
Packit Service |
310c69 |
bio->bi_opf |= flag;
|
|
Packit Service |
310c69 |
#else
|
|
Packit Service |
310c69 |
bio->bi_rw |= flag;
|
|
Packit Service |
310c69 |
#endif
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static inline void clearBioOperationFlag(BIO *bio, unsigned int flag)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
|
|
Packit Service |
310c69 |
bio->bi_opf &= ~flag;
|
|
Packit Service |
310c69 |
#else
|
|
Packit Service |
310c69 |
bio->bi_rw &= ~flag;
|
|
Packit Service |
310c69 |
#endif
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static inline void setBioOperationFlagPreflush(BIO *bio)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
|
|
Packit Service |
310c69 |
setBioOperationFlag(bio, REQ_PREFLUSH);
|
|
Packit Service |
310c69 |
#else
|
|
Packit Service |
310c69 |
// Preflushes and empty flushes are not currently distinguished.
|
|
Packit Service |
310c69 |
setBioOperation(bio, WRITE_FLUSH);
|
|
Packit Service |
310c69 |
#endif
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static inline void setBioOperationFlagSync(BIO *bio)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
setBioOperationFlag(bio, REQ_SYNC);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static inline void clearBioOperationFlagSync(BIO *bio)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
clearBioOperationFlag(bio, REQ_SYNC);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static inline void setBioOperationFlagFua(BIO *bio)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
setBioOperationFlag(bio, REQ_FUA);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static inline void clearBioOperationFlagFua(BIO *bio)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
clearBioOperationFlag(bio, REQ_FUA);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static inline bool isDiscardBio(BIO *bio)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
|
|
Packit Service |
310c69 |
return (bio != NULL) && (bio_op(bio) == REQ_OP_DISCARD);
|
|
Packit Service |
310c69 |
#else
|
|
Packit Service |
310c69 |
return (bio != NULL) && ((bio->bi_rw & REQ_DISCARD) != 0);
|
|
Packit Service |
310c69 |
#endif
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static inline bool isFlushBio(BIO *bio)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
|
|
Packit Service |
310c69 |
return (bio_op(bio) == REQ_OP_FLUSH) || ((bio->bi_opf & REQ_PREFLUSH) != 0);
|
|
Packit Service |
310c69 |
#else
|
|
Packit Service |
310c69 |
return (bio->bi_rw & REQ_FLUSH) != 0;
|
|
Packit Service |
310c69 |
#endif
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static inline bool isFUABio(BIO *bio)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
|
|
Packit Service |
310c69 |
return (bio->bi_opf & REQ_FUA) != 0;
|
|
Packit Service |
310c69 |
#else
|
|
Packit Service |
310c69 |
return (bio->bi_rw & REQ_FUA) != 0;
|
|
Packit Service |
310c69 |
#endif
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static inline bool isReadBio(BIO *bio)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return bio_data_dir(bio) == READ;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static inline bool isWriteBio(BIO *bio)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
return bio_data_dir(bio) == WRITE;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Get the error from the bio.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param bio The bio
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return the bio's error if any
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline int getBioResult(BIO *bio)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)
|
|
Packit Service |
310c69 |
return blk_status_to_errno(bio->bi_status);
|
|
Packit Service |
310c69 |
#else
|
|
Packit Service |
310c69 |
return bio->bi_error;
|
|
Packit Service |
310c69 |
#endif
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
#endif // newer than 4.4
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set the block device for a bio.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param bio The bio to modify
|
|
Packit Service |
310c69 |
* @param device The new block device for the bio
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void setBioBlockDevice(BIO *bio, struct block_device *device)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)
|
|
Packit Service |
310c69 |
bio_set_dev(bio, device);
|
|
Packit Service |
310c69 |
#else
|
|
Packit Service |
310c69 |
bio->bi_bdev = device;
|
|
Packit Service |
310c69 |
#endif
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Get a bio's size.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param bio The bio
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return the bio's size
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline unsigned int getBioSize(BIO *bio)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
#ifdef USE_BI_ITER
|
|
Packit Service |
310c69 |
return bio->bi_iter.bi_size;
|
|
Packit Service |
310c69 |
#else
|
|
Packit Service |
310c69 |
return bio->bi_size;
|
|
Packit Service |
310c69 |
#endif
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set the bio's sector.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param bio The bio
|
|
Packit Service |
310c69 |
* @param sector The sector
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void setBioSector(BIO *bio, sector_t sector)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
#ifdef USE_BI_ITER
|
|
Packit Service |
310c69 |
bio->bi_iter.bi_sector = sector;
|
|
Packit Service |
310c69 |
#else
|
|
Packit Service |
310c69 |
bio->bi_sector = sector;
|
|
Packit Service |
310c69 |
#endif
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Get the bio's sector.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param bio The bio
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return the sector
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline sector_t getBioSector(BIO *bio)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
#ifdef USE_BI_ITER
|
|
Packit Service |
310c69 |
return bio->bi_iter.bi_sector;
|
|
Packit Service |
310c69 |
#else
|
|
Packit Service |
310c69 |
return bio->bi_sector;
|
|
Packit Service |
310c69 |
#endif
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Tell the kernel we've completed processing of this bio.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param bio The bio to complete
|
|
Packit Service |
310c69 |
* @param error A system error code, or 0 for success
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline void completeBio(BIO *bio, int error)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)
|
|
Packit Service |
310c69 |
bio->bi_status = errno_to_blk_status(error);
|
|
Packit Service |
310c69 |
bio_endio(bio);
|
|
Packit Service |
310c69 |
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)
|
|
Packit Service |
310c69 |
bio->bi_error = error;
|
|
Packit Service |
310c69 |
bio_endio(bio);
|
|
Packit Service |
310c69 |
#else
|
|
Packit Service |
310c69 |
bio_endio(bio, error);
|
|
Packit Service |
310c69 |
#endif
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Frees up a bio structure
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param bio The bio to free
|
|
Packit Service |
310c69 |
* @param layer The layer the bio was created in
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void freeBio(BIO *bio, KernelLayer *layer);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Count the statistics for the bios. This is used for calls into VDO and
|
|
Packit Service |
310c69 |
* for calls out of VDO.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param bioStats Statistics structure to update
|
|
Packit Service |
310c69 |
* @param bio The bio
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void countBios(AtomicBioStats *bioStats, BIO *bio);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Reset a bio so it can be used again.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param bio The bio to reset
|
|
Packit Service |
310c69 |
* @param layer The physical layer
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void resetBio(BIO *bio, KernelLayer *layer);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Check to see whether a bio's data are all zeroes.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param bio The bio
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return true if the bio's data are all zeroes
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
bool bioIsZeroData(BIO *bio);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Set a bio's data to all zeroes.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param [in] bio The bio
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void bioZeroData(BIO *bio);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Create a new bio structure for kernel buffer storage.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param [in] layer The physical layer
|
|
Packit Service |
310c69 |
* @param [in] data The buffer (can be NULL)
|
|
Packit Service |
310c69 |
* @param [out] bioPtr A pointer to hold new bio
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return VDO_SUCCESS or an error
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
int createBio(KernelLayer *layer, char *data, BIO **bioPtr);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Prepare a BIO to issue a flush to the device below.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param bio The flush BIO
|
|
Packit Service |
310c69 |
* @param context The context for the callback
|
|
Packit Service |
310c69 |
* @param device The device to flush
|
|
Packit Service |
310c69 |
* @param endIOCallback The function to call when the flush is complete
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
void prepareFlushBIO(BIO *bio,
|
|
Packit Service |
310c69 |
void *context,
|
|
Packit Service |
310c69 |
struct block_device *device,
|
|
Packit Service |
310c69 |
bio_end_io_t *endIOCallback);
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**
|
|
Packit Service |
310c69 |
* Perform IO with a bio, waiting for completion and returning its result.
|
|
Packit Service |
310c69 |
* The bio must already have its sector, block device, and operation set.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @param bio The bio to do IO with
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* @return The bio result
|
|
Packit Service |
310c69 |
**/
|
|
Packit Service |
310c69 |
static inline int submitBioAndWait(BIO *bio)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
submit_bio_wait(bio);
|
|
Packit Service |
310c69 |
return getBioResult(bio);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#endif /* BIO_H */
|