Rolf Fokkens 8189001
diff -ruN bcache-tools-1.0.8/69-bcache.rules bcache-tools-1.0.8.2/69-bcache.rules
Rolf Fokkens 8189001
--- bcache-tools-1.0.8/69-bcache.rules	2014-12-04 23:51:24.000000000 +0100
Rolf Fokkens 8189001
+++ bcache-tools-1.0.8.2/69-bcache.rules	2015-02-07 22:32:35.000000000 +0100
Rolf Fokkens 8189001
@@ -22,11 +22,14 @@
Rolf Fokkens 8189001
 RUN+="bcache-register $tempnode"
Rolf Fokkens 8189001
 LABEL="bcache_backing_end"
Rolf Fokkens 8189001
 
Rolf Fokkens 8189001
-# Cached devices: symlink
Rolf Fokkens 8189001
-DRIVER=="bcache", ENV{CACHED_UUID}=="?*", \
Rolf Fokkens 8189001
-        SYMLINK+="bcache/by-uuid/$env{CACHED_UUID}"
Rolf Fokkens 8189001
-DRIVER=="bcache", ENV{CACHED_LABEL}=="?*", \
Rolf Fokkens 8189001
-        SYMLINK+="bcache/by-label/$env{CACHED_LABEL}"
Rolf Fokkens 8189001
+# Handling of cached devices
Rolf Fokkens 8189001
+DRIVER!="bcache", GOTO="bcache_end"
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+# Apply kernel cmdline parameters
Rolf Fokkens 8189001
+RUN+="bcache-params $kernel"
Rolf Fokkens 8189001
+# Symlink
Rolf Fokkens 8189001
+ENV{CACHED_UUID}=="?*", SYMLINK+="bcache/by-uuid/$env{CACHED_UUID}"
Rolf Fokkens 8189001
+ENV{CACHED_LABEL}=="?*", SYMLINK+="bcache/by-label/$env{CACHED_LABEL}"
Rolf Fokkens 8189001
 
Rolf Fokkens 8189001
 LABEL="bcache_end"
Rolf Fokkens 8189001
 
