]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Summary: Merge disk-factoring.
authorrobertc <>
Tue, 22 Jul 2003 21:23:01 +0000 (21:23 +0000)
committerrobertc <>
Tue, 22 Jul 2003 21:23:01 +0000 (21:23 +0000)
Keywords:

Patches applied:

 * robertc@squid-cache.org--squid/squid--disk-io--3.0--patch-14
   Merge of robertc@squid-cache.org--squid/squid--HEAD--3.0--patch-283-285

 * robertc@squid-cache.org--squid/squid--disk-io--3.0--patch-13
   Further OOification of the store drivers.

 * robertc@squid-cache.org--squid/squid--disk-io--3.0--patch-12
   And more OOification.

 * robertc@squid-cache.org--squid/squid--disk-io--3.0--patch-11
   And more OOification of the store drivers.

 * robertc@squid-cache.org--squid/squid--disk-io--3.0--patch-10
   And more OOification.

 * robertc@squid-cache.org--squid/squid--disk-io--3.0--patch-9
   More store OOification.

 * robertc@squid-cache.org--squid/squid--disk-io--3.0--patch-8
   Dist missing files.

 * robertc@squid-cache.org--squid/squid--disk-io--3.0--patch-7
   And moe OOification.

 * robertc@squid-cache.org--squid/squid--disk-io--3.0--patch-6
   And more OOification.

 * robertc@squid-cache.org--squid/squid--disk-io--3.0--patch-5
   More store FS OOification.

 * robertc@squid-cache.org--squid/squid--disk-io--3.0--patch-4
   More OOification for the store.

 * robertc@squid-cache.org--squid/squid--disk-io--3.0--patch-3
   OO'ing the store layer.

 * robertc@squid-cache.org--squid/squid--disk-io--3.0--patch-2
   BUGFIX: array.cc compilation.

 * robertc@squid-cache.org--squid/squid--disk-io--3.0--patch-1
   Update to latest HEAD code.

 * robertc@squid-cache.org--squid/squid--disk-io--3.0--base-0
   tag of robertc@squid-cache.org--squid/squid--HEAD--3.0--patch-220

45 files changed:
configure.in
doc/debug-sections.txt
lib/Array.cc
src/Makefile.am
src/Store.h
src/StoreFileSystem.cc [new file with mode: 0644]
src/StoreFileSystem.h [new file with mode: 0644]
src/StoreIOState.h
src/SwapDir.cc
src/SwapDir.h
src/cache_cf.cc
src/fs/Makefile.am
src/fs/aufs/StoreFSaufs.cc [new file with mode: 0644]
src/fs/aufs/async_io.cc
src/fs/aufs/store_asyncufs.h
src/fs/aufs/store_dir_aufs.cc [deleted file]
src/fs/aufs/store_io_aufs.cc
src/fs/coss/StoreFScoss.cc [new file with mode: 0644]
src/fs/coss/StoreFScoss.h [new file with mode: 0644]
src/fs/coss/async_io.h
src/fs/coss/store_coss.h
src/fs/coss/store_dir_coss.cc
src/fs/diskd/StoreFSdiskd.cc [new file with mode: 0644]
src/fs/diskd/store_dir_diskd.cc [deleted file]
src/fs/diskd/store_diskd.h
src/fs/diskd/store_io_diskd.cc
src/fs/null/StoreFSnull.cc [new file with mode: 0644]
src/fs/null/StoreFSnull.h [new file with mode: 0644]
src/fs/null/store_null.cc
src/fs/null/store_null.h [new file with mode: 0644]
src/fs/ufs/IOModule.h [new file with mode: 0644]
src/fs/ufs/StoreFSufs.cc [new file with mode: 0644]
src/fs/ufs/StoreFSufs.h [new file with mode: 0644]
src/fs/ufs/store_dir_ufs.cc
src/fs/ufs/store_io_ufs.cc
src/fs/ufs/store_ufs.h
src/globals.h
src/main.cc
src/protos.h
src/store.cc
src/store_dir.cc
src/store_modules.sh [deleted file]
src/structs.h
src/typedefs.h
src/ufscommon.h

index 24ca1357f90a03f69af61d499eb91c51a2802d55..f3731fe1597f61fd2430fa092483d489e7532112 100644 (file)
@@ -3,7 +3,7 @@ dnl  Configuration input file for Squid
 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
@@ -13,7 +13,7 @@ AC_CONFIG_SRCDIR([src/main.cc])
 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
 
@@ -428,6 +428,10 @@ if test -n "$STORE_MODULES"; then
     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
@@ -464,13 +468,14 @@ if test -z "$UFS_FOUND" && test -n "$NEED_UFS"; then
    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\"
index 197f72cdcbe5640f522fff0d69efc77d4eeed99f..a7d44c5643b5cec048be6a2698d94e94f46a3360 100644 (file)
@@ -95,3 +95,4 @@ section 88    Client side reply management - from store to stream
 section 89    NAT / IP Interception
 section 90    Store Client
 section 91    Http Surrogate-Control Header
