aglew%fang@xenurus.gould.com (Andy Glew) (04/15/88)
>Just a side note. As I understand it, checking the return value of >write() does not really tell you what you want to know, due to the >fact that write's happen asynchronously. All the return value can >tell you is whether the data was successfully copied into the >kernel's buffer. Then when the disk is not busy and kernel gets >around to it, the actual write happens, by which time your process is >off doing other things, or perhaps has already exited. > > Mark of the Valley of Roses > ...!{harvard,ima}!bbn!aoa!mbr True - BSD write()s are delayed, to be sure that what you have written out was written out do an fsync() and check it's error return. I would also go so far as checking the error returned by close(). Just had an NFS-related bug in this respect. NFS writes were being delayed in the client's buffer cache, and then in the server's. The filesystem being written to was full, but the write()s were returning no errors, although the close() was. Seems NFS writes are even more delayed than BSD's: under BSD you are at least certain that there was disk space for your file when write() returns. An fsync fixed the problem, but there is a lot of broken code out there, so making the server writes non-delayed is an option. Take this to a more abstract level: in a system with multiple levels of caching, what should an fsync()-like call look like. Currently, fsync() should flush all the levels of cache - client/server/server's disk processor... But, in a situation where you are trying to do software coherency control, there's no reason to go all the way down. Eg. if two processors run on different clients but share a server, then they may need to flush their client's cache, but there is no need to flush the server's. Alternatively, two server's share a dual ported disk - you need to flush the server's buffer cache, but not the disk controllers. And then, there are the people who need to flush the controller cache, to be as sure as possible that their info was recorded for posterity. n = number_of_caching_levels(fd); synchronize_caches(n-2); /* fsync = synchronize_caches(number_of_caching_levels(fd)) */ This is not entirely pleasing. It might be nice to know the nature of a particular level of cache, and/or what the first level of cache one process shares with another is. Andy "Krazy" Glew. Gould CSD-Urbana. 1101 E. University, Urbana, IL 61801 aglew@gould.com - preferred, if you have MX records aglew@xenurus.gould.com - if you don't ...!ihnp4!uiucuxc!ccvaxa!aglew - paths may still be the only way My opinions are my own, and are not the opinions of my employer, or any other organisation. I indicate my company only so that the reader may account for any possible bias I may have towards our products.