On 8/19/19 3:53 PM, Denis V. Lunev wrote: >>>> Or even better, fix the call site of fallocate() to skip attempting an >>>> unaligned fallocate(), and just directly return ENOTSUP, rather than >>>> trying to diagnose EINVAL after the fact. >>>> >>> No way. Single ENOTSUP will turn off fallocate() support on caller side >>> while >>> aligned (99.99% of calls) works normally. >> I didn't mean skip fallocate() unconditionally, only when unaligned: >> >> if (request not aligned enough) >> return -ENOTSUP; >> fallocate() ... >> >> so that the 99.99% requests that ARE aligned get to use fallocate() >> normally. >> > static int handle_aiocb_write_zeroes(void *opaque) > { > ... > #ifdef CONFIG_FALLOCATE_ZERO_RANGE > if (s->has_write_zeroes) { > int ret = do_fallocate(s->fd, FALLOC_FL_ZERO_RANGE, > aiocb->aio_offset, aiocb->aio_nbytes); > if (ret == 0 || ret != -ENOTSUP) { > return ret; > } > s->has_write_zeroes = false; > } > #endif > > thus, right now, single ENOTSUP disables fallocate > functionality completely setting s->has_write_zeroes > to false and that is pretty much correct. > > ENOTSUP is "static" error code which returns persistent > ENOTSUP under any consequences.
Not always true. And the block layer doesn't expect it to be true. It is perfectly fine for one invocation to return ENOTSUP ('I can't handle this request, so fall back to pwrite for me) and the next to just work ('this one was aligned, so I handled it just fine). It just means that you have to be more careful with the logic: never set s->has_write_zeroes=false if you skipped the fallocate, or if the fallocate failed due to EINVAL rather than ENOTSUP (but still report ENOTSUP to the block layer, to document that you want the EINVAL for unaligned request to be turned into a fallback to pwrite). -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
signature.asc
Description: OpenPGP digital signature