+section 92    Store File System
index 0b1cfd805f21b9e74bb3acd6478258c2425215f6..24397a30c37f3465eaebbc851511909b77985c24 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $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));
-}
index 83d34be0fbc0879784fea0f2c14911e62ec2ee18..a0d508f2403ddcb5dec24cf5fb4114cd9549aa62 100644 (file)
@@ -1,12 +1,13 @@
 #
 #  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
@@ -185,7 +186,15 @@ cf_gen.$(OBJEXT): cf_gen_defines.h
 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 \
@@ -400,6 +409,8 @@ squid_SOURCES = \
        stmem.h \
        store.cc \
        Store.h \
+       StoreFileSystem.cc \
+       StoreFileSystem.h \
        store_io.cc \
        StoreIOBuffer.h \
        StoreIOState.cc \
@@ -426,6 +437,7 @@ squid_SOURCES = \
        StoreMetaURL.h \
        StoreMetaVary.cc \
        StoreMetaVary.h \
+       $(STORE_SOURCES) \
        StoreSwapLogData.cc \
        StoreSwapLogData.h \
        structs.h \
@@ -457,7 +469,6 @@ noinst_HEADERS = ACLChecklist.cci \
 nodist_squid_SOURCES = \
        repl_modules.cc \
        auth_modules.cc \
-       store_modules.cc \
        cf_parser.h \
        globals.cc \
        string_arrays.c
@@ -466,6 +477,7 @@ squid_LDADD = \
        -L../lib \
        @XTRA_OBJS@ \
        @REPL_OBJS@ \
+       @STORE_LINKOBJS@ \
        @STORE_OBJS@ \
        @AUTH_OBJS@ \
        @CRYPTLIB@ \
@@ -476,7 +488,7 @@ squid_LDADD = \
        -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
@@ -652,7 +664,6 @@ ufsdump_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a
 nodist_ufsdump_SOURCES = \
        repl_modules.cc \
        auth_modules.cc \
-       store_modules.cc \
        cf_parser.h \
        globals.cc \
        string_arrays.c
@@ -666,8 +677,7 @@ BUILT_SOURCES = \
        globals.cc \
        string_arrays.c \
        repl_modules.cc \
-       auth_modules.cc \
-       store_modules.cc
+       auth_modules.cc
 
 sysconf_DATA = \
        squid.conf.default \
@@ -684,7 +694,6 @@ EXTRA_DIST = \
        mk-globals-c.pl \
        mk-string-arrays.pl \
        auth_modules.sh \
-       store_modules.sh \
        repl_modules.sh \
        mib.txt \
        mime.conf.default
@@ -760,9 +769,6 @@ cf.data: cf.data.pre Makefile
        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
 
@@ -797,7 +803,7 @@ uninstall-local:
 #      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); \
index 7699254e3627ae8a6f04ef859ff0959285e3f764..696a73af148abf97a442501e3d7973a806672756 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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/
@@ -46,13 +46,10 @@ class StoreClient;
 
 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;
 
@@ -218,12 +215,8 @@ SQUIDCEXTERN void storeHeapPositionUpdate(StoreEntry *, SwapDir *);
 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
diff --git a/src/StoreFileSystem.cc b/src/StoreFileSystem.cc
new file mode 100644 (file)
index 0000000..5f516ac
--- /dev/null
@@ -0,0 +1,91 @@
+
+/*
+ * $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();
+    }
+}
+
diff --git a/src/StoreFileSystem.h b/src/StoreFileSystem.h
new file mode 100644 (file)
index 0000000..3be1789
--- /dev/null
@@ -0,0 +1,73 @@
+
+/*
+ * $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 */
index 5695deef5fe1dc562b1f419c25c2fc8d94f3a72d..7e08d09ba96ca0083ae96cda81da78489e91f4e1 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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/
@@ -44,7 +44,7 @@ public:
     /* 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();
index 002a88b3715c7ab1d8b4007e4a25852dd9832b33..f022ca865c6e8d8a2de440bf8500d2f09095fd96 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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()
 {
@@ -128,3 +121,149 @@ SwapDir::writeCleanDone(){}
 
 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);
+}
index b5e67018f7c060a0a544caec8ee74571381ce725..e13580123f826b01037bbebc8abfe10e4a09b4a4 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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;
index afb31adad45be41cd9b8a0a9c6e33265bfa30c67..65ac7cce9f4752f82611daf63789a4c5a95410ea 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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
@@ -39,6 +39,7 @@
 #include "SwapDir.h"
 #include "ConfigParser.h"
 #include "ACL.h"
+#include "StoreFileSystem.h"
 
 #if SQUID_SNMP
 #include "snmp.h"
@@ -64,10 +65,6 @@ static const char *const B_GBYTES_STR = "GB";
 
 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);
@@ -78,13 +75,6 @@ static void free_logformat(logformat ** 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);
@@ -221,7 +211,7 @@ wordlistDup(const wordlist * w)
  * These functions is the same as atoi/l/f, except that they check for errors
  */
 
