The unified diff between revisions [6676c716..] and [816b792b..] is displayed below. It can also be downloaded as a raw diff.

#
#
# patch "src/enums.h"
#  from [d3225c7b17f9312bef8509d7dd1284df1f0fcf98]
#    to [955437e924a040325c5940579961596c655549ca]
#
# patch "src/fs/aufs/store_dir_aufs.c"
#  from [99f2f1eebf5dd0b8e29deb65369dcd0c44bb0cd6]
#    to [323cdf961a164cc4a8a1a4c304b20a5bc5d86bd4]
#
# patch "src/fs/coss/store_dir_coss.c"
#  from [19d4f9ab9f40836bd89d4b34d6a707fb07315f80]
#    to [76fa0c36aeb9fe9686300c9510eee08786bfdb95]
#
# patch "src/fs/diskd/store_dir_diskd.c"
#  from [b338483de8d86584e890188328fb92711677fc7f]
#    to [914cb5910c1c7948856f7c7ecf30cdb7f32a6b47]
#
# patch "src/fs/null/store_null.c"
#  from [fa5f237c80376f490212dc9b5431584958991925]
#    to [e0f5a054b8726ecf54ca634771f958004fa80433]
#
# patch "src/fs/ufs/store_dir_ufs.c"
#  from [4793d2c314a1b2a0085408592b65bb858ab30058]
#    to [dccf7803c07b1fc7e38e934e671a166bb2d8f560]
#
# patch "src/store_io.c"
#  from [b3189954bb7b33712f066ccf62783d2b0506f710]
#    to [95f7644af900412f7c758eb99b822ef82a559d46]
#
# patch "src/structs.h"
#  from [09fd7df0ee0cc66a8be6be822cf34b2203aac563]
#    to [2cc0257c851aa9f3899204538a4037888a0465cf]
#
# patch "src/typedefs.h"
#  from [0a1930b4adf4cddddda7f44324e88fb53311162f]
#    to [46547ecc7cfd53f7995b2043f00d273feaf2a0f5]
#
============================================================
--- src/enums.h	d3225c7b17f9312bef8509d7dd1284df1f0fcf98
+++ src/enums.h	955437e924a040325c5940579961596c655549ca
@@ -744,4 +744,10 @@ enum {

 #endif

+typedef enum {
+	ST_OP_NONE,
+	ST_OP_OPEN,
+	ST_OP_CREATE
+} store_op_t;
+
 #endif /* SQUID_ENUMS_H */
============================================================
--- src/fs/aufs/store_dir_aufs.c	99f2f1eebf5dd0b8e29deb65369dcd0c44bb0cd6
+++ src/fs/aufs/store_dir_aufs.c	323cdf961a164cc4a8a1a4c304b20a5bc5d86bd4
@@ -106,6 +106,7 @@ static STCHECKOBJ storeAufsDirCheckObj;
 static STDUMP storeAufsDirDump;
 static STMAINTAINFS storeAufsDirMaintain;
 static STCHECKOBJ storeAufsDirCheckObj;
+static STCHECKLOADAV storeAufsDirCheckLoadAv;
 static STREFOBJ storeAufsDirRefObj;
 static STUNREFOBJ storeAufsDirUnrefObj;
 static QS rev_int_sort;
@@ -1613,6 +1614,19 @@ storeAufsDirCheckObj(SwapDir * SD, const
     return loadav;
 }

+char
+storeAufsDirCheckLoadAv(SwapDir *SD, store_op_t op)
+{
+	int loadav, ql;
+
+	ql = aioQueueSize();
+	if (ql == 0) {
+		return 1;
+	}
+	loadav = ql * 1000 / MAGIC1;
+	return (loadav < 1000);
+}
+
 /*
  * storeAufsDirRefObj
  *
@@ -1896,6 +1910,7 @@ storeAufsDirParse(SwapDir * sd, int inde
     sd->statfs = storeAufsDirStats;
     sd->maintainfs = storeAufsDirMaintain;
     sd->checkobj = storeAufsDirCheckObj;
+    sd->checkload = storeAufsDirCheckLoadAv;
     sd->refobj = storeAufsDirRefObj;
     sd->unrefobj = storeAufsDirUnrefObj;
     sd->callback = aioCheckCallbacks;
============================================================
--- src/fs/coss/store_dir_coss.c	19d4f9ab9f40836bd89d4b34d6a707fb07315f80
+++ src/fs/coss/store_dir_coss.c	76fa0c36aeb9fe9686300c9510eee08786bfdb95
@@ -707,7 +707,15 @@ storeCossDirCheckObj(SwapDir * SD, const
     return loadav;
 }

+char
+storeCossDirCheckLoadAv(SwapDir *SD, store_op_t op)
+{
+    CossInfo *cs = (CossInfo *) SD->fsdata;

+    return (cs->aq.aq_numpending < MAX_ASYNCOP);
+}
+
+
 /*
  * storeCossDirCallback - do the IO completions
  */
@@ -780,6 +788,7 @@ storeCossDirParse(SwapDir * sd, int inde
     sd->statfs = storeCossDirStats;
     sd->maintainfs = NULL;
     sd->checkobj = storeCossDirCheckObj;
+    sd->checkload = storeCossDirCheckLoadAv;
     sd->refobj = NULL;		/* LRU is done in storeCossRead */
     sd->unrefobj = NULL;
     sd->callback = storeCossDirCallback;
============================================================
--- src/fs/diskd/store_dir_diskd.c	b338483de8d86584e890188328fb92711677fc7f
+++ src/fs/diskd/store_dir_diskd.c	914cb5910c1c7948856f7c7ecf30cdb7f32a6b47
@@ -110,6 +110,7 @@ static STCHECKOBJ storeDiskdDirCheckObj;
 static STDUMP storeDiskdDirDump;
 static STMAINTAINFS storeDiskdDirMaintain;
 static STCHECKOBJ storeDiskdDirCheckObj;
+static STCHECKLOADAV storeDiskdDirCheckLoadAv;
 static STREFOBJ storeDiskdDirRefObj;
 static STUNREFOBJ storeDiskdDirUnrefObj;
 static QS rev_int_sort;
@@ -1831,6 +1832,15 @@ storeDiskdDirCheckObj(SwapDir * SD, cons
     return diskdinfo->away * 1000 / diskdinfo->magic2;
 }

+char
+storeDiskdDirCheckLoadAv(SwapDir *SD, store_op_t op)
+{
+    diskdinfo_t *diskdinfo = SD->fsdata;
+    if (diskdinfo->away >= diskdinfo->magic1)
+        return 0;
+    return 1;
+}
+
 /*
  * storeDiskdDirRefObj
  *
@@ -2199,6 +2209,7 @@ storeDiskdDirParse(SwapDir * sd, int ind
     sd->statfs = storeDiskdDirStats;
     sd->maintainfs = storeDiskdDirMaintain;
     sd->checkobj = storeDiskdDirCheckObj;
+    sd->checkload = storeDiskdDirCheckLoadAv;
     sd->refobj = storeDiskdDirRefObj;
     sd->unrefobj = storeDiskdDirUnrefObj;
     sd->callback = storeDiskdDirCallback;
============================================================
--- src/fs/null/store_null.c	fa5f237c80376f490212dc9b5431584958991925
+++ src/fs/null/store_null.c	e0f5a054b8726ecf54ca634771f958004fa80433
@@ -93,6 +93,15 @@ storeNullDirCheckObj(SwapDir * SD, const
     return -1;
 }

+/*
+ * We should never, in theory, see an open/create, but just in case..
+ */
+static char
+storeNullDirCheckLoadAv(SwapDir *SD, store_op_t op)
+{
+    return 0;
+}
+
 static int
 storeNullDirWriteCleanStart(SwapDir * unused)
 {
@@ -113,6 +122,7 @@ storeNullDirParse(SwapDir * sd, int inde
     sd->statfs = storeNullDirStats;
     sd->init = storeNullDirInit;
     sd->checkobj = storeNullDirCheckObj;
+    sd->checkload = storeNullDirCheckLoadAv;
     sd->log.clean.start = storeNullDirWriteCleanStart;
     sd->log.clean.done = storeNullDirWriteCleanDone;
     parse_cachedir_options(sd, NULL, 0);
============================================================
--- src/fs/ufs/store_dir_ufs.c	4793d2c314a1b2a0085408592b65bb858ab30058
+++ src/fs/ufs/store_dir_ufs.c	dccf7803c07b1fc7e38e934e671a166bb2d8f560
@@ -104,6 +104,7 @@ static STCHECKOBJ storeUfsDirCheckObj;
 static STDUMP storeUfsDirDump;
 static STMAINTAINFS storeUfsDirMaintain;
 static STCHECKOBJ storeUfsDirCheckObj;
+static STCHECKLOADAV storeUfsDirCheckLoadAv;
 static STREFOBJ storeUfsDirRefObj;
 static STUNREFOBJ storeUfsDirUnrefObj;
 static QS rev_int_sort;
@@ -1621,6 +1622,19 @@ storeUfsDirCheckObj(SwapDir * SD, const
 }

 /*
+ * storeUfsDirCheckLoadAv
+ *
+ * Return 1 whether the store isn't too busy to service the current operation,
+ * 0 otherwise.
+ */
+char
+storeUfsDirCheckLoadAv(SwapDir *SD, store_op_t op)
+{
+	/* ufs will always be fine doing IO. */
+	return 1;
+}
+
+/*
  * storeUfsDirRefObj
  *
  * This routine is called whenever an object is referenced, so we can
@@ -1906,6 +1920,7 @@ storeUfsDirParse(SwapDir * sd, int index
     sd->statfs = storeUfsDirStats;
     sd->maintainfs = storeUfsDirMaintain;
     sd->checkobj = storeUfsDirCheckObj;
+    sd->checkload = storeUfsDirCheckLoadAv;
     sd->refobj = storeUfsDirRefObj;
     sd->unrefobj = storeUfsDirUnrefObj;
     sd->callback = NULL;
============================================================
--- src/store_io.c	b3189954bb7b33712f066ccf62783d2b0506f710
+++ src/store_io.c	95f7644af900412f7c758eb99b822ef82a559d46
@@ -7,6 +7,11 @@ static struct {
 	int create_fail;
 	int success;
     } create;
+    struct {
+        int calls;
+        int success;
+        int fail;
+    } open;
 } store_io_stats;

 OBJH storeIOStats;
@@ -61,8 +66,21 @@ storeOpen(StoreEntry * e, STFNCB * file_
 storeOpen(StoreEntry * e, STFNCB * file_callback, STIOCB * callback,
     void *callback_data)
 {
+    storeIOState *sio;
+
     SwapDir *SD = &Config.cacheSwap.swapDirs[e->swap_dirn];
-    return SD->obj.open(SD, e, file_callback, callback, callback_data);
+    store_io_stats.open.calls++;
+    if (SD->checkload(SD, ST_OP_OPEN) == 0) {
+        store_io_stats.open.fail++;
+        return NULL;
+    }
+    sio = SD->obj.open(SD, e, file_callback, callback, callback_data);
+    if (sio == NULL) {
+        store_io_stats.open.fail++;
+    } else {
+        store_io_stats.open.success++;
+    }
+    return sio;
 }

 void
@@ -114,4 +132,7 @@ storeIOStats(StoreEntry * sentry)
     storeAppendPrintf(sentry, "create.select_fail %d\n", store_io_stats.create.select_fail);
     storeAppendPrintf(sentry, "create.create_fail %d\n", store_io_stats.create.create_fail);
     storeAppendPrintf(sentry, "create.success %d\n", store_io_stats.create.success);
+    storeAppendPrintf(sentry, "open.calls %d\n", store_io_stats.open.calls);
+    storeAppendPrintf(sentry, "open.success %d\n", store_io_stats.open.success);
+    storeAppendPrintf(sentry, "open.fail %d\n", store_io_stats.open.fail);
 }
============================================================
--- src/structs.h	09fd7df0ee0cc66a8be6be822cf34b2203aac563
+++ src/structs.h	2cc0257c851aa9f3899204538a4037888a0465cf
@@ -1616,6 +1616,7 @@ struct _SwapDir {
     STSTATFS *statfs;		/* Dump fs statistics */
     STMAINTAINFS *maintainfs;	/* Replacement maintainence */
     STCHECKOBJ *checkobj;	/* Check if the fs will store an object */
+    STCHECKLOADAV *checkload;	/* Check if the fs is getting overloaded .. */
     /* These two are notifications */
     STREFOBJ *refobj;		/* Reference this object */
     STUNREFOBJ *unrefobj;	/* Unreference this object */
============================================================
--- src/typedefs.h	0a1930b4adf4cddddda7f44324e88fb53311162f
+++ src/typedefs.h	46547ecc7cfd53f7995b2043f00d273feaf2a0f5
@@ -288,6 +288,7 @@ typedef void STMAINTAINFS(SwapDir *);
 typedef int STDBLCHECK(SwapDir *, StoreEntry *);
 typedef void STSTATFS(SwapDir *, StoreEntry *);
 typedef void STMAINTAINFS(SwapDir *);
+typedef char STCHECKLOADAV(SwapDir *, store_op_t op);
 typedef int STCHECKOBJ(SwapDir *, const StoreEntry *);
 typedef void STREFOBJ(SwapDir *, StoreEntry *);
 typedef void STUNREFOBJ(SwapDir *, StoreEntry *);