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