-static long
+long
 xatol(const char *token)
 {
     char *end;
@@ -233,7 +223,7 @@ xatol(const char *token)
     return ret;
 }
 
-static int
+int
 xatoi(const char *token)
 {
     return xatol(token);
@@ -1204,19 +1194,6 @@ free_http_header_replace(header_mangler header[])
 
 #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)
@@ -1227,13 +1204,13 @@ dump_cachedir(StoreEntry * entry, const char *name, _SquidConfig::_cacheSwap swa
 
     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)
 {
@@ -1351,16 +1328,13 @@ allocate_new_swapdir(_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);
 }
@@ -1426,7 +1400,7 @@ parse_cachedir(_SquidConfig::_cacheSwap * swap)
     }
 
     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);
@@ -1435,103 +1409,6 @@ parse_cachedir(_SquidConfig::_cacheSwap * swap)
     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)
 {
index c01b8717c45b0eea6c212bbbfa61280335cc7100..354bfc8edb2ae65b725a508b382c7852a55345ef 100644 (file)
@@ -1,6 +1,6 @@
 #  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
@@ -13,10 +13,10 @@ EXTRA_LIBRARIES = libaufs.a libcoss.a libdiskd.a libnull.a libufs.a
 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
 
@@ -32,7 +32,9 @@ libnull_a_SOURCES = null/store_null.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/
diff --git a/src/fs/aufs/StoreFSaufs.cc b/src/fs/aufs/StoreFSaufs.cc
new file mode 100644 (file)
index 0000000..577e379
--- /dev/null
@@ -0,0 +1,42 @@
+
+/*
+ * $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");
index 605dae6661d46213c2721049011f66f8cf1145ec..c949b27470c81184d881832042207a947e71fab6 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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>
@@ -95,7 +95,6 @@ typedef struct squidaio_unlinkq_t
 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);
@@ -107,9 +106,8 @@ aioFDWasClosed(int fd)
         fd_close(fd);
 }
 
-
 void
-aioInit(void)
+AufsIO::init(void)
 {
     if (initialised)
         return;
@@ -119,14 +117,18 @@ aioInit(void)
     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
@@ -134,7 +136,7 @@ aioOpen(const char *path, int oflag, mode_t mode, AIOCB * callback, void *callba
 {
     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;
@@ -152,7 +154,7 @@ aioClose(int fd)
 {
     squidaio_ctrl_t *ctrlp;
 
-    assert(initialised);
+    assert(AufsIO::Instance.initialised);
     squidaio_counts.close_start++;
     aioCancel(fd);
     ctrlp = (squidaio_ctrl_t *)memPoolAlloc(squidaio_ctrl_pool);
@@ -172,7 +174,7 @@ aioCancel(int fd)
     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) {
@@ -214,7 +216,7 @@ aioWrite(int fd, int offset, char *bufp, int len, AIOCB * callback, void *callba
     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;
@@ -243,7 +245,7 @@ aioRead(int fd, int offset, int len, AIOCB * callback, void *callback_data)
     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;
@@ -272,7 +274,7 @@ aioStat(char *path, struct stat *sb, AIOCB * callback, void *callback_data)
 {
     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;
@@ -289,7 +291,7 @@ void
 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;
@@ -305,7 +307,7 @@ void
 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;
@@ -319,7 +321,7 @@ aioTruncate(const char *path, off_t length, AIOCB * callback, void *callback_dat
 
 
 int
-AUFSSwapDir::callback()
+AufsIO::callback()
 {
     squidaio_result_t *resultp;
     squidaio_ctrl_t *ctrlp;
@@ -428,7 +430,7 @@ aioStats(StoreEntry * sentry)
 
 /* Flush all pending I/O */
 void
-AUFSSwapDir::sync()
+AufsIO::sync()
 {
     if (!initialised)
         return;                        /* nothing to do then */
@@ -443,6 +445,8 @@ AUFSSwapDir::sync()
     debug(32, 1) ("aioSync: done\n");
 }
 
+AufsIO::AufsIO() : initialised (false) {}
+
 int
 aioQueueSize(void)
 {
index e2da87ebae5dcbcba4d097d1f2d1b4703286b29c..2c498763a8efac7894c7b30b9b961ef48b66779b 100644 (file)
@@ -98,12 +98,13 @@ public:
     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
@@ -125,6 +126,7 @@ private:
     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;
@@ -135,73 +137,45 @@ private:
     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
diff --git a/src/fs/aufs/store_dir_aufs.cc b/src/fs/aufs/store_dir_aufs.cc
deleted file mode 100644 (file)
index a837c04..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-
-/*
- * $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();
-}
index a546e5cfbc8afdd688bf202e0b182e96191a1799..820375a7a576bd7f59969a3786acaa79ffcf6e7a 100644 (file)
@@ -9,45 +9,10 @@
 #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
@@ -67,6 +32,24 @@ AufsIO::shedLoad()
     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
 {
@@ -76,7 +59,7 @@ 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
@@ -85,6 +68,47 @@ AufsIO::newFile (char const *path)
     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)
@@ -109,7 +133,8 @@ AUFSFile::operator delete (void *address)
 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);
@@ -141,6 +166,8 @@ AUFSFile::open (int flags, mode_t mode, IORequestor::Pointer callback)
 
     ioRequestor = callback;
 
+    ++inProgressIOs;
+
 #if ASYNC_OPEN
 
     aioOpen(path_, flags, mode, AUFSFile::OpenDone, this);
@@ -158,6 +185,7 @@ AUFSFile::read(char *buf, off_t offset, size_t size)
     assert (fd > -1);
     assert (ioRequestor.getRaw());
     statCounter.syscalls.disk.reads++;
+    ++inProgressIOs;
 #if ASYNC_READ
 
     aioRead(fd, offset, size, ReadDone, this);
@@ -186,6 +214,8 @@ AUFSFile::create (int flags, mode_t mode, IORequestor::Pointer callback)
 
     ioRequestor = callback;
 
+    ++inProgressIOs;
+
 #if ASYNC_CREATE
 
     aioOpen(path_, flags, mode, AUFSFile::OpenDone, this);
@@ -232,6 +262,7 @@ AUFSFile::openDone(int unused, const char *unused2, int anFD, int errflag)
     debug(79, 3) ("AUFSFile::openDone: exiting\n");
 
     IORequestor::Pointer t = ioRequestor;
+    --inProgressIOs;
     t->ioCompletedNotification();
 }
 
@@ -251,7 +282,7 @@ StoreIOState::Pointer
 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);
 }
@@ -260,25 +291,22 @@ storeAufsOpen(SwapDir * SD, StoreEntry * e, STFNCB * file_callback,
 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
@@ -293,6 +321,7 @@ AUFSFile::write(char const *buf, size_t size, off_t offset, FREE *free_func)
 {
     debug(79, 3) ("storeAufsWrite: FD %d\n", fd);
     statCounter.syscalls.disk.writes++;
+    ++inProgressIOs;
 #if ASYNC_WRITE
 
     aioWrite(fd, offset, (char *)buf, size, WriteDone, this,
@@ -310,15 +339,10 @@ AUFSFile::canWrite() const
     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 =========================================================== */
@@ -367,80 +391,9 @@ AUFSFile::readDone(int rvfd, const char *buf, int len, int errflag)
 
 #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
@@ -477,118 +430,10 @@ AUFSFile::writeDone (int rvfd, int errflag, size_t len)
 
     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");
-}
diff --git a/src/fs/coss/StoreFScoss.cc b/src/fs/coss/StoreFScoss.cc
new file mode 100644 (file)
index 0000000..e01725c
--- /dev/null
@@ -0,0 +1,82 @@
+
+/*
+ * $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;
+}
diff --git a/src/fs/coss/StoreFScoss.h b/src/fs/coss/StoreFScoss.h
new file mode 100644 (file)
index 0000000..16cf45c
--- /dev/null
@@ -0,0 +1,59 @@
+
+/*
+ * $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 */
index b09f428de4ac4d19e35430cc7199a441ff217cd2..fcc67827ff10998b34588f0f09c1dd7763ddd731 100644 (file)
@@ -1,5 +1,6 @@
 #ifndef __ASYNC_IO_H__
 #define __ASYNC_IO_H__
+#include <aio.h>
 
 #define MAX_ASYNCOP            128
 
index 776e08af47690f26aac5381c8326c7093d04639a..e8c4ea0c947f1b58dbe5f283b7c20d258febab10 100644 (file)
@@ -2,6 +2,7 @@
 #define __COSS_H__
 
 #include "SwapDir.h"
+#include "async_io.h"
 
 #ifndef COSS_MEMBUF_SZ
 #define        COSS_MEMBUF_SZ  1048576
index ae112af7d8da103f75403c0b5883a59e36c14500..3a5bbc8f9cfa6c391cca8daab4995397a4d8f87b 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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
@@ -35,9 +35,7 @@
 
 #include "squid.h"
 #include "Store.h"
-#include <aio.h>
 
-#include "async_io.h"
 #include "store_coss.h"
 #include "fde.h"
 #include "SwapDir.h"
@@ -47,7 +45,6 @@
 
 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;
@@ -87,9 +84,6 @@ static void storeCossDirRebuild(CossSwapDir * sd);
 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)
 {
@@ -828,7 +822,7 @@ CossSwapDir::parse(int anIndex, char *aPath)
 
     max_size = size;
 
-    parse_cachedir_options(this, NULL, 0);
+    parseOptions(0);
 
     /* Enforce maxobjsize being set to something */
     if (max_objsize == -1)
@@ -855,7 +849,7 @@ CossSwapDir::reconfigure(int index, char *path)
         max_size = size;
     }
 