Rolf Fokkens 8189001
diff -ruN bcache-tools-1.0.8/bcache-params.c bcache-tools-1.0.8.2/bcache-params.c
Rolf Fokkens 8189001
--- bcache-tools-1.0.8/bcache-params.c	1970-01-01 01:00:00.000000000 +0100
Rolf Fokkens 8189001
+++ bcache-tools-1.0.8.2/bcache-params.c	2015-02-07 22:32:35.000000000 +0100
Rolf Fokkens 8189001
@@ -0,0 +1,196 @@
Rolf Fokkens 8189001
+/*
Rolf Fokkens 8189001
+ * Author: Rolf Fokkens <rolf@rolffokkens.nl>
Rolf Fokkens 8189001
+ *
Rolf Fokkens 8189001
+ * GPLv2
Rolf Fokkens 8189001
+ *
Rolf Fokkens 8189001
+ * For experimenting (or production) it may be useful to set bcache
Rolf Fokkens 8189001
+ * parameters in an early stage during boot, for example to tune the
Rolf Fokkens 8189001
+ * boot performance when the root fs is on a bcache device. The best
Rolf Fokkens 8189001
+ * moment is right before the root fs is actually mounted, which means
Rolf Fokkens 8189001
+ * it may need to be done in the initramfs.
Rolf Fokkens 8189001
+ *
Rolf Fokkens 8189001
+ * The bcache kernel driver does not support passing kernel cmdline
Rolf Fokkens 8189001
+ * arguments to it. This udev helper can be excuted from udev rules to
Rolf Fokkens 8189001
+ * take care of cmdline arguments by changing bcache parameters using
Rolf Fokkens 8189001
+ * the /sys interface right after a bcache device is brought up. This
Rolf Fokkens 8189001
+ * works both in the initramfs and later.
Rolf Fokkens 8189001
+ *
Rolf Fokkens 8189001
+ * It recognizes cmdline arguments like these:
Rolf Fokkens 8189001
+ *   bcache=sco:0,crdthr:0,cache/congested_write_threshold_us:0
Rolf Fokkens 8189001
+ * This means:
Rolf Fokkens 8189001
+ * - for any bcache device set the following parameters:
Rolf Fokkens 8189001
+ * - sequential_cutoff (sco) is set to 0
Rolf Fokkens 8189001
+ * - cache/congested_read_threshold_us (crdthr) is set to 0
Rolf Fokkens 8189001
+ * - cache/congested_write_threshold_us (cwrthr) is set to 0
Rolf Fokkens 8189001
+ * Both short aliases (for user convenience) and full parameters can be used,
Rolf Fokkens 8189001
+ * they are defined in the parm_map below.
Rolf Fokkens 8189001
+ *
Rolf Fokkens 8189001
+ * Other parameters are not accepted, because they're not useful or 
Rolf Fokkens 8189001
+ * potentially harmful (e.g. changing the label, stopping bcache devices)
Rolf Fokkens 8189001
+ *
Rolf Fokkens 8189001
+ * Parsing of each kernel cmdline argument is done in a simple way:
Rolf Fokkens 8189001
+ * - does the argument start with "bcache="? If not: next argument.
Rolf Fokkens 8189001
+ * - for the rest of the argument, identify "subarguments":
Rolf Fokkens 8189001
+ *   - is what follows of the form <stringP>:<stringV>? If not: next argument
Rolf Fokkens 8189001
+ *   - is <stringP> a know parameter name? If not: next subargument
Rolf Fokkens 8189001
+ *   - process the subargument
Rolf Fokkens 8189001
+ *   - next subargument
Rolf Fokkens 8189001
+ */
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+#include <ctype.h>
Rolf Fokkens 8189001
+#include <stdio.h>
Rolf Fokkens 8189001
+#include <unistd.h>
Rolf Fokkens 8189001
+#include <fcntl.h>
Rolf Fokkens 8189001
+#include <stdlib.h>
Rolf Fokkens 8189001
+#include <string.h>
Rolf Fokkens 8189001
+#include <error.h>
Rolf Fokkens 8189001
+#include <errno.h>
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+#ifndef TESTING
Rolf Fokkens 8189001
+#   define CMDLINE "/proc/cmdline"
Rolf Fokkens 8189001
+#   define SYSPFX "/sys/block"
Rolf Fokkens 8189001
+#else
Rolf Fokkens 8189001
+#   define CMDLINE "/tmp/cmdline"   
Rolf Fokkens 8189001
+#   define SYSPFX "/tmp"            
Rolf Fokkens 8189001
+#endif
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+struct parm_map {
Rolf Fokkens 8189001
+    char *id;
Rolf Fokkens 8189001
+    char *full;
Rolf Fokkens 8189001
+};
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+/*
Rolf Fokkens 8189001
+ * The list of kernel cmdline patameters that can be processed by 
Rolf Fokkens 8189001
+ * bcache-patams.
Rolf Fokkens 8189001
+ */
Rolf Fokkens 8189001
+struct parm_map parm_map[] = {
Rolf Fokkens 8189001
+    { "crdthr",                       "cache/congested_read_threshold_us"  }
Rolf Fokkens 8189001
+,   { "cwrthr",                       "cache/congested_write_threshold_us" }
Rolf Fokkens 8189001
+,   { "rdahed",                       "readahead"                          }
Rolf Fokkens 8189001
+,   { "sctoff",                       "sequential_cutoff"                  }
Rolf Fokkens 8189001
+,   { "wrbdly",                       "writeback_delay"                    }
Rolf Fokkens 8189001
+,   { "wrbpct",                       "writeback_percent"                  }
Rolf Fokkens 8189001
+,   { "wrbupd",                       "writeback_rate_update_seconds"      }
Rolf Fokkens 8189001
+,   { NULL                          , NULL                                 }
Rolf Fokkens 8189001
+};
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+/*
Rolf Fokkens 8189001
+ * Read characters from fp (/proc/cmdline) into buf until maxlen characters are
Rolf Fokkens 8189001
+ * read or until a character is read that is in the list of terminators.
Rolf Fokkens 8189001
+ *
Rolf Fokkens 8189001
+ * lookaheadp points to the current lookahead symbol, and is returned as such to
Rolf Fokkens 8189001
+ * the caller.
Rolf Fokkens 8189001
+ *
Rolf Fokkens 8189001
+ * When a characters is read that is a terminator charachter, the lookehead is moved
Rolf Fokkens 8189001
+ * one character ahead and the encountered terminator is returned.
Rolf Fokkens 8189001
+ *
Rolf Fokkens 8189001
+ * If for another reason reading characters stops, 0 is returned.
Rolf Fokkens 8189001
+ */
Rolf Fokkens 8189001
+int read_until (int *lookaheadp, FILE *fp, char *buf, int maxlen, char *terminators)
Rolf Fokkens 8189001
+{
Rolf Fokkens 8189001
+    char *cp = buf, *ep = buf + maxlen;
Rolf Fokkens 8189001
+    int lookahead = *lookaheadp;
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+    while (   cp < ep
Rolf Fokkens 8189001
+           && lookahead != EOF
Rolf Fokkens 8189001
+           && isprint (lookahead)
Rolf Fokkens 8189001
+           && !strchr (terminators, lookahead)) {
Rolf Fokkens 8189001
+        *cp++ = lookahead;
Rolf Fokkens 8189001
+        lookahead = fgetc (fp);
Rolf Fokkens 8189001
+    }
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+    *lookaheadp = lookahead;
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+    *cp = '\0';
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+    if (strchr (terminators, lookahead)) {
Rolf Fokkens 8189001
+        *lookaheadp = fgetc (fp);
Rolf Fokkens 8189001
+        return lookahead;
Rolf Fokkens 8189001
+    }
Rolf Fokkens 8189001
+    return 0;
Rolf Fokkens 8189001
+}
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+int main(int argc, char *argv[])
Rolf Fokkens 8189001
+{
Rolf Fokkens 8189001
+    char buf[256];
Rolf Fokkens 8189001
+    int  la, bufsz = sizeof (buf);
Rolf Fokkens 8189001
+    FILE *fp;
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+    if (argc != 2) {
Rolf Fokkens 8189001
+        fprintf (stderr, "bcache-params takes exactly one argument\n");
Rolf Fokkens 8189001
+        return 1;
Rolf Fokkens 8189001
+    }
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+    fp = fopen (CMDLINE, "r");
Rolf Fokkens 8189001
+    if (fp == NULL) {
Rolf Fokkens 8189001
+        perror ("Error opening /proc/cmdline");
Rolf Fokkens 8189001
+        return 1;
Rolf Fokkens 8189001
+    }
Rolf Fokkens 8189001
+    /* la is our lookahead character */
Rolf Fokkens 8189001
+    la = fgetc (fp);
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+    while (la != EOF) {
Rolf Fokkens 8189001
+        /* skip any spaces */
Rolf Fokkens 8189001
+        while (la == ' ') {
Rolf Fokkens 8189001
+            la = fgetc (fp);
Rolf Fokkens 8189001
+        }
Rolf Fokkens 8189001
+        /* stop ehen end of the line */
Rolf Fokkens 8189001
+        if (la == EOF) break;
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+        /* process until '=' */
Rolf Fokkens 8189001
+        if (read_until (&la, fp, buf, bufsz, " =") != '=') goto nextarg;
Rolf Fokkens 8189001
+        /* did we get a "bcache=" prefix? */
Rolf Fokkens 8189001
+        if (strcmp (buf, "bcache") != 0) goto nextarg;
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+        /* process subarguments */
Rolf Fokkens 8189001
+        for (;;) {
Rolf Fokkens 8189001
+            struct parm_map *pmp;
Rolf Fokkens 8189001
+            char sysfile[256];
Rolf Fokkens 8189001
+            int term, fd;
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+            /* all subargs start with "<string>:" */
Rolf Fokkens 8189001
+            if (read_until (&la, fp, buf, bufsz, " :") != ':') goto nextarg;
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+            /* now identify <string> */
Rolf Fokkens 8189001
+            for (pmp = parm_map; pmp->id != NULL; pmp++) {
Rolf Fokkens 8189001
+                if (strcmp (buf, pmp->id)   == 0) break;
Rolf Fokkens 8189001
+                if (strcmp (buf, pmp->full) == 0) break;
Rolf Fokkens 8189001
+            }
Rolf Fokkens 8189001
+            /* no match for <string>? next subargument */
Rolf Fokkens 8189001
+            if (pmp->id == NULL) {
Rolf Fokkens 8189001
+                error (0, 0, "Unknown bcache parameter %s", buf);
Rolf Fokkens 8189001
+            } else {
Rolf Fokkens 8189001
+                /* Now we know what /sys file to write to */
Rolf Fokkens 8189001
+                sprintf (sysfile, "%s/%s/bcache/%s", SYSPFX, argv[1], pmp->full);
Rolf Fokkens 8189001
+             }
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+            /* What follows is the data to be written */
Rolf Fokkens 8189001
+            term = read_until (&la, fp, buf, bufsz, " ,");
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+            if (pmp->id == NULL) goto nextsubarg;
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
+            /* no data identified? next subargument */
Rolf Fokkens 8189001
+            if (buf[0] == '\0') {
Rolf Fokkens 8189001
+                error (0, 0, "Missing data for parameter %s(%s)", pmp->full, pmp->id);
Rolf Fokkens 8189001
+                goto nextsubarg;
Rolf Fokkens 8189001
+            }
Rolf Fokkens 8189001
+            /* we're ready to actually write the data */
Rolf Fokkens 8189001
+            fd = open (sysfile, O_WRONLY);
Rolf Fokkens 8189001
+            if (fd < 0) {
Rolf Fokkens 8189001
+                error (0, errno, "Error opening %s", sysfile);
Rolf Fokkens 8189001
+                goto nextsubarg;
Rolf Fokkens 8189001
+            }
Rolf Fokkens 8189001
+            if (dprintf (fd, "%s\n", buf) < 0) {
Rolf Fokkens 8189001
+                error (0, errno, "Error writing %s to %s", buf, sysfile);
Rolf Fokkens 8189001
+            }
Rolf Fokkens 8189001
+            close (fd);
Rolf Fokkens 8189001
+            /* From here there's the hope for another subargument */
Rolf Fokkens 8189001
+        nextsubarg:
Rolf Fokkens 8189001
+            if (term != ',') break;
Rolf Fokkens 8189001
+        }
Rolf Fokkens 8189001
+    nextarg:
Rolf Fokkens 8189001
+        while (la != EOF && la != ' ') la = fgetc (fp);
Rolf Fokkens 8189001
+    }
Rolf Fokkens 8189001
+    return 0;
Rolf Fokkens 8189001
+}
Rolf Fokkens 8189001
+
Rolf Fokkens 8189001
diff -ruN bcache-tools-1.0.8/dracut/module-setup.sh bcache-tools-1.0.8.2/dracut/module-setup.sh
Rolf Fokkens 8189001
--- bcache-tools-1.0.8/dracut/module-setup.sh	2014-12-04 23:51:24.000000000 +0100
Rolf Fokkens 8189001
+++ bcache-tools-1.0.8.2/dracut/module-setup.sh	2015-02-07 22:32:35.000000000 +0100
Rolf Fokkens 8189001
@@ -29,6 +29,9 @@
Rolf Fokkens 8189001
 }
