File.v: add fgrow and fshrink
File.v: add fgrow and fshrink

Interesting issue comes up: when we are growing the file, we first
allocate a block, and if that succeeds, we try to write out the new
inode containing the new block address.  But this write might fail
(because the log is full), and now we can't free the block either
(because that also requires writing via the log).

One answer seems to be leave the transaction in some unspecified
active state on error, thereby effectively requiring the caller
to abort, which is what the current theorem/spec says.

Another option is to reason more precisely about available log
space.  This doesn't seem super appealing, but I suspect this is
what Adam might tell us.

mit-pdos/fscq-impl,mit-pdos/fscq-impl,mit-pdos/fscq-impl,mit-pdos/fscq-impl,mit-pdos/fscq-impl