-    parse_cachedir_options(this, NULL, 1);
+    parseOptions(1);
     /* Enforce maxobjsize being set to something */
 
     if (max_objsize == -1)
@@ -865,9 +859,8 @@ CossSwapDir::reconfigure(int index, char *path)
 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
@@ -916,25 +909,7 @@ storeCossDirPick(void)
 }
 
 #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;
@@ -942,13 +917,3 @@ CossSwapDir::CossSwapDir() : fd (-1), swaplog_fd(-1), count(0), current_membuf (
     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;
-}
diff --git a/src/fs/diskd/StoreFSdiskd.cc b/src/fs/diskd/StoreFSdiskd.cc
new file mode 100644 (file)
index 0000000..63ff45c
--- /dev/null
@@ -0,0 +1,42 @@
+
+/*
+ * $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");
diff --git a/src/fs/diskd/store_dir_diskd.cc b/src/fs/diskd/store_dir_diskd.cc
deleted file mode 100644 (file)
index adacce4..0000000
+++ /dev/null
@@ -1,402 +0,0 @@
-
-/*
- * $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;
-}
index 74207677242524a6dc5773deb3b4698f2c0334a2..166d258c990fb646c3f267571b9c1e345614d7f3 100644 (file)
@@ -37,6 +37,7 @@ public:
     virtual void close ();
     virtual bool error() const;
     virtual bool canRead() const;
+    virtual bool ioInProgress()const;
 
     /* Temporary */
     int getID() const {return id;}