Rolf Fokkens 8189001
 
Rolf Fokkens 8189001
 install() {
Rolf Fokkens 8189001
-    inst_multiple ${udevdir}/probe-bcache ${udevdir}/bcache-register
Rolf Fokkens 8189001
+    inst_multiple \
Rolf Fokkens 8189001
+        ${udevdir}/probe-bcache \
Rolf Fokkens 8189001
+        ${udevdir}/bcache-register \
Rolf Fokkens 8189001
+        ${udevdir}/bcache-params
Rolf Fokkens 8189001
     inst_rules 69-bcache.rules
Rolf Fokkens 8189001
 }
Rolf Fokkens 8189001
diff -ruN bcache-tools-1.0.8/.gitignore bcache-tools-1.0.8.2/.gitignore
Rolf Fokkens 8189001
--- bcache-tools-1.0.8/.gitignore	2014-12-04 23:51:24.000000000 +0100
Rolf Fokkens 8189001
+++ bcache-tools-1.0.8.2/.gitignore	2015-02-07 22:32:35.000000000 +0100
Rolf Fokkens 8189001
@@ -1,6 +1,7 @@
Rolf Fokkens 8189001
 /bcache-super-show
Rolf Fokkens 8189001
 /bcache-test
Rolf Fokkens 8189001
 /bcache-register
