Hello community, here is the log from the commit of package blktrace for openSUSE:Factory checked in at 2018-06-08 23:15:05 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/blktrace (Old) and /work/SRC/openSUSE:Factory/.blktrace.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "blktrace" Fri Jun 8 23:15:05 2018 rev:35 rq:614371 version:1.2.0+git.20180516 Changes: -------- --- /work/SRC/openSUSE:Factory/blktrace/blktrace.changes 2017-08-13 14:57:35.090306598 +0200 +++ /work/SRC/openSUSE:Factory/.blktrace.new/blktrace.changes 2018-06-08 23:15:09.756720392 +0200 @@ -1,0 +2,22 @@ +Tue Jun 05 17:58:47 UTC 2018 - opensuse-packag...@opensuse.org + +- Update to version 1.2.0+git.20180516: + * make btt scripts python3-ready + * btt: make device/devno use PATH_MAX to avoid overflow (bsc#1091942). + * blkparse: add documetation for 'R' requeue request + * blkparse: remove duplicated entry for flag M + +------------------------------------------------------------------- +Tue Mar 20 20:52:02 UTC 2018 - je...@suse.com + +- Update to version 1.2.0+git.20180124: + * blktrace: don't stop tracer if not setup trace successfully + * fix parallel build failures + * respect LDFLAGS when linking programs + * btt: Fix overlapping IO stats. + * btt/devs: silence warning on sprintf overflow + * jhash: fix annoying gcc fall through warnings + * Blktrace 1.2.0 + * blktrace: abort if device ioctl setup fails + +------------------------------------------------------------------- Old: ---- blktrace-1.1.0+git.20170126.tar.xz New: ---- blktrace-1.2.0+git.20180516.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ blktrace.spec ++++++ --- /var/tmp/diff_new_pack.u5a6bA/_old 2018-06-08 23:15:10.848680955 +0200 +++ /var/tmp/diff_new_pack.u5a6bA/_new 2018-06-08 23:15:10.864680378 +0200 @@ -1,7 +1,7 @@ # # spec file for package blktrace # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ %{!?_without_docs: %global with_docs 1} Name: blktrace -Version: 1.1.0+git.20170126 +Version: 1.2.0+git.20180516 Release: 0 Summary: Block IO tracer License: GPL-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.u5a6bA/_old 2018-06-08 23:15:10.960676910 +0200 +++ /var/tmp/diff_new_pack.u5a6bA/_new 2018-06-08 23:15:10.960676910 +0200 @@ -4,7 +4,7 @@ <param name="scm">git</param> <param name="changesgenerate">enable</param> <param name="filename">blktrace</param> - <param name="versionformat">1.1.0+git.%cd</param> + <param name="versionformat">1.2.0+git.%cd</param> </service> <service mode="disabled" name="recompress"> <param name="file">*.tar</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.u5a6bA/_old 2018-06-08 23:15:10.988675900 +0200 +++ /var/tmp/diff_new_pack.u5a6bA/_new 2018-06-08 23:15:10.988675900 +0200 @@ -1,4 +1,4 @@ <servicedata> <service name="tar_scm"> <param name="url">git://git.kernel.dk/blktrace.git</param> - <param name="changesrevision">8772bc4fb049bdd879de5952d6f291a34112fae0</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">70d5ca2d5f3d6b97c11c641b7e0c5836983219a0</param></service></servicedata> \ No newline at end of file ++++++ blktrace-1.1.0+git.20170126.tar.xz -> blktrace-1.2.0+git.20180516.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blktrace-1.1.0+git.20170126/Makefile new/blktrace-1.2.0+git.20180516/Makefile --- old/blktrace-1.1.0+git.20170126/Makefile 2017-01-26 18:06:05.000000000 +0100 +++ new/blktrace-1.2.0+git.20180516/Makefile 2018-05-16 21:09:58.000000000 +0200 @@ -4,41 +4,37 @@ PROGS = blkparse blktrace verify_blkparse blkrawverify blkiomon LIBS = -lpthread SCRIPTS = btrace +SUBDIRS = btreplay btt iowatcher -ALL = $(PROGS) $(SCRIPTS) btt/btt btreplay/btrecord btreplay/btreplay \ +ALL = $(PROGS) $(SCRIPTS) +INSTALL_ALL = $(ALL) btt/btt btreplay/btrecord btreplay/btreplay \ btt/bno_plot.py iowatcher/iowatcher -all: $(ALL) +all: $(ALL) $(SUBDIRS) -btt/btt: - $(MAKE) -C btt - -iowatcher/iowatcher: - $(MAKE) -C iowatcher - -btreplay/btrecord: - $(MAKE) -C btreplay - -btreplay/btreplay: - $(MAKE) -C btreplay +# We always descend into subdirs because they contain their own dependency +# information which we don't track in this top level Makefile. +$(SUBDIRS): + $(MAKE) -C $@ +.PHONY: $(SUBDIRS) %.o: %.c $(CC) -o $*.o -c $(ALL_CFLAGS) $< blkparse: blkparse.o blkparse_fmt.o rbtree.o act_mask.o - $(CC) $(ALL_CFLAGS) -o $@ $(filter %.o,$^) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(filter %.o,$^) blktrace: blktrace.o act_mask.o - $(CC) $(ALL_CFLAGS) -o $@ $(filter %.o,$^) $(LIBS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(filter %.o,$^) $(LIBS) verify_blkparse: verify_blkparse.o - $(CC) $(ALL_CFLAGS) -o $@ $(filter %.o,$^) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(filter %.o,$^) blkrawverify: blkrawverify.o - $(CC) $(ALL_CFLAGS) -o $@ $(filter %.o,$^) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(filter %.o,$^) blkiomon: blkiomon.o rbtree.o - $(CC) $(ALL_CFLAGS) -o $@ $(filter %.o,$^) $(LIBS) -lrt + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(filter %.o,$^) $(LIBS) -lrt $(PROGS): | depend @@ -85,7 +81,7 @@ $(INSTALL) -m 755 -d $(DESTDIR)$(bindir) $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1 $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man8 - $(INSTALL) -m 755 $(ALL) $(DESTDIR)$(bindir) + $(INSTALL) -m 755 $(INSTALL_ALL) $(DESTDIR)$(bindir) $(INSTALL) -m 644 doc/*.1 $(DESTDIR)$(mandir)/man1 $(INSTALL) -m 644 doc/*.8 $(DESTDIR)$(mandir)/man8 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blktrace-1.1.0+git.20170126/blkparse.c new/blktrace-1.2.0+git.20180516/blkparse.c --- old/blktrace-1.1.0+git.20170126/blkparse.c 2017-01-26 18:06:05.000000000 +0100 +++ new/blktrace-1.2.0+git.20180516/blkparse.c 2018-05-16 21:09:58.000000000 +0200 @@ -36,7 +36,7 @@ #include "rbtree.h" #include "jhash.h" -static char blkparse_version[] = "1.1.0"; +static char blkparse_version[] = "1.2.0"; struct skip_info { unsigned long start, end; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blktrace-1.1.0+git.20170126/blktrace.c new/blktrace-1.2.0+git.20180516/blktrace.c --- old/blktrace-1.1.0+git.20170126/blktrace.c 2017-01-26 18:06:05.000000000 +0100 +++ new/blktrace-1.2.0+git.20180516/blktrace.c 2018-05-16 21:09:58.000000000 +0200 @@ -112,6 +112,7 @@ struct cl_host *ch; u32 cl_id; time_t cl_connect_time; + int setup_done; /* ioctl BLKTRACESETUP done */ struct io_info *ios; }; @@ -1066,9 +1067,10 @@ } } -static void setup_buts(void) +static int setup_buts(void) { struct list_head *p; + int ret = 0; __list_for_each(p, &devpaths) { struct blk_user_trace_setup buts; @@ -1082,14 +1084,19 @@ if (ioctl(dpp->fd, BLKTRACESETUP, &buts) >= 0) { dpp->ncpus = max_cpus; dpp->buts_name = strdup(buts.name); + dpp->setup_done = 1; if (dpp->stats) free(dpp->stats); dpp->stats = calloc(dpp->ncpus, sizeof(*dpp->stats)); memset(dpp->stats, 0, dpp->ncpus * sizeof(*dpp->stats)); - } else + } else { fprintf(stderr, "BLKTRACESETUP(2) %s failed: %d/%s\n", dpp->path, errno, strerror(errno)); + ret++; + } } + + return ret; } static void start_buts(void) @@ -1280,7 +1287,8 @@ struct devpath *dpp = list_entry(p, struct devpath, head); list_del(&dpp->head); - __stop_trace(dpp->fd); + if (dpp->setup_done) + __stop_trace(dpp->fd); close(dpp->fd); if (dpp->heads) @@ -2676,7 +2684,8 @@ if (net_mode == Net_client) printf("blktrace: connecting to %s\n", hostname); - setup_buts(); + if (setup_buts()) + return 1; if (use_tracer_devpaths()) { if (setup_tracer_devpaths()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blktrace-1.1.0+git.20170126/btreplay/Makefile new/blktrace-1.2.0+git.20180516/btreplay/Makefile --- old/blktrace-1.1.0+git.20170126/btreplay/Makefile 2017-01-26 18:06:05.000000000 +0100 +++ new/blktrace-1.2.0+git.20180516/btreplay/Makefile 2018-05-16 21:09:58.000000000 +0200 @@ -32,10 +32,10 @@ $(CC) $(CFLAGS) -c -o $*.o $< btrecord: btrecord.o - $(CC) $(CFLAGS) -o $@ $(filter %.o,$^) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(filter %.o,$^) btreplay: btreplay.o - $(CC) $(CFLAGS) -o $@ $(filter %.o,$^) $(LIBS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(filter %.o,$^) $(LIBS) depend: @$(CC) -MM $(CFLAGS) *.c 1> .depend diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blktrace-1.1.0+git.20170126/btt/Makefile new/blktrace-1.2.0+git.20180516/btt/Makefile --- old/blktrace-1.1.0+git.20170126/btt/Makefile 2017-01-26 18:06:05.000000000 +0100 +++ new/blktrace-1.2.0+git.20180516/btt/Makefile 2018-05-16 21:09:58.000000000 +0200 @@ -38,7 +38,7 @@ $(CC) $(CFLAGS) -c -o $*.o $< btt: $(OBJS) - $(CC) $(CFLAGS) -o $@ $(filter %.o,$^) $(LIBS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(filter %.o,$^) $(LIBS) ifneq ($(wildcard .depend),) include .depend diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blktrace-1.1.0+git.20170126/btt/bno_plot.py new/blktrace-1.2.0+git.20180516/btt/bno_plot.py --- old/blktrace-1.1.0+git.20170126/btt/bno_plot.py 2017-01-26 18:06:05.000000000 +0100 +++ new/blktrace-1.2.0+git.20180516/btt/bno_plot.py 2018-05-16 21:09:58.000000000 +0200 @@ -38,6 +38,8 @@ To exit the plotter, enter 'quit' or ^D at the 'gnuplot> ' prompt. """ +from __future__ import absolute_import +from __future__ import print_function import getopt, glob, os, sys, tempfile verbose = 0 @@ -60,14 +62,14 @@ try: (opts, args) = getopt.getopt(in_args, s_opts, l_opts) - except getopt.error, msg: - print >>sys.stderr, msg - print >>sys.stderr, __doc__ + except getopt.error as msg: + print(msg, file=sys.stderr) + print(__doc__, file=sys.stderr) sys.exit(1) for (o, a) in opts: if o in ('-h', '--help'): - print __doc__ + print(__doc__) sys.exit(0) elif o in ('-v', '--verbose'): verbose += 1 @@ -84,10 +86,10 @@ (bnos, keys_below) = parse_args(sys.argv[1:]) if verbose: - print 'Using files:', - for bno in bnos: print bno, - if keys_below: print '\nKeys are to be placed below graph' - else: print '' + print('Using files:', end=' ') + for bno in bnos: print(bno, end=' ') + if keys_below: print('\nKeys are to be placed below graph') + else: print('') tmpdir = tempfile.mktemp() os.mkdir(tmpdir) @@ -99,7 +101,7 @@ fo = open(t, 'w') for line in open(f, 'r'): fld = line.split(None) - print >>fo, fld[0], fld[1], int(fld[2])-int(fld[1]) + print(fld[0], fld[1], int(fld[2])-int(fld[1]), file=fo) fo.close() t = t[t.rfind('/')+1:] @@ -107,16 +109,16 @@ else: plot_cmd = "%s,'%s'" % (plot_cmd, t) fo = open('%s/plot.cmds' % tmpdir, 'w') - print >>fo, cmds - if len(bnos) > 10 or keys_below: print >>fo, 'set key below' - print >>fo, plot_cmd + print(cmds, file=fo) + if len(bnos) > 10 or keys_below: print('set key below', file=fo) + print(plot_cmd, file=fo) fo.close() pid = os.fork() if pid == 0: cmd = 'gnuplot %s/plot.cmds -' % tmpdir - if verbose: print 'Executing %s' % cmd + if verbose: print('Executing %s' % cmd) os.chdir(tmpdir) os.system(cmd) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blktrace-1.1.0+git.20170126/btt/btt_plot.py new/blktrace-1.2.0+git.20180516/btt/btt_plot.py --- old/blktrace-1.1.0+git.20170126/btt/btt_plot.py 2017-01-26 18:06:05.000000000 +0100 +++ new/blktrace-1.2.0+git.20180516/btt/btt_plot.py 2018-05-16 21:09:58.000000000 +0200 @@ -55,6 +55,10 @@ but the -o (--output) and -T (--title) options will be ignored. """ +from __future__ import absolute_import +from __future__ import print_function +import six +from six.moves import range __author__ = 'Alan D. Brunelle <alan.brune...@hp.com>' #------------------------------------------------------------------------------ @@ -82,7 +86,7 @@ def fatal(msg): """Generate fatal error message and exit""" - print >>sys.stderr, 'FATAL: %s' % msg + print('FATAL: %s' % msg, file=sys.stderr) sys.exit(1) #------------------------------------------------------------------------------ @@ -163,7 +167,7 @@ if not os.path.exists(file): fatal('%s not found' % file) elif verbose: - print 'Processing %s' % file + print('Processing %s' % file) xs = [] ys = [] @@ -214,8 +218,8 @@ try: (opts, args) = getopt.getopt(args[1:], s_opts, l_opts) - except getopt.error, msg: - print >>sys.stderr, msg + except getopt.error as msg: + print(msg, file=sys.stderr) fatal(__doc__) for (o, a) in opts: @@ -293,15 +297,15 @@ def color(idx, style): """Returns a color/symbol type based upon the index passed.""" - colors = [ 'b', 'g', 'r', 'c', 'm', 'y', 'k' ] + colors = [ 'b', 'g', 'r', 'c', 'm', 'y', 'k' ] l_styles = [ '-', ':', '--', '-.' ] m_styles = [ 'o', '+', '.', ',', 's', 'v', 'x', '<', '>' ] color = colors[idx % len(colors)] if style == 'line': - style = l_styles[(idx / len(l_styles)) % len(l_styles)] + style = l_styles[int((idx / len(l_styles)) % len(l_styles))] elif style == 'marker': - style = m_styles[(idx / len(m_styles)) % len(m_styles)] + style = m_styles[int((idx / len(m_styles)) % len(m_styles))] return '%s%s' % (color, style) @@ -314,7 +318,7 @@ ofile = '%s.png' % type if verbose: - print 'Generating plot into %s' % ofile + print('Generating plot into %s' % ofile) fig = plt.figure(figsize=plot_size) ax = fig.add_subplot(111) @@ -329,7 +333,7 @@ legends = None keys = [] - for file in db.iterkeys(): + for file in six.iterkeys(db): if not file in ['min_x', 'max_x', 'min_y', 'max_y']: keys.append(file) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blktrace-1.1.0+git.20170126/btt/devmap.c new/blktrace-1.2.0+git.20180516/btt/devmap.c --- old/blktrace-1.1.0+git.20170126/btt/devmap.c 2017-01-26 18:06:05.000000000 +0100 +++ new/blktrace-1.2.0+git.20180516/btt/devmap.c 2018-05-16 21:09:58.000000000 +0200 @@ -23,7 +23,7 @@ struct devmap { struct list_head head; - char device[32], devno[32]; + char device[PATH_MAX], devno[PATH_MAX]; }; LIST_HEAD(all_devmaps); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blktrace-1.1.0+git.20170126/btt/devs.c new/blktrace-1.2.0+git.20180516/btt/devs.c --- old/blktrace-1.1.0+git.20170126/btt/devs.c 2017-01-26 18:06:05.000000000 +0100 +++ new/blktrace-1.2.0+git.20180516/btt/devs.c 2018-05-16 21:09:58.000000000 +0200 @@ -108,7 +108,7 @@ static inline FILE *open_pit(struct d_info *dip) { FILE *fp; - char str[256]; + char str[272]; sprintf(str, "%s_pit.dat", dip->dip_name); if ((fp = my_fopen(str, "w")) == NULL) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blktrace-1.1.0+git.20170126/btt/dip_rb.c new/blktrace-1.2.0+git.20180516/btt/dip_rb.c --- old/blktrace-1.1.0+git.20170126/btt/dip_rb.c 2017-01-26 18:06:05.000000000 +0100 +++ new/blktrace-1.2.0+git.20180516/btt/dip_rb.c 2018-05-16 21:09:58.000000000 +0200 @@ -57,7 +57,7 @@ __iop = rb_entry(n, struct io, rb_node); if (sec < BIT_START(__iop)) n = n->rb_left; - else if (sec >= BIT_END(__iop)) + else if (sec > BIT_START(__iop)) n = n->rb_right; else return __iop; @@ -82,7 +82,7 @@ } if (iop_s < this_s) rb_foreach(n->rb_left, iop, fnc, head); - if (this_e < iop_e) + if ((this_e < iop_e) || (this_s < iop_s)) rb_foreach(n->rb_right, iop, fnc, head); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blktrace-1.1.0+git.20170126/doc/blkparse.1 new/blktrace-1.2.0+git.20180516/doc/blkparse.1 --- old/blktrace-1.1.0+git.20170126/doc/blkparse.1 2017-01-26 18:06:05.000000000 +0100 +++ new/blktrace-1.2.0+git.20180516/doc/blkparse.1 2018-05-16 21:09:58.000000000 +0200 @@ -243,10 +243,6 @@ requests starts. .HP 4 -\fBM --front or back merge\fR -One of the above - -.HP 4 \fBM -- front or back merge\fR One of the above. @@ -289,6 +285,10 @@ For stacked devices, incoming i/o is remapped to device below it in the i/o stack. The remap action details what exactly is being remapped to what. +.HP 4 +\fBR -- requeue\fR +Put a request back on queue. + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blktrace-1.1.0+git.20170126/iowatcher/Makefile new/blktrace-1.2.0+git.20180516/iowatcher/Makefile --- old/blktrace-1.1.0+git.20170126/iowatcher/Makefile 2017-01-26 18:06:05.000000000 +0100 +++ new/blktrace-1.2.0+git.20180516/iowatcher/Makefile 2018-05-16 21:09:58.000000000 +0200 @@ -19,7 +19,7 @@ $(CC) -o $*.o -c $(ALL_CFLAGS) $< iowatcher: blkparse.o plot.o main.o tracers.o mpstat.o fio.o - $(CC) $(ALL_CFLAGS) -o $@ $(filter %.o,$^) -lm -lrt + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(filter %.o,$^) -lm -lrt depend: @$(CC) -MM $(ALL_CFLAGS) *.c 1> .depend diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/blktrace-1.1.0+git.20170126/jhash.h new/blktrace-1.2.0+git.20180516/jhash.h --- old/blktrace-1.1.0+git.20170126/jhash.h 2017-01-26 18:06:05.000000000 +0100 +++ new/blktrace-1.2.0+git.20180516/jhash.h 2018-05-16 21:09:58.000000000 +0200 @@ -73,22 +73,21 @@ k += 12; } - /* last block: affect all 32 bits of (c) */ - /* all the case statements fall through */ + /* Last block: affect all 32 bits of (c) */ switch (length) { - case 12: c += (u32)k[11]<<24; - case 11: c += (u32)k[10]<<16; - case 10: c += (u32)k[9]<<8; - case 9 : c += k[8]; - case 8 : b += (u32)k[7]<<24; - case 7 : b += (u32)k[6]<<16; - case 6 : b += (u32)k[5]<<8; - case 5 : b += k[4]; - case 4 : a += (u32)k[3]<<24; - case 3 : a += (u32)k[2]<<16; - case 2 : a += (u32)k[1]<<8; - case 1 : a += k[0]; - __jhash_final(a, b, c); + case 12: c += (u32)k[11]<<24; /* fall through */ + case 11: c += (u32)k[10]<<16; /* fall through */ + case 10: c += (u32)k[9]<<8; /* fall through */ + case 9: c += k[8]; /* fall through */ + case 8: b += (u32)k[7]<<24; /* fall through */ + case 7: b += (u32)k[6]<<16; /* fall through */ + case 6: b += (u32)k[5]<<8; /* fall through */ + case 5: b += k[4]; /* fall through */ + case 4: a += (u32)k[3]<<24; /* fall through */ + case 3: a += (u32)k[2]<<16; /* fall through */ + case 2: a += (u32)k[1]<<8; /* fall through */ + case 1: a += k[0]; + __jhash_final(a, b, c); case 0 : break; } @@ -117,10 +116,9 @@ } /* handle the last 3 u32's */ - /* all the case statements fall through */ switch (length) { - case 3: c += k[2]; - case 2: b += k[1]; + case 3: c += k[2]; /* fall through */ + case 2: b += k[1]; /* fall through */ case 1: a += k[0]; __jhash_final(a, b, c); case 0: /* case 0: nothing left to add */