@@ -58,6 +59,9 @@ private:
     int mode;
     void notifyClient();
     bool canNotifyClient() const;
+    void ioAway();
+    void ioCompleted();
+    size_t inProgressIOs;
 };
 
 class SharedMemory
@@ -80,29 +84,6 @@ public:
     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
@@ -128,29 +109,29 @@ 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
 {
@@ -163,6 +144,13 @@ public:
     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;
@@ -170,6 +158,18 @@ public:
     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
index 742682788690b279cb610de49e44697aba740893..8808c193566f6fbc3fc91e59dc07ca4fdc44a0e8 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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()
 {
@@ -90,7 +98,7 @@ DiskdIO::openFailed()
 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
@@ -100,6 +108,54 @@ DiskdIO::newFile (char const *path)
 }
 
 
+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
  */
@@ -203,7 +259,8 @@ DiskdFile::operator delete (void *address)
 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);
@@ -213,6 +270,7 @@ DiskdFile::DiskdFile (char const *aPath, DiskdIO *anIO) : errorOccured (false),
 
 DiskdFile::~DiskdFile()
 {
+    assert (inProgressIOs == 0);
     safe_free (path_);
 }
 
@@ -227,6 +285,7 @@ DiskdFile::open (int flags, mode_t aMode, IORequestor::Pointer callback)
     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,
@@ -236,6 +295,7 @@ DiskdFile::open (int flags, mode_t aMode, IORequestor::Pointer callback)
                            shm_offset);
 
     if (x < 0) {
+        ioCompleted();
         errorOccured = true;
         IO->shm.put (shm_offset);
         ioRequestor->ioCompletedNotification();
@@ -256,6 +316,7 @@ DiskdFile::create (int flags, mode_t aMode, IORequestor::Pointer callback)
     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,
@@ -265,6 +326,7 @@ DiskdFile::create (int flags, mode_t aMode, IORequestor::Pointer callback)
                            shm_offset);
 
     if (x < 0) {
+        ioCompleted();
         errorOccured = true;
         IO->shm.put (shm_offset);
         debug(79, 1) ("storeDiskdSend CREATE: %s\n", xstrerror());
@@ -283,6 +345,7 @@ DiskdFile::read(char *buf, off_t offset, size_t size)
     off_t shm_offset;
     char *rbuf = (char *)IO->shm.get(&shm_offset);
     assert(rbuf);
+    ioAway();
     int x = storeDiskdSend(_MQD_READ,
                            IO,
                            id,
@@ -292,6 +355,7 @@ DiskdFile::read(char *buf, off_t offset, size_t size)
                            shm_offset);
 
     if (x < 0) {
+        ioCompleted();
         errorOccured = true;
         IO->shm.put (shm_offset);
         debug(79, 1) ("storeDiskdSend READ: %s\n", xstrerror());
@@ -308,6 +372,7 @@ DiskdFile::close()
 {
     debug (79,3)("DiskdFile::close: %p closing for %p\n", this, ioRequestor.getRaw());
     assert (ioRequestor.getRaw());
+    ioAway();
     int x = storeDiskdSend(_MQD_CLOSE,
                            IO,
                            id,
@@ -317,6 +382,7 @@ DiskdFile::close()
                            -1);
 
     if (x < 0) {
+        ioCompleted();
         errorOccured = true;
         debug(79, 1) ("storeDiskdSend CLOSE: %s\n", xstrerror());
         notifyClient();
@@ -411,6 +477,7 @@ DiskdFile::openDone(diomsg *M)
         diskd_stats.open.success++;
     }
 
+    ioCompleted();
     notifyClient();
 }
 
@@ -427,111 +494,14 @@ DiskdFile::createDone(diomsg *M)
         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);
@@ -539,6 +509,8 @@ DiskdFile::write(char const *buf, size_t size, off_t offset, FREE *free_func)
     if (free_func)
         free_func(const_cast<char *>(buf));
 
+    ioAway();
+
     int x = storeDiskdSend(_MQD_WRITE,
                            IO,
                            id,
@@ -548,6 +520,7 @@ DiskdFile::write(char const *buf, size_t size, off_t offset, FREE *free_func)
                            shm_offset);
 
     if (x < 0) {
+        ioCompleted();
         errorOccured = true;
         debug(79, 1) ("storeDiskdSend WRITE: %s\n", xstrerror());
         IO->shm.put (shm_offset);
@@ -559,55 +532,26 @@ DiskdFile::write(char const *buf, size_t size, off_t offset, FREE *free_func)
     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++;
@@ -616,6 +560,8 @@ DiskdFile::closeDone(diomsg * M)
         diskd_stats.close.success++;
     }
 
+    ioCompleted();
+
     if (canNotifyClient())
         ioRequestor->closeCompleted();
 
@@ -630,6 +576,7 @@ DiskdFile::readDone(diomsg * M)
 
     if (M->status < 0) {
         diskd_stats.read.fail++;
+        ioCompleted();
         errorOccured = true;
         ioRequestor->readCompleted(NULL, -1, DISK_ERROR);
         return;
@@ -637,55 +584,10 @@ DiskdFile::readDone(diomsg * M)
 
     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)
 {
@@ -695,19 +597,27 @@ 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)
@@ -717,7 +627,7 @@ storeDiskdUnlinkDone(diomsg * M)
 }
 
 void
