Building on top of D25090, here is an attempt to teach UFS to recognise O_DSYNC.
However... there is something I don't understand. I used my test program at https://github.com/macdice/some-io-tests/blob/master/sync.c to exercise the various syncing methods. Starting with an empty file "rm -f test_file && touch test_file", and then observing the I/O behaviour with "dtrace -n 'io:::start { @[stack()] = count(); }'" I found that neither "sync --fdatasync --append test_file" nor "sync --o-dsync --append test_file" ever reaches I/O via the ffs_update() path, but "sync --fsync --append test_file" and "sync --o-sync --append test_file" do. That is what I expected when using the "--overwrite" mode (no need for inode update), but not when using the "--append" mode of the test. Will keep looking...