(Illustration by Gaich Muramatsu)
On Thu, Feb 15, 2001 at 04:01:06PM -0700, K. Leif D. Van Horn wrote: > > It seems that the kernel drops the return value of release()/close(). > Is there any possibility of coda implementing a flush() method for > the file_operations struct? > > Thanks, > -Leif I'm looking at it. Hmm, annoying. We need to only pass the last close, which is a sideeffect of the fput() dropping the count to zero and the file structure being released. Flush is called before that point and there is no protective lock. If we make the close upcall from flush when f.i. the refcount is one there is a possibility for the following race, thread 1: close(fd) -> coda_flush() -> refcount == 1 -> CODA_CLOSE upcall thread 2: fd2 = dup(fd) -> refcount goes to 2. thread 1: error = result of flush thread 1: fput() -> refcount falls back to one thread n: close(fd2) -> coda_flush() -> refcount == 1 -> CODA_CLOSE upcall thread n: fput() -> refcount falls to zero -> coda_release() So we would see 2 close upcalls for the same file. We _need_ to make the upcall to get the correct error return code, but userspace wouldn't like the double CLOSE at all. With the current kernel code, there is no problem because we won't make the upcall until the file is released and dup will not be possible. However, the kernel doesn't expect errors being passed back from fput. * The only way I can see of fixing this correctly is to redefine the * kernel to userspace protocol to separate FILE_FLUSH from FILE_RELEASE. * Most kernel implementations should call both FLUSH and RELEASE upcalls * from their coda_close. Flush has the semantic of forcing a write to * the server/logging the operation, while release informs userspace that * the filehandle is really gone now and no more flushes are expected. Which is ofcourse a big pain, breaking compatibility for both kernel modules and userspace applications. And consider that most applications don't even bother to check the return value of close(2). JanReceived on 2001-02-15 18:34:29