-storeDiskdHandle(diomsg * M)
+DiskdIO::storeDiskdHandle(diomsg * M)
 {
     if (!cbdataReferenceValid (M->callback_data)) {
         debug(79, 3) ("storeDiskdHandle: Invalid callback_data %p\n",
@@ -746,7 +656,7 @@ storeDiskdHandle(diomsg * M)
             break;
 
         case _MQD_UNLINK:
-            storeDiskdUnlinkDone(M);
+            unlinkDone(M);
             break;
 
         default:
@@ -757,23 +667,6 @@ storeDiskdHandle(diomsg * M)
     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)
 {
@@ -893,4 +786,291 @@ storeDiskdSend(int mtype, DiskdIO *IO, int id, StoreIOState::Pointer sio, int si
     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);
+}
diff --git a/src/fs/null/StoreFSnull.cc b/src/fs/null/StoreFSnull.cc
new file mode 100644 (file)
index 0000000..6f172b9
--- /dev/null
@@ -0,0 +1,79 @@
+
+
+/*
+ * $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;
+}
diff --git a/src/fs/null/StoreFSnull.h b/src/fs/null/StoreFSnull.h
new file mode 100644 (file)
index 0000000..d53d9ba
--- /dev/null
@@ -0,0 +1,59 @@
+
+/*
+ * $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 */
index 0b88411dc0e7152c6d197d7c89c75f7d8af2e212..79a2d562ee7f7a6c59e25e4a465840adb77f80dc 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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)
@@ -66,18 +51,6 @@ 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()
@@ -122,16 +95,6 @@ NullSwapDir::parse(int anIndex, char *aPath)
 {
     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;
-}
diff --git a/src/fs/null/store_null.h b/src/fs/null/store_null.h
new file mode 100644 (file)
index 0000000..521f682
--- /dev/null
@@ -0,0 +1,53 @@
+
+/*
+ * $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 */
diff --git a/src/fs/ufs/IOModule.h b/src/fs/ufs/IOModule.h
new file mode 100644 (file)
index 0000000..87ccc12
--- /dev/null
@@ -0,0 +1,53 @@
+
+/*
+ * $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 */
diff --git a/src/fs/ufs/StoreFSufs.cc b/src/fs/ufs/StoreFSufs.cc
new file mode 100644 (file)
index 0000000..ab74d6f
--- /dev/null
@@ -0,0 +1,44 @@
+
+
+/*
+ * $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");
+
diff --git a/src/fs/ufs/StoreFSufs.h b/src/fs/ufs/StoreFSufs.h
new file mode 100644 (file)
index 0000000..947fad1
--- /dev/null
@@ -0,0 +1,103 @@
+
+/*
+ * $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 */
index 813c7bd221b2ab4b12fb1bba160e378ba3724e07..fe0ff71aca393818dfe1f3ba049bdd5e01700082 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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
  *
@@ -56,51 +52,19 @@ STSETUP storeFsSetup_ufs;
  * 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;
@@ -109,17 +73,7 @@ UFSSwapDir::reconfigure(int index, char *path)
     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)