Rolf Fokkens 8189001
+/bcache-params
Rolf Fokkens 8189001
 /make-bcache
Rolf Fokkens 8189001
 /probe-bcache
Rolf Fokkens 8189001
 .*
Rolf Fokkens 8189001
diff -ruN bcache-tools-1.0.8/Makefile bcache-tools-1.0.8.2/Makefile
Rolf Fokkens 8189001
--- bcache-tools-1.0.8/Makefile	2014-12-04 23:51:24.000000000 +0100
Rolf Fokkens 8189001
+++ bcache-tools-1.0.8.2/Makefile	2015-02-07 22:32:35.000000000 +0100
Rolf Fokkens 8189001
@@ -5,11 +5,11 @@
Rolf Fokkens 8189001
 INSTALL=install
Rolf Fokkens 8189001
 CFLAGS+=-O2 -Wall -g
Rolf Fokkens 8189001
 
Rolf Fokkens 8189001
-all: make-bcache probe-bcache bcache-super-show bcache-register
Rolf Fokkens 8189001
+all: make-bcache probe-bcache bcache-super-show bcache-register bcache-params
Rolf Fokkens 8189001
 
Rolf Fokkens 8189001
-install: make-bcache probe-bcache bcache-super-show
Rolf Fokkens 8189001
+install: make-bcache probe-bcache bcache-super-show bcache-register bcache-params
Rolf Fokkens 8189001
 	$(INSTALL) -m0755 make-bcache bcache-super-show	$(DESTDIR)${PREFIX}/sbin/
Rolf Fokkens 8189001
-	$(INSTALL) -m0755 probe-bcache bcache-register		$(DESTDIR)$(UDEVLIBDIR)/
Rolf Fokkens 8189001
+	$(INSTALL) -m0755 probe-bcache bcache-register bcache-params	$(DESTDIR)$(UDEVLIBDIR)/
Rolf Fokkens 8189001
 	$(INSTALL) -m0644 69-bcache.rules	$(DESTDIR)$(UDEVLIBDIR)/rules.d/
Rolf Fokkens 8189001
 	$(INSTALL) -m0644 -- *.8 $(DESTDIR)${PREFIX}/share/man/man8/
Rolf Fokkens 8189001
 	$(INSTALL) -D -m0755 initramfs/hook	$(DESTDIR)/usr/share/initramfs-tools/hooks/bcache
Rolf Fokkens 8189001
@@ -30,3 +30,4 @@
Rolf Fokkens 8189001
 bcache-super-show: CFLAGS += -std=gnu99
Rolf Fokkens 8189001
 bcache-super-show: bcache.o
Rolf Fokkens 8189001
 bcache-register: bcache-register.o
Rolf Fokkens 8189001
+bcache-params: bcache-params.o