HEX
Server: LiteSpeed
System: Linux CentOS-79-64-minimal 3.10.0-1160.119.1.el7.x86_64 #1 SMP Tue Jun 4 14:43:51 UTC 2024 x86_64
User: vishn3436 (5293)
PHP: 8.0.15
Disabled: NONE
Upload Files
File: //usr/src/dattobd-0.11.2/bio_helper.h
// SPDX-License-Identifier: GPL-2.0-only

/*
 * Copyright (C) 2022 Datto Inc.
 */

#ifndef BIO_HELPER_H

#define BIO_HELPER_H

#include "includes.h"
#include "tracing_params.h"

//#if LINUX_VERSION_CODE < KERNEL_VERSION(4,17,0)
#ifndef SECTOR_SHIFT
#define SECTOR_SHIFT 9
#endif
#ifndef SECTOR_SIZE
#define SECTOR_SIZE (1 << SECTOR_SHIFT)
#endif

#define SECTORS_PER_BLOCK (COW_BLOCK_SIZE / SECTOR_SIZE)
#define SECTOR_TO_BLOCK(sect) ((sect) / SECTORS_PER_BLOCK)

#if !defined HAVE_MAKE_REQUEST_FN_IN_QUEUE && defined HAVE_BDOPS_SUBMIT_BIO
        // Linux kernel version 5.9+
        // make_request_fn has been moved from the request queue structure to the
        // block_device_operations as submit_bio function.
        // See https://github.com/torvalds/linux/commit/c62b37d96b6eb3ec5ae4cbe00db107bf15aebc93
        #define USE_BDOPS_SUBMIT_BIO
#endif

// macros for working with bios
#define BIO_SET_SIZE 256
#define bio_last_sector(bio) (bio_sector(bio) + (bio_size(bio) / SECTOR_SIZE))

// the kernel changed the usage of bio_for_each_segment in 3.14. Do not use any
// fields directly or you will lose compatibility.
#ifndef HAVE_BVEC_ITER
//#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)
typedef int bio_iter_t;
typedef struct bio_vec *bio_iter_bvec_t;
#define bio_iter_len(bio, iter) ((bio)->bi_io_vec[(iter)].bv_len)
#define bio_iter_offset(bio, iter) ((bio)->bi_io_vec[(iter)].bv_offset)
#define bio_iter_page(bio, iter) ((bio)->bi_io_vec[(iter)].bv_page)
#define bio_iter_idx(iter) (iter)
#define bio_sector(bio) (bio)->bi_sector
#define bio_size(bio) (bio)->bi_size
#define bio_idx(bio) (bio)->bi_idx
#else
typedef struct bvec_iter bio_iter_t;
typedef struct bio_vec bio_iter_bvec_t;
#define bio_iter_idx(iter) ((iter).bi_idx)
#define bio_sector(bio) (bio)->bi_iter.bi_sector
#define bio_size(bio) (bio)->bi_iter.bi_size
#define bio_idx(bio) (bio)->bi_iter.bi_idx
#endif

#ifndef HAVE_BIOSET_INIT
//#if LINUX_VERSION_CODE < KERNEL_VERSION(4,18,0)
#define dev_bioset(dev) ((dev)->sd_bioset)
#else
#define dev_bioset(dev) (&(dev)->sd_bioset)
#endif

struct bio_sector_map {
        struct bio *bio;
        sector_t sect;
        unsigned int size;
        struct bio_sector_map *next;
};

struct request_queue *dattobd_bio_get_queue(struct bio *bio);

void dattobd_bio_set_dev(struct bio *bio, struct block_device *bdev);

void dattobd_bio_copy_dev(struct bio *dst, struct bio *src);

/* don't perform COW operation */
#ifdef HAVE_ENUM_REQ_OP
//#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0) && LINUX_VERSION_CODE <
// KERNEL_VERSION(4,10,0)
/* special case for deb9's 4.9 train
 * Bit 30 conflicts with struct bio's bi_opf opcode bitfield, which occupies the
 * top 3 bits of the member. If we set that bit, it will mutate the operation
 * that the bio is representing. Setting this to 28 puts this in an unused flag
 * for bi_opf (that flag means something in struct request's cmd_flags, but
 * we're not setting that).
 */
#define __DATTOBD_PASSTHROUGH 28 // set as the last flag bit
#else
// set as an unused flag in versions older than 4.8
// set as an unused opcode bit in kernels newer than 4.9
#define __DATTOBD_PASSTHROUGH 30
#endif
#define DATTOBD_PASSTHROUGH (1ULL << __DATTOBD_PASSTHROUGH)

#ifndef HAVE_SUBMIT_BIO_1
//#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0)

#ifndef REQ_DISCARD
#define REQ_DISCARD 0
#endif

#ifndef HAVE_ENUM_REQ_OP
typedef enum req_op {
        REQ_OP_READ,
        REQ_OP_WRITE,
        REQ_OP_DISCARD, /* request to discard sectors */
        REQ_OP_SECURE_ERASE, /* request to securely erase sectors */
        REQ_OP_WRITE_SAME, /* write same block many times */
        REQ_OP_FLUSH, /* request for cache flush */
} req_op_t;

extern void dattobd_set_bio_ops(struct bio *bio, req_op_t op,
                                unsigned op_flags);
#else

typedef enum req_op req_op_t;
#define dattobd_set_bio_ops(bio, op, flags) bio_set_op_attrs(bio, op, flags)

#endif

#define bio_is_discard(bio) ((bio)->bi_rw & REQ_DISCARD)
#define dattobd_submit_bio(bio) submit_bio(0, bio)
#define dattobd_submit_bio_wait(bio) submit_bio_wait(0, bio)

int dattobd_bio_op_flagged(struct bio *bio, unsigned int flag);
void dattobd_bio_op_set_flag(struct bio *bio, unsigned int flag);
void dattobd_bio_op_clear_flag(struct bio *bio, unsigned int flag);

#else

#ifndef HAVE_ENUM_REQ_OPF
//#if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)
typedef enum req_op req_op_t;
#else
typedef enum req_opf req_op_t;
#endif

void dattobd_set_bio_ops(struct bio *bio, req_op_t op, unsigned op_flags);
int dattobd_bio_op_flagged(struct bio *bio, unsigned int flag);
void dattobd_bio_op_set_flag(struct bio *bio, unsigned int flag);
void dattobd_bio_op_clear_flag(struct bio *bio, unsigned int flag);

#ifdef REQ_DISCARD
#define bio_is_discard(bio) ((bio)->bi_opf & REQ_DISCARD)
#else
#define bio_is_discard(bio)                                                    \
        (bio_op(bio) == REQ_OP_DISCARD || bio_op(bio) == REQ_OP_SECURE_ERASE)
#endif

#define dattobd_submit_bio(bio) submit_bio(bio)
#define dattobd_submit_bio_wait(bio) submit_bio_wait(bio)

#endif

struct inode *page_get_inode(struct page *pg);

int bio_needs_cow(struct bio *bio, struct inode *inode);

void bio_free_clone(struct bio *bio);

int bio_make_read_clone(struct bio_set *bs, struct tracing_params *tp,
                        struct bio *orig_bio, sector_t sect, unsigned int pages,
                        struct bio **bio_out, unsigned int *bytes_added);

#ifdef HAVE_BIO_ENDIO_INT
void dattobd_bio_endio(struct bio *bio, int err);
#elif !defined HAVE_BIO_ENDIO_1
void dattobd_bio_endio(struct bio *bio, int err);
#elif defined HAVE_BLK_STATUS_T
void dattobd_bio_endio(struct bio *bio, int err);
#else
void dattobd_bio_endio(struct bio *bio, int err);
#endif

#ifdef HAVE_BIO_BI_BDEV_BD_DISK
    #define dattobd_bio_bi_disk(bio) ((bio)->bi_bdev->bd_disk)
#else
    #define dattobd_bio_bi_disk(bio) ((bio)->bi_disk)
#endif

#endif /* BIO_HELPER_H */