]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/store/Disk.cc
6a0af3f1dacbe09676952236a5726a36f606792d
2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
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.
9 /* DEBUG: section 20 Swap Dir base object */
13 #include "compat/strtoll.h"
14 #include "ConfigOption.h"
15 #include "ConfigParser.h"
18 #include "SquidConfig.h"
20 #include "store/Disk.h"
21 #include "StoreFileSystem.h"
24 Store::Disk::Disk(char const *aType
): theType(aType
),
25 max_size(0), min_objsize(-1), max_objsize (-1),
26 path(NULL
), index(-1), disker(-1),
27 repl(NULL
), removals(0), scanned(0),
35 // TODO: should we delete repl?
40 Store::Disk::create() {}
43 Store::Disk::dump(StoreEntry
&)const {}
46 Store::Disk::doubleCheck(StoreEntry
&)
52 Store::Disk::getStats(StoreInfoStats
&stats
) const
57 stats
.swap
.size
= currentSize();
58 stats
.swap
.capacity
= maxSize();
59 stats
.swap
.count
= currentCount();
63 Store::Disk::stat(StoreEntry
&output
) const
68 storeAppendPrintf(&output
, "Store Directory #%d (%s): %s\n", index
, type(),
70 storeAppendPrintf(&output
, "FS Block Size %d Bytes\n",
75 storeAppendPrintf(&output
, "Removal policy: %s\n", repl
->_type
);
78 repl
->Stats(repl
, &output
);
83 Store::Disk::statfs(StoreEntry
&)const {}
86 Store::Disk::maintain() {}
89 Store::Disk::minSize() const
91 // XXX: Not all disk stores use Config.Swap.lowWaterMark
92 return ((maxSize() * Config
.Swap
.lowWaterMark
) / 100);
96 Store::Disk::minObjectSize() const
98 // per-store min-size=N value is authoritative
99 return min_objsize
> -1 ? min_objsize
: Config
.Store
.minObjectSize
;
103 Store::Disk::maxObjectSize() const
105 // per-store max-size=N value is authoritative
106 if (max_objsize
> -1)
109 // store with no individual max limit is limited by configured maximum_object_size
110 // or the total store size, whichever is smaller
111 return min(static_cast<int64_t>(maxSize()), Config
.Store
.maxObjectSize
);
115 Store::Disk::maxObjectSize(int64_t newMax
)
117 // negative values mean no limit (-1)
119 max_objsize
= -1; // set explicitly in case it had a non-default value previously
123 // prohibit values greater than total storage area size
124 // but set max_objsize to the maximum allowed to override maximum_object_size global config
125 if (static_cast<uint64_t>(newMax
) > maxSize()) {
126 debugs(47, DBG_PARSE_NOTE(2), "WARNING: Ignoring 'max-size' option for " << path
<<
127 " which is larger than total cache_dir size of " << maxSize() << " bytes.");
128 max_objsize
= maxSize();
132 max_objsize
= newMax
;
136 Store::Disk::reference(StoreEntry
&) {}
139 Store::Disk::dereference(StoreEntry
&)
141 return true; // keep in global store_table
145 Store::Disk::diskFull()
147 if (currentSize() >= maxSize())
150 max_size
= currentSize();
152 debugs(20, DBG_IMPORTANT
, "WARNING: Shrinking cache_dir #" << index
<< " to " << currentSize() / 1024.0 << " KB");
156 Store::Disk::objectSizeIsAcceptable(int64_t objsize
) const
158 // need either the expected or the already accumulated object size
159 assert(objsize
>= 0);
160 return minObjectSize() <= objsize
&& objsize
<= maxObjectSize();
164 Store::Disk::canStore(const StoreEntry
&e
, int64_t diskSpaceNeeded
, int &load
) const
166 debugs(47,8, HERE
<< "cache_dir[" << index
<< "]: needs " <<
167 diskSpaceNeeded
<< " <? " << max_objsize
);
169 if (EBIT_TEST(e
.flags
, ENTRY_SPECIAL
))
170 return false; // we do not store Squid-generated entries
172 if (!objectSizeIsAcceptable(diskSpaceNeeded
))
173 return false; // does not satisfy size limits
176 return false; // cannot write at all
178 if (currentSize() > maxSize())
179 return false; // already overflowing
181 /* Return 999 (99.9%) constant load; TODO: add a named constant for this */
183 return true; // kids may provide more tests and should report true load
186 /* Move to StoreEntry ? */
188 Store::Disk::canLog(StoreEntry
const &e
)const
190 if (e
.swap_filen
< 0)
193 if (e
.swap_status
!= SWAPOUT_DONE
)
196 if (e
.swap_file_sz
<= 0)
199 if (EBIT_TEST(e
.flags
, RELEASE_REQUEST
))
202 if (EBIT_TEST(e
.flags
, KEY_PRIVATE
))
205 if (EBIT_TEST(e
.flags
, ENTRY_SPECIAL
))
212 Store::Disk::openLog() {}
215 Store::Disk::closeLog() {}
218 Store::Disk::writeCleanStart()
224 Store::Disk::writeCleanDone() {}
227 Store::Disk::logEntry(const StoreEntry
&, int) const {}
230 Store::Disk::type() const
236 Store::Disk::active() const
238 if (IamWorkerProcess())
241 // we are inside a disker dedicated to this disk
242 if (KidIdentifier
== disker
)
245 return false; // Coordinator, wrong disker, etc.
249 Store::Disk::needsDiskStrand() const
254 /* NOT performance critical. Really. Don't bother optimising for speed
258 Store::Disk::getOptionTree() const
260 ConfigOptionVector
*result
= new ConfigOptionVector
;
261 result
->options
.push_back(new ConfigOptionAdapter
<Disk
>(*const_cast<Disk
*>(this), &Store::Disk::optionReadOnlyParse
, &Store::Disk::optionReadOnlyDump
));
262 result
->options
.push_back(new ConfigOptionAdapter
<Disk
>(*const_cast<Disk
*>(this), &Store::Disk::optionObjectSizeParse
, &Store::Disk::optionObjectSizeDump
));
267 Store::Disk::parseOptions(int isaReconfig
)
269 const bool old_read_only
= flags
.read_only
;
272 ConfigOption
*newOption
= getOptionTree();
274 while ((name
= ConfigParser::NextToken()) != NULL
) {
275 value
= strchr(name
, '=');
278 *value
= '\0'; /* cut on = */
282 debugs(3,2, "cache_dir " << name
<< '=' << (value
? value
: ""));
285 if (!newOption
->parse(name
, value
, isaReconfig
)) {
294 * Handle notifications about reconfigured single-options with no value
295 * where the removal of the option cannot be easily detected in the
300 if (old_read_only
!= flags
.read_only
) {
301 debugs(3, DBG_IMPORTANT
, "Cache dir '" << path
<< "' now " << (flags
.read_only
? "No-Store" : "Read-Write"));
307 Store::Disk::dumpOptions(StoreEntry
* entry
) const
309 ConfigOption
*newOption
= getOptionTree();
312 newOption
->dump(entry
);
318 Store::Disk::optionReadOnlyParse(char const *option
, const char *value
, int)
320 if (strcmp(option
, "no-store") != 0 && strcmp(option
, "read-only") != 0)
323 if (strcmp(option
, "read-only") == 0) {
324 debugs(3, DBG_PARSE_NOTE(3), "UPGRADE WARNING: Replace cache_dir option 'read-only' with 'no-store'.");
330 read_only
= (xatoi(value
) != 0);
334 flags
.read_only
= read_only
;
340 Store::Disk::optionReadOnlyDump(StoreEntry
* e
) const
343 storeAppendPrintf(e
, " no-store");
347 Store::Disk::optionObjectSizeParse(char const *option
, const char *value
, int isaReconfig
)
350 if (strcmp(option
, "max-size") == 0) {
352 } else if (strcmp(option
, "min-size") == 0) {
362 int64_t size
= strtoll(value
, NULL
, 10);
364 if (isaReconfig
&& *val
!= size
) {
365 if (allowOptionReconfigure(option
)) {
366 debugs(3, DBG_IMPORTANT
, "cache_dir '" << path
<< "' object " <<
367 option
<< " now " << size
<< " Bytes");
369 debugs(3, DBG_IMPORTANT
, "WARNING: cache_dir '" << path
<< "' "
370 "object " << option
<< " cannot be changed dynamically, " <<
371 "value left unchanged (" << *val
<< " Bytes)");
382 Store::Disk::optionObjectSizeDump(StoreEntry
* e
) const
384 if (min_objsize
!= -1)
385 storeAppendPrintf(e
, " min-size=%" PRId64
, min_objsize
);
387 if (max_objsize
!= -1)
388 storeAppendPrintf(e
, " max-size=%" PRId64
, max_objsize
);
391 // some SwapDirs may maintain their indexes and be able to lookup an entry key
393 Store::Disk::get(const cache_key
*)