// Copyright (c) Vitaliy Filippov, 2019+ // License: VNPL-1.1 or GNU GPL-2.0+ (see README.md for details) #pragma once #include "cluster_client.h" #define PART_SENT 1 #define PART_DONE 2 #define PART_ERROR 4 #define PART_RETRY 8 #define PART_VALID 16 #define CACHE_DIRTY 1 #define CACHE_WRITTEN 2 #define CACHE_FLUSHING 3 #define CACHE_REPEATING 4 #define OP_FLUSH_BUFFER 0x02 #define OP_IMMEDIATE_COMMIT 0x04 struct cluster_buffer_t { uint8_t *buf; uint64_t len; int state; uint64_t flush_id; uint64_t *refcnt; }; typedef std::map::iterator dirty_buf_it_t; class writeback_cache_t { public: uint64_t writeback_bytes = 0; int writeback_queue_size = 0; int writebacks_active = 0; uint64_t last_flush_id = 0; std::map dirty_buffers; std::vector writeback_overflow; std::vector writeback_queue; std::multimap flushed_buffers; // flush_id => refcnt ~writeback_cache_t(); bool has_inode(uint64_t inode); dirty_buf_it_t find_dirty(uint64_t inode, uint64_t offset); bool is_left_merged(dirty_buf_it_t dirty_it); bool is_right_merged(dirty_buf_it_t dirty_it); void copy_write(cluster_op_t *op, int state, uint64_t new_flush_id = 0); int repeat_ops_for(cluster_client_t *cli, osd_num_t peer_osd, pool_id_t pool_id, pg_num_t pg_num); void start_writebacks(cluster_client_t *cli, int count); bool read_from_cache(cluster_op_t *op, uint32_t bitmap_granularity); void flush_buffers(cluster_client_t *cli, dirty_buf_it_t from_it, dirty_buf_it_t to_it); void mark_flush_written(uint64_t inode, uint64_t offset, uint64_t len, uint64_t flush_id); void delete_flush(uint64_t inode, uint64_t offset, uint64_t len, uint64_t flush_id); void fsync_start(); void fsync_error(); void fsync_ok(); };