1 /** @file 2 3 A brief file description 4 5 @section license License 6 7 Licensed to the Apache Software Foundation (ASF) under one 8 or more contributor license agreements. See the NOTICE file 9 distributed with this work for additional information 10 regarding copyright ownership. The ASF licenses this file 11 to you under the Apache License, Version 2.0 (the 12 "License"); you may not use this file except in compliance 13 with the License. You may obtain a copy of the License at 14 15 http://www.apache.org/licenses/LICENSE-2.0 16 17 Unless required by applicable law or agreed to in writing, software 18 distributed under the License is distributed on an "AS IS" BASIS, 19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 See the License for the specific language governing permissions and 21 limitations under the License. 22 */ 23 24 #pragma once 25 26 #include "I_Cache.h" 27 28 extern int cache_config_max_disk_errors; 29 30 #define DISK_BAD(_x) ((_x)->num_errors >= cache_config_max_disk_errors) 31 #define DISK_BAD_SIGNALLED(_x) (_x->num_errors > cache_config_max_disk_errors) 32 #define SET_DISK_BAD(_x) (_x->num_errors = cache_config_max_disk_errors) 33 #define SET_DISK_OKAY(_x) (_x->num_errors = 0) 34 35 #define VOL_BLOCK_SIZE (1024 * 1024 * 128) 36 #define MIN_VOL_SIZE VOL_BLOCK_SIZE 37 #define ROUND_DOWN_TO_VOL_BLOCK(_x) (((_x) & ~(VOL_BLOCK_SIZE - 1))) 38 #define VOL_BLOCK_SHIFT 27 39 #define ROUND_DOWN_TO_STORE_BLOCK(_x) (((_x) >> STORE_BLOCK_SHIFT) << STORE_BLOCK_SHIFT) 40 41 #define STORE_BLOCKS_PER_VOL (VOL_BLOCK_SIZE / STORE_BLOCK_SIZE) 42 #define DISK_HEADER_MAGIC 0xABCD1237 43 44 /* each disk vol block has a corresponding Vol object */ 45 struct CacheDisk; 46 47 struct DiskVolBlock { 48 uint64_t offset; // offset in bytes from the start of the disk 49 uint64_t len; // length in in store blocks 50 int number; 51 unsigned int type : 3; 52 unsigned int free : 1; 53 }; 54 55 struct DiskVolBlockQueue { 56 DiskVolBlock *b = nullptr; 57 int new_block = 0; /* whether an existing vol or a new one */ 58 LINK(DiskVolBlockQueue, link); 59 DiskVolBlockQueueDiskVolBlockQueue60 DiskVolBlockQueue() {} 61 }; 62 63 struct DiskVol { 64 int num_volblocks; /* number of disk volume blocks in this volume */ 65 int vol_number; /* the volume number of this volume */ 66 uint64_t size; /* size in store blocks */ 67 CacheDisk *disk; 68 Queue<DiskVolBlockQueue> dpb_queue; 69 }; 70 71 struct DiskHeader { 72 unsigned int magic; 73 unsigned int num_volumes; /* number of discrete volumes (DiskVol) */ 74 unsigned int num_free; /* number of disk volume blocks free */ 75 unsigned int num_used; /* number of disk volume blocks in use */ 76 unsigned int num_diskvol_blks; /* number of disk volume blocks */ 77 uint64_t num_blocks; 78 DiskVolBlock vol_info[1]; 79 }; 80 81 struct CacheDisk : public Continuation { 82 DiskHeader *header = nullptr; 83 char *path = nullptr; 84 int header_len = 0; 85 AIOCallbackInternal io; 86 off_t len = 0; // in blocks (STORE_BLOCK) 87 off_t start = 0; 88 off_t skip = 0; 89 off_t num_usable_blocks = 0; 90 int hw_sector_size = 0; 91 int fd = -1; 92 off_t free_space = 0; 93 off_t wasted_space = 0; 94 DiskVol **disk_vols = nullptr; 95 DiskVol *free_blocks = nullptr; 96 int num_errors = 0; 97 int cleared = 0; 98 bool read_only_p = false; 99 bool online = true; /* flag marking cache disk online or offline (because of too many failures or by the operator). */ 100 101 // Extra configuration values 102 int forced_volume_num = -1; ///< Volume number for this disk. 103 ats_scoped_str hash_base_string; ///< Base string for hash seed. 104 CacheDiskCacheDisk105 CacheDisk() : Continuation(new_ProxyMutex()) {} 106 107 ~CacheDisk() override; 108 109 int open(bool clear); 110 int open(char *s, off_t blocks, off_t skip, int hw_sector_size, int fildes, bool clear); 111 int clearDisk(); 112 int clearDone(int event, void *data); 113 int openStart(int event, void *data); 114 int openDone(int event, void *data); 115 int sync(); 116 int syncDone(int event, void *data); 117 DiskVolBlock *create_volume(int number, off_t size, int scheme); 118 int delete_volume(int number); 119 int delete_all_volumes(); 120 void update_header(); 121 DiskVol *get_diskvol(int vol_number); 122 void incrErrors(const AIOCallback *io); 123 }; 124