diff options
Diffstat (limited to 'fs/incfs/data_mgmt.h')
-rw-r--r-- | fs/incfs/data_mgmt.h | 130 |
1 files changed, 78 insertions, 52 deletions
diff --git a/fs/incfs/data_mgmt.h b/fs/incfs/data_mgmt.h index 6722cef1608c..b7aecdd5bf4a 100644 --- a/fs/incfs/data_mgmt.h +++ b/fs/incfs/data_mgmt.h @@ -20,63 +20,74 @@ #define SEGMENTS_PER_FILE 3 -struct read_log_record { - u32 bitfield; - - u64 timestamp_us; +enum LOG_RECORD_TYPE { + FULL, + SAME_FILE, + SAME_FILE_NEXT_BLOCK, + SAME_FILE_NEXT_BLOCK_SHORT, +}; +struct full_record { + enum LOG_RECORD_TYPE type : 2; /* FULL */ + u32 block_index : 30; incfs_uuid_t file_id; -} __packed; - -#define RLR_BLOCK_INDEX_MASK 0x7fff -#define RLR_TIMED_OUT_MASK 0x8000 - -static inline u32 get_block_index(const struct read_log_record *rlr) -{ - return rlr->bitfield & RLR_BLOCK_INDEX_MASK; -} + u64 absolute_ts_us; +} __packed; /* 28 bytes */ + +struct same_file_record { + enum LOG_RECORD_TYPE type : 2; /* SAME_FILE */ + u32 block_index : 30; + u32 relative_ts_us; /* max 2^32 us ~= 1 hour (1:11:30) */ +} __packed; /* 12 bytes */ + +struct same_file_next_block { + enum LOG_RECORD_TYPE type : 2; /* SAME_FILE_NEXT_BLOCK */ + u32 relative_ts_us : 30; /* max 2^30 us ~= 15 min (17:50) */ +} __packed; /* 4 bytes */ + +struct same_file_next_block_short { + enum LOG_RECORD_TYPE type : 2; /* SAME_FILE_NEXT_BLOCK_SHORT */ + u16 relative_ts_us : 14; /* max 2^14 us ~= 16 ms */ +} __packed; /* 2 bytes */ + +union log_record { + struct full_record full_record; + struct same_file_record same_file_record; + struct same_file_next_block same_file_next_block; + struct same_file_next_block_short same_file_next_block_short; +}; -static inline void set_block_index(struct read_log_record *rlr, - u32 block_index) -{ - rlr->bitfield = (rlr->bitfield & ~RLR_BLOCK_INDEX_MASK) - | (block_index & RLR_BLOCK_INDEX_MASK); -} +struct read_log_state { + /* Log buffer generation id, incremented on configuration changes */ + u32 generation_id; -static inline bool get_timed_out(const struct read_log_record *rlr) -{ - return (rlr->bitfield & RLR_TIMED_OUT_MASK) == RLR_TIMED_OUT_MASK; -} + /* Offset in rl_ring_buf to write into. */ + u32 next_offset; -static inline void set_timed_out(struct read_log_record *rlr, bool timed_out) -{ - if (timed_out) - rlr->bitfield |= RLR_TIMED_OUT_MASK; - else - rlr->bitfield &= ~RLR_TIMED_OUT_MASK; -} + /* Current number of writer passes over rl_ring_buf */ + u32 current_pass_no; -struct read_log_state { - /* Next slot in rl_ring_buf to write to. */ - u32 next_index; + /* Current full_record to diff against */ + struct full_record base_record; - /* Current number of writer pass over rl_ring_buf */ - u32 current_pass_no; + /* Current record number counting from configuration change */ + u64 current_record_no; }; /* A ring buffer to save records about data blocks which were recently read. */ struct read_log { - struct read_log_record *rl_ring_buf; + void *rl_ring_buf; - struct read_log_state rl_state; + int rl_size; - spinlock_t rl_writer_lock; + struct read_log_state rl_head; - int rl_size; + struct read_log_state rl_tail; - /* - * A queue of waiters who want to be notified about reads. - */ + /* A lock to protect the above fields */ + spinlock_t rl_lock; + + /* A queue of waiters who want to be notified about reads */ wait_queue_head_t ml_notif_wq; }; @@ -131,6 +142,12 @@ struct mount_info { /* Temporary buffer for read logger. */ struct read_log mi_log; + + void *log_xattr; + size_t log_xattr_size; + + void *pending_read_xattr; + size_t pending_read_xattr_size; }; struct data_file_block { @@ -203,16 +220,20 @@ struct data_file { /* File size in bytes */ loff_t df_size; - int df_block_count; /* File size in DATA_FILE_BLOCK_SIZE blocks */ + /* File header flags */ + u32 df_header_flags; + + /* File size in DATA_FILE_BLOCK_SIZE blocks */ + int df_data_block_count; + + /* Total number of blocks, data + hash */ + int df_total_block_count; struct file_attr n_attr; struct mtree *df_hash_tree; - struct ondisk_signature *df_signature; - - /* True, if file signature has already been validated. */ - bool df_signature_validated; + struct incfs_df_signature *df_signature; }; struct dir_file { @@ -239,6 +260,9 @@ struct mount_info *incfs_alloc_mount_info(struct super_block *sb, struct mount_options *options, struct path *backing_dir_path); +int incfs_realloc_mount_info(struct mount_info *mi, + struct mount_options *options); + void incfs_free_mount_info(struct mount_info *mi); struct data_file *incfs_open_data_file(struct mount_info *mi, struct file *bf); @@ -253,14 +277,16 @@ ssize_t incfs_read_data_file_block(struct mem_range dst, struct data_file *df, int index, int timeout_ms, struct mem_range tmp); +int incfs_get_filled_blocks(struct data_file *df, + struct incfs_get_filled_blocks_args *arg); + int incfs_read_file_signature(struct data_file *df, struct mem_range dst); int incfs_process_new_data_block(struct data_file *df, - struct incfs_new_data_block *block, u8 *data); + struct incfs_fill_block *block, u8 *data); int incfs_process_new_hash_block(struct data_file *df, - struct incfs_new_data_block *block, u8 *data); - + struct incfs_fill_block *block, u8 *data); bool incfs_fresh_pending_reads_exist(struct mount_info *mi, int last_number); @@ -279,7 +305,7 @@ int incfs_collect_logged_reads(struct mount_info *mi, int reads_size); struct read_log_state incfs_get_log_state(struct mount_info *mi); int incfs_get_uncollected_logs_count(struct mount_info *mi, - struct read_log_state state); + const struct read_log_state *state); static inline struct inode_info *get_incfs_node(struct inode *inode) { @@ -297,7 +323,7 @@ static inline struct inode_info *get_incfs_node(struct inode *inode) static inline struct data_file *get_incfs_data_file(struct file *f) { - struct inode_info *node; + struct inode_info *node = NULL; if (!f) return NULL; |