1 /*
2  * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 #ifndef SQUID_STORE_DISK_H
10 #define SQUID_STORE_DISK_H
11 
12 #include "store/Controlled.h"
13 #include "StoreIOState.h"
14 
15 class ConfigOption;
16 class RemovalPolicy;
17 
18 namespace Store {
19 
20 /// manages a single cache_dir
21 class Disk: public Controlled
22 {
23 
24 public:
25     typedef RefCount<Disk> Pointer;
26 
27     explicit Disk(char const *aType);
28     virtual ~Disk();
29     virtual void reconfigure() = 0;
30     char const *type() const;
31 
32     virtual bool needsDiskStrand() const; ///< needs a dedicated kid process
33     virtual bool active() const; ///< may be used in this strand
34     /// whether stat should be reported by this SwapDir
doReportStat()35     virtual bool doReportStat() const { return active(); }
36     /// whether SwapDir may benefit from unlinkd
37     virtual bool unlinkdUseful() const = 0;
38 
39     /**
40      * Notify this disk that it is full.
41      \todo XXX move into a protected api call between store files and their stores, rather than a top level api call
42      */
43     virtual void diskFull();
44 
45     /* Controlled API */
46     virtual void create() override;
47     virtual StoreEntry *get(const cache_key *) override;
maxSize()48     virtual uint64_t maxSize() const override { return max_size; }
49     virtual uint64_t minSize() const override;
50     virtual int64_t maxObjectSize() const override;
51     virtual void getStats(StoreInfoStats &stats) const override;
52     virtual void stat(StoreEntry &) const override;
53     virtual void reference(StoreEntry &e) override;
54     virtual bool dereference(StoreEntry &e) override;
55     virtual void maintain() override;
smpAware()56     virtual bool smpAware() const override { return false; }
57 
58     /// the size of the smallest entry this cache_dir can store
59     int64_t minObjectSize() const;
60 
61     /// configure the maximum object size for this storage area.
62     /// May be any size up to the total storage area.
63     void maxObjectSize(int64_t newMax);
64 
65     /// whether we can store an object of the given size
66     /// negative objSize means the object size is currently unknown
67     bool objectSizeIsAcceptable(int64_t objSize) const;
68 
69     /// called when the entry is about to forget its association with cache_dir
disconnect(StoreEntry &)70     virtual void disconnect(StoreEntry &) {}
71 
72     /// finalize the successful swapout that has been already noticed by Store
73     virtual void finalizeSwapoutSuccess(const StoreEntry &) = 0;
74     /// abort the failed swapout that has been already noticed by Store
75     virtual void finalizeSwapoutFailure(StoreEntry &) = 0;
76 
77     /// whether this cache dir has an entry with `e.key`
78     virtual bool hasReadableEntry(const StoreEntry &e) const = 0;
79 
80 protected:
81     void parseOptions(int reconfiguring);
82     void dumpOptions(StoreEntry * e) const;
83     virtual ConfigOption *getOptionTree() const;
allowOptionReconfigure(const char * const)84     virtual bool allowOptionReconfigure(const char *const) const { return true; }
85 
sizeInBlocks(const int64_t size)86     int64_t sizeInBlocks(const int64_t size) const { return (size + fs.blksize - 1) / fs.blksize; }
87 
88 private:
89     bool optionReadOnlyParse(char const *option, const char *value, int reconfiguring);
90     void optionReadOnlyDump(StoreEntry * e) const;
91     bool optionObjectSizeParse(char const *option, const char *value, int reconfiguring);
92     void optionObjectSizeDump(StoreEntry * e) const;
93     char const *theType;
94 
95 protected:
96     uint64_t max_size;        ///< maximum allocatable size of the storage area
97     int64_t min_objsize;      ///< minimum size of any object stored here (-1 for no limit)
98     int64_t max_objsize;      ///< maximum size of any object stored here (-1 for no limit)
99 
100 public:
101     char *path;
102     int index;          /* This entry's index into the swapDirs array */
103     int disker; ///< disker kid id dedicated to this SwapDir or -1
104     RemovalPolicy *repl;
105     int removals;
106     int scanned;
107 
108     struct Flags {
FlagsFlags109         Flags() : selected(false), read_only(false) {}
110         bool selected;
111         bool read_only;
112     } flags;
113 
114     virtual void dump(StoreEntry &)const;   /* Dump fs config snippet */
115     virtual bool doubleCheck(StoreEntry &); /* Double check the obj integrity */
116     virtual void statfs(StoreEntry &) const;    /* Dump fs statistics */
117 
118     /// check whether we can store the entry; if we can, report current load
119     virtual bool canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const = 0;
120 
121     virtual StoreIOState::Pointer createStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *) = 0;
122     virtual StoreIOState::Pointer openStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *) = 0;
123 
124     bool canLog(StoreEntry const &e)const;
125     virtual void openLog();
126     virtual void closeLog();
127     virtual void logEntry(const StoreEntry & e, int op) const;
128 
129     class CleanLog
130     {
131 
132     public:
~CleanLog()133         virtual ~CleanLog() {}
134 
135         virtual const StoreEntry *nextEntry() = 0;
136         virtual void write(StoreEntry const &) = 0;
137     };
138 
139     CleanLog *cleanLog;
140     virtual int writeCleanStart();
141     virtual void writeCleanDone();
142     virtual void parse(int index, char *path) = 0;
143 
144     struct {
145         int blksize;
146     } fs;
147 };
148 
149 } // namespace Store
150 
151 #endif /* SQUID_STORE_DISK_H */
152 
153