dnl
dnl Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9)
dnl
-dnl $Id: configure.in,v 1.339 2003/07/16 12:09:08 robertc Exp $
+dnl $Id: configure.in,v 1.340 2003/07/22 15:24:00 robertc Exp $
dnl
dnl
dnl
AC_CONFIG_AUX_DIR(cfgaux)
AM_INIT_AUTOMAKE(squid, 3.0-PRE1-CVS)
AM_CONFIG_HEADER(include/autoconf.h)
-AC_REVISION($Revision: 1.339 $)dnl
+AC_REVISION($Revision: 1.340 $)dnl
AC_PREFIX_DEFAULT(/usr/local/squid)
AM_MAINTAINER_MODE
echo "Store modules built: $STORE_MODULES"
STORE_OBJS="fs/lib`echo $STORE_MODULES|sed -e 's% %.a fs/lib%g'`.a"
STORE_LIBS="`echo $STORE_OBJS|sed -e 's%fs/%%g'`"
+ STORE_LINKOBJS=
+ for module in $STORE_MODULES; do
+ STORE_LINKOBJS="$STORE_LINKOBJS fs/${module}/StoreFS${module}.o"
+ done
fi
dnl remove all but diskd - its the only module that needs to recurse
dnl into the sub directory
STORE_OBJS="$STORE_OBJS fs/libufs.a"
STORE_LIBS="$STORE_LIBS libufs.a"
STORE_MODULES="$STORE_MODULES ufs"
+ STORE_LINKOBJS="$STORE_SOURCE fs/ufs/StoreFSufs.o"
fi
AC_SUBST(STORE_OBJS)
AC_SUBST(STORE_LIBS)
-AC_SUBST(STORE_MODULES)
AC_SUBST(STORE_PROGRAMS)
AC_SUBST(STORE_MODULE_SUBDIRS)
+AC_SUBST(STORE_LINKOBJS)
AC_ARG_ENABLE(removal-policies,
[ --enable-removal-policies=\"list of policies\"
section 89 NAT / IP Interception
section 90 Store Client
section 91 Http Surrogate-Control Header
+section 92 Store File System
/*
- * $Id: Array.cc,v 1.10 2003/01/23 00:37:00 robertc Exp $
+ * $Id: Array.cc,v 1.11 2003/07/22 15:23:18 robertc Exp $
*
* AUTHOR: Alex Rousskov
*
#endif
#include "util.h"
#include "Array.h"
-
-Array *arrayCreate(void) {return new Array;}
-void arrayClean(Array * s) {s->clean();}
-void arrayDestroy(Array * s) { delete s;}
-void arrayAppend(Array * s, void *obj) {s->push_back(obj);}
-void arrayPreAppend(Array * s, int app_count) {s->preAppend(app_count);}
-
-void
-arrayInit(Array * a)
-{
- assert(a);
- memset(a, 0, sizeof(Array));
-}
#
# Makefile for the Squid Object Cache server
#
-# $Id: Makefile.am,v 1.85 2003/07/15 13:15:04 robertc Exp $
+# $Id: Makefile.am,v 1.86 2003/07/22 15:23:01 robertc Exp $
#
# Uncomment and customize the following to suit your needs:
#
+AUTOMAKE_OPTIONS = subdir-objects
if USE_DNSSERVER
DNSSOURCE = dns.cc
DNSSERVER = dnsserver
squidclient_SOURCES = client.cc
cachemgr__CGIEXT__SOURCES = cachemgr.cc
+all_FSMODULES = \
+ fs/aufs/StoreFSaufs.cc \
+ fs/coss/StoreFScoss.cc \
+ fs/diskd/StoreFSdiskd.cc \
+ fs/null/StoreFSnull.cc \
+ fs/ufs/StoreFSufs.cc
+
EXTRA_squid_SOURCES = \
+ $(all_FSMODULES) \
$(ARP_ACL_ALL_SOURCE) \
$(DELAY_POOL_ALL_SOURCE) \
dns.cc \
stmem.h \
store.cc \
Store.h \
+ StoreFileSystem.cc \
+ StoreFileSystem.h \
store_io.cc \
StoreIOBuffer.h \
StoreIOState.cc \
StoreMetaURL.h \
StoreMetaVary.cc \
StoreMetaVary.h \
+ $(STORE_SOURCES) \
StoreSwapLogData.cc \
StoreSwapLogData.h \
structs.h \
nodist_squid_SOURCES = \
repl_modules.cc \
auth_modules.cc \
- store_modules.cc \
cf_parser.h \
globals.cc \
string_arrays.c
-L../lib \
@XTRA_OBJS@ \
@REPL_OBJS@ \
+ @STORE_LINKOBJS@ \
@STORE_OBJS@ \
@AUTH_OBJS@ \
@CRYPTLIB@ \
-lmiscutil \
@XTRA_LIBS@ \
@EPOLL_LIBS@
-squid_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a @STORE_OBJS@
+squid_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a @STORE_OBJS@ @STORE_LINKOBJS@
unlinkd_SOURCES = unlinkd.cc SquidNew.cc
unlinkd_CXXFLAGS = -DUNLINK_DAEMON
nodist_ufsdump_SOURCES = \
repl_modules.cc \
auth_modules.cc \
- store_modules.cc \
cf_parser.h \
globals.cc \
string_arrays.c
globals.cc \
string_arrays.c \
repl_modules.cc \
- auth_modules.cc \
- store_modules.cc
+ auth_modules.cc
sysconf_DATA = \
squid.conf.default \
mk-globals-c.pl \
mk-string-arrays.pl \
auth_modules.sh \
- store_modules.sh \
repl_modules.sh \
mib.txt \
mime.conf.default
s%@[V]ERSION@%$(VERSION)%g;"\
< $(srcdir)/cf.data.pre >$@
-store_modules.cc: store_modules.sh Makefile
- $(SHELL) $(srcdir)/store_modules.sh $(STORE_MODULES) >store_modules.cc
-
repl_modules.cc: repl_modules.sh Makefile
$(SHELL) $(srcdir)/repl_modules.sh $(REPL_POLICIES) > repl_modules.cc
# fi
DISTCLEANFILES = cf_gen_defines.h cf.data cf_parser.h squid.conf.default \
- globals.cc string_arrays.c repl_modules.cc auth_modules.cc store_modules.cc
+ globals.cc string_arrays.c repl_modules.cc auth_modules.cc
##install-pinger:
## @f=$(PINGER_EXE); \
/*
- * $Id: Store.h,v 1.10 2003/03/15 04:17:39 robertc Exp $
+ * $Id: Store.h,v 1.11 2003/07/22 15:23:01 robertc Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
class MemObject;
-typedef void STSETUP(storefs_entry_t *);
-
class StoreEntry : public hash_link
{
public:
- static void FsAdd(const char *, STSETUP *);
static DeferredRead::DeferrableRead DeferReader;
bool checkDeferRead(int fd) const;
SQUIDCEXTERN void storeSwapFileNumberSet(StoreEntry * e, sfileno filn);
SQUIDCEXTERN void storeFsInit(void);
SQUIDCEXTERN void storeFsDone(void);
-typedef void STSETUP(storefs_entry_t *);
SQUIDCEXTERN void storeReplAdd(const char *, REMOVALPOLICYCREATE *);
-/* store_modules.c */
-SQUIDCEXTERN void storeFsSetup(void);
-
#ifdef _USE_INLINE_
#include "Store.cci"
#endif
--- /dev/null
+
+/*
+ * $Id: StoreFileSystem.cc,v 1.1 2003/07/22 15:23:01 robertc Exp $
+ *
+ * DEBUG: section 92 Storage File System
+ * AUTHOR: Robert Collins
+ *
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#include "squid.h"
+#include "StoreFileSystem.h"
+
+Vector<StoreFileSystem*> *StoreFileSystem::_FileSystems = NULL;
+
+void
+StoreFileSystem::SetupAllFs()
+{
+ for (iterator i = GetFileSystems().begin(); i != GetFileSystems().end(); ++i)
+ /* Call the FS to set up capabilities and initialize the FS driver */
+ (*i)->setup();
+}
+
+void
+StoreFileSystem::FsAdd(StoreFileSystem &instance)
+{
+ iterator i = GetFileSystems().begin();
+
+ while (i != GetFileSystems().end()) {
+ assert(strcmp((*i)->type(), instance.type()) != 0);
+ ++i;
+ }
+
+ GetFileSystems().push_back (&instance);
+}
+
+Vector<StoreFileSystem *> const &
+StoreFileSystem::FileSystems()
+{
+ return GetFileSystems();
+}
+
+Vector<StoreFileSystem*> &
+StoreFileSystem::GetFileSystems()
+{
+ if (!_FileSystems)
+ _FileSystems = new Vector<StoreFileSystem *>;
+
+ return *_FileSystems;
+}
+
+/*
+ * called when a graceful shutdown is to occur
+ * of each fs module.
+ */
+void
+StoreFileSystem::FreeAllFs()
+{
+ while (GetFileSystems().size()) {
+ StoreFileSystem *fs = GetFileSystems().back();
+ GetFileSystems().pop_back();
+ fs->done();
+ }
+}
+
--- /dev/null
+
+/*
+ * $Id: StoreFileSystem.h,v 1.1 2003/07/22 15:23:01 robertc Exp $
+ *
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#ifndef SQUID_STOREFILESYSTEM_H
+#define SQUID_STOREFILESYSTEM_H
+
+#include "squid.h"
+#include "Array.h"
+
+class StoreFileSystem
+{
+
+public:
+ static void SetupAllFs();
+ static void FsAdd(StoreFileSystem &);
+ static void FreeAllFs();
+ static Vector<StoreFileSystem*> const &FileSystems();
+ typedef Vector<StoreFileSystem*>::iterator iterator;
+ typedef Vector<StoreFileSystem*>::const_iterator const_iterator;
+ StoreFileSystem() : initialised (false) {}
+
+ virtual ~StoreFileSystem(){}
+
+ virtual char const *type () const = 0;
+ virtual SwapDir *createSwapDir() = 0;
+ virtual void done() = 0;
+ virtual void setup() = 0;
+ // Not implemented
+ StoreFileSystem(StoreFileSystem const &);
+ StoreFileSystem &operator=(StoreFileSystem const&);
+
+protected:
+ bool initialised;
+
+private:
+ static Vector<StoreFileSystem*> &GetFileSystems();
+ static Vector<StoreFileSystem*> *_FileSystems;
+};
+
+typedef StoreFileSystem storefs_entry_t;
+
+
+#endif /* SQUID_STOREFILESYSTEM_H */
/*
- * $Id: StoreIOState.h,v 1.4 2003/02/21 22:50:06 robertc Exp $
+ * $Id: StoreIOState.h,v 1.5 2003/07/22 15:23:01 robertc Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
/* storeIOState does not get mempooled - it's children do */
void *operator new (size_t amount);
void operator delete (void *address);
- void deleteSelf() const = 0;
+ virtual void deleteSelf() const = 0;
virtual ~storeIOState();
storeIOState();
/*
- * $Id: SwapDir.cc,v 1.3 2003/02/21 22:50:06 robertc Exp $
+ * $Id: SwapDir.cc,v 1.4 2003/07/22 15:23:01 robertc Exp $
*
* DEBUG: section ?? Swap Dir base object
* AUTHOR: Robert Collins
#include "squid.h"
#include "SwapDir.h"
#include "Store.h"
-
-SwapDir *
-SwapDir::Factory (_storefs_entry const &fs)
-{
- SwapDir *result = fs.newfunc();
- result->type = fs.typestr;
- return result;
-}
+#include "StoreFileSystem.h"
SwapDir::~SwapDir()
{
void
SwapDir::logEntry(const StoreEntry & e, int op) const{}
+
+char const *
+SwapDir::type() const
+{
+ return theType;
+}
+
+/* NOT performance critical. Really. Don't bother optimising for speed
+ * - RBC 20030718
+ */
+SwapDirOption *
+SwapDir::getOptionTree() const
+{
+ SwapDirOptionVector *result = new SwapDirOptionVector;
+ result->options.push_back(new SwapDirOptionAdapter<SwapDir>(*const_cast<SwapDir *>(this), &SwapDir::optionReadOnlyParse, &SwapDir::optionReadOnlyDump));
+ result->options.push_back(new SwapDirOptionAdapter<SwapDir>(*const_cast<SwapDir *>(this), &SwapDir::optionMaxSizeParse, &SwapDir::optionMaxSizeDump));
+ return result;
+}
+
+void
+SwapDir::parseOptions(int reconfiguring)
+{
+ unsigned int old_read_only = flags.read_only;
+ char *name, *value;
+
+ SwapDirOption *newOption = getOptionTree();
+
+ while ((name = strtok(NULL, w_space)) != NULL) {
+ value = strchr(name, '=');
+
+ if (value)
+ *value++ = '\0'; /* cut on = */
+
+ if (newOption)
+ if (!newOption->parse(name, value, reconfiguring))
+ self_destruct();
+ }
+
+ delete newOption;
+
+ /*
+ * Handle notifications about reconfigured single-options with no value
+ * where the removal of the option cannot be easily detected in the
+ * parsing...
+ */
+
+ if (reconfiguring) {
+ if (old_read_only != flags.read_only) {
+ debug(3, 1) ("Cache dir '%s' now %s\n",
+ path, flags.read_only ? "Read-Only" : "Read-Write");
+ }
+ }
+}
+
+void
+SwapDir::dumpOptions(StoreEntry * entry) const
+{
+ SwapDirOption *newOption = getOptionTree();
+
+ if (newOption)
+ newOption->dump(entry);
+
+ delete newOption;
+}
+
+bool
+SwapDir::optionReadOnlyParse(char const *option, const char *value, int reconfiguring)
+{
+ if (strcmp(option, "read-only") != 0)
+ return false;
+
+ int read_only = 0;
+
+ if (value)
+ read_only = xatoi(value);
+ else
+ read_only = 1;
+
+ flags.read_only = read_only;
+
+ return true;
+}
+
+void
+SwapDir::optionReadOnlyDump(StoreEntry * e) const
+{
+ if (flags.read_only)
+ storeAppendPrintf(e, " read-only");
+}
+
+bool
+SwapDir::optionMaxSizeParse(char const *option, const char *value, int reconfiguring)
+{
+ if (strcmp(option, "max-size") != 0)
+ return false;
+
+ if (!value)
+ self_destruct();
+
+ ssize_t size = xatoi(value);
+
+ if (reconfiguring && max_objsize != size)
+ debug(3, 1) ("Cache dir '%s' max object size now %ld\n", path, (long int) size);
+
+ max_objsize = size;
+
+ return true;
+}
+
+void
+SwapDir::optionMaxSizeDump(StoreEntry * e) const
+{
+ if (max_objsize != -1)
+ storeAppendPrintf(e, " max-size=%ld", (long int) max_objsize);
+}
+
+SwapDirOptionVector::~SwapDirOptionVector()
+{
+ while (options.size()) {
+ delete options.back();
+ options.pop_back();
+ }
+}
+
+bool
+SwapDirOptionVector::parse(char const *option, const char *value, int reconfiguring)
+{
+ Vector<SwapDirOption *>::iterator i = options.begin();
+
+ while (i != options.end()) {
+ if ((*i)->parse(option,value, reconfiguring))
+ return true;
+
+ ++i;
+ }
+
+ return false;
+}
+
+void
+SwapDirOptionVector::dump(StoreEntry * e) const
+{
+ for(Vector<SwapDirOption *>::const_iterator i = options.begin();
+ i != options.end(); ++i)
+ (*i)->dump(e);
+}
/*
- * $Id: SwapDir.h,v 1.5 2003/07/15 23:12:02 robertc Exp $
+ * $Id: SwapDir.h,v 1.6 2003/07/22 15:23:01 robertc Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
#define SQUID_SWAPDIR_H
#include "StoreIOState.h"
+#include "Array.h"
+
+/* cache option parsers */
+
+class SwapDirOption
+{
+
+public:
+ virtual ~SwapDirOption() {}
+
+ virtual bool parse(char const *option, const char *value, int reconfiguring) = 0;
+ virtual void dump (StoreEntry * e) const = 0;
+};
+
+class SwapDirOptionVector : public SwapDirOption
+{
+
+public:
+ virtual ~SwapDirOptionVector();
+ virtual bool parse(char const *option, const char *value, int reconfiguring);
+ virtual void dump(StoreEntry * e) const;
+ Vector<SwapDirOption *>options;
+};
+
+template <class C>
+
+class SwapDirOptionAdapter : public SwapDirOption
+{
+
+public:
+ SwapDirOptionAdapter (C& theObject, bool (C::*parseFP)(char const *option, const char *value, int reconfiguring), void (C::*dumpFP) (StoreEntry * e) const) : object(theObject), parser (parseFP), dumper(dumpFP) {}
+
+ bool parse(char const *option, const char *value, int reconfiguring)
+ {
+ if (parser)
+ return (object.*parser)(option, value, reconfiguring);
+
+ return false;
+ }
+
+ void dump (StoreEntry * e) const
+ {
+ if (dumper)
+ (object.*dumper) (e);
+ }
+
+private:
+ C &object;
+ bool (C::*parser) (char const *option, const char *value, int reconfiguring) ;
+ void (C::*dumper)(StoreEntry * e) const;
+};
/* Store dir configuration routines */
/* SwapDir *sd, char *path ( + char *opt later when the strtok mess is gone) */
-typedef void STFSSTARTUP(void);
-typedef void STFSSHUTDOWN(void);
-typedef SwapDir *STFSNEW(void);
class SwapDir
{
public:
- static SwapDir *Factory (_storefs_entry const &fs);
- SwapDir() : cur_size (0), low_size(0), max_size(0), max_objsize (-1)
+ SwapDir(char const *aType) : theType (aType), cur_size (0), low_size(0), max_size(0), max_objsize (-1)
{
fs.blksize = 1024;
}
virtual ~SwapDir();
virtual void reconfigure(int, char *) = 0;
- const char *type;
+ char const *type() const;
+
+protected:
+ void parseOptions(int reconfiguring);
+ void dumpOptions(StoreEntry * e) const;
+ virtual SwapDirOption *getOptionTree() const;
+
+private:
+ bool optionReadOnlyParse(char const *option, const char *value, int reconfiguring);
+ void optionReadOnlyDump(StoreEntry * e) const;
+ bool optionMaxSizeParse(char const *option, const char *value, int reconfiguring);
+ void optionMaxSizeDump(StoreEntry * e) const;
+ char const *theType;
+
+public:
int cur_size;
int low_size;
int max_size;
/*
- * $Id: cache_cf.cc,v 1.446 2003/07/16 12:54:42 hno Exp $
+ * $Id: cache_cf.cc,v 1.447 2003/07/22 15:23:01 robertc Exp $
*
* DEBUG: section 3 Configuration File Parsing
* AUTHOR: Harvest Derived
#include "SwapDir.h"
#include "ConfigParser.h"
#include "ACL.h"
+#include "StoreFileSystem.h"
#if SQUID_SNMP
#include "snmp.h"
static const char *const list_sep = ", \t\n\r";
-static void parse_cachedir_option_readonly(SwapDir * sd, const char *option, const char *value, int reconfiguring);
-static void dump_cachedir_option_readonly(StoreEntry * e, const char *option, SwapDir const * sd);
-static void parse_cachedir_option_maxsize(SwapDir * sd, const char *option, const char *value, int reconfiguring);
-static void dump_cachedir_option_maxsize(StoreEntry * e, const char *option, SwapDir const * sd);
static void parse_logformat(logformat ** logformat_definitions);
static void parse_access_log(customlog ** customlog_definitions);
static int check_null_access_log(customlog *customlog_definitions);
static void free_access_log(customlog ** definitions);
-static struct cache_dir_option common_cachedir_options[] =
- {
- {"read-only", parse_cachedir_option_readonly, dump_cachedir_option_readonly},
-
- {"max-size", parse_cachedir_option_maxsize, dump_cachedir_option_maxsize},
- {NULL, NULL}
- };
static void update_maxobjsize(void);
* These functions is the same as atoi/l/f, except that they check for errors
*/
-static long
+long
xatol(const char *token)
{
char *end;
return ret;
}
-static int
+int
xatoi(const char *token)
{
return xatol(token);
#endif
-void
-
-dump_cachedir_options(StoreEntry * entry, struct cache_dir_option *options, SwapDir const * sd)
-{
-
- struct cache_dir_option *option;
-
- if (!options)
- return;
-
- for (option = options; option->name; option++)
- option->dump(entry, option->name, sd);
-}
static void
dump_cachedir(StoreEntry * entry, const char *name, _SquidConfig::_cacheSwap swap)
for (i = 0; i < swap.n_configured; i++) {
s = swap.swapDirs[i];
- storeAppendPrintf(entry, "%s %s %s", name, s->type, s->path);
+ storeAppendPrintf(entry, "%s %s %s", name, s->type(), s->path);
s->dump(*entry);
- dump_cachedir_options(entry, common_cachedir_options, s);
storeAppendPrintf(entry, "\n");
}
}
+
static int
check_null_cachedir(_SquidConfig::_cacheSwap swap)
{
}
}
+/* TODO: just return the object, the # is irrelevant */
static int
find_fstype(char *type)
{
- int i;
-
- for (i = 0; storefs_list[i].typestr != NULL; i++) {
- if (strcasecmp(type, storefs_list[i].typestr) == 0) {
- return i;
- }
- }
+ for (size_t i = 0; i < StoreFileSystem::FileSystems().size(); ++i)
+ if (strcasecmp(type, StoreFileSystem::FileSystems().items[i]->type()) == 0)
+ return (int)i;
return (-1);
}
}
allocate_new_swapdir(swap);
- swap->swapDirs[swap->n_configured] = SwapDir::Factory(storefs_list[fs]);
+ swap->swapDirs[swap->n_configured] = StoreFileSystem::FileSystems().items[fs]->createSwapDir();
sd = swap->swapDirs[swap->n_configured];
/* parse the FS parameters and options */
sd->parse(swap->n_configured, path_str);
update_maxobjsize();
}
-static void
-parse_cachedir_option_readonly(SwapDir * sd, const char *option, const char *value, int reconfiguring)
-{
- int read_only = 0;
-
- if (value)
- read_only = xatoi(value);
- else
- read_only = 1;
-
- sd->flags.read_only = read_only;
-}
-
-static void
-dump_cachedir_option_readonly(StoreEntry * e, const char *option, SwapDir const * sd)
-{
- if (sd->flags.read_only)
- storeAppendPrintf(e, " %s", option);
-}
-
-static void
-parse_cachedir_option_maxsize(SwapDir * sd, const char *option, const char *value, int reconfiguring)
-{
- ssize_t size;
-
- if (!value)
- self_destruct();
-
- size = xatoi(value);
-
- if (reconfiguring && sd->max_objsize != size)
- debug(3, 1) ("Cache dir '%s' max object size now %ld\n", sd->path, (long int) size);
-
- sd->max_objsize = size;
-}
-
-static void
-dump_cachedir_option_maxsize(StoreEntry * e, const char *option, SwapDir const * sd)
-{
- if (sd->max_objsize != -1)
- storeAppendPrintf(e, " %s=%ld", option, (long int) sd->max_objsize);
-}
-
-void
-
-parse_cachedir_options(SwapDir * sd, struct cache_dir_option *options, int reconfiguring)
-{
- unsigned int old_read_only = sd->flags.read_only;
- char *name, *value;
-
- struct cache_dir_option *option, *op;
-
- while ((name = strtok(NULL, w_space)) != NULL)
- {
- value = strchr(name, '=');
-
- if (value)
- *value++ = '\0'; /* cut on = */
-
- option = NULL;
-
- if (options) {
- for (op = options; !option && op->name; op++) {
- if (strcmp(op->name, name) == 0) {
- option = op;
- break;
- }
- }
- }
-
- for (op = common_cachedir_options; !option && op->name; op++) {
- if (strcmp(op->name, name) == 0) {
- option = op;
- break;
- }
- }
-
- if (!option || !option->parse)
- self_destruct();
-
- option->parse(sd, name, value, reconfiguring);
- }
-
- /*
- * Handle notifications about reconfigured single-options with no value
- * where the removal of the option cannot be easily detected in the
- * parsing...
- */
- if (reconfiguring)
- {
- if (old_read_only != sd->flags.read_only) {
- debug(3, 1) ("Cache dir '%s' now %s\n",
- sd->path, sd->flags.read_only ? "Read-Only" : "Read-Write");
- }
- }
-}
-
static void
free_cachedir(_SquidConfig::_cacheSwap * swap)
{
# Makefile for storage modules in the Squid Object Cache server
#
-# $Id: Makefile.am,v 1.7 2003/03/11 22:11:39 robertc Exp $
+# $Id: Makefile.am,v 1.8 2003/07/22 15:23:18 robertc Exp $
#
AUTOMAKE_OPTIONS = subdir-objects
noinst_LIBRARIES = @STORE_LIBS@
libaufs_a_SOURCES = aufs/aiops.cc aufs/async_io.cc aufs/store_asyncufs.h \
- aufs/store_dir_aufs.cc aufs/store_io_aufs.cc
+ aufs/store_io_aufs.cc
libcoss_a_SOURCES = coss/store_coss.h coss/store_io_coss.cc coss/store_dir_coss.cc \
coss/async_io.cc coss/async_io.h
-libdiskd_a_SOURCES = diskd/diskd.cc diskd/store_dir_diskd.cc \
+libdiskd_a_SOURCES = diskd/diskd.cc \
diskd/store_diskd.h \
diskd/store_io_diskd.cc
libufs_a_SOURCES = ufs/store_dir_ufs.cc ufs/store_io_ufs.cc ufs/store_ufs.h
EXTRA_DIST = \
- coss/coss-notes.txt
+ coss/coss-notes.txt \
+ ufs/IOModule.h \
+ ufs/StoreFSufs.h
INCLUDES = -I. -I$(top_builddir)/include -I$(top_srcdir)/include \
-I$(top_srcdir)/src/
--- /dev/null
+
+/*
+ * $Id: StoreFSaufs.cc,v 1.1 2003/07/22 15:23:10 robertc Exp $
+ *
+ * DEBUG: section 47 Store Directory Routines
+ * AUTHOR: Robert Collins
+ *
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#include "squid.h"
+#include "StoreFileSystem.h"
+#include "fs/ufs/StoreFSufs.h"
+#include "fs/aufs/store_asyncufs.h"
+
+static StoreFSufs<UFSSwapDir> AufsInstance(AufsIOModule::GetInstance(), "aufs");
/*
- * $Id: async_io.cc,v 1.23 2003/02/21 22:50:29 robertc Exp $
+ * $Id: async_io.cc,v 1.24 2003/07/22 15:23:10 robertc Exp $
*
* DEBUG: section 32 Asynchronous Disk I/O
* AUTHOR: Pete Bentley <pete@demon.net>
squidaio_unlinkq_t;
static dlink_list used_list;
-static int initialised = 0;
static OBJH aioStats;
static MemPool *squidaio_ctrl_pool;
static void aioFDWasClosed(int fd);
fd_close(fd);
}
-
void
-aioInit(void)
+AufsIO::init(void)
{
if (initialised)
return;
cachemgrRegister("squidaio_counts", "Async IO Function Counters",
aioStats, 0, 1);
- initialised = 1;
+ initialised = true;
}
void
-aioDone(void)
+AufsIO::done(void)
{
+ if (!initialised)
+ return;
+
memPoolDestroy(&squidaio_ctrl_pool);
- initialised = 0;
+
+ initialised = false;
}
void
{
squidaio_ctrl_t *ctrlp;
- assert(initialised);
+ assert(AufsIO::Instance.initialised);
squidaio_counts.open_start++;
ctrlp = (squidaio_ctrl_t *)memPoolAlloc(squidaio_ctrl_pool);
ctrlp->fd = -2;
{
squidaio_ctrl_t *ctrlp;
- assert(initialised);
+ assert(AufsIO::Instance.initialised);
squidaio_counts.close_start++;
aioCancel(fd);
ctrlp = (squidaio_ctrl_t *)memPoolAlloc(squidaio_ctrl_pool);
squidaio_ctrl_t *ctrlp;
dlink_node *m, *next;
- assert(initialised);
+ assert(AufsIO::Instance.initialised);
squidaio_counts.cancel++;
for (m = used_list.head; m; m = next) {
squidaio_ctrl_t *ctrlp;
int seekmode;
- assert(initialised);
+ assert(AufsIO::Instance.initialised);
squidaio_counts.write_start++;
ctrlp = (squidaio_ctrl_t *)memPoolAlloc(squidaio_ctrl_pool);
ctrlp->fd = fd;
squidaio_ctrl_t *ctrlp;
int seekmode;
- assert(initialised);
+ assert(AufsIO::Instance.initialised);
squidaio_counts.read_start++;
ctrlp = (squidaio_ctrl_t *)memPoolAlloc(squidaio_ctrl_pool);
ctrlp->fd = fd;
{
squidaio_ctrl_t *ctrlp;
- assert(initialised);
+ assert(AufsIO::Instance.initialised);
squidaio_counts.stat_start++;
ctrlp = (squidaio_ctrl_t *)memPoolAlloc(squidaio_ctrl_pool);
ctrlp->fd = -2;
aioUnlink(const char *path, AIOCB * callback, void *callback_data)
{
squidaio_ctrl_t *ctrlp;
- assert(initialised);
+ assert(AufsIO::Instance.initialised);
squidaio_counts.unlink_start++;
ctrlp = (squidaio_ctrl_t *)memPoolAlloc(squidaio_ctrl_pool);
ctrlp->fd = -2;
aioTruncate(const char *path, off_t length, AIOCB * callback, void *callback_data)
{
squidaio_ctrl_t *ctrlp;
- assert(initialised);
+ assert(AufsIO::Instance.initialised);
squidaio_counts.unlink_start++;
ctrlp = (squidaio_ctrl_t *)memPoolAlloc(squidaio_ctrl_pool);
ctrlp->fd = -2;
int
-AUFSSwapDir::callback()
+AufsIO::callback()
{
squidaio_result_t *resultp;
squidaio_ctrl_t *ctrlp;
/* Flush all pending I/O */
void
-AUFSSwapDir::sync()
+AufsIO::sync()
{
if (!initialised)
return; /* nothing to do then */
debug(32, 1) ("aioSync: done\n");
}
+AufsIO::AufsIO() : initialised (false) {}
+
int
aioQueueSize(void)
{
virtual void create (int, mode_t, IORequestor::Pointer);
virtual void read(char *, off_t, size_t);
virtual void write(char const *buf, size_t size, off_t offset, FREE *free_func);
- void close();
+ virtual void close ();
virtual bool error() const;
virtual int getFD() const { return fd;}
virtual bool canRead() const;
virtual bool canWrite() const;
+ virtual bool ioInProgress()const;
private:
#if ASYNC_READ
bool errorOccured;
char const *path_;
AufsIO* IO;
+ size_t inProgressIOs;
static AIOCB OpenDone;
void openDone(int fd, const char *buf, int aio_return, int aio_errno);
IORequestor::Pointer ioRequestor;
void writeDone (int fd, int errflag, size_t len);
};
-class squidaiostate_t : public UFSStoreState
-{
-
-public:
- virtual void deleteSelf() const {delete this;}
-
- void * operator new (size_t);
- void operator delete (void *);
- squidaiostate_t(SwapDir *, StoreEntry *, STIOCB *, void *);
- ~squidaiostate_t();
-
- void close();
- int fd;
-
- struct
- {
-
-unsigned int write_kicking:
- 1;
-
-unsigned int read_kicking:
- 1;
-
-unsigned int inreaddone:
- 1;
- }
-
- flags;
- void ioCompletedNotification();
- void closeCompleted();
- void readCompleted(const char *buf, int len, int errflag);
- void writeCompleted(int errflag, size_t len);
- void writeDone(int fd, int errflag, size_t len);
-
-private:
- CBDATA_CLASS(squidaiostate_t);
- void openDone();
-};
-
/*
* Store IO stuff
*/
-#include "SwapDir.h"
-class AUFSSwapDir : public UFSSwapDir
+class SwapDir;
+
+#include "fs/ufs/IOModule.h"
+
+class AufsIOModule : public IOModule
{
public:
- virtual void dump(StoreEntry &)const;
- virtual void unlink(StoreEntry &);
- virtual int canStore(StoreEntry const &)const;
- virtual int callback();
- virtual void sync();
- virtual void parse (int index, char *path);
- virtual void reconfigure(int, char *);
- virtual void unlinkFile(char const *);
+ static AufsIOModule &GetInstance();
+ virtual void init();
+ virtual void shutdown();
+ virtual UFSStrategy *createSwapDirIOStrategy();
+
+private:
+ static AufsIOModule *Instance;
};
class AufsIO : public UFSStrategy
{
public:
+ AufsIO();
virtual bool shedLoad();
+ virtual int load();
virtual void deleteSelf() const;
virtual StoreIOState::Pointer createState(SwapDir *SD, StoreEntry *e, STIOCB * callback, void *callback_data) const;
virtual DiskFile::Pointer newFile(char const *path);
+ virtual void unlinkFile (char const *);
+ virtual void sync();
+ virtual int callback();
+ void init();
+ void done();
static AufsIO Instance;
+ bool initialised;
};
+
#endif
+++ /dev/null
-
-/*
- * $Id: store_dir_aufs.cc,v 1.56 2003/05/11 10:00:41 hno Exp $
- *
- * DEBUG: section 47 Store Directory Routines
- * AUTHOR: Duane Wessels
- *
- * SQUID Web Proxy Cache http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- * Squid is the result of efforts by numerous individuals from
- * the Internet community; see the CONTRIBUTORS file for full
- * details. Many organizations have provided support for Squid's
- * development; see the SPONSORS file for full details. Squid is
- * Copyrighted (C) 2001 by the Regents of the University of
- * California; see the COPYRIGHT file for full details. Squid
- * incorporates software developed and/or copyrighted by other
- * sources; see the CREDITS file for full details.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
- *
- */
-
-#include "squid.h"
-#include "Store.h"
-
-#include "store_asyncufs.h"
-#include "ufscommon.h"
-#include "SwapDir.h"
-
-static int asyncufs_initialised = 0;
-
-/* The MAIN externally visible function */
-STSETUP storeFsSetup_aufs;
-
-/*
- * storeAufsDirCheckObj
- *
- * This routine is called by storeDirSelectSwapDir to see if the given
- * object is able to be stored on this filesystem. AUFS filesystems will
- * happily store anything as long as the LRU time isn't too small.
- */
-int
-AUFSSwapDir::canStore(StoreEntry const &e) const
-{
- int loadav;
- int ql;
-
-#if OLD_UNUSED_CODE
-
- if (storeAufsDirExpiredReferenceAge(this) < 300) {
- debug(47, 3) ("storeAufsDirCheckObj: NO: LRU Age = %d\n",
- storeAufsDirExpiredReferenceAge(this));
- /* store_check_cachable_hist.no.lru_age_too_low++; */
- return -1;
- }
-
-#endif
- ql = aioQueueSize();
-
- if (ql == 0)
- loadav = 0;
-
- loadav = ql * 1000 / MAGIC1;
-
- debug(47, 9) ("storeAufsDirCheckObj: load=%d\n", loadav);
-
- return loadav;
-}
-
-void
-AUFSSwapDir::unlinkFile(char const *path)
-{
-#if USE_TRUNCATE_NOT_UNLINK
- aioTruncate(path, NULL, NULL);
-#else
-
- aioUnlink(path, NULL, NULL);
-#endif
-}
-
-/* ========== LOCAL FUNCTIONS ABOVE, GLOBAL FUNCTIONS BELOW ========== */
-
-static struct cache_dir_option options[] =
- {
-#if NOT_YET_DONE
- {"L1", storeAufsDirParseL1, storeAufsDirDumpL1},
- {"L2", storeAufsDirParseL2, storeAufsDirDumpL2},
-#endif
- {NULL, NULL}
- };
-
-/*
- * storeAufsDirReconfigure
- *
- * This routine is called when the given swapdir needs reconfiguring
- */
-void
-AUFSSwapDir::reconfigure(int anIndex, char *aPath)
-{
- UFSSwapDir::reconfigure (anIndex, aPath);
-
- parse_cachedir_options(this, options, 0);
-}
-
-void
-AUFSSwapDir::dump(StoreEntry & entry) const
-{
- UFSSwapDir::dump(entry);
- dump_cachedir_options(&entry, options, this);
-}
-
-/*
- * storeAufsDirParse *
- * Called when a *new* fs is being setup.
- */
-void
-AUFSSwapDir::parse(int anIndex, char *aPath)
-{
- UFSSwapDir::parse(anIndex, aPath);
-
- parse_cachedir_options(this, options, 0);
-}
-
-/*
- * Initial setup / end destruction
- */
-static void
-storeAufsDirDone(void)
-{
- aioDone();
- asyncufs_initialised = 0;
-}
-
-static SwapDir *
-storeAufsNew(void)
-{
- AUFSSwapDir *result = new AUFSSwapDir;
- result->IO = &AufsIO::Instance;
- return result;
-}
-
-void
-storeFsSetup_aufs(storefs_entry_t * storefs)
-{
- assert(!asyncufs_initialised);
- storefs->donefunc = storeAufsDirDone;
- storefs->newfunc = storeAufsNew;
-
- asyncufs_initialised = 1;
- aioInit();
-}
#include "ufscommon.h"
#include "SwapDir.h"
-static void storeAufsIOCallback(storeIOState * sio, int errflag);
-static int storeAufsNeedCompletetion(storeIOState *);
-
/* === PUBLIC =========================================================== */
-CBDATA_CLASS_INIT(squidaiostate_t);
-
-void *
-squidaiostate_t::operator new (size_t)
-{
- CBDATA_INIT_TYPE(squidaiostate_t);
- squidaiostate_t *result = cbdataAlloc(squidaiostate_t);
- /* Mark result as being owned - we want the refcounter to do the delete
- * call */
- cbdataReference(result);
- return result;
-}
-
-void
-squidaiostate_t::operator delete (void *address)
-{
- squidaiostate_t *t = static_cast<squidaiostate_t *>(address);
- cbdataFree(address);
- /* And allow the memory to be freed */
- cbdataReferenceDone (t);
-}
-
-squidaiostate_t::squidaiostate_t(SwapDir * SD, StoreEntry * anEntry, STIOCB * callback_, void *callback_data_)
-{
- swap_filen = anEntry->swap_filen;
- swap_dirn = SD->index;
- mode = O_BINARY;
- callback = callback_;
- callback_data = cbdataReference(callback_data_);
- e = anEntry;
- fd = -1;
-}
AufsIO AufsIO::Instance;
bool
return false;
}
+int
+AufsIO::load()
+{
+ int loadav;
+ int ql;
+
+ ql = aioQueueSize();
+
+ if (ql == 0)
+ loadav = 0;
+
+ loadav = ql * 1000 / MAGIC1;
+
+ debug(47, 9) ("storeAufsDirCheckObj: load=%d\n", loadav);
+
+ return loadav;
+}
+
void
AufsIO::deleteSelf() const
{
StoreIOState::Pointer
AufsIO::createState(SwapDir *SD, StoreEntry *e, STIOCB * callback, void *callback_data) const
{
- return new squidaiostate_t (SD, e, callback, callback_data);
+ return new UFSStoreState (SD, e, callback, callback_data);
}
DiskFile::Pointer
return new AUFSFile (path, this);
}
+void
+AufsIO::unlinkFile(char const *path)
+{
+ statCounter.syscalls.disk.unlinks++;
+#if USE_TRUNCATE_NOT_UNLINK
+
+ aioTruncate(path, NULL, NULL);
+#else
+
+ aioUnlink(path, NULL, NULL);
+#endif
+}
+
+AufsIOModule *AufsIOModule::Instance = NULL;
+AufsIOModule &
+AufsIOModule::GetInstance()
+{
+ if (!Instance)
+ Instance = new AufsIOModule;
+
+ return *Instance;
+}
+
+void
+AufsIOModule::init()
+{
+ AufsIO::Instance.init();
+}
+
+void
+AufsIOModule::shutdown()
+{
+ AufsIO::Instance.done();
+}
+
+UFSStrategy *
+AufsIOModule::createSwapDirIOStrategy()
+{
+ return new InstanceToSingletonAdapter<AufsIO>(&AufsIO::Instance);
+}
+
CBDATA_CLASS_INIT(AUFSFile);
void *
AUFSFile::operator new (size_t)
void
AUFSFile::deleteSelf() const {delete this;}
-AUFSFile::AUFSFile (char const *aPath, AufsIO *anIO):fd(-1), errorOccured (false), IO(anIO)
+AUFSFile::AUFSFile (char const *aPath, AufsIO *anIO):fd(-1), errorOccured (false), IO(anIO),
+ inProgressIOs (0)
{
assert (aPath);
debug (79,3)("UFSFile::UFSFile: %s\n", aPath);
ioRequestor = callback;
+ ++inProgressIOs;
+
#if ASYNC_OPEN
aioOpen(path_, flags, mode, AUFSFile::OpenDone, this);
assert (fd > -1);
assert (ioRequestor.getRaw());
statCounter.syscalls.disk.reads++;
+ ++inProgressIOs;
#if ASYNC_READ
aioRead(fd, offset, size, ReadDone, this);
ioRequestor = callback;
+ ++inProgressIOs;
+
#if ASYNC_CREATE
aioOpen(path_, flags, mode, AUFSFile::OpenDone, this);
debug(79, 3) ("AUFSFile::openDone: exiting\n");
IORequestor::Pointer t = ioRequestor;
+ --inProgressIOs;
t->ioCompletedNotification();
}
storeAufsOpen(SwapDir * SD, StoreEntry * e, STFNCB * file_callback,
STIOCB * callback, void *callback_data)
{
- UFSStrategy *IO = dynamic_cast <UFSStrategy *>(((AUFSSwapDir *)SD)->IO);
+ UFSStrategy *IO = dynamic_cast <UFSStrategy *>(((UFSSwapDir *)SD)->IO);
assert (IO);
return IO->open (SD, e, file_callback, callback, callback_data);
}
StoreIOState::Pointer
storeAufsCreate(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, STIOCB * callback, void *callback_data)
{
- UFSStrategy *IO = dynamic_cast <UFSStrategy *>(((AUFSSwapDir *)SD)->IO);
+ UFSStrategy *IO = dynamic_cast <UFSStrategy *>(((UFSSwapDir *)SD)->IO);
assert (IO);
return IO->create (SD, e, file_callback, callback, callback_data);
}
-/* Close */
+
void
-squidaiostate_t::close()
+AUFSFile::close ()
{
- debug(79, 3) ("storeAufsClose: dirno %d, fileno %08X, FD %d\n",
- swap_dirn, swap_filen, fd);
- /* mark the object to be closed on the next io that completes */
+ debug (79,3)("AUFSFile::close: %p closing for %p\n", this, ioRequestor.getRaw());
- if (storeAufsNeedCompletetion(this)) {
- closing = true;
- return;
+ if (!ioInProgress()) {
+ doClose();
+ assert (ioRequestor.getRaw());
+ ioRequestor->closeCompleted();
}
-
- storeAufsIOCallback(this, DISK_OK);
}
bool
{
debug(79, 3) ("storeAufsWrite: FD %d\n", fd);
statCounter.syscalls.disk.writes++;
+ ++inProgressIOs;
#if ASYNC_WRITE
aioWrite(fd, offset, (char *)buf, size, WriteDone, this,
return fd > -1;
}
-/* Unlink */
-void
-AUFSSwapDir::unlink(StoreEntry & e)
+bool
+AUFSFile::ioInProgress()const
{
- debug(79, 3) ("storeAufsUnlink: dirno %d, fileno %08X\n", index, e.swap_filen);
- statCounter.syscalls.disk.unlinks++;
- replacementRemove(&e);
- mapBitReset(e.swap_filen);
- UFSSwapDir::unlinkFile(e.swap_filen);
+ return inProgressIOs > 0;
}
/* === STATIC =========================================================== */
#endif
- ioRequestor->readCompleted(buf, rlen, errflag);
-}
-
-void
-squidaiostate_t::readCompleted(const char *buf, int len, int errflag)
-{
- int localinreaddone = flags.inreaddone; /* Protect from callback loops */
- flags.inreaddone = 1;
- reading = false;
- debug(79, 3) ("squidaiostate_t::readCompleted: dirno %d, fileno %08X, len %d\n",
- swap_dirn, swap_filen, len);
-
- if (len > 0)
- offset_ += len;
-
- STRCB *callback = read.callback;
-
- assert(callback);
-
- read.callback = NULL;
-
- void *cbdata;
-
- if (!closing && cbdataReferenceValidDone(read.callback_data, &cbdata)) {
- if (len > 0 && read_buf != buf)
- memcpy(read_buf, buf, len);
-
- callback(cbdata, read_buf, len);
- }
-
- flags.inreaddone = 0;
-
- if (closing && !localinreaddone)
- storeAufsIOCallback(this, errflag);
-}
-
-
-void
-squidaiostate_t::writeCompleted(int errflag, size_t len)
-{
- debug(79, 3) ("storeAufsWriteDone: dirno %d, fileno %08X, len %ld, err=%d\n",
- swap_dirn, swap_filen, (long int) len, errflag);
- writing = false;
-
- if (errflag) {
- debug(79, 0) ("storeAufsWriteDone: got failure (%d)\n", errflag);
- storeAufsIOCallback(this, errflag);
- return;
- }
-
- offset_ += len;
+ --inProgressIOs;
-#if ASYNC_WRITE
-
- if (!kickWriteQueue())
- 0;
- else if (closing)
- storeAufsIOCallback(this, errflag);
-
-#else
-
- if (!flags.write_kicking) {
- flags.write_kicking = 1;
-
- while (kickWriteQueue())
- (void) 0;
-
- flags.write_kicking = 0;
-
- if (closing)
- storeAufsIOCallback(this, errflag);
- }
-
-#endif
+ ioRequestor->readCompleted(buf, rlen, errflag);
}
void
assert(++loop_detect < 10);
+ --inProgressIOs;
+
ioRequestor->writeCompleted(errflag, len);
--loop_detect;
}
-static void
-storeAufsIOCallback(storeIOState * sio, int errflag)
-{
- STIOCB *callback = sio->callback;
- squidaiostate_t *aiostate = dynamic_cast<squidaiostate_t *>(sio);
- int fd = aiostate->fd;
- debug(79, 3) ("storeAufsIOCallback: errflag=%d\n", errflag);
- debug(79, 9) ("%s:%d\n", __FILE__, __LINE__);
-
- if (callback) {
- void *cbdata;
- sio->callback = NULL;
-
- if (cbdataReferenceValidDone(sio->callback_data, &cbdata))
- callback(cbdata, errflag, sio);
- }
-
- debug(79, 9) ("%s:%d\n", __FILE__, __LINE__);
- aiostate->fd = -1;
-
- if (aiostate->opening || aiostate->creating)
- Opening_FD--;
-
- if (fd < 0)
- return;
-
- debug(79, 9) ("%s:%d\n", __FILE__, __LINE__);
-
- aiostate->theFile = NULL;
-
- debug(79, 9) ("%s:%d\n", __FILE__, __LINE__);
-}
-
-
-static int
-storeAufsNeedCompletetion(storeIOState * sio)
-{
- squidaiostate_t *aiostate = dynamic_cast<squidaiostate_t *>(sio);
-
- if (aiostate->writing)
- return true;
-
- if (aiostate->creating && FILE_MODE(sio->mode) == O_WRONLY)
- return 1;
-
- if (aiostate->reading)
- return 1;
-
- if (aiostate->flags.inreaddone)
- return 1;
-
- return 0;
-}
-
-
-/*
- * Clean up references from the SIO before it gets released.
- * The actuall SIO is managed by cbdata so we do not need
- * to bother with that.
- */
-squidaiostate_t::~squidaiostate_t()
-{}
-
-void
-squidaiostate_t::ioCompletedNotification()
-{
- if (opening) {
- opening = false;
- openDone();
- return;
- }
-
- if (creating) {
- creating = false;
- openDone();
- return;
- }
-
- assert (0);
-}
-
-void
-squidaiostate_t::closeCompleted()
-{
- assert (0);
-}
-
-void
-squidaiostate_t::openDone()
-{
- if (theFile->error()) {
- storeAufsIOCallback(this, DISK_ERROR);
- return;
- }
-
- fd = theFile->getFD();
-
- if (FILE_MODE(mode) == O_WRONLY) {
- if (kickWriteQueue())
- return;
- } else if ((FILE_MODE(mode) == O_RDONLY) && !closing) {
- if (kickReadQueue())
- return;
- }
-
- if (closing)
- storeAufsIOCallback(this, theFile->error() ? -1 : 0);
-
- debug(79, 3) ("squidaiostate_t::openDone: exiting\n");
-}
--- /dev/null
+
+/*
+ * $Id: StoreFScoss.cc,v 1.1 2003/07/22 15:23:10 robertc Exp $
+ *
+ * DEBUG: section 47 Store Directory Routines
+ * AUTHOR: Robert Collins
+ *
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#include "StoreFileSystem.h"
+#include "fs/coss/StoreFScoss.h"
+#include "store_coss.h"
+
+StoreFScoss StoreFScoss::_instance;
+
+StoreFileSystem &
+StoreFScoss::GetInstance()
+{
+ return _instance;
+}
+
+StoreFScoss::StoreFScoss()
+{
+ FsAdd(*this);
+}
+
+char const *
+StoreFScoss::type() const
+{
+ return "coss";
+}
+
+void
+StoreFScoss::done()
+{
+ /* memPoolDestroy(&coss_index_pool); XXX Should be here? */
+ initialised = false;
+}
+
+SwapDir *
+StoreFScoss::createSwapDir()
+{
+ SwapDir *result = new CossSwapDir;
+ return result;
+}
+
+
+void
+StoreFScoss::setup()
+{
+ assert(!initialised);
+
+ coss_index_pool = memPoolCreate("COSS index data", sizeof(CossIndexNode));
+ initialised = true;
+}
--- /dev/null
+
+/*
+ * $Id: StoreFScoss.h,v 1.1 2003/07/22 15:23:10 robertc Exp $
+ *
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#ifndef SQUID_STOREFSCOSS_H
+#define SQUID_STOREFSCOSS_H
+
+#include "squid.h"
+
+class StoreFScoss : public StoreFileSystem
+{
+
+public:
+ static StoreFileSystem &GetInstance();
+ StoreFScoss();
+ virtual ~StoreFScoss() {}
+
+ virtual char const *type() const;
+ virtual SwapDir *createSwapDir();
+ virtual void done();
+ virtual void setup();
+ /* Not implemented */
+ StoreFScoss (StoreFScoss const &);
+ StoreFScoss &operator=(StoreFScoss const &);
+
+private:
+ static StoreFScoss _instance;
+};
+
+#endif /* SQUID_STOREFSCOSS_H */
#ifndef __ASYNC_IO_H__
#define __ASYNC_IO_H__
+#include <aio.h>
#define MAX_ASYNCOP 128
#define __COSS_H__
#include "SwapDir.h"
+#include "async_io.h"
#ifndef COSS_MEMBUF_SZ
#define COSS_MEMBUF_SZ 1048576
/*
- * $Id: store_dir_coss.cc,v 1.45 2003/07/15 11:33:23 robertc Exp $
+ * $Id: store_dir_coss.cc,v 1.46 2003/07/22 15:23:10 robertc Exp $
*
* DEBUG: section 47 Store COSS Directory Routines
* AUTHOR: Eric Stern
#include "squid.h"
#include "Store.h"
-#include <aio.h>
-#include "async_io.h"
#include "store_coss.h"
#include "fde.h"
#include "SwapDir.h"
int n_coss_dirs = 0;
/* static int last_coss_pick_index = -1; */
-int coss_initialised = 0;
MemPool *coss_index_pool = NULL;
typedef struct _RebuildState RebuildState;
static void storeCossDirCloseTmpSwapLog(CossSwapDir * sd);
static FILE *storeCossDirOpenTmpSwapLog(CossSwapDir *, int *, int *);
-/* The "only" externally visible function */
-STSETUP storeFsSetup_coss;
-
static char *
storeCossDirSwapLogFile(SwapDir * sd, const char *ext)
{
max_size = size;
- parse_cachedir_options(this, NULL, 0);
+ parseOptions(0);
/* Enforce maxobjsize being set to something */
if (max_objsize == -1)
max_size = size;
}
- parse_cachedir_options(this, NULL, 1);
+ parseOptions(1);
/* Enforce maxobjsize being set to something */
if (max_objsize == -1)
void
CossSwapDir::dump(StoreEntry &entry)const
{
- storeAppendPrintf(&entry, " %d",
- max_size >> 20);
- dump_cachedir_options(&entry, NULL, this);
+ storeAppendPrintf(&entry, " %d", max_size >> 20);
+ dumpOptions(&entry);
}
#if OLD_UNUSED_CODE
}
#endif
-
-/*
- * initial setup/done code
- */
-static void
-storeCossDirDone(void)
-{
- /* memPoolDestroy(&coss_index_pool); XXX Should be here? */
- coss_initialised = 0;
-}
-
-static SwapDir *
-storeCossNew(void)
-{
- SwapDir *result = new CossSwapDir;
- return result;
-}
-
-CossSwapDir::CossSwapDir() : fd (-1), swaplog_fd(-1), count(0), current_membuf (NULL), current_offset(0), numcollisions(0)
+CossSwapDir::CossSwapDir() : SwapDir ("coss"), fd (-1), swaplog_fd(-1), count(0), current_membuf (NULL), current_offset(0), numcollisions(0)
{
membufs.head = NULL;
membufs.tail = NULL;
cossindex.tail = NULL;
}
-void
-storeFsSetup_coss(storefs_entry_t * storefs)
-{
- assert(!coss_initialised);
-
- storefs->donefunc = storeCossDirDone;
- storefs->newfunc = storeCossNew;
- coss_index_pool = memPoolCreate("COSS index data", sizeof(CossIndexNode));
- coss_initialised = 1;
-}
--- /dev/null
+
+/*
+ * $Id: StoreFSdiskd.cc,v 1.1 2003/07/22 15:23:11 robertc Exp $
+ *
+ * DEBUG: section 47 Store Directory Routines
+ * AUTHOR: Robert Collins
+ *
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+
+#include "StoreFileSystem.h"
+#include "fs/ufs/StoreFSufs.h"
+#include "fs/diskd/store_diskd.h"
+
+static StoreFSufs<UFSSwapDir> DiskdInstance(DiskdIOModule::GetInstance(), "diskd");
+++ /dev/null
-
-/*
- * $Id: store_dir_diskd.cc,v 1.76 2003/02/21 22:50:40 robertc Exp $
- *
- * DEBUG: section 47 Store Directory Routines
- * AUTHOR: Duane Wessels
- *
- * SQUID Web Proxy Cache http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- * Squid is the result of efforts by numerous individuals from
- * the Internet community; see the CONTRIBUTORS file for full
- * details. Many organizations have provided support for Squid's
- * development; see the SPONSORS file for full details. Squid is
- * Copyrighted (C) 2001 by the Regents of the University of
- * California; see the COPYRIGHT file for full details. Squid
- * incorporates software developed and/or copyrighted by other
- * sources; see the CREDITS file for full details.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
- *
- */
-
-#include "squid.h"
-#include "Store.h"
-
-#include <sys/ipc.h>
-#include <sys/msg.h>
-#include <sys/shm.h>
-
-#include "store_diskd.h"
-
-#include "ufscommon.h"
-
-#include "SwapDir.h"
-
-diskd_stats_t diskd_stats;
-
-static int diskd_initialised = 0;
-
-static void storeDiskdStats(StoreEntry * sentry);
-
-/* The only externally visible interface */
-STSETUP storeFsSetup_diskd;
-
-
-
-void
-DiskdSwapDir::init()
-{
- int x;
- int rfd;
- int ikey;
- const char *args[5];
- char skey1[32];
- char skey2[32];
- char skey3[32];
- DiskdIO *DIO = dynamic_cast<DiskdIO *>(IO);
-
- ikey = (getpid() << 10) + (index << 2);
- ikey &= 0x7fffffff;
- DIO->smsgid = msgget((key_t) ikey, 0700 | IPC_CREAT);
-
- if (DIO->smsgid < 0) {
- debug(50, 0) ("storeDiskdInit: msgget: %s\n", xstrerror());
- fatal("msgget failed");
- }
-
- DIO->rmsgid = msgget((key_t) (ikey + 1), 0700 | IPC_CREAT);
-
- if (DIO->rmsgid < 0) {
- debug(50, 0) ("storeDiskdInit: msgget: %s\n", xstrerror());
- fatal("msgget failed");
- }
-
- DIO->shm.init(ikey, DIO->magic2);
- snprintf(skey1, 32, "%d", ikey);
- snprintf(skey2, 32, "%d", ikey + 1);
- snprintf(skey3, 32, "%d", ikey + 2);
- args[0] = "diskd";
- args[1] = skey1;
- args[2] = skey2;
- args[3] = skey3;
- args[4] = NULL;
- x = ipcCreate(IPC_STREAM,
- Config.Program.diskd,
- args,
- "diskd",
- &rfd,
- &DIO->wfd);
-
- if (x < 0)
- fatalf("execl: %s", Config.Program.diskd);
-
- if (rfd != DIO->wfd)
- comm_close(rfd);
-
- fd_note(DIO->wfd, "squid -> diskd");
-
- commSetTimeout(DIO->wfd, -1, NULL, NULL);
-
- commSetNonBlocking(DIO->wfd);
-
- UFSSwapDir::init();
-
- comm_quick_poll_required();
-}
-
-
-static void
-storeDiskdStats(StoreEntry * sentry)
-{
- storeAppendPrintf(sentry, "sent_count: %d\n", diskd_stats.sent_count);
- storeAppendPrintf(sentry, "recv_count: %d\n", diskd_stats.recv_count);
- storeAppendPrintf(sentry, "max_away: %d\n", diskd_stats.max_away);
- storeAppendPrintf(sentry, "max_shmuse: %d\n", diskd_stats.max_shmuse);
- storeAppendPrintf(sentry, "open_fail_queue_len: %d\n", diskd_stats.open_fail_queue_len);
- storeAppendPrintf(sentry, "block_queue_len: %d\n", diskd_stats.block_queue_len);
- diskd_stats.max_away = diskd_stats.max_shmuse = 0;
- storeAppendPrintf(sentry, "\n OPS SUCCESS FAIL\n");
- storeAppendPrintf(sentry, "%7s %7d %7d %7d\n",
- "open", diskd_stats.open.ops, diskd_stats.open.success, diskd_stats.open.fail);
- storeAppendPrintf(sentry, "%7s %7d %7d %7d\n",
- "create", diskd_stats.create.ops, diskd_stats.create.success, diskd_stats.create.fail);
- storeAppendPrintf(sentry, "%7s %7d %7d %7d\n",
- "close", diskd_stats.close.ops, diskd_stats.close.success, diskd_stats.close.fail);
- storeAppendPrintf(sentry, "%7s %7d %7d %7d\n",
- "unlink", diskd_stats.unlink.ops, diskd_stats.unlink.success, diskd_stats.unlink.fail);
- storeAppendPrintf(sentry, "%7s %7d %7d %7d\n",
- "read", diskd_stats.read.ops, diskd_stats.read.success, diskd_stats.read.fail);
- storeAppendPrintf(sentry, "%7s %7d %7d %7d\n",
- "write", diskd_stats.write.ops, diskd_stats.write.success, diskd_stats.write.fail);
-}
-
-/*
- * storeDiskdDirSync
- *
- * Sync any pending data. We just sit around and read the queue
- * until the data has finished writing.
- */
-void
-DiskdSwapDir::sync()
-{
- static time_t lastmsg = 0;
- DiskdIO *DIO = dynamic_cast<DiskdIO *>(IO);
-
- while (DIO->away > 0) {
- if (squid_curtime > lastmsg) {
- debug(47, 1) ("storeDiskdDirSync: %d messages away\n",
- DIO->away);
- lastmsg = squid_curtime;
- }
-
- callback();
- }
-}
-
-
-/*
- * storeDiskdDirCallback
- *
- * Handle callbacks. If we have more than magic2 requests away, we block
- * until the queue is below magic2. Otherwise, we simply return when we
- * don't get a message.
- */
-int
-DiskdSwapDir::callback()
-{
- diomsg M;
- int x;
- int retval = 0;
-
- DiskdIO *DIO = dynamic_cast<DiskdIO *>(IO);
-
- if (DIO->away >= DIO->magic2) {
- diskd_stats.block_queue_len++;
- retval = 1; /* We might not have anything to do, but our queue
- * is full.. */
- }
-
- if (diskd_stats.sent_count - diskd_stats.recv_count >
- diskd_stats.max_away) {
- diskd_stats.max_away = diskd_stats.sent_count - diskd_stats.recv_count;
- }
-
- while (1) {
-#ifdef ALWAYS_ZERO_BUFFERS
- memset(&M, '\0', sizeof(M));
-#endif
-
- x = msgrcv(DIO->rmsgid, &M, msg_snd_rcv_sz, 0, IPC_NOWAIT);
-
- if (x < 0)
- break;
- else if (x != msg_snd_rcv_sz) {
- debug(47, 1) ("storeDiskdDirCallback: msgget returns %d\n",
- x);
- break;
- }
-
- diskd_stats.recv_count++;
- --DIO->away;
- storeDiskdHandle(&M);
- retval = 1; /* Return that we've actually done some work */
-
- if (M.shm_offset > -1)
- DIO->shm.put ((off_t) M.shm_offset);
- }
-
- return retval;
-}
-
-/*
- * storeDiskdDirCheckObj
- *
- * This routine is called by storeDirSelectSwapDir to see if the given
- * object is able to be stored on this filesystem. DISKD filesystems will
- * happily store anything as long as the LRU time isn't too small.
- */
-int
-DiskdSwapDir::canStore(StoreEntry const &e)const
-{
- if (IO->shedLoad())
- return -1;
-
- return IO->load();
-}
-
-void
-DiskdSwapDir::unlinkFile(char const *path)
-{
-#if USE_UNLINKD
- unlinkdUnlink(path);
-#elif USE_TRUNCATE
-
- truncate(path, 0);
-#else
-
- unlink(path);
-#endif
-
-}
-
-/* ========== LOCAL FUNCTIONS ABOVE, GLOBAL FUNCTIONS BELOW ========== */
-
-void
-DiskdSwapDir::statfs(StoreEntry & sentry)const
-{
- UFSSwapDir::statfs (sentry);
- DiskdIO *DIO = dynamic_cast<DiskdIO *>(IO);
- storeAppendPrintf(&sentry, "Pending operations: %d\n", DIO->away);
-}
-
-static void
-storeDiskdDirParseQ1(SwapDir * sd, const char *name, const char *value, int reconfiguring)
-{
- DiskdIO *IO = dynamic_cast<DiskdIO *>(((DiskdSwapDir *)sd)->IO);
- int old_magic1 = IO->magic1;
- IO->magic1 = atoi(value);
-
- if (!reconfiguring)
- return;
-
- if (old_magic1 < IO->magic1) {
- /*
- * This is because shm.nbufs is computed at startup, when
- * we call shmget(). We can't increase the Q1/Q2 parameters
- * beyond their initial values because then we might have
- * more "Q2 messages" than shared memory chunks, and this
- * will cause an assertion in storeDiskdShmGet().
- */
- debug(3, 1) ("WARNING: cannot increase cache_dir '%s' Q1 value while Squid is running.\n", sd->path);
- IO->magic1 = old_magic1;
- return;
- }
-
- if (old_magic1 != IO->magic1)
- debug(3, 1) ("cache_dir '%s' new Q1 value '%d'\n",
- sd->path, IO->magic1);
-}
-
-static void
-storeDiskdDirDumpQ1(StoreEntry * e, const char *option, SwapDir const * sd)
-{
- DiskdIO *IO = dynamic_cast<DiskdIO *>(((DiskdSwapDir *)sd)->IO);
- storeAppendPrintf(e, " Q1=%d", IO->magic1);
-}
-
-static void
-storeDiskdDirParseQ2(SwapDir * sd, const char *name, const char *value, int reconfiguring)
-{
- DiskdIO *IO = dynamic_cast<DiskdIO *>(((DiskdSwapDir *)sd)->IO);
- assert (IO);
- int old_magic2 = IO->magic2;
- IO->magic2 = atoi(value);
-
- if (!reconfiguring)
- return;
-
- if (old_magic2 < IO->magic2) {
- /* See comments in Q1 function above */
- debug(3, 1) ("WARNING: cannot increase cache_dir '%s' Q2 value while Squid is running.\n", sd->path);
- IO->magic2 = old_magic2;
- return;
- }
-
- if (old_magic2 != IO->magic2)
- debug(3, 1) ("cache_dir '%s' new Q2 value '%d'\n",
- sd->path, IO->magic2);
-}
-
-static void
-storeDiskdDirDumpQ2(StoreEntry * e, const char *option, SwapDir const * sd)
-{
- DiskdIO *IO = dynamic_cast<DiskdIO *>(((DiskdSwapDir *)sd)->IO);
- storeAppendPrintf(e, " Q2=%d", IO->magic2);
-}
-
-struct cache_dir_option options[] =
- {
-#if NOT_YET
- {"L1", storeDiskdDirParseL1, storeDiskdDirDumpL1},
- {"L2", storeDiskdDirParseL2, storeDiskdDirDumpL2},
-#endif
- {"Q1", storeDiskdDirParseQ1, storeDiskdDirDumpQ1},
- {"Q2", storeDiskdDirParseQ2, storeDiskdDirDumpQ2},
- {NULL, NULL}
- };
-
-/*
- * storeDiskdDirReconfigure
- *
- * This routine is called when the given swapdir needs reconfiguring
- */
-void
-DiskdSwapDir::reconfigure(int anIndex, char *aPath)
-{
- UFSSwapDir::reconfigure (anIndex, aPath);
-
- parse_cachedir_options(this, options, 1);
-}
-
-void
-DiskdSwapDir::dump(StoreEntry & entry)const
-{
- UFSSwapDir::dump (entry);
- dump_cachedir_options(&entry, options, this);
-}
-
-/*
- * storeDiskdDirParse
- *
- * Called when a *new* fs is being setup.
- */
-void
-DiskdSwapDir::parse(int anIndex, char *aPath)
-{
- UFSSwapDir::parse(anIndex, aPath);
-
- parse_cachedir_options(this, options, 0);
-}
-
-/*
- * Initial setup / end destruction
- */
-static void
-storeDiskdDirDone(void)
-{
- diskd_initialised = 0;
-}
-
-static SwapDir *
-storeDiskdNew(void)
-{
- DiskdSwapDir *result = new DiskdSwapDir;
- result->IO = new DiskdIO;
- return result;
-}
-
-void
-storeFsSetup_diskd(storefs_entry_t * storefs)
-{
- assert(!diskd_initialised);
- storefs->donefunc = storeDiskdDirDone;
- storefs->newfunc = storeDiskdNew;
- memset(&diskd_stats, '\0', sizeof(diskd_stats));
- cachemgrRegister("diskd", "DISKD Stats", storeDiskdStats, 0, 1);
- debug(47, 1) ("diskd started\n");
- diskd_initialised = 1;
-}
virtual void close ();
virtual bool error() const;
virtual bool canRead() const;
+ virtual bool ioInProgress()const;
/* Temporary */
int getID() const {return id;}
int mode;
void notifyClient();
bool canNotifyClient() const;
+ void ioAway();
+ void ioCompleted();
+ size_t inProgressIOs;
};
class SharedMemory
int id;
};
-class diskdstate_t : public UFSStoreState
-{
-
-public:
- virtual void deleteSelf() const {delete this;}
-
- void * operator new (size_t);
- void operator delete (void *);
- diskdstate_t(SwapDir *SD, StoreEntry *e, STIOCB * callback, void *callback_data);
- ~diskdstate_t();
-
- void close();
-
- void ioCompletedNotification();
- void readCompleted(const char *buf, int len, int errflag);
- void writeCompleted(int errflag, size_t len);
- void closeCompleted();
-
-private:
- CBDATA_CLASS(diskdstate_t);
- void doCallback(int);
-};
-
#include "dio.h"
struct _diskd_stats
typedef struct _diskd_stats diskd_stats_t;
-extern void storeDiskdHandle(diomsg * M);
+class SwapDir;
+#define SHMBUF_BLKSZ SM_PAGE_SIZE
+
+extern diskd_stats_t diskd_stats;
-#include "SwapDir.h"
+#include "fs/ufs/IOModule.h"
-class DiskdSwapDir : public UFSSwapDir
+class DiskdIOModule : public IOModule
{
public:
+ static DiskdIOModule &GetInstance();
+ DiskdIOModule();
virtual void init();
- virtual void dump(StoreEntry &)const;
- virtual void unlink(StoreEntry &);
- virtual void statfs (StoreEntry &) const;
- virtual int canStore(StoreEntry const &) const;
- virtual int callback();
- virtual void sync();
- virtual void parse (int index, char *path);
- virtual void reconfigure (int, char *);
- virtual void unlinkFile(char const *);
-};
+ virtual void shutdown();
+ virtual UFSStrategy *createSwapDirIOStrategy();
-#define SHMBUF_BLKSZ SM_PAGE_SIZE
+private:
+ static DiskdIOModule *Instance;
+ bool initialised;
+};
-extern diskd_stats_t diskd_stats;
+/* Per SwapDir instance */
class DiskdIO : public UFSStrategy
{
virtual int load();
virtual StoreIOState::Pointer createState(SwapDir *SD, StoreEntry *e, STIOCB * callback, void *callback_data) const;
virtual DiskFile::Pointer newFile (char const *path);
+ virtual SwapDirOption *getOptionTree() const;
+ virtual void unlinkFile (char const *);
+ void storeDiskdHandle(diomsg * M);
+ virtual void init();
+ virtual int callback();
+ virtual void sync();
+ virtual void statfs(StoreEntry & sentry)const;
int away;
int magic1;
int magic2;
int rmsgid;
int wfd;
SharedMemory shm;
+
+private:
+ static size_t newInstance();
+ bool optionQ1Parse(char const *option, const char *value, int reconfiguring);
+ void optionQ1Dump(StoreEntry * e) const;
+ bool optionQ2Parse(char const *option, const char *value, int reconfiguring);
+ void optionQ2Dump(StoreEntry * e) const;
+ void unlinkDone(diomsg * M);
+ static size_t nextInstanceID;
+ size_t instanceID;
};
+extern void storeDiskdStats(StoreEntry * sentry);
+
#endif
/*
- * $Id: store_io_diskd.cc,v 1.33 2003/02/21 22:50:40 robertc Exp $
+ * $Id: store_io_diskd.cc,v 1.34 2003/07/22 15:23:11 robertc Exp $
*
* DEBUG: section 79 Squid-side DISKD I/O functions.
* AUTHOR: Duane Wessels
#include "store_diskd.h"
#include "SwapDir.h"
+size_t DiskdIO::nextInstanceID (0);
+
static int storeDiskdSend(int, DiskdIO *, int, StoreIOState::Pointer, int, int, off_t);
static int storeDiskdSend(int, DiskdIO *, int, DiskdFile *, int, int, off_t);
/* === PUBLIC =========================================================== */
-DiskdIO::DiskdIO() : away (0), magic1(64), magic2(72)
+DiskdIO::DiskdIO() : away (0), magic1(64), magic2(72), instanceID(newInstance())
{}
+size_t
+DiskdIO::newInstance()
+{
+ return ++nextInstanceID;
+}
+
bool
DiskdIO::shedLoad()
{
StoreIOState::Pointer
DiskdIO::createState(SwapDir *SD, StoreEntry *e, STIOCB * callback, void *callback_data) const
{
- return new diskdstate_t (SD, e, callback, callback_data);
+ return new UFSStoreState (SD, e, callback, callback_data);
}
DiskFile::Pointer
}
+void
+DiskdIO::unlinkFile(char const *path)
+{
+ if (shedLoad()) {
+ /* Damn, we need to issue a sync unlink here :( */
+ debug(79, 2) ("storeDiskUnlink: Out of queue space, sync unlink\n");
+#if USE_UNLINKD
+
+ unlinkdUnlink(path);
+#elif USE_TRUNCATE
+
+ truncate(path, 0);
+#else
+
+ unlink(path);
+#endif
+
+ return;
+ }
+
+ /* We can attempt a diskd unlink */
+ int x;
+
+ off_t shm_offset;
+
+ char *buf;
+
+ buf = (char *)shm.get(&shm_offset);
+
+ xstrncpy(buf, path, SHMBUF_BLKSZ);
+
+ x = storeDiskdSend(_MQD_UNLINK,
+ this,
+ 0,
+ (StoreIOState::Pointer )NULL,
+ 0,
+ 0,
+ shm_offset);
+
+ if (x < 0) {
+ debug(79, 1) ("storeDiskdSend UNLINK: %s\n", xstrerror());
+ ::unlink(buf); /* XXX EWW! */
+ shm.put (shm_offset);
+ }
+
+ diskd_stats.unlink.ops++;
+}
+
/*
* SHM manipulation routines
*/
void
DiskdFile::deleteSelf() const {delete this;}
-DiskdFile::DiskdFile (char const *aPath, DiskdIO *anIO) : errorOccured (false), IO(anIO)
+DiskdFile::DiskdFile (char const *aPath, DiskdIO *anIO) : errorOccured (false), IO(anIO),
+ inProgressIOs (0)
{
assert (aPath);
debug (79,3)("DiskdFile::DiskdFile: %s\n", aPath);
DiskdFile::~DiskdFile()
{
+ assert (inProgressIOs == 0);
safe_free (path_);
}
off_t shm_offset;
char *buf = (char *)IO->shm.get(&shm_offset);
xstrncpy(buf, path_, SHMBUF_BLKSZ);
+ ioAway();
int x = storeDiskdSend(_MQD_OPEN,
IO,
id,
shm_offset);
if (x < 0) {
+ ioCompleted();
errorOccured = true;
IO->shm.put (shm_offset);
ioRequestor->ioCompletedNotification();
off_t shm_offset;
char *buf = (char *)IO->shm.get(&shm_offset);
xstrncpy(buf, path_, SHMBUF_BLKSZ);
+ ioAway();
int x = storeDiskdSend(_MQD_CREATE,
IO,
id,
shm_offset);
if (x < 0) {
+ ioCompleted();
errorOccured = true;
IO->shm.put (shm_offset);
debug(79, 1) ("storeDiskdSend CREATE: %s\n", xstrerror());
off_t shm_offset;
char *rbuf = (char *)IO->shm.get(&shm_offset);
assert(rbuf);
+ ioAway();
int x = storeDiskdSend(_MQD_READ,
IO,
id,
shm_offset);
if (x < 0) {
+ ioCompleted();
errorOccured = true;
IO->shm.put (shm_offset);
debug(79, 1) ("storeDiskdSend READ: %s\n", xstrerror());
{
debug (79,3)("DiskdFile::close: %p closing for %p\n", this, ioRequestor.getRaw());
assert (ioRequestor.getRaw());
+ ioAway();
int x = storeDiskdSend(_MQD_CLOSE,
IO,
id,
-1);
if (x < 0) {
+ ioCompleted();
errorOccured = true;
debug(79, 1) ("storeDiskdSend CLOSE: %s\n", xstrerror());
notifyClient();
diskd_stats.open.success++;
}
+ ioCompleted();
notifyClient();
}
diskd_stats.create.success++;
}
+ ioCompleted();
notifyClient();
}
-CBDATA_CLASS_INIT(diskdstate_t);
-
-void *
-diskdstate_t::operator new (size_t)
-{
- CBDATA_INIT_TYPE(diskdstate_t);
- diskdstate_t *result = cbdataAlloc(diskdstate_t);
- /* Mark result as being owned - we want the refcounter to do the delete
- * call */
- cbdataReference(result);
- debug (79,3)("diskdstate with base %p allocating\n", result);
- return result;
-}
-
-void
-diskdstate_t::operator delete (void *address)
-{
- debug (79,3)("diskdstate with base %p deleting\n",address);
- diskdstate_t *t = static_cast<diskdstate_t *>(address);
- cbdataFree(address);
- /* And allow the memory to be freed */
- cbdataReferenceDone (t);
-}
-
-diskdstate_t::diskdstate_t(SwapDir *SD, StoreEntry *e_, STIOCB * callback_, void *callback_data_)
-{
- swap_filen = e_->swap_filen;
- swap_dirn = SD->index;
- mode = O_BINARY;
- callback = callback_;
- callback_data = cbdataReference(callback_data_);
- e = e_;
-}
-
-/*
- * We can't pass memFree() as a free function here, because we need to free
- * the fsdata variable ..
- */
-diskdstate_t::~diskdstate_t()
-{}
-
-void
-diskdstate_t::ioCompletedNotification()
-{
- if (opening) {
- opening = false;
- debug(79, 3) ("storeDiskdOpenDone: dirno %d, fileno %08x status %d\n",
- swap_dirn, swap_filen, theFile->error());
- assert (FILE_MODE(mode) == O_RDONLY);
-
- if (theFile->error()) {
- doCallback(DISK_ERROR);
- }
-
- return;
- }
-
- if (creating) {
- creating = false;
- debug(79, 3) ("storeDiskdCreateDone: dirno %d, fileno %08x status %d\n",
- swap_dirn, swap_filen, theFile->error());
-
- if (theFile->error()) {
- doCallback(DISK_ERROR);
- }
-
- return;
- }
-
- assert (!closing);
- debug(79, 3) ("diskd::ioCompleted: dirno %d, fileno %08x status %d\n", swap_dirn, swap_filen, theFile->error());
- /* Ok, notification past open means an error has occured */
- assert (theFile->error());
- doCallback(DISK_ERROR);
-}
-
-void
-diskdstate_t::closeCompleted()
-{
- assert (closing);
- debug(79, 3) ("storeDiskdCloseDone: dirno %d, fileno %08x status %d\n",
- swap_dirn, swap_filen, theFile->error());
-
- if (theFile->error()) {
- doCallback(DISK_ERROR);
- } else {
- doCallback(DISK_OK);
- }
-}
-
-void
-diskdstate_t::close()
-{
- debug(79, 3) ("storeDiskdClose: dirno %d, fileno %08X\n", swap_dirn,
- swap_filen);
- closing = true;
- ((DiskdFile *)theFile.getRaw())->close();
-}
-
void
DiskdFile::write(char const *buf, size_t size, off_t offset, FREE *free_func)
{
+ debug(79, 3) ("DiskdFile::write: this %p , buf %p, off %ld, len %d\n", this, buf, offset, size);
off_t shm_offset;
char *sbuf = (char *)IO->shm.get(&shm_offset);
xmemcpy(sbuf, buf, size);
if (free_func)
free_func(const_cast<char *>(buf));
+ ioAway();
+
int x = storeDiskdSend(_MQD_WRITE,
IO,
id,
shm_offset);
if (x < 0) {
+ ioCompleted();
errorOccured = true;
debug(79, 1) ("storeDiskdSend WRITE: %s\n", xstrerror());
IO->shm.put (shm_offset);
diskd_stats.write.ops++;
}
-void
-DiskdSwapDir::unlink(StoreEntry & e)
-{
- int x;
- off_t shm_offset;
- char *buf;
-
- debug(79, 3) ("storeDiskdUnlink: dirno %d, fileno %08X\n", index,
- e.swap_filen);
- replacementRemove(&e);
- mapBitReset(e.swap_filen);
-
- if (IO->shedLoad()) {
- /* Damn, we need to issue a sync unlink here :( */
- debug(79, 2) ("storeDiskUnlink: Out of queue space, sync unlink\n");
- UFSSwapDir::unlinkFile(e.swap_filen);
- return;
- }
-
- /* We can attempt a diskd unlink */
- buf = (char *)((DiskdIO *)IO)->shm.get(&shm_offset);
-
- xstrncpy(buf, fullPath(e.swap_filen, NULL), SHMBUF_BLKSZ);
- x = storeDiskdSend(_MQD_UNLINK,
- (DiskdIO *)IO,
- e.swap_filen,
- (StoreIOState::Pointer )NULL,
- 0,
- 0,
- shm_offset);
-
- if (x < 0) {
- debug(79, 1) ("storeDiskdSend UNLINK: %s\n", xstrerror());
- ::unlink(buf); /* XXX EWW! */
- ((DiskdIO *)IO)->shm.put (shm_offset);
- }
+/* === STATIC =========================================================== */
- diskd_stats.unlink.ops++;
+void
+DiskdFile::ioAway()
+{
+ ++inProgressIOs;
}
-
-/* === STATIC =========================================================== */
+void
+DiskdFile::ioCompleted()
+{
+ --inProgressIOs;
+}
void
DiskdFile::closeDone(diomsg * M)
{
statCounter.syscalls.disk.closes++;
- debug(79, 3) ("storeDiskdCloseDone: status %d\n", M->status);
+ debug(79, 3) ("DiskdFile::closeDone: status %d\n", M->status);
if (M->status < 0) {
diskd_stats.close.fail++;
diskd_stats.close.success++;
}
+ ioCompleted();
+
if (canNotifyClient())
ioRequestor->closeCompleted();
if (M->status < 0) {
diskd_stats.read.fail++;
+ ioCompleted();
errorOccured = true;
ioRequestor->readCompleted(NULL, -1, DISK_ERROR);
return;
diskd_stats.read.success++;
+ ioCompleted();
ioRequestor->readCompleted (IO->shm.buf + M->shm_offset, M->status, DISK_OK);
}
-void
-diskdstate_t::readCompleted(const char *buf, int len, int errflag)
-{
- reading = false;
- debug(79, 3) ("storeDiskdReadDone: dirno %d, fileno %08x len %d\n",
- swap_dirn, swap_filen, len);
-
- if (len > 0)
- offset_ += len;
-
- STRCB *callback = read.callback;
-
- assert(callback);
-
- read.callback = NULL;
-
- void *cbdata;
-
- if (cbdataReferenceValidDone(read.callback_data, &cbdata)) {
- assert (!closing);
- /*
- * Only copy the data if the callback is still valid,
- * if it isn't valid then the request should have been
- * aborted.
- * -- adrian
- */
-
- if (len > 0 && read_buf != buf)
- memcpy(read_buf, buf, len);
-
- callback(cbdata, read_buf, len);
- }
-}
-
-void
-diskdstate_t::writeCompleted(int errflag, size_t len)
-{
- writing = false;
- debug(79, 3) ("storeDiskdWriteDone: dirno %d, fileno %08x status %d\n",
- swap_dirn, swap_filen, len);
- offset_ += len;
-
- if (errflag)
- doCallback(DISK_ERROR);
-}
-
void
DiskdFile::writeDone(diomsg *M)
{
if (M->status < 0) {
errorOccured = true;
diskd_stats.write.fail++;
+ ioCompleted();
ioRequestor->writeCompleted (DISK_ERROR,0);
return;
}
diskd_stats.write.success++;
+ ioCompleted();
ioRequestor->writeCompleted (DISK_OK,M->status);
}
-static void
-storeDiskdUnlinkDone(diomsg * M)
+bool
+DiskdFile::ioInProgress()const
+{
+ return inProgressIOs != 0;
+}
+
+void
+DiskdIO::unlinkDone(diomsg * M)
{
- debug(79, 3) ("storeDiskdUnlinkDone: fileno %08x status %d\n",
- M->id, M->status);
+ debug(79, 3) ("storeDiskdUnlinkDone: file %s status %d\n",shm.buf + M->shm_offset,
+ M->status);
statCounter.syscalls.disk.unlinks++;
if (M->status < 0)
}
void
-storeDiskdHandle(diomsg * M)
+DiskdIO::storeDiskdHandle(diomsg * M)
{
if (!cbdataReferenceValid (M->callback_data)) {
debug(79, 3) ("storeDiskdHandle: Invalid callback_data %p\n",
break;
case _MQD_UNLINK:
- storeDiskdUnlinkDone(M);
+ unlinkDone(M);
break;
default:
cbdataReferenceDone (M->callback_data);
}
-void
-diskdstate_t::doCallback(int errflag)
-{
- if (!this || !cbdataReferenceValid(this)) {
- debug (79, 0) ("storeDiskdIOCallback: invalid siocb %p\n",this);
- return;
- }
-
- void *cbdata;
- STIOCB *theCallback = callback;
- debug(79, 3) ("storeUfsIOCallback: errflag=%d\n", errflag);
- callback = NULL;
-
- if (cbdataReferenceValidDone(callback_data, &cbdata) && theCallback)
- theCallback(cbdata, errflag, this);
-}
-
int
storeDiskdSend(int mtype, DiskdIO *IO, int id, DiskdFile *theFile, int size, int offset, off_t shm_offset)
{
return x;
}
+SwapDirOption *
+DiskdIO::getOptionTree() const
+{
+ SwapDirOptionVector *result = new SwapDirOptionVector;
+ result->options.push_back(new SwapDirOptionAdapter<DiskdIO>(*const_cast<DiskdIO *>(this), &DiskdIO::optionQ1Parse, &DiskdIO::optionQ1Dump));
+ result->options.push_back(new SwapDirOptionAdapter<DiskdIO>(*const_cast<DiskdIO *>(this), &DiskdIO::optionQ2Parse, &DiskdIO::optionQ2Dump));
+ return result;
+}
+
+bool
+DiskdIO::optionQ1Parse(const char *name, const char *value, int reconfiguring)
+{
+ if (strcmp(name, "Q1") != 0)
+ return false;
+
+ int old_magic1 = magic1;
+
+ magic1 = atoi(value);
+
+ if (!reconfiguring)
+ return true;
+
+ if (old_magic1 < magic1) {
+ /*
+ * This is because shm.nbufs is computed at startup, when
+ * we call shmget(). We can't increase the Q1/Q2 parameters
+ * beyond their initial values because then we might have
+ * more "Q2 messages" than shared memory chunks, and this
+ * will cause an assertion in storeDiskdShmGet().
+ */
+ /* TODO: have DiskdIO hold a link to the swapdir, to allow detailed reporting again */
+ debug(3, 1) ("WARNING: cannot increase cache_dir Q1 value while Squid is running.\n");
+ magic1 = old_magic1;
+ return true;
+ }
+
+ if (old_magic1 != magic1)
+ debug(3, 1) ("cache_dir new Q1 value '%d'\n",
+ magic1);
+
+ return true;
+}
+
+void
+DiskdIO::optionQ1Dump(StoreEntry * e) const
+{
+ storeAppendPrintf(e, " Q1=%d", magic1);
+}
+
+bool
+DiskdIO::optionQ2Parse(const char *name, const char *value, int reconfiguring)
+{
+ if (strcmp(name, "Q2") != 0)
+ return false;
+
+ int old_magic2 = magic2;
+
+ magic2 = atoi(value);
+
+ if (!reconfiguring)
+ return true;
+
+ if (old_magic2 < magic2) {
+ /* See comments in Q1 function above */
+ debug(3, 1) ("WARNING: cannot increase cache_dir Q2 value while Squid is running.\n");
+ magic2 = old_magic2;
+ return true;
+ }
+
+ if (old_magic2 != magic2)
+ debug(3, 1) ("cache_dir new Q2 value '%d'\n",
+ magic2);
+
+ return true;
+}
+
+void
+DiskdIO::optionQ2Dump(StoreEntry * e) const
+{
+ storeAppendPrintf(e, " Q2=%d", magic2);
+}
+
+void
+DiskdIO::init()
+{
+ int x;
+ int rfd;
+ int ikey;
+ const char *args[5];
+ char skey1[32];
+ char skey2[32];
+ char skey3[32];
+
+ ikey = (getpid() << 10) + (instanceID << 2);
+ ikey &= 0x7fffffff;
+ smsgid = msgget((key_t) ikey, 0700 | IPC_CREAT);
+
+ if (smsgid < 0) {
+ debug(50, 0) ("storeDiskdInit: msgget: %s\n", xstrerror());
+ fatal("msgget failed");
+ }
+
+ rmsgid = msgget((key_t) (ikey + 1), 0700 | IPC_CREAT);
+
+ if (rmsgid < 0) {
+ debug(50, 0) ("storeDiskdInit: msgget: %s\n", xstrerror());
+ fatal("msgget failed");
+ }
+
+ shm.init(ikey, magic2);
+ snprintf(skey1, 32, "%d", ikey);
+ snprintf(skey2, 32, "%d", ikey + 1);
+ snprintf(skey3, 32, "%d", ikey + 2);
+ args[0] = "diskd";
+ args[1] = skey1;
+ args[2] = skey2;
+ args[3] = skey3;
+ args[4] = NULL;
+ x = ipcCreate(IPC_STREAM,
+ Config.Program.diskd,
+ args,
+ "diskd",
+ &rfd,
+ &wfd);
+ if (x < 0)
+ fatalf("execl: %s", Config.Program.diskd);
+
+ if (rfd != wfd)
+ comm_close(rfd);
+
+ fd_note(wfd, "squid -> diskd");
+
+ commSetTimeout(wfd, -1, NULL, NULL);
+
+ commSetNonBlocking(wfd);
+
+ comm_quick_poll_required();
+}
+
+/*
+ * Sync any pending data. We just sit around and read the queue
+ * until the data has finished writing.
+ */
+void
+DiskdIO::sync()
+{
+ static time_t lastmsg = 0;
+
+ while (away > 0) {
+ if (squid_curtime > lastmsg) {
+ debug(47, 1) ("storeDiskdDirSync: %d messages away\n",
+ away);
+ lastmsg = squid_curtime;
+ }
+
+ callback();
+ }
+}
+
+
+/*
+ * Handle callbacks. If we have more than magic2 requests away, we block
+ * until the queue is below magic2. Otherwise, we simply return when we
+ * don't get a message.
+ */
+int
+DiskdIO::callback()
+{
+ diomsg M;
+ int x;
+ int retval = 0;
+
+ DiskdIO *DIO = this;//dynamic_cast<DiskdIO *>(IO);
+
+ if (DIO->away >= DIO->magic2) {
+ diskd_stats.block_queue_len++;
+ retval = 1;
+ /* We might not have anything to do, but our queue
+ * is full.. */
+ }
+
+ if (diskd_stats.sent_count - diskd_stats.recv_count >
+ diskd_stats.max_away) {
+ diskd_stats.max_away = diskd_stats.sent_count - diskd_stats.recv_count;
+ }
+
+ while (1) {
+#ifdef ALWAYS_ZERO_BUFFERS
+ memset(&M, '\0', sizeof(M));
+#endif
+
+ x = msgrcv(DIO->rmsgid, &M, msg_snd_rcv_sz, 0, IPC_NOWAIT);
+
+ if (x < 0)
+ break;
+ else if (x != msg_snd_rcv_sz) {
+ debug(47, 1) ("storeDiskdDirCallback: msgget returns %d\n",
+ x);
+ break;
+ }
+
+ diskd_stats.recv_count++;
+ --DIO->away;
+ DIO->storeDiskdHandle(&M);
+ retval = 1; /* Return that we've actually done some work */
+
+ if (M.shm_offset > -1)
+ DIO->shm.put ((off_t) M.shm_offset);
+ }
+
+ return retval;
+}
+
+void
+DiskdIO::statfs(StoreEntry & sentry)const
+{
+ storeAppendPrintf(&sentry, "Pending operations: %d\n", away);
+}
+
+DiskdIOModule::DiskdIOModule() : initialised(false) {}
+
+DiskdIOModule &
+DiskdIOModule::GetInstance()
+{
+ if (!Instance)
+ Instance = new DiskdIOModule;
+
+ return *Instance;
+}
+
+void
+DiskdIOModule::init()
+{
+ /* We may be reused - for instance in coss - eventually.
+ * When we do, we either need per-using-module stats (
+ * no singleton pattern), or we need to refcount the
+ * initialisation level and handle multiple clients.
+ * RBC - 20030718.
+ */
+ assert(!initialised);
+ memset(&diskd_stats, '\0', sizeof(diskd_stats));
+ cachemgrRegister("diskd", "DISKD Stats", storeDiskdStats, 0, 1);
+
+ debug(47, 1) ("diskd started\n");
+ initialised = true;
+}
+
+void
+DiskdIOModule::shutdown()
+{
+ initialised = false;
+}
+
+UFSStrategy *
+DiskdIOModule::createSwapDirIOStrategy()
+{
+ return new DiskdIO;
+}
+
+DiskdIOModule *DiskdIOModule::Instance = NULL;
+
+diskd_stats_t diskd_stats;
+
+void
+storeDiskdStats(StoreEntry * sentry)
+{
+ storeAppendPrintf(sentry, "sent_count: %d\n", diskd_stats.sent_count);
+ storeAppendPrintf(sentry, "recv_count: %d\n", diskd_stats.recv_count);
+ storeAppendPrintf(sentry, "max_away: %d\n", diskd_stats.max_away);
+ storeAppendPrintf(sentry, "max_shmuse: %d\n", diskd_stats.max_shmuse);
+ storeAppendPrintf(sentry, "open_fail_queue_len: %d\n", diskd_stats.open_fail_queue_len);
+ storeAppendPrintf(sentry, "block_queue_len: %d\n", diskd_stats.block_queue_len);
+ diskd_stats.max_away = diskd_stats.max_shmuse = 0;
+ storeAppendPrintf(sentry, "\n OPS SUCCESS FAIL\n");
+ storeAppendPrintf(sentry, "%7s %7d %7d %7d\n",
+ "open", diskd_stats.open.ops, diskd_stats.open.success, diskd_stats.open.fail);
+ storeAppendPrintf(sentry, "%7s %7d %7d %7d\n",
+ "create", diskd_stats.create.ops, diskd_stats.create.success, diskd_stats.create.fail);
+ storeAppendPrintf(sentry, "%7s %7d %7d %7d\n",
+ "close", diskd_stats.close.ops, diskd_stats.close.success, diskd_stats.close.fail);
+ storeAppendPrintf(sentry, "%7s %7d %7d %7d\n",
+ "unlink", diskd_stats.unlink.ops, diskd_stats.unlink.success, diskd_stats.unlink.fail);
+ storeAppendPrintf(sentry, "%7s %7d %7d %7d\n",
+ "read", diskd_stats.read.ops, diskd_stats.read.success, diskd_stats.read.fail);
+ storeAppendPrintf(sentry, "%7s %7d %7d %7d\n",
+ "write", diskd_stats.write.ops, diskd_stats.write.success, diskd_stats.write.fail);
+}
--- /dev/null
+
+
+/*
+ * $Id: StoreFSnull.cc,v 1.1 2003/07/22 15:23:14 robertc Exp $
+ *
+ * DEBUG: section 47 Store Directory Routines
+ * AUTHOR: Robert Collins
+ *
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+
+#include "StoreFileSystem.h"
+#include "fs/null/StoreFSnull.h"
+#include "fs/null/store_null.h"
+
+StoreFSnull StoreFSnull::_instance;
+
+StoreFileSystem &
+StoreFSnull::GetInstance()
+{
+ return _instance;
+}
+
+StoreFSnull::StoreFSnull()
+{
+ FsAdd(*this);
+}
+
+char const *
+StoreFSnull::type() const
+{
+ return "null";
+}
+
+void
+StoreFSnull::done()
+{
+ initialised = false;
+}
+
+SwapDir *
+StoreFSnull::createSwapDir()
+{
+ return new NullSwapDir;
+}
+
+void
+StoreFSnull::setup()
+{
+ assert(!initialised);
+ initialised = true;
+}
--- /dev/null
+
+/*
+ * $Id: StoreFSnull.h,v 1.1 2003/07/22 15:23:14 robertc Exp $
+ *
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#ifndef SQUID_STOREFSNULL_H
+#define SQUID_STOREFSNULL_H
+
+#include "squid.h"
+
+class StoreFSnull : public StoreFileSystem
+{
+
+public:
+ static StoreFileSystem &GetInstance();
+ StoreFSnull();
+ virtual ~StoreFSnull() {}
+
+ virtual char const *type() const;
+ virtual SwapDir *createSwapDir();
+ virtual void done();
+ virtual void setup();
+ /* Not implemented */
+ StoreFSnull (StoreFSnull const &);
+ StoreFSnull &operator=(StoreFSnull const &);
+
+private:
+ static StoreFSnull _instance;
+};
+
+#endif /* SQUID_STOREFSNULL_H */
/*
- * $Id: store_null.cc,v 1.6 2003/02/21 22:50:44 robertc Exp $
+ * $Id: store_null.cc,v 1.7 2003/07/22 15:23:14 robertc Exp $
*
* DEBUG: section 47 Store Directory Routines
* AUTHOR: Duane Wessels
#include <sys/statvfs.h>
#endif
#endif
-#include "SwapDir.h"
#include "Store.h"
+#include "fs/null/store_null.h"
-class NullSwapDir : public SwapDir
-{
-
-public:
- virtual void init();
- virtual int canStore(StoreEntry const &)const;
- virtual StoreIOState::Pointer createStoreIO(StoreEntry &, STFNCB *, STIOCB *, void *);
- virtual StoreIOState::Pointer openStoreIO(StoreEntry &, STFNCB *, STIOCB *, void *);
- virtual void parse(int, char*);
- virtual void reconfigure (int, char *);
-};
-
-static int null_initialised = 0;
static EVH storeNullDirRebuildComplete;
-
-/* The only externally visible interface */
-STSETUP storeFsSetup_null;
+NullSwapDir::NullSwapDir() : SwapDir ("null") {}
void
NullSwapDir::reconfigure(int index, char *path)
(void) 0;
}
-static void
-storeNullDirDone(void)
-{
- null_initialised = 0;
-}
-
-static SwapDir *
-storeNullNew(void)
-{
- SwapDir *result = new NullSwapDir;
- return result;
-}
void
NullSwapDir::init()
{
index = anIndex;
path = xstrdup(aPath);
- parse_cachedir_options(this, NULL, 0);
+ parseOptions(0);
}
-/* Setup and register the store module */
-
-void
-storeFsSetup_null(storefs_entry_t * storefs)
-{
- assert(!null_initialised);
- storefs->donefunc = storeNullDirDone;
- storefs->newfunc = storeNullNew;
- null_initialised = 1;
-}
--- /dev/null
+
+/*
+ * $Id: store_null.h,v 1.1 2003/07/22 15:23:14 robertc Exp $
+ *
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#ifndef SQUID_STORE_NULL_H
+#define SQUID_STORE_NULL_H
+
+#include "squid.h"
+#include "SwapDir.h"
+
+class NullSwapDir : public SwapDir
+{
+
+public:
+ NullSwapDir();
+ virtual void init();
+ virtual int canStore(StoreEntry const &)const;
+ virtual StoreIOState::Pointer createStoreIO(StoreEntry &, STFNCB *, STIOCB *, void *);
+ virtual StoreIOState::Pointer openStoreIO(StoreEntry &, STFNCB *, STIOCB *, void *);
+ virtual void parse(int, char*);
+ virtual void reconfigure (int, char *);
+};
+
+#endif /* SQUID_STORE_NULL_H */
--- /dev/null
+
+/*
+ * $Id: IOModule.h,v 1.1 2003/07/22 15:23:14 robertc Exp $
+ *
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#ifndef SQUID_IOMODULE_H
+#define SQUID_IOMODULE_H
+
+#include "squid.h"
+
+class UFSStrategy;
+
+class IOModule
+{
+
+public:
+ virtual ~IOModule(){}
+
+ virtual void init() = 0;
+ virtual void shutdown() = 0;
+ virtual UFSStrategy *createSwapDirIOStrategy() = 0;
+};
+
+
+#endif /* SQUID_IOMODULE_H */
--- /dev/null
+
+
+/*
+ * $Id: StoreFSufs.cc,v 1.1 2003/07/22 15:23:14 robertc Exp $
+ *
+ * DEBUG: section 47 Store Directory Routines
+ * AUTHOR: Robert Collins
+ *
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+
+#include "StoreFileSystem.h"
+#include "fs/ufs/StoreFSufs.h"
+#include "fs/ufs/store_ufs.h"
+
+static StoreFSufs<UFSSwapDir> UfsInstance(UfsIOModule::GetInstance(), "ufs");
+
--- /dev/null
+
+/*
+ * $Id: StoreFSufs.h,v 1.1 2003/07/22 15:23:14 robertc Exp $
+ *
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#ifndef SQUID_STOREFSUFS_H
+#define SQUID_STOREFSUFS_H
+
+#include "squid.h"
+
+class IOModule;
+
+template <class TheSwapDir>
+
+class StoreFSufs : public StoreFileSystem
+{
+
+public:
+ static StoreFileSystem &GetInstance();
+ StoreFSufs(IOModule &, char const *label);
+ virtual ~StoreFSufs() {}
+
+ virtual char const *type() const;
+ virtual SwapDir *createSwapDir();
+ virtual void done();
+ virtual void setup();
+ /* Not implemented */
+ StoreFSufs (StoreFSufs const &);
+ StoreFSufs &operator=(StoreFSufs const &);
+
+protected:
+ IOModule &IO;
+ char const *label;
+};
+
+template <class C>
+StoreFSufs<C>::StoreFSufs(IOModule &anIO, char const *aLabel) : IO(anIO), label(aLabel)
+{
+ FsAdd(*this);
+}
+
+template <class C>
+char const *
+StoreFSufs<C>::type() const
+{
+ return label;
+}
+
+template <class C>
+SwapDir *
+StoreFSufs<C>::createSwapDir()
+{
+ C *result = new C(type());
+ result->IO = IO.createSwapDirIOStrategy();
+ return result;
+}
+
+template <class C>
+void
+StoreFSufs<C>::done()
+{
+ IO.shutdown();
+ initialised = false;
+}
+
+template <class C>
+void
+StoreFSufs<C>::setup()
+{
+ assert(!initialised);
+ initialised = true;
+ IO.init();
+}
+
+#endif /* SQUID_STOREFSUFS_H */
/*
- * $Id: store_dir_ufs.cc,v 1.59 2003/07/15 11:33:23 robertc Exp $
+ * $Id: store_dir_ufs.cc,v 1.60 2003/07/22 15:23:14 robertc Exp $
*
* DEBUG: section 47 Store Directory Routines
* AUTHOR: Duane Wessels
#include "StoreSwapLogData.h"
#include "SwapDir.h"
-static int ufs_initialised = 0;
-
int UFSSwapDir::NumberOfUFSDirs = 0;
int *UFSSwapDir::UFSDirToGlobalDirMapping = NULL;
-STSETUP storeFsSetup_ufs;
-
/*
* storeUfsDirCheckObj
*
* happily store anything as long as the LRU time isn't too small.
*/
int
-UfsSwapDir::canStore(StoreEntry const &e)const
+UFSSwapDir::canStore(StoreEntry const &e)const
{
- /* Return 999 (99.9%) constant load */
- return 999;
-}
-
-void
-UfsSwapDir::unlinkFile(char const *path)
-{
-#if USE_UNLINKD
- unlinkdUnlink(path);
-#elif USE_TRUNCATE
-
- truncate(path, 0);
-#else
+ if (IO->shedLoad())
+ return -1;
- ::unlink(path);
-#endif
+ return IO->load();
}
-/* ========== LOCAL FUNCTIONS ABOVE, GLOBAL FUNCTIONS BELOW ========== */
-
-static struct cache_dir_option options[] =
- {
-#if NOT_YET_DONE
- {"L1", storeUfsDirParseL1, storeUfsDirDumpL1},
- {"L2", storeUfsDirParseL2, storeUfsDirDumpL2},
-#endif
- {NULL, NULL}
- };
-/*
- * storeUfsDirReconfigure
- *
- * This routine is called when the given swapdir needs reconfiguring
- */
-void
-UfsSwapDir::reconfigure(int anIndex, char *aPath)
-{
- UFSSwapDir::reconfigure (anIndex, aPath);
- parse_cachedir_options(this, options, 1);
-}
+/* ========== LOCAL FUNCTIONS ABOVE, GLOBAL FUNCTIONS BELOW ========== */
void
-UFSSwapDir::reconfigure(int index, char *path)
+UFSSwapDir::parseSizeL1L2()
{
int i;
int size;
size = i << 10; /* Mbytes to kbytes */
if (size <= 0)
- fatal("storeDiskdDirReconfigure: invalid size value");
-
- l1 = GetInteger();
-
- if (l1 <= 0)
- fatal("storeDiskdDirReconfigure: invalid level 1 directories value");
-
- l2 = GetInteger();
-
- if (l2 <= 0)
- fatal("storeDiskdDirReconfigure: invalid level 2 directories value");
+ fatal("UFSSwapDir::parseSizeL1L2: invalid size value");
/* just reconfigure it */
if (size == max_size)
path, size);
max_size = size;
+
+ l1 = GetInteger();
+
+ if (l1 <= 0)
+ fatal("UFSSwapDir::parseSizeL1L2: invalid level 1 directories value");
+
+ l2 = GetInteger();
+
+ if (l2 <= 0)
+ fatal("UFSSwapDir::parseSizeL1L2: invalid level 2 directories value");
}
+/*
+ * storeUfsDirReconfigure
+ *
+ * This routine is called when the given swapdir needs reconfiguring
+ */
+
void
-UfsSwapDir::dump(StoreEntry & entry)const
+UFSSwapDir::reconfigure(int index, char *path)
{
- UFSSwapDir::dump (entry);
- dump_cachedir_options(&entry, options, this);
+ parseSizeL1L2();
+ parseOptions(1);
}
/*
* Called when a *new* fs is being setup.
*/
void
-UfsSwapDir::parse(int anIndex, char *aPath)
+UFSSwapDir::parse (int anIndex, char *aPath)
{
- UFSSwapDir::parse (anIndex, aPath);
+ parseSizeL1L2();
- parse_cachedir_options(this, options, 1);
-}
+ index = anIndex;
-void
-UFSSwapDir::parse (int anIndex, char *aPath)
-{
- max_size = GetInteger() << 10; /* Mbytes to kbytes */
+ path = xstrdup(aPath);
- if (max_size <= 0)
- fatal("storeAufsDirParse: invalid size value");
+ /* Initialise replacement policy stuff */
+ repl = createRemovalPolicy(Config.replPolicy);
- l1 = GetInteger();
+ parseOptions(0);
+}
- if (l1 <= 0)
- fatal("storeAufsDirParse: invalid level 1 directories value");
+SwapDirOption *
+UFSSwapDir::getOptionTree() const
+{
+ SwapDirOption *parentResult = SwapDir::getOptionTree();
+ SwapDirOption *ioOptions = IO->getOptionTree();
- l2 = GetInteger();
+ if (!ioOptions)
+ return parentResult;
- if (l2 <= 0)
- fatal("storeAufsDirParse: invalid level 2 directories value");
+ SwapDirOptionVector *result = new SwapDirOptionVector();
- index = anIndex;
+ result->options.push_back(parentResult);
- path = xstrdup(aPath);
+ result->options.push_back(ioOptions);
- /* Initialise replacement policy stuff */
- repl = createRemovalPolicy(Config.replPolicy);
+ return result;
}
/*
"\tFailed to verify one of the swap directories, Check cache.log\n"
"\tfor details. Run 'squid -z' to create swap directories\n"
"\tif needed, or if running Squid for the first time.";
+ IO->init();
initBitmap();
if (verifyCacheDirs())
createSwapSubDirs();
}
-UFSSwapDir::UFSSwapDir() : IO(NULL), map(NULL), suggest(0), swaplog_fd (-1) {}
+UFSSwapDir::UFSSwapDir(char const *aType) : SwapDir(aType), IO(NULL), map(NULL), suggest(0), swaplog_fd (-1) {}
UFSSwapDir::~UFSSwapDir()
{
IO = NULL;
}
-static void
-storeUfsDirDone(void)
-{
- ufs_initialised = 0;
-}
-
-static SwapDir *
-storeUfsNew(void)
-{
- UfsSwapDir *result = new UfsSwapDir;
- result->IO = &UfsIO::Instance;
- return result;
-}
-
-void
-storeFsSetup_ufs(storefs_entry_t * storefs)
-{
- assert(!ufs_initialised);
- storefs->donefunc = storeUfsDirDone;
- storefs->newfunc = storeUfsNew;
- ufs_initialised = 1;
-}
-
void
UFSSwapDir::dumpEntry(StoreEntry &e) const
{
storeAppendPrintf(&sentry, " READ-ONLY");
storeAppendPrintf(&sentry, "\n");
+
+ IO->statfs(sentry);
}
void
void
UFSSwapDir::createSwapSubDirs()
{
- int i, k;
- int should_exist;
LOCAL_ARRAY(char, name, MAXPATHLEN);
- for (i = 0; i < l1; i++) {
+ for (int i = 0; i < l1; i++) {
snprintf(name, MAXPATHLEN, "%s/%02X", path, i);
+ int should_exist;
+
if (createDirectory(name, 0))
should_exist = 0;
else
debug(47, 1) ("Making directories in %s\n", name);
- for (k = 0; k < l2; k++) {
+ for (int k = 0; k < l2; k++) {
snprintf(name, MAXPATHLEN, "%s/%02X/%02X", path, i, k);
createDirectory(name, should_exist);
}
swaplog_fd = -1;
- NumberOfUFSDirs--;
+ --NumberOfUFSDirs;
assert(NumberOfUFSDirs >= 0);
#define CLEAN_BUF_SZ 16384
-/*
- * Begin the process to write clean cache state. For AUFS this means
- * opening some log files and allocating write buffers. Return 0 if
- * we succeed, and assign the 'func' and 'data' return pointers.
- */
UFSCleanLog::UFSCleanLog(SwapDir *aSwapDir) : cur(NULL),newLog(NULL),cln(NULL),outbuf(NULL),
outbuf_offset(0), fd(-1),walker(NULL), sd(aSwapDir)
{}
+/*
+ * Begin the process to write clean cache state. For AUFS this means
+ * opening some log files and allocating write buffers. Return 0 if
+ * we succeed, and assign the 'func' and 'data' return pointers.
+ */
int
UFSSwapDir::writeCleanStart()
{
return 1;
}
+
+
/*
* UFSSwapDir::unlinkFile
*
void
UFSSwapDir::unlinkFile(sfileno f)
{
- debug(79, 3) ("UFSSwapDir::unlinkFile: unlinking fileno %08X\n", f);
+ debug(79, 3) ("UFSSwapDir::unlinkFile: unlinking fileno %08X '%s'\n", f, fullPath(f,NULL));
/* commonUfsDirMapBitReset(this, f); */
- unlinkFile(fullPath(f, NULL));
+ IO->unlinkFile(fullPath(f,NULL));
+}
+
+void
+UFSSwapDir::unlink(StoreEntry & e)
+{
+ debug(79, 3) ("storeUfsUnlink: dirno %d, fileno %08X\n", index, e.swap_filen);
+ replacementRemove(&e);
+ mapBitReset(e.swap_filen);
+ UFSSwapDir::unlinkFile(e.swap_filen);
}
/*
max_size >> 10,
l1,
l2);
+ dumpOptions(&entry);
}
char *
return fullpath;
}
+
+int
+UFSSwapDir::callback()
+{
+ return IO->callback();
+}
+
+void
+UFSSwapDir::sync()
+{
+ IO->sync();
+}
/*
- * $Id: store_io_ufs.cc,v 1.19 2003/07/15 23:12:02 robertc Exp $
+ * $Id: store_io_ufs.cc,v 1.20 2003/07/22 15:23:15 robertc Exp $
*
* DEBUG: section 79 Storage Manager UFS Interface
* AUTHOR: Duane Wessels
return false;
}
+int
+UfsIO::load()
+{
+ /* Return 999 (99.9%) constant load */
+ return 999;
+}
+
void
UfsIO::deleteSelf() const
{
StoreIOState::Pointer
UfsIO::createState(SwapDir *SD, StoreEntry *e, STIOCB * callback, void *callback_data) const
{
- return new ufsstate_t (SD, e, callback, callback_data);
+ return new UFSStoreState (SD, e, callback, callback_data);
}
DiskFile::Pointer
return new UFSFile (path);
}
-CBDATA_CLASS_INIT(ufsstate_t);
+void
+UfsIO::unlinkFile(char const *path)
+{
+#if USE_UNLINKD
+ unlinkdUnlink(path);
+#elif USE_TRUNCATE
+
+ truncate(path, 0);
+#else
+
+ ::unlink(path);
+#endif
+}
+
+CBDATA_CLASS_INIT(UFSStoreState);
void *
-ufsstate_t::operator new (size_t)
+UFSStoreState::operator new (size_t)
{
- CBDATA_INIT_TYPE(ufsstate_t);
- ufsstate_t *result = cbdataAlloc(ufsstate_t);
- /* Mark result as being owned - we want the refcounter to do the delete
- * call */
- cbdataReference(result);
- return result;
+ CBDATA_INIT_TYPE(UFSStoreState);
+ return cbdataAlloc(UFSStoreState);
}
void
-ufsstate_t::operator delete (void *address)
+UFSStoreState::operator delete (void *address)
{
- ufsstate_t *t = static_cast<ufsstate_t *>(address);
cbdataFree(address);
- /* And allow the memory to be freed */
- cbdataReferenceDone (t);
-}
-
-ufsstate_t::ufsstate_t(SwapDir * SD, StoreEntry * anEntry, STIOCB * callback_, void *callback_data_)
-{
- swap_filen = anEntry->swap_filen;
- swap_dirn = SD->index;
- mode = O_BINARY;
- callback = callback_;
- callback_data = cbdataReference(callback_data_);
- e = anEntry;
}
CBDATA_CLASS_INIT(UFSFile);
void
UFSFile::deleteSelf() const {delete this;}
-UFSFile::UFSFile (char const *aPath) : fd (-1)
+UFSFile::UFSFile (char const *aPath) : fd (-1), closed (true)
{
assert (aPath);
debug (79,3)("UFSFile::UFSFile: %s\n", aPath);
if (fd < 0) {
debug(79, 3) ("UFSFile::open: got failure (%d)\n", errno);
} else {
+ closed = false;
store_open_disk_fd++;
debug(79, 3) ("UFSFile::open: opened FD %d\n", fd);
}
void UFSFile::doClose()
{
if (fd > -1) {
+ closed = true;
file_close(fd);
store_open_disk_fd--;
fd = -1;
bool
UFSFile::error() const
{
- if (fd < 0)
+ if (fd < 0 && !closed)
return true;
return false;
}
void
-ufsstate_t::ioCompletedNotification()
+UFSStoreState::ioCompletedNotification()
{
if (opening) {
opening = false;
- /* There is no 'opened' callback */
+ debug(79, 3) ("storeDiskdOpenDone: dirno %d, fileno %08x status %d\n",
+ swap_dirn, swap_filen, theFile->error());
+ assert (FILE_MODE(mode) == O_RDONLY);
+ openDone();
+
return;
}
if (creating) {
creating = false;
+ debug(79, 3) ("storeDiskdCreateDone: dirno %d, fileno %08x status %d\n",
+ swap_dirn, swap_filen, theFile->error());
+ openDone();
+
return;
}
- assert(0);
+ assert (!(closing ||opening));
+ debug(79, 3) ("diskd::ioCompleted: dirno %d, fileno %08x status %d\n", swap_dirn, swap_filen, theFile->error());
+ /* Ok, notification past open means an error has occured */
+ assert (theFile->error());
+ doCallback(DISK_ERROR);
}
void
-ufsstate_t::closeCompleted()
+UFSStoreState::openDone()
{
- doCallback(theFile->error() ? 0 : -1);
+ if (theFile->error()) {
+ doCallback(DISK_ERROR);
+ return;
+ }
+
+ if (FILE_MODE(mode) == O_WRONLY) {
+ if (kickWriteQueue())
+ return;
+ } else if ((FILE_MODE(mode) == O_RDONLY) && !closing) {
+ if (kickReadQueue())
+ return;
+ }
+
+ if (closing && !theFile->ioInProgress())
+ doCallback(theFile->error() ? -1 : 0);
+
+ debug(79, 3) ("squidaiostate_t::openDone: exiting\n");
}
void
-ufsstate_t::close()
+UFSStoreState::closeCompleted()
{
- debug(79, 3) ("storeUfsClose: dirno %d, fileno %08X\n",
- swap_dirn, swap_filen);
- closing = true;
+ assert (closing);
+ debug(79, 3) ("UFSStoreState::closeCompleted: dirno %d, fileno %08x status %d\n",
+ swap_dirn, swap_filen, theFile->error());
- if (!(reading || writing)) {
- ((UFSFile *)theFile.getRaw())->close();
- }
+ if (theFile->error())
+ doCallback(DISK_ERROR);
+ else
+ doCallback(DISK_OK);
+
+ closing = false;
+}
+
+/* Close */
+void
+UFSStoreState::close()
+{
+ debug(79, 3) ("UFSStoreState::close: dirno %d, fileno %08X\n", swap_dirn,
+ swap_filen);
+ /* mark the object to be closed on the next io that completes */
+ closing = true;
+ theFile->close();
}
void
{
debug(79, 3) ("UFSStoreState::write: dirn %d, fileno %08X\n", swap_dirn, swap_filen);
- if (!theFile->canWrite() || writing) {
+ if (!theFile->canWrite()) {
assert(creating || writing);
queueWrite(buf, size, offset, free_func);
return;
theFile->write(buf,size,offset,free_func);
}
-void
-UfsSwapDir::unlink(StoreEntry & e)
+bool
+UFSFile::ioInProgress()const
{
- debug(79, 3) ("storeUfsUnlink: fileno %08X\n", e.swap_filen);
- replacementRemove(&e);
- mapBitReset(e.swap_filen);
- UFSSwapDir::unlinkFile(e.swap_filen);
+ /* IO is never pending with UFS */
+ return false;
}
/* === STATIC =========================================================== */
}
void
-ufsstate_t::readCompleted(const char *buf, int len, int errflag)
+UFSStoreState::readCompleted(const char *buf, int len, int errflag)
{
-
reading = false;
- debug(79, 3) ("storeUfsReadDone: dirno %d, fileno %08X, len %d\n",
+ debug(79, 3) ("storeDiskdReadDone: dirno %d, fileno %08x len %d\n",
swap_dirn, swap_filen, len);
if (len > 0)
void *cbdata;
+ /* A note:
+ * diskd IO queues closes via the diskd queue. So close callbacks
+ * occur strictly after reads and writes.
+ * ufs doesn't queue, it simply completes, so close callbacks occur
+ * strictly after reads and writes.
+ * aufs performs closes syncronously, so close events must be managed
+ * to force strict ordering.
+ * The below does this:
+ * closing is set when close() is called, and close only triggers
+ * when no io's are pending.
+ * writeCompleted likewise.
+ */
if (!closing && cbdataReferenceValidDone(read.callback_data, &cbdata)) {
if (len > 0 && read_buf != buf)
memcpy(read_buf, buf, len);
callback(cbdata, read_buf, len);
- } else if (closing)
- fatal("Sync ufs doesn't support overlapped close and read calls\n");
+ } else if (closing && theFile.getRaw()!= NULL && !theFile->ioInProgress())
+ doCallback(errflag);
}
void
}
void
-ufsstate_t::writeCompleted(int errflag, size_t len)
+UFSStoreState::writeCompleted(int errflag, size_t len)
{
debug(79, 3) ("storeUfsWriteDone: dirno %d, fileno %08X, len %ld\n",
swap_dirn, swap_filen, (long int) len);
writing = false;
- if (theFile->error())
+ offset_ += len;
+
+ if (theFile->error()) {
doCallback(DISK_ERROR);
+ return;
+ }
- offset_ += len;
+ if (closing && !theFile->ioInProgress()) {
+ theFile->close();
+ return;
+ }
+
+ if (!flags.write_kicking) {
+ flags.write_kicking = true;
+ /* While we start and complete syncronously io's. */
+
+ while (kickWriteQueue() && !theFile->ioInProgress())
- if (closing)
- ((UFSFile *)theFile.getRaw())->close();
+ ;
+ flags.write_kicking = false;
+
+ if (!theFile->ioInProgress() && closing)
+ doCallback(errflag);
+ }
}
void
-ufsstate_t::doCallback(int errflag)
+UFSStoreState::doCallback(int errflag)
{
debug(79, 3) ("storeUfsIOCallback: errflag=%d\n", errflag);
- /* We are finished with the file */
+ /* We are finished with the file as this is on close or error only.*/
theFile = NULL;
- void *cbdata;
-
- if (cbdataReferenceValidDone(callback_data, &cbdata))
- callback(cbdata, errflag, this);
+ STIOCB *theCallback = callback;
callback = NULL;
-}
-
-
-/*
- * Clean up any references from the SIO before it get's released.
- */
-ufsstate_t::~ufsstate_t()
-{}
+ void *cbdata;
+ if (cbdataReferenceValidDone(callback_data, &cbdata) && theCallback)
+ theCallback(cbdata, errflag, this);
+}
/* ============= THE REAL UFS CODE ================ */
-UFSStoreState::UFSStoreState() : opening (false), creating (false), closing (false), reading(false), writing(false), pending_reads(NULL), pending_writes (NULL){}
+UFSStoreState::UFSStoreState(SwapDir * SD, StoreEntry * anEntry, STIOCB * callback_, void *callback_data_) : opening (false), creating (false), closing (false), reading(false), writing(false), pending_reads(NULL), pending_writes (NULL)
+{
+ swap_filen = anEntry->swap_filen;
+ swap_dirn = SD->index;
+ mode = O_BINARY;
+ callback = callback_;
+ callback_data = cbdataReference(callback_data_);
+ e = anEntry;
+ flags.write_kicking = false;
+}
UFSStoreState::~UFSStoreState()
{
UFSStrategy::open(SwapDir * SD, StoreEntry * e, STFNCB * file_callback,
STIOCB * callback, void *callback_data)
{
- assert (((UfsSwapDir *)SD)->IO == this);
+ assert (((UFSSwapDir *)SD)->IO == this);
debug(79, 3) ("UFSStrategy::open: fileno %08X\n", e->swap_filen);
if (shedLoad()) {
UFSStrategy::create(SwapDir * SD, StoreEntry * e, STFNCB * file_callback,
STIOCB * callback, void *callback_data)
{
- assert (((UfsSwapDir *)SD)->IO == this);
+ assert (((UFSSwapDir *)SD)->IO == this);
/* Allocate a number */
sfileno filn = ((UFSSwapDir *)SD)->mapBitAllocate();
debug(79, 3) ("UFSStrategy::create: fileno %08X\n", filn);
return sio;
}
+
+UfsIOModule &
+UfsIOModule::GetInstance()
+{
+ if (!Instance)
+ Instance = new UfsIOModule;
+
+ return *Instance;
+}
+
+void
+UfsIOModule::init()
+{}
+
+void
+UfsIOModule::shutdown()
+{}
+
+UFSStrategy *
+UfsIOModule::createSwapDirIOStrategy()
+{
+ return new InstanceToSingletonAdapter<UfsIO>(&UfsIO::Instance);
+}
+
+UfsIOModule *UfsIOModule::Instance = NULL;
virtual int getFD() const { return fd;}
virtual bool canRead() const;
+ virtual bool ioInProgress()const;
private:
static DRCB ReadDone;
static DWCB WriteDone;
CBDATA_CLASS(UFSFile);
int fd;
+ bool closed;
char const *path_;
IORequestor::Pointer ioRequestor;
void doClose();
void writeDone(int fd, int errflag, size_t len);
};
-class ufsstate_t : public UFSStoreState
-{
-
-public:
- virtual void deleteSelf() const {delete this;}
-
- void * operator new (size_t);
- void operator delete (void *);
- ufsstate_t(SwapDir *SD, StoreEntry *e, STIOCB * callback, void *callback_data);
- ~ufsstate_t();
- void close();
- void ioCompletedNotification();
- void readCompleted(const char *buf, int len, int errflag);
- void writeCompleted(int errflag, size_t len);
- void closeCompleted();
-
-private:
- CBDATA_CLASS(ufsstate_t);
- void doCallback (int);
-};
-
-
#include "SwapDir.h"
/*
* Store IO stuff
*/
/* For things that aren't factored well yet */
-class UfsSwapDir: public UFSSwapDir
-{
- virtual void dump(StoreEntry &)const;
- virtual void unlink(StoreEntry &);
- virtual int canStore(StoreEntry const&)const;
- virtual void parse (int index, char *path);
- virtual void reconfigure (int, char *);
- virtual void unlinkFile (char const *);
-};
-
class UfsIO : public UFSStrategy
{
public:
virtual bool shedLoad();
+ virtual int load();
virtual void deleteSelf() const;
virtual StoreIOState::Pointer createState(SwapDir *SD, StoreEntry *e, STIOCB * callback, void *callback_data) const;
virtual DiskFile::Pointer newFile (char const *path);
+ virtual void unlinkFile (char const *);
static UfsIO Instance;
};
+#include "fs/ufs/IOModule.h"
+
+class UfsIOModule : public IOModule
+{
+
+public:
+ static UfsIOModule &GetInstance();
+ virtual void init();
+ virtual void shutdown();
+ virtual UFSStrategy *createSwapDirIOStrategy();
+
+private:
+ static UfsIOModule *Instance;
+};
+
#endif
/*
- * $Id: globals.h,v 1.125 2003/07/09 14:14:58 hno Exp $
+ * $Id: globals.h,v 1.126 2003/07/22 15:23:02 robertc Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
extern int store_open_disk_fd; /* 0 */
extern const char *SwapDirType[];
extern authscheme_entry_t *authscheme_list; /* NULL */
-extern storefs_entry_t *storefs_list; /* NULL */
extern storerepl_entry_t *storerepl_list; /* NULL */
extern int store_swap_low; /* 0 */
extern int store_swap_high; /* 0 */
/*
- * $Id: main.cc,v 1.384 2003/07/15 06:50:42 robertc Exp $
+ * $Id: main.cc,v 1.385 2003/07/22 15:23:02 robertc Exp $
*
* DEBUG: section 1 Startup and Main Loop
* AUTHOR: Harvest Derived
#include "ACLASN.h"
#include "ACL.h"
#include "htcp.h"
+#include "StoreFileSystem.h"
#if USE_WIN32_SERVICE
storeFsInit(); /* required for config parsing */
+ /* Shouldn't be needed for config parsing, but have not audited for such */
+ StoreFileSystem::SetupAllFs();
+
authenticateSchemeInit(); /* required for config parsign */
parse_err = parseConfigFile(ConfigFile);
#endif
storeDirSync(); /* Flush log close */
- storeFsDone();
+ StoreFileSystem::FreeAllFs();
#if PURIFY || XMALLOC_TRACE
configFreeMemory();
/*
- * $Id: protos.h,v 1.484 2003/07/15 11:33:22 robertc Exp $
+ * $Id: protos.h,v 1.485 2003/07/22 15:23:02 robertc Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
SQUIDCEXTERN void self_destruct(void);
SQUIDCEXTERN int GetInteger(void);
SQUIDCEXTERN void add_http_port(char *portspec);
+extern int xatoi(const char *token);
+extern long xatol(const char *token);
/* extra functions from cache_cf.c useful for lib modules */
SQUIDCEXTERN void requirePathnameExists(const char *name, const char *path);
SQUIDCEXTERN void parse_time_t(time_t * var);
-SQUIDCEXTERN void parse_cachedir_options(SwapDir * sd, struct cache_dir_option *options, int reconfiguring);
-
-SQUIDCEXTERN void dump_cachedir_options(StoreEntry * e, struct cache_dir_option *options, SwapDir const * sd);
SQUIDCEXTERN void parse_sockaddr_in_list_token(sockaddr_in_list **, char *);
/* ----------------------------------------------------------------- */
-/* store_modules.c */
-SQUIDCEXTERN void storeFsSetup(void);
-
/* repl_modules.c */
SQUIDCEXTERN void storeReplSetup(void);
/*
- * $Id: store.cc,v 1.571 2003/07/14 10:36:42 robertc Exp $
+ * $Id: store.cc,v 1.572 2003/07/22 15:23:02 robertc Exp $
*
* DEBUG: section 20 Storage Manager
* AUTHOR: Harvest Derived
storeFsInit(void)
{
storeReplSetup();
- storeFsSetup();
-}
-
-
-/*
- * similar to above, but is called when a graceful shutdown is to occur
- * of each fs module.
- */
-void
-storeFsDone(void)
-{
- int i = 0;
-
- while (storefs_list[i].typestr != NULL) {
- storefs_list[i].donefunc();
- i++;
- }
-}
-
-/*
- * called to add another store fs module
- * RBC: doesn't belong here. Move IT.
- */
-void
-StoreEntry::FsAdd(const char *type, STSETUP * setup)
-{
- int i;
- /* find the number of currently known storefs types */
-
- for (i = 0; storefs_list && storefs_list[i].typestr; i++) {
- assert(strcmp(storefs_list[i].typestr, type) != 0);
- }
-
- /* add the new type */
- storefs_list = static_cast<storefs_entry_t *>(xrealloc(storefs_list, (i + 2) * sizeof(storefs_entry_t)));
-
- memset(&storefs_list[i + 1], 0, sizeof(storefs_entry_t));
-
- storefs_list[i].typestr = type;
-
- /* Call the FS to set up capabilities and initialize the FS driver */
- setup(&storefs_list[i]);
}
/*
/*
- * $Id: store_dir.cc,v 1.147 2003/07/17 15:40:27 wessels Exp $
+ * $Id: store_dir.cc,v 1.148 2003/07/22 15:23:02 robertc Exp $
*
* DEBUG: section 47 Store Directory Routines
* AUTHOR: Duane Wessels
for (i = 0; i < Config.cacheSwap.n_configured; i++) {
storeAppendPrintf(sentry, "\n");
SD = INDEXSD(i);
- storeAppendPrintf(sentry, "Store Directory #%d (%s): %s\n", i, SD->type,
+ storeAppendPrintf(sentry, "Store Directory #%d (%s): %s\n", i, SD->type(),
storeSwapDir(i));
storeAppendPrintf(sentry, "FS Block Size %d Bytes\n",
SD->fs.blksize);
++ndir;
j += SD->callback();
+
+ if (j > 100)
+ fatal ("too much io\n");
}
} while (j > 0);
+++ /dev/null
-#!/bin/sh
-echo "/* automatically generated by $0 $*"
-echo " * do not edit"
-echo " */"
-echo "#include \"squid.h\""
-echo "#include \"Store.h\""
-echo ""
-for module in "$@"; do
- echo "extern STSETUP storeFsSetup_${module};"
-done
-echo "void storeFsSetup(void)"
-echo "{"
-for module in "$@"; do
- echo " StoreEntry::FsAdd(\"$module\", storeFsSetup_${module});"
-done
-echo "}"
/*
- * $Id: structs.h,v 1.475 2003/07/17 22:22:53 wessels Exp $
+ * $Id: structs.h,v 1.476 2003/07/22 15:23:02 robertc Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
int zero_object_sz;
};
-/*
- * This defines an fs type
- */
-
-struct _storefs_entry
-{
- const char *typestr;
- STFSSHUTDOWN *donefunc;
- STFSNEW *newfunc;
-};
-
/*
* This defines an repl type
*/
/*
- * $Id: typedefs.h,v 1.167 2003/07/15 11:33:22 robertc Exp $
+ * $Id: typedefs.h,v 1.168 2003/07/22 15:23:02 robertc Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
typedef struct _link_list link_list;
-typedef struct _storefs_entry storefs_entry_t;
-
typedef struct _storerepl_entry storerepl_entry_t;
typedef struct _diskd_queue diskd_queue;
typedef void HLPCMDOPTS(int *argc, char **argv);
typedef void IDNSCB(void *, rfc1035_rr *, int);
-typedef void STFSSHUTDOWN(void);
-typedef SwapDir *STFSNEW(void);
-
typedef double hbase_f(double);
typedef void StatHistBinDumper(StoreEntry *, int idx, double val, double size, int count);
/*
- * $Id: ufscommon.h,v 1.6 2003/07/15 11:33:22 robertc Exp $
+ * $Id: ufscommon.h,v 1.7 2003/07/22 15:23:03 robertc Exp $
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
* ----------------------------------------------------------
static int DirClean(int swap_index);
static int FilenoBelongsHere(int fn, int F0, int F1, int F2);
- UFSSwapDir();
+ UFSSwapDir(char const *aType);
virtual void init();
virtual void newFileSystem();
virtual void dump(StoreEntry &) const;
~UFSSwapDir();
virtual bool doubleCheck(StoreEntry &);
- virtual void unlink(StoreEntry &) = 0;
+ virtual void unlink(StoreEntry &);
virtual void statfs(StoreEntry &)const;
virtual void maintainfs();
- virtual int canStore(StoreEntry const &)const = 0;
+ virtual int canStore(StoreEntry const &)const;
virtual void reference(StoreEntry &);
virtual void dereference(StoreEntry &);
virtual StoreIOState::Pointer createStoreIO(StoreEntry &, STFNCB *, STIOCB *, void *);
virtual void logEntry(const StoreEntry & e, int op) const;
virtual void parse(int index, char *path);
virtual void reconfigure(int, char *);
+ virtual int callback();
+ virtual void sync();
void unlinkFile(sfileno f);
- virtual void unlinkFile (char const *) = 0;
// move down when unlink is a virtual method
//protected:
UFSStrategy *IO;
int clean);
int validFileno(sfileno filn, int flag) const;
int mapBitAllocate();
+ virtual SwapDirOption *getOptionTree() const;
+
void *fsdata;
bool validL2(int) const;
int l2;
private:
+ void parseSizeL1L2();
static int NumberOfUFSDirs;
static int * UFSDirToGlobalDirMapping;
bool pathIsDirectory(const char *path)const;
virtual void create (int, mode_t, IORequestor::Pointer) = 0;
virtual void read(char *, off_t, size_t) = 0;
virtual void write(char const *buf, size_t size, off_t offset, FREE *free_func) = 0;
+ virtual void close () = 0;
virtual bool canRead() const = 0;
virtual bool canWrite() const {return true;}
virtual int getFD() const {return -1;}
virtual bool error() const = 0;
+
+ /* Inform callers if there is IO in progress */
+ virtual bool ioInProgress() const = 0;
};
/* UFS dir specific IO calls */
STIOCB *, void *);
/* virtual void strategyStats(StoreEntry *sentry) const = 0; */
/* virtual void dumpCacheDirParams(StoreEntry * e, const char *option) const = 0; */
+ virtual SwapDirOption *getOptionTree() const { return NULL;}
+
+ virtual void unlinkFile (char const *) = 0;
+ virtual void sync() {}
+
+ virtual int callback() { return 0; }
+
+ /* Init per-instance logic */
+ virtual void init() {}
+
+ /* cachemgr output on the IO instance stats */
+ virtual void statfs(StoreEntry & sentry)const {}}
+
+;
+
+class IOStrategy
+{
+
+public:
+ virtual ~IOStrategy(){}
+
+ /* Can the IO Strategy handle more requests ? */
+ virtual bool shedLoad() = 0;
+ /* What is the current load? 999 = 99.9% */
+ virtual int load() = 0;
+ /* Return a handle for performing IO operations */
+ virtual DiskFile::Pointer newFile (char const *path) = 0;
+ /* flush all IO operations */
+ virtual void sync() {}
+
+ /* perform any pending callbacks */
+ virtual int callback() { return 0; }
+
+ /* Init per-instance logic */
+ virtual void init() {}
+
+ /* cachemgr output on the IO instance stats */
+ virtual void statfs(StoreEntry & sentry)const {}}
+
+;
+
+/* RBC 20030718 - use this to provide instance expecting classes a pointer to a
+ * singleton
+ */
+
+template <class C>
+
+class InstanceToSingletonAdapter : public C
+{
+
+public:
+ void *operator new (size_t byteCount) { return ::operator new (byteCount);}
+
+ void operator delete (void *address) { ::operator delete (address);}
+
+ InstanceToSingletonAdapter(C const *instance) : theInstance (instance) {}
+
+ C const * operator-> () const {return theInstance; }
+
+ C * operator-> () {return const_cast<C *>(theInstance); }
+
+ C const & operator * () const {return *theInstance; }
+
+ C & operator * () {return *const_cast<C *>(theInstance); }
+
+ operator C const * () const {return theInstance;}
+
+ operator C *() {return const_cast<C *>(theInstance);}
+
+ // This will go when we remove the deleteSelf idiom
+ virtual void deleteSelf() const {delete const_cast<InstanceToSingletonAdapter*>(this);}
+
+private:
+ C const *theInstance;
};
/* Common ufs-store-dir logic */
{
public:
- virtual void deleteSelf() const = 0;
- UFSStoreState();
+ virtual void deleteSelf() const {delete this;}
+
+ void * operator new (size_t);
+ void operator delete (void *);
+ UFSStoreState(SwapDir * SD, StoreEntry * anEntry, STIOCB * callback_, void *callback_data_);
~UFSStoreState();
+ virtual void close();
+ virtual void closeCompleted();
// protected:
+ virtual void ioCompletedNotification();
+ virtual void readCompleted(const char *buf, int len, int errflag);
+ virtual void writeCompleted(int errflag, size_t len);
DiskFile::Pointer theFile;
bool opening;
bool creating;
void write(char const *buf, size_t size, off_t offset, FREE * free_func);
protected:
+ virtual void doCallback (int errflag);
class _queued_read
{
static MemPool *Pool;
};
+ /* These should be in the IO strategy */
+
+ struct
+ {
+ bool write_kicking;
+ }
+
+ flags;
link_list *pending_reads;
link_list *pending_writes;
void queueRead(char *, size_t, off_t, STRCB *, void *);
bool kickReadQueue();
bool kickWriteQueue();
char *read_buf;
+
+private:
+ CBDATA_CLASS(UFSStoreState);
+ void openDone();
};
class RebuildState : public RefCountable