]>
Commit | Line | Data |
---|---|---|
4d6d905e | 1 | |
2 | /* | |
47f6e231 | 3 | * $Id: ufscommon.h,v 1.12 2007/08/13 17:20:57 hno Exp $ |
4d6d905e | 4 | * |
5 | * SQUID Web Proxy Cache http://www.squid-cache.org/ | |
6 | * ---------------------------------------------------------- | |
7 | * | |
8 | * Squid is the result of efforts by numerous individuals from | |
9 | * the Internet community; see the CONTRIBUTORS file for full | |
10 | * details. Many organizations have provided support for Squid's | |
11 | * development; see the SPONSORS file for full details. Squid is | |
12 | * Copyrighted (C) 2001 by the Regents of the University of | |
13 | * California; see the COPYRIGHT file for full details. Squid | |
14 | * incorporates software developed and/or copyrighted by other | |
15 | * sources; see the CREDITS file for full details. | |
16 | * | |
17 | * This program is free software; you can redistribute it and/or modify | |
18 | * it under the terms of the GNU General Public License as published by | |
19 | * the Free Software Foundation; either version 2 of the License, or | |
20 | * (at your option) any later version. | |
21 | * | |
22 | * This program is distributed in the hope that it will be useful, | |
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25 | * GNU General Public License for more details. | |
26 | * | |
27 | * You should have received a copy of the GNU General Public License | |
28 | * along with this program; if not, write to the Free Software | |
29 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | |
30 | * | |
31 | */ | |
32 | ||
33 | #ifndef SQUID_UFSCOMMON_H | |
34 | #define SQUID_UFSCOMMON_H | |
35 | ||
36 | #include "squid.h" | |
a553a5a3 | 37 | #include "event.h" |
4d6d905e | 38 | |
39 | #define DefaultLevelOneDirs 16 | |
40 | #define DefaultLevelTwoDirs 256 | |
41 | #define STORE_META_BUFSZ 4096 | |
42 | ||
d3b3ab85 | 43 | /* Common UFS routines */ |
d3b3ab85 | 44 | #include "SwapDir.h" |
c8f4eac4 | 45 | #include "StoreSearch.h" |
4d6d905e | 46 | |
d3b3ab85 | 47 | class UFSStrategy; |
48 | ||
b9ae18aa | 49 | class ConfigOptionVector; |
50 | ||
51 | class DiskIOModule; | |
52 | ||
62e76326 | 53 | class UFSSwapDir : public SwapDir |
54 | { | |
55 | ||
d3b3ab85 | 56 | public: |
62e76326 | 57 | static int IsUFSDir(SwapDir* sd); |
58 | static int DirClean(int swap_index); | |
59 | static int FilenoBelongsHere(int fn, int F0, int F1, int F2); | |
60 | ||
b9ae18aa | 61 | UFSSwapDir(char const *aType, const char *aModuleType); |
62e76326 | 62 | virtual void init(); |
c8f4eac4 | 63 | virtual void create(); |
62e76326 | 64 | virtual void dump(StoreEntry &) const; |
65 | ~UFSSwapDir(); | |
30abd221 | 66 | virtual StoreSearch *search(String const url, HttpRequest *); |
62e76326 | 67 | virtual bool doubleCheck(StoreEntry &); |
59b2d47f | 68 | virtual void unlink(StoreEntry &); |
62e76326 | 69 | virtual void statfs(StoreEntry &)const; |
c8f4eac4 | 70 | virtual void maintain(); |
59b2d47f | 71 | virtual int canStore(StoreEntry const &)const; |
62e76326 | 72 | virtual void reference(StoreEntry &); |
73 | virtual void dereference(StoreEntry &); | |
4fcc8876 | 74 | virtual StoreIOState::Pointer createStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *); |
75 | virtual StoreIOState::Pointer openStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *); | |
62e76326 | 76 | virtual void openLog(); |
77 | virtual void closeLog(); | |
78 | virtual int writeCleanStart(); | |
79 | virtual void writeCleanDone(); | |
80 | virtual void logEntry(const StoreEntry & e, int op) const; | |
81 | virtual void parse(int index, char *path); | |
82 | virtual void reconfigure(int, char *); | |
59b2d47f | 83 | virtual int callback(); |
84 | virtual void sync(); | |
62e76326 | 85 | |
86 | void unlinkFile(sfileno f); | |
62e76326 | 87 | // move down when unlink is a virtual method |
88 | //protected: | |
89 | UFSStrategy *IO; | |
90 | char *fullPath(sfileno, char *) const; | |
91 | /* temp */ | |
92 | void closeTmpSwapLog(); | |
93 | FILE *openTmpSwapLog(int *clean_flag, int *zero_flag); | |
94 | char *swapSubDir(int subdirn) const; | |
95 | int mapBitTest(sfileno filn); | |
96 | void mapBitReset(sfileno filn); | |
97 | void mapBitSet(sfileno filn); | |
98 | StoreEntry *addDiskRestore(const cache_key * key, | |
99 | sfileno file_number, | |
47f6e231 | 100 | uint64_t swap_file_sz, |
62e76326 | 101 | time_t expires, |
102 | time_t timestamp, | |
103 | time_t lastref, | |
104 | time_t lastmod, | |
105 | u_int32_t refcount, | |
106 | u_int16_t flags, | |
107 | int clean); | |
108 | int validFileno(sfileno filn, int flag) const; | |
109 | int mapBitAllocate(); | |
b9ae18aa | 110 | virtual ConfigOption *getOptionTree() const; |
59b2d47f | 111 | |
d3b3ab85 | 112 | void *fsdata; |
113 | ||
114 | bool validL2(int) const; | |
115 | bool validL1(int) const; | |
116 | ||
117 | void replacementAdd(StoreEntry *e); | |
118 | void replacementRemove(StoreEntry *e); | |
62e76326 | 119 | |
d3b3ab85 | 120 | protected: |
4d6d905e | 121 | fileMap *map; |
122 | int suggest; | |
d3b3ab85 | 123 | int l1; |
124 | int l2; | |
62e76326 | 125 | |
d3b3ab85 | 126 | private: |
59b2d47f | 127 | void parseSizeL1L2(); |
d3b3ab85 | 128 | static int NumberOfUFSDirs; |
129 | static int * UFSDirToGlobalDirMapping; | |
130 | bool pathIsDirectory(const char *path)const; | |
131 | int swaplog_fd; | |
62e76326 | 132 | static EVH CleanEvent; |
62e76326 | 133 | bool verifyCacheDirs(); |
134 | void rebuild(); | |
135 | int createDirectory(const char *path, int); | |
136 | void createSwapSubDirs(); | |
137 | void dumpEntry(StoreEntry &) const; | |
138 | char *logFile(char const *ext = NULL)const; | |
b9ae18aa | 139 | void changeIO(DiskIOModule *); |
140 | bool optionIOParse(char const *option, const char *value, int reconfiguring); | |
141 | void optionIODump(StoreEntry * e) const; | |
e2a8733e | 142 | mutable ConfigOptionVector *currentIOOptions; |
b9ae18aa | 143 | char const *ioType; |
d3b3ab85 | 144 | |
145 | }; | |
146 | ||
147 | #include "RefCount.h" | |
b9ae18aa | 148 | #include "DiskIO/IORequestor.h" |
d3b3ab85 | 149 | |
b7717b61 | 150 | /* UFS dir specific IO calls |
151 | * | |
152 | * This should be whittled away - DiskIOModule should be providing the | |
153 | * entire needed api. | |
154 | */ | |
62e76326 | 155 | |
b9ae18aa | 156 | class DiskIOStrategy; |
d3b3ab85 | 157 | |
b9ae18aa | 158 | class DiskFile; |
62e76326 | 159 | |
d3b3ab85 | 160 | class UFSStrategy |
161 | { | |
62e76326 | 162 | |
d3b3ab85 | 163 | public: |
b9ae18aa | 164 | UFSStrategy (DiskIOStrategy *); |
165 | virtual ~UFSStrategy (); | |
166 | /* Not implemented */ | |
167 | UFSStrategy (UFSStrategy const &); | |
168 | UFSStrategy &operator=(UFSStrategy const &); | |
62e76326 | 169 | |
b9ae18aa | 170 | virtual bool shedLoad(); |
62e76326 | 171 | |
b9ae18aa | 172 | virtual int load(); |
173 | ||
4fcc8876 | 174 | StoreIOState::Pointer createState(SwapDir *SD, StoreEntry *e, StoreIOState::STIOCB * callback, void *callback_data) const; |
62e76326 | 175 | /* UFS specific */ |
b9ae18aa | 176 | virtual RefCount<DiskFile> newFile (char const *path); |
4fcc8876 | 177 | StoreIOState::Pointer open(SwapDir *, StoreEntry *, StoreIOState::STFNCB *, |
178 | StoreIOState::STIOCB *, void *); | |
179 | StoreIOState::Pointer create(SwapDir *, StoreEntry *, StoreIOState::STFNCB *, | |
180 | StoreIOState::STIOCB *, void *); | |
59b2d47f | 181 | |
b9ae18aa | 182 | virtual void unlinkFile (char const *); |
183 | virtual void sync(); | |
59b2d47f | 184 | |
b9ae18aa | 185 | virtual int callback(); |
59b2d47f | 186 | |
187 | /* Init per-instance logic */ | |
b9ae18aa | 188 | virtual void init(); |
59b2d47f | 189 | |
190 | /* cachemgr output on the IO instance stats */ | |
b9ae18aa | 191 | virtual void statfs(StoreEntry & sentry)const; |
59b2d47f | 192 | |
b7717b61 | 193 | /* The io strategy in use */ |
194 | DiskIOStrategy *io; | |
b9ae18aa | 195 | protected: |
59b2d47f | 196 | |
b9ae18aa | 197 | friend class UFSSwapDir; |
d3b3ab85 | 198 | }; |
199 | ||
200 | /* Common ufs-store-dir logic */ | |
62e76326 | 201 | |
b9ae18aa | 202 | class ReadRequest; |
203 | ||
e877aaac | 204 | class UFSStoreState : public StoreIOState, public IORequestor |
62e76326 | 205 | { |
206 | ||
207 | public: | |
59b2d47f | 208 | void * operator new (size_t); |
209 | void operator delete (void *); | |
210 | UFSStoreState(SwapDir * SD, StoreEntry * anEntry, STIOCB * callback_, void *callback_data_); | |
d3b3ab85 | 211 | ~UFSStoreState(); |
59b2d47f | 212 | virtual void close(); |
213 | virtual void closeCompleted(); | |
62e76326 | 214 | // protected: |
59b2d47f | 215 | virtual void ioCompletedNotification(); |
b9ae18aa | 216 | virtual void readCompleted(const char *buf, int len, int errflag, RefCount<ReadRequest>); |
217 | virtual void writeCompleted(int errflag, size_t len, RefCount<WriteRequest>); | |
218 | RefCount<DiskFile> theFile; | |
d3b3ab85 | 219 | bool opening; |
220 | bool creating; | |
221 | bool closing; | |
222 | bool reading; | |
223 | bool writing; | |
224 | void read_(char *buf, size_t size, off_t offset, STRCB * callback, void *callback_data); | |
528b2c61 | 225 | void write(char const *buf, size_t size, off_t offset, FREE * free_func); |
62e76326 | 226 | |
227 | protected: | |
3e2cded3 | 228 | virtual void doCloseCallback (int errflag); |
62e76326 | 229 | |
230 | class _queued_read | |
231 | { | |
232 | ||
233 | public: | |
b001e822 | 234 | MEMPROXY_CLASS(UFSStoreState::_queued_read); |
62e76326 | 235 | char *buf; |
236 | size_t size; | |
237 | off_t offset; | |
238 | STRCB *callback; | |
239 | void *callback_data; | |
240 | ||
d3b3ab85 | 241 | }; |
62e76326 | 242 | |
243 | class _queued_write | |
244 | { | |
245 | ||
246 | public: | |
b001e822 | 247 | MEMPROXY_CLASS(UFSStoreState::_queued_write); |
62e76326 | 248 | char const *buf; |
249 | size_t size; | |
250 | off_t offset; | |
251 | FREE *free_func; | |
252 | ||
d3b3ab85 | 253 | }; |
62e76326 | 254 | |
59b2d47f | 255 | /* These should be in the IO strategy */ |
256 | ||
257 | struct | |
258 | { | |
1e0d7905 | 259 | /* |
260 | * DPW 2006-05-24 | |
261 | * the write_draining flag is used to avoid recursion inside | |
262 | * the UFSStoreState::drainWriteQueue() method. | |
263 | */ | |
264 | bool write_draining; | |
265 | /* | |
266 | * DPW 2006-05-24 | |
267 | * The try_closing flag is set by UFSStoreState::tryClosing() | |
268 | * when UFSStoreState wants to close the file, but cannot | |
269 | * because of pending I/Os. If set, UFSStoreState will | |
270 | * try to close again in the I/O callbacks. | |
271 | */ | |
272 | bool try_closing; | |
59b2d47f | 273 | } |
274 | ||
275 | flags; | |
d3b3ab85 | 276 | link_list *pending_reads; |
277 | link_list *pending_writes; | |
278 | void queueRead(char *, size_t, off_t, STRCB *, void *); | |
528b2c61 | 279 | void queueWrite(char const *, size_t, off_t, FREE *); |
d3b3ab85 | 280 | bool kickReadQueue(); |
1e0d7905 | 281 | void drainWriteQueue(); |
282 | void tryClosing(); | |
d3b3ab85 | 283 | char *read_buf; |
59b2d47f | 284 | |
285 | private: | |
286 | CBDATA_CLASS(UFSStoreState); | |
287 | void openDone(); | |
1e0d7905 | 288 | void freePending(); |
289 | void doWrite(); | |
d3b3ab85 | 290 | }; |
291 | ||
b001e822 | 292 | MEMPROXY_CLASS_INLINE(UFSStoreState::_queued_read) |
293 | MEMPROXY_CLASS_INLINE(UFSStoreState::_queued_write) | |
294 | ||
c8f4eac4 | 295 | class StoreSearchUFS : public StoreSearch |
296 | { | |
297 | ||
298 | public: | |
299 | StoreSearchUFS(RefCount<UFSSwapDir> sd); | |
300 | StoreSearchUFS(StoreSearchUFS const &); | |
301 | virtual ~StoreSearchUFS(); | |
302 | /* Iterator API - garh, wrong place */ | |
303 | /* callback the client when a new StoreEntry is available | |
304 | * or an error occurs | |
305 | */ | |
306 | virtual void next(void (callback)(void *cbdata), void *cbdata); | |
307 | /* return true if a new StoreEntry is immediately available */ | |
308 | virtual bool next(); | |
309 | virtual bool error() const; | |
310 | virtual bool isDone() const; | |
311 | virtual StoreEntry *currentItem(); | |
312 | ||
313 | RefCount<UFSSwapDir> sd; | |
314 | RemovalPolicyWalker *walker; | |
315 | ||
316 | private: | |
317 | CBDATA_CLASS2(StoreSearchUFS); | |
318 | void (callback)(void *cbdata); | |
319 | void *cbdata; | |
320 | StoreEntry * current; | |
321 | bool _done; | |
322 | }; | |
323 | ||
47f6e231 | 324 | class StoreSwapLogData; |
325 | class UFSSwapLogParser{ | |
326 | ||
327 | public: | |
328 | FILE *log; | |
329 | int log_entries; | |
330 | int record_size; | |
331 | ||
332 | UFSSwapLogParser(FILE *fp):log(fp),log_entries(-1), record_size(0){ | |
333 | } | |
334 | virtual ~UFSSwapLogParser(){}; | |
335 | ||
336 | static UFSSwapLogParser *GetUFSSwapLogParser(FILE *fp); | |
337 | ||
338 | virtual bool ReadRecord(StoreSwapLogData &swapData) = 0; | |
339 | int SwapLogEntries(); | |
340 | void Close() | |
341 | { | |
342 | if(log){ | |
343 | fclose(log); | |
344 | log = NULL; | |
345 | } | |
346 | } | |
347 | }; | |
348 | ||
62e76326 | 349 | class RebuildState : public RefCountable |
350 | { | |
351 | ||
d3b3ab85 | 352 | public: |
c8f4eac4 | 353 | static EVH RebuildStep; |
d3b3ab85 | 354 | |
c8f4eac4 | 355 | RebuildState(RefCount<UFSSwapDir> sd); |
d3b3ab85 | 356 | ~RebuildState(); |
c8f4eac4 | 357 | |
358 | /* Iterator API - garh, wrong place */ | |
359 | /* callback the client when a new StoreEntry is available | |
360 | * or an error occurs | |
361 | */ | |
362 | virtual void next(void (callback)(void *cbdata), void *cbdata); | |
363 | /* return true if a new StoreEntry is immediately available */ | |
364 | virtual bool next(); | |
365 | virtual bool error() const; | |
366 | virtual bool isDone() const; | |
367 | virtual StoreEntry *currentItem(); | |
368 | ||
369 | RefCount<UFSSwapDir> sd; | |
d3b3ab85 | 370 | int n_read; |
47f6e231 | 371 | /* FILE *log;*/ |
372 | UFSSwapLogParser *LogParser; | |
d3b3ab85 | 373 | int speed; |
374 | int curlvl1; | |
375 | int curlvl2; | |
62e76326 | 376 | |
377 | struct | |
378 | { | |
379 | ||
380 | unsigned int need_to_validate: | |
381 | 1; | |
382 | ||
383 | unsigned int clean: | |
384 | 1; | |
385 | ||
386 | unsigned int init: | |
387 | 1; | |
388 | } | |
389 | ||
390 | flags; | |
d3b3ab85 | 391 | int in_dir; |
c8f4eac4 | 392 | int done; |
d3b3ab85 | 393 | int fn; |
62e76326 | 394 | |
d3b3ab85 | 395 | struct dirent *entry; |
396 | DIR *td; | |
397 | char fullpath[SQUID_MAXPATHLEN]; | |
398 | char fullfilename[SQUID_MAXPATHLEN]; | |
62e76326 | 399 | |
d3b3ab85 | 400 | struct _store_rebuild_data counts; |
62e76326 | 401 | |
d3b3ab85 | 402 | private: |
c8f4eac4 | 403 | CBDATA_CLASS2(RebuildState); |
d3b3ab85 | 404 | void rebuildFromDirectory(); |
405 | void rebuildFromSwapLog(); | |
c8f4eac4 | 406 | void rebuildStep(); |
d3b3ab85 | 407 | int getNextFile(sfileno *, int *size); |
822b78b5 | 408 | StoreEntry *currentEntry() const; |
409 | void currentEntry(StoreEntry *); | |
410 | StoreEntry *e; | |
c8f4eac4 | 411 | bool fromLog; |
412 | bool _done; | |
413 | void (callback)(void *cbdata); | |
414 | void *cbdata; | |
4d6d905e | 415 | }; |
416 | ||
528b2c61 | 417 | #ifdef _USE_INLINE_ |
418 | #include "ufscommon.cci" | |
419 | #endif | |
4d6d905e | 420 | |
421 | #endif /* SQUID_UFSCOMMON_H */ |