@@ -130,13 +84,29 @@ UFSSwapDir::reconfigure(int index, char *path)
                      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);
 }
 
 /*
@@ -145,37 +115,36 @@ UfsSwapDir::dump(StoreEntry & entry)const
  * 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;
 }
 
 /*
@@ -189,6 +158,7 @@ UFSSwapDir::init()
         "\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())
@@ -214,7 +184,7 @@ UFSSwapDir::newFileSystem()
     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()
 {
@@ -231,29 +201,6 @@ 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
 {
@@ -330,6 +277,8 @@ UFSSwapDir::statfs(StoreEntry & sentry) const
         storeAppendPrintf(&sentry, " READ-ONLY");
 
     storeAppendPrintf(&sentry, "\n");
+
+    IO->statfs(sentry);
 }
 
 void
@@ -569,13 +518,13 @@ UFSSwapDir::verifyCacheDirs()
 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
@@ -583,7 +532,7 @@ UFSSwapDir::createSwapSubDirs()
 
         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);
         }
@@ -664,7 +613,7 @@ UFSSwapDir::closeLog()
 
     swaplog_fd = -1;
 
-    NumberOfUFSDirs--;
+    --NumberOfUFSDirs;
 
     assert(NumberOfUFSDirs >= 0);
 
@@ -882,16 +831,16 @@ public:
 
 #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()
 {
@@ -1308,6 +1257,8 @@ UFSSwapDir::validFileno(sfileno filn, int flag) const
     return 1;
 }
 
+
+
 /*
  * UFSSwapDir::unlinkFile
  *
@@ -1318,9 +1269,18 @@ UFSSwapDir::validFileno(sfileno filn, int flag) const
 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);
 }
 
 /*
@@ -1362,6 +1322,7 @@ UFSSwapDir::dump(StoreEntry & entry) const
                       max_size >> 10,
                       l1,
                       l2);
+    dumpOptions(&entry);
 }
 
 char *
@@ -1384,3 +1345,15 @@ UFSSwapDir::fullPath(sfileno filn, char *fullpath) const
 
     return fullpath;
 }
+
+int
+UFSSwapDir::callback()
+{
+    return IO->callback();
+}
+
+void
+UFSSwapDir::sync()
+{
+    IO->sync();
+}
index 9923d22d1e1791919e0547b525fd249d2a302e9f..a875c1563b3b926393de453eb812f4902654ba77 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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
@@ -47,6 +47,13 @@ UfsIO::shedLoad()
     return false;
 }
 
+int
+UfsIO::load()
+{
+    /* Return 999 (99.9%) constant load */
+    return 999;
+}
+
 void
 UfsIO::deleteSelf() const
 {
@@ -56,7 +63,7 @@ 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
@@ -65,36 +72,33 @@ UfsIO::newFile (char const *path)
     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);
@@ -121,7 +125,7 @@ UFSFile::operator delete (void *address)
 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);
@@ -144,6 +148,7 @@ UFSFile::open (int flags, mode_t mode, IORequestor::Pointer callback)
     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);
     }
@@ -162,6 +167,7 @@ UFSFile::create (int flags, mode_t mode, IORequestor::Pointer callback)
 void UFSFile::doClose()
 {
     if (fd > -1) {
+        closed = true;
         file_close(fd);
         store_open_disk_fd--;
         fd = -1;
@@ -186,45 +192,87 @@ UFSFile::canRead() const
 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
@@ -286,7 +334,7 @@ UFSStoreState::write(char const *buf, size_t size, off_t offset, FREE * free_fun
 {
     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;
@@ -296,13 +344,11 @@ UFSStoreState::write(char const *buf, size_t size, off_t offset, FREE * free_fun
     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 =========================================================== */
@@ -329,11 +375,10 @@ UFSFile::readDone(int rvfd, const char *buf, int len, int errflag)
 }
 
 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)
@@ -347,13 +392,25 @@ ufsstate_t::readCompleted(const char *buf, int len, int errflag)
 
     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
@@ -381,47 +438,66 @@ UFSFile::writeDone(int rvfd, int errflag, size_t len)
 }
 
 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()
 {
@@ -545,7 +621,7 @@ StoreIOState::Pointer
 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()) {
@@ -582,7 +658,7 @@ StoreIOState::Pointer
 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);
@@ -625,3 +701,28 @@ UFSStrategy::create(SwapDir * SD, StoreEntry * e, STFNCB * file_callback,
 
     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;
index d2f09e7aec7e13d9c285078195a55fc92cadce35..c30ce25d036bd360289250a0781b6625b6ab16a9 100644 (file)
@@ -27,12 +27,14 @@ public:
     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();
@@ -40,53 +42,38 @@ private:
     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
index 028b9485fbd47d6174eb634ee8299047f1fb32ad..1144a29a79db8edd2529cf44b79d5555123b6617 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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/
@@ -148,7 +148,6 @@ extern int refresh_nocache_hack;    /* 0 */
 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 */
index b87552a1e931bd33a1dba340c150ad136fd5f1fb..a4f7793fd44a1ccf4c3f18f3a9945420eadc600a 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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
@@ -42,6 +42,7 @@
 #include "ACLASN.h"
 #include "ACL.h"
 #include "htcp.h"
+#include "StoreFileSystem.h"
 
 #if USE_WIN32_SERVICE
 
@@ -982,6 +983,9 @@ main(int argc, char **argv)
 
         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);
@@ -1485,7 +1489,7 @@ SquidShutdown(void *unused)
 #endif
 
     storeDirSync();            /* Flush log close */
-    storeFsDone();
+    StoreFileSystem::FreeAllFs();
 #if PURIFY || XMALLOC_TRACE
 
     configFreeMemory();
index 055a3b70de1e9d031c3271112c5015162f208552..5b596951a8df825caedee7366996832b72d1df16 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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/
@@ -69,6 +69,8 @@ SQUIDCEXTERN void allocate_new_swapdir(cacheSwap *);
 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 */
@@ -79,9 +81,6 @@ SQUIDCEXTERN void parse_wordlist(wordlist ** list);
 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 *);
 
 
@@ -733,9 +732,6 @@ SQUIDCEXTERN int memPoolsTotalAllocated(void);
 
 /* ----------------------------------------------------------------- */
 
-/* store_modules.c */
-SQUIDCEXTERN void storeFsSetup(void);
-
 /* repl_modules.c */
 SQUIDCEXTERN void storeReplSetup(void);
 
index f2e270eb4e511e9771f7fcef88870e463ef8c044..63f75390ef5bbe4e75a8384379b9bb33adcf7cfd 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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
@@ -1684,48 +1684,6 @@ void
 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]);
 }
 
 /*
index 0edb6d46f05381961b50d5a2dd118eeab7e180e4..cdb7257d25ddfa88a9922997739123dd7b669ceb 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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
@@ -362,7 +362,7 @@ storeDirStats(StoreEntry * sentry)
     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);
@@ -545,6 +545,9 @@ storeDirCallback(void)
             ++ndir;
 
             j += SD->callback();
+
+            if (j > 100)
+                fatal ("too much io\n");
         }
     } while (j > 0);
 
diff --git a/src/store_modules.sh b/src/store_modules.sh
deleted file mode 100644 (file)
index 0f8a781..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/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 "}"
index 489933621f792cc41385bfa3337f521fbde206a7..ed6ab210b8d177a17681a30504036669b8a682f6 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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/
@@ -2172,17 +2172,6 @@ struct _store_rebuild_data
     int zero_object_sz;
 };
 
-/*
- * This defines an fs type
- */
-
-struct _storefs_entry
-{
-    const char *typestr;
-    STFSSHUTDOWN *donefunc;
-    STFSNEW *newfunc;
-};
-
 /*
  * This defines an repl type
  */
index 4d38215c509118a77e9bfd930a47034d16703a69..422d91367ad710b9b7255e574014f06566b7aa46 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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/
@@ -251,8 +251,6 @@ class storeIOState;
 
 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;
@@ -332,9 +330,6 @@ typedef void HLPSONEQ(void *);
 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);
 
index 8b471cc6d4d1b5fe72c849b3cc076e7bbeb7e056..df450195100432eec6630fc0899df654a05a8de1 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $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/
  * ----------------------------------------------------------
@@ -52,16 +52,16 @@ public:
     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 *);
@@ -73,9 +73,10 @@ public:
     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;
@@ -99,6 +100,8 @@ public:
                                int clean);
     int validFileno(sfileno filn, int flag) const;
     int mapBitAllocate();
+    virtual SwapDirOption *getOptionTree() const;
+
     void *fsdata;
 
     bool validL2(int) const;
@@ -114,6 +117,7 @@ protected:
     int l2;
 
 private:
+    void parseSizeL1L2();
     static int NumberOfUFSDirs;
     static int * UFSDirToGlobalDirMapping;
     bool pathIsDirectory(const char *path)const;
@@ -152,6 +156,7 @@ public:
     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;}
 
@@ -159,6 +164,9 @@ public:
     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 */
@@ -182,6 +190,80 @@ public:
                                  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 */
@@ -190,10 +272,18 @@ class UFSStoreState : public storeIOState, public IORequestor
 {
 
 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;
@@ -204,6 +294,7 @@ public:
     void write(char const *buf, size_t size, off_t offset, FREE * free_func);
 
 protected:
+    virtual void doCallback (int errflag);
 
     class _queued_read
     {
@@ -236,6 +327,14 @@ protected:
         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 *);
@@ -243,6 +342,10 @@ protected:
     bool kickReadQueue();
     bool kickWriteQueue();
     char *read_buf;
+
+private:
+    CBDATA_CLASS(UFSStoreState);
+    void openDone();
 };
 
 class RebuildState : public RefCountable