/** @file file_contexts.h @brief Store the opened file contexts(inode + pid) @details Copyright (c) 2023 Acronis International GmbH @author Bruce Wang ([email protected]) @since $Id: $ */ #pragma once #include "interval_set.h" #include "transport.h" #include "transport_id.h" typedef struct { long long tv_sec; long tv_nsec; } timespec_compat_t; typedef struct { file_key_t file_key; timespec_compat_t i_mtime; /* last modify time */ timespec_compat_t i_ctime; /* last change time */ } file_context_key_t; // This struct is stored in msg_t, to keep the necessary information typedef struct { file_context_key_t key; transport_id_t skipped_transport_ids[MAX_TRANSPORT_SIZE]; } file_context_msg_info_t; // A struct to store the temporary file context information typedef struct { pid_t pid; uint64_t low; uint64_t high; int flags; file_context_msg_info_t msg_info; } file_context_info_t; // Context that is global per file typedef struct { // currently unused } file_context_open_file_t; // Context that is global per file + process typedef struct { atomic_t flags; } file_context_open_process_t; typedef struct { interval_set_t interval_set; spinlock_t spinlock; atomic_t is_reported; } file_context_rw_t; typedef enum { FILE_CONTEXT_OPEN_TABLE = 0, FILE_CONTEXT_READ_TABLE, FILE_CONTEXT_WRITE_TABLE, } file_context_table_type_t; #ifdef HAVE_FILE_CONTEXTS void file_contexts_init(void); void file_contexts_deinit(void); void remove_common_cache_all(const file_key_t* file_key); int acquire_file_context_entry(transport_id_t id); void release_file_context_entry(transport_id_t id); bool check_open_cache(const transport_ids_t* ids, file_context_info_t *info); int add_open_cache(transport_id_t id, const file_context_info_t *info, file_context_open_file_t **file_node, file_context_open_process_t **process_node); void put_open_cache(file_context_open_file_t *file_node, file_context_open_process_t *process_node); file_context_rw_t *add_rw_cache(transport_id_t id, file_context_info_t *info, file_context_table_type_t type); bool check_and_update_read_cache(const transport_ids_t* ids, file_context_info_t *info); bool check_write_cache(const transport_ids_t* ids, file_context_info_t *info, file_context_table_type_t type); void put_rw_cache(file_context_rw_t *node); #else static inline void file_contexts_init(void) {} static inline void file_contexts_deinit(void) {} static inline void remove_common_cache_all(const file_key_t* key) { (void) key; } static inline int acquire_file_context_entry(transport_id_t id) { (void) id; return 0; } static inline void release_file_context_entry(transport_id_t id) { (void) id; } static inline bool check_open_cache(const transport_ids_t* ids, file_context_info_t *info) { (void) ids; (void) info; return false; } static inline int add_open_cache(transport_id_t id, const file_context_info_t *info, file_context_open_file_t **file_node, file_context_open_process_t **process_node) { (void) id; (void) info; (void) file_node; (void) process_node; return 0; } static inline void put_open_cache(file_context_open_file_t *file_node, file_context_open_process_t *process_node) { (void) file_node; (void) process_node; } static inline file_context_rw_t *add_rw_cache(transport_id_t id, file_context_info_t *info, file_context_table_type_t type) { (void) id; (void) info; (void) type; return NULL; } static inline bool check_and_update_read_cache(const transport_ids_t* ids, file_context_info_t *info) { (void) ids; (void) info; return false; } static inline bool check_write_cache(const transport_ids_t* ids, file_context_info_t *info, file_context_table_type_t type) { (void) ids; (void) info; (void) type; return false; } static inline void put_rw_cache(file_context_rw_t *node) { (void) node; } #endif