On the silliness of close() giving EDQUOT

Jonathan I. Kamens jik at athena.mit.edu
Fri Oct 19 15:59:13 AEST 1990


  Dan, I think this is one of those issues where we are arguing because you
are convinced that the way you think Unix should be is the One True Way and
that everyone who thinks differently from you is wrong.  Or, at least, that's
the tone you project in your postings on this topic (you projected exactly the
same tone when we discussed syslog).

In article <24048:Oct1822:23:2090 at kramden.acf.nyu.edu>, brnstnd at kramden.acf.nyu.edu (Dan Bernstein) writes:
|> In article <1990Oct18.200939.17427 at athena.mit.edu> jik at athena.mit.edu (Jonathan I. Kamens) writes:
|> > In article <19547:Oct1818:25:2690 at kramden.acf.nyu.edu>, brnstnd at kramden.acf.nyu.edu (Dan Bernstein) writes:
|>     [ NFS should deal with quotas correctly ]

  Here's the first example of what I mean.  You summarize what you posted as
"NFS should deal with quotas correctly."  Dan, if we all agreed that the way
you want NFS to deal with quotas is the "correct" way, then we wouldn't be
arguing.  But no, everyone who disagrees with you must be wrong, since you
know the One True Way that Unix should work, so you have the right to call
your ideas "correct" and everyone else's "wrong".

|> That's a truism. Yes, any system call might return -1/EINTR. Yes,
|> close() should return -1/EBADF if the descriptor isn't open. These two
|> errors are documented and reasonable for close() to return, and it's
|> reasonable to expect the programmer to deal with them.

  Actually, my close(2) says nothing about EINTR.  Does that mean my program
doesn't have to be prepared to deal with an interrupted close()?  No, it means
that the man page should be updated.  Which is what I said about close(2) and
EDQUOT in my last posting.  Point for me, I think.

|> No other close() errors make sense.

  It is your *opinion* that no other close() errors make sense.  There are a
whole lot of people, including the designers of NFS and the designers of AFS,
who may not agree with you.

  Actually, I take that back.  I have heard that the designers of AFS are
working on a fix for a later release which will report cause quota problems to
be reported to users in a more timely manner, although I don't know what
mechanism they are using to do so.

  However, that doesn't change my main point, which is that I do not think it
is reasonable to place a restriction on all future filesystems developed for
Unix that they all must detect quota problems immediately.  You may be able to
foresee what kinds of filesystems we'll be developing in ten or fifteen years
(when, of course, Unix will have taken over the world :-), but I don't think I
can, and I think it's completely reasonable to expect that there will probably
be filesystem developers who will want to be able to defer quota errors until
close(), and it may even be a justifiable thing to do on the filesystems they
are developing.

  The only justification you have given for your claim that no other close()
errors "make sense" is that you don't think filesystems should work that way. 
I'm afraid that's just not good enough.

  And your comment, "No other close() errors make sense," is yet another
example of your One True Way attitude.  Lighten up.

|> You say that close() should be able to return -1/EDQUOT. That's hogwash.
|> EDQUOT can and should be detected immediately upon the write() that
|> triggers it. There's no reason that the system call for saying ``Okay,
|> forget about this descriptor, I'm done with it'' should produce an errno
|> saying ``But wait! I neglected to mention this to you when you actually
|> wrote the data, but you're out of space! Don't you dare forget about
|> this descriptor when you're out of space! Hold the presses!''

  You are still back in the days when all the world was UFS.  Close() doesn't
mean what you say above anymore (actually, it's possible to argue that it
never did).  What it means is, "I'm done with this file descriptor, so please
do any finishing touches that you need to on it and then close it up, and let
me know if you have any problems with that."

  Your argument above boils down to, "Close() didn't used to be able to return
EDQUOT, so it shouldn't be able to do so now."  Sorry, but that just doesn't
cut it.  Try again.

|> Perhaps you don't yet see how silly that is. Has it occurred to you that
|> the application may have erased the data that it wrote to disk? Are you
|> going to insist that every write() be backed up by temporary buffers
|> that accumulate a copy of all data written until the program dies? Well?

  First of all, the problem isn't as large as you are trying to make it out to
be, because most of the programs I've worked/used don't even deal well with a
write() failing because of a quota problem; they just say, "Oops, I can't
write, I'm going to give up completely," and forget about whatever they were
doing; they make hardly any effort to preserve data.  Therefore, an error on
close() wouldn't be any worse than an error on write() for most programs.

  For the few programs that are planning on doing serious error recovery if
they can't write to the disk and that are planning on trying to preserve all
data even if a disk write fails, then yes, I expect them to do some sort of
buffering.  If you want a robust program, then you put more work into it.

|> I fail to see your logic. Can I substitute any two system calls there?
|> ``Just as it is reasonable for unlink() to return an error when the file
|> doesn't exist, it is reasonable for setuid() to do so, and the man page
|> should be updated to reflect that.''
|> 
|> Now what is your argument?

  Although not everyone may agree that the behavior we are discussing is
reasonable for remote filesystems, I think even the most thick-headed reader
of this group can recognize that is more reasonable for a system call that
operates on the filesystem to encounter quota-related errors than it is for a
system call that changes your UID in the kernel to encounter quota-related
errors.  Your introduction of fallacious reductio ad absurdum arguments into
the discussion just makes it harder to discuss the subject matter with you
intelligently.

  My comparison of write() to close() was reasonable because both deal with
writing files.  Your comparison of unlink() to setuid() is ludicrous.

  And your comment, "Now what is your argument?" is another One True Way
comment.  Once again, lighten up.

|> No. I am saying that there is no excuse for a filesystem to let a
|> program write() more than the user's quota without giving an error.

  This is your opinion, and you are entitled to it.  You are also entitled to
write code that does not check close() for EDQUOT, in which case your code
will lose data when writing to remote filesystems and your customers will
complain to you, and you can tell them that you can't fix it because close()
*shouldn't* return EDQUOT.

  When you've written a filesystem as successful as NFS, which works as well
as AFS, which doesn't have the close() problem we're discussing, I'll gladly
use it, and I'll gladly try to get other people to use it, and I'll think you
a thousand times.  But until then, I'll stick with the people who *have* done
it.  And I'll admit that i may not be able to see forever into the future and
tell that we will never ever be able to justify a filesystem that doesn't
detect quota problems on write().

|> ``But then it has to send a request immediately over the network and
|> wait to find out how much space is left!'' you say. Not so. Does TCP
|> force each side to stay synchronized on every packet? Of course not. The
|> file server can just pass out ``allocations'' of disk space. Things only
|> slow down when you're very close to the hard limit.

  Please explain what you're proposing here -- I don't quite get it.

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik at Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710



More information about the Comp.unix.internals mailing list