Passes FUA and flush requests unchanged. A convenient way to turn the
filter into a no-op without rewriting the whole nbdkit command line.
---
filters/fua/nbdkit-fua-filter.pod | 5 +++++
filters/fua/fua.c | 12 +++++++++++-
tests/test-fua.sh | 21 ++++++++++++++++++---
3 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/filters/fua/nbdkit-fua-filter.pod b/filters/fua/nbdkit-fua-filter.pod
index 6e8f87e2..3d20b56a 100644
--- a/filters/fua/nbdkit-fua-filter.pod
+++ b/filters/fua/nbdkit-fua-filter.pod
@@ -48,6 +48,11 @@ client did not request it. In turn client flush requests become
no-ops. It refuses to load if the plugin's C<.can_fua> callback
returns C<NBDKIT_FUA_NONE>.
+=item B<fuamode=pass>
+
+Pass through FUA and flush requests unchanged. Turns the filter into
+a no-op.
+
=back
=head1 EXAMPLES
diff --git a/filters/fua/fua.c b/filters/fua/fua.c
index cee05eed..6bc62a02 100644
--- a/filters/fua/fua.c
+++ b/filters/fua/fua.c
@@ -46,6 +46,7 @@ static enum FuaMode {
EMULATE,
NATIVE,
FORCE,
+ PASS,
} fuamode;
static int
@@ -61,6 +62,8 @@ fua_config (nbdkit_next_config *next, void *nxdata,
fuamode = NATIVE;
else if (strcmp (value, "force") == 0)
fuamode = FORCE;
+ else if (strcmp (value, "pass") == 0)
+ fuamode = PASS;
else {
nbdkit_error ("unknown fuamode '%s'", value);
return -1;
@@ -71,7 +74,8 @@ fua_config (nbdkit_next_config *next, void *nxdata,
}
#define fua_config_help \
- "fuamode=<MODE> One of 'none' (default), 'emulate',
'native', 'force'.\n" \
+ "fuamode=<MODE> One of 'none' (default), 'emulate',
'native',\n" \
+ " 'force', 'pass'."
/* Check that desired mode is supported by plugin. */
static int
@@ -86,6 +90,7 @@ fua_prepare (struct nbdkit_next_ops *next_ops, void *nxdata, void
*handle,
switch (fuamode) {
case NONE:
+ case PASS:
break;
case EMULATE:
r = next_ops->can_flush (nxdata);
@@ -132,6 +137,8 @@ fua_can_fua (struct nbdkit_next_ops *next_ops, void *nxdata, void
*handle)
case NATIVE:
case FORCE:
return NBDKIT_FUA_NATIVE;
+ case PASS:
+ return next_ops->can_fua (nxdata);
}
abort ();
}
@@ -155,6 +162,7 @@ fua_pwrite (struct nbdkit_next_ops *next_ops, void *nxdata,
}
break;
case NATIVE:
+ case PASS:
break;
case FORCE:
flags |= NBDKIT_FLAG_FUA;
@@ -194,6 +202,7 @@ fua_trim (struct nbdkit_next_ops *next_ops, void *nxdata,
}
break;
case NATIVE:
+ case PASS:
break;
case FORCE:
flags |= NBDKIT_FLAG_FUA;
@@ -224,6 +233,7 @@ fua_zero (struct nbdkit_next_ops *next_ops, void *nxdata,
}
break;
case NATIVE:
+ case PASS:
break;
case FORCE:
flags |= NBDKIT_FLAG_FUA;
diff --git a/tests/test-fua.sh b/tests/test-fua.sh
index 1c869e96..5fb5e929 100755
--- a/tests/test-fua.sh
+++ b/tests/test-fua.sh
@@ -39,7 +39,8 @@ files="fua.img
fua1.log fua1.pid
fua2.log fua2.pid
fua3.log fua3.pid
- fua4.log fua4.pid"
+ fua4.log fua4.pid
+ fua5.log fua5.pid"
rm -f $files
# Prep images, and check that qemu-io understands the actions we plan on
@@ -63,16 +64,19 @@ cleanup ()
cat fua3.log || :
echo "Log 4 file contents:"
cat fua4.log || :
+ echo "Log 5 file contents:"
+ cat fua5.log || :
rm -f $files
rm -rf $sockdir
}
cleanup_fn cleanup
-# Run four parallel nbdkit; to compare the logs and see what changes.
+# Run parallel nbdkit; to compare the logs and see what changes.
# 1: fuamode=none (default): client should send flush instead
# 2: fuamode=emulate: log shows that blocksize optimizes fua to flush
# 3: fuamode=native: log shows that blocksize preserves fua
# 4: fuamode=force: log shows that fua is always enabled
+# 5: fuamode=pass: fua flag and flush unchanged
start_nbdkit -P fua1.pid -U $sockdir/fua1.sock \
--filter=log --filter=fua \
file logfile=fua1.log fua.img
@@ -85,10 +89,13 @@ start_nbdkit -P fua3.pid -U $sockdir/fua3.sock \
start_nbdkit -P fua4.pid -U $sockdir/fua4.sock \
--filter=fua --filter=log \
file logfile=fua4.log fua.img fuamode=force
+start_nbdkit -P fua5.pid -U $sockdir/fua5.sock \
+ --filter=fua --filter=log \
+ file logfile=fua5.log fua.img fuamode=pass
# Perform a flush, write, and zero, first without then with FUA
for f in '' -f; do
- for i in {1..4}; do
+ for i in {1..5}; do
qemu-io -f raw -t none -c flush -c "w $f 0 64k" -c "w -z $f 64k 64k"
\
"nbd+unix://?socket=$sockdir/fua$i.sock"
done
@@ -124,3 +131,11 @@ if grep 'Flush' fua4.log; then
echo "filter should have elided flush"
exit 1
fi
+
+# Test 5: Flush should be passed through.
+# There should also be one set of fua=0 and a second set of fua=1.
+grep 'Flush' fua5.log
+grep 'connection=1 Write.*fua=0' fua5.log
+grep 'connection=2 Write.*fua=1' fua5.log
+grep 'connection=1 Zero.*fua=0' fua5.log
+grep 'connection=2 Zero.*fua=1' fua5.log
--
2.25.0