Path: csiph.com!x330-a1.tempe.blueboxinc.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!news.glorb.com!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Rainer Weikusat Newsgroups: comp.os.linux.development.apps Subject: Re: mkdir() and thread safety() Date: Thu, 31 Mar 2011 11:14:25 +0100 Lines: 46 Message-ID: <87tyejtx4u.fsf@sapphire.mobileactivedefense.com> References: <9d56213c-a054-428e-866c-559da29fbbc3@o21g2000prh.googlegroups.com> <2d58ece6-bb9c-42e0-a990-fc13b92723ec@a21g2000prj.googlegroups.com> <87oc4vtn8o.fsf@sapphire.mobileactivedefense.com> Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-Trace: individual.net EPleEIwsI3x3GTmhfiG7DAkfWI+SCbLJFY3NhNJA00E0VVo0c= Cancel-Lock: sha1:ydWvCShISDvb6Yb2NrQIIHFbz4k= sha1:ZbPmq7YLYhuGPqtyTDCOBX9TDTE= User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.2 (gnu/linux) Xref: x330-a1.tempe.blueboxinc.net comp.os.linux.development.apps:58 David Schwartz writes: > On Mar 28, 5:59 am, Rainer Weikusat wrote: >> Also, the UNIX(*) standard demands that mkdir is supposed to fail with >> EEXIST when the named file already existed. This is not possible when >> mkdir is not an atomic operation. > > Yes, it is. The algorithm I specified will always fail if the named > file already existed before the operation started. The operation starts when the 'backend' (whatever that happens to be) starts to process the mkdir request, not at some arbitrarily distant random time in the past. It is not possible to fail with EEXIST when a file already existed before a mkdir request was processed unless no such file can be created between the time the test for existence is made and the directory creation request is actually processed. Your 'algorithm' is in no way different from one where the OS creates a database of all files during bootup and uses that to determine if some file exists until the next boot in this respect: Some check is made. Then, and unspecified amount of time passses. Then, an operation is carried out, based on the presumption that the result of this check is still valid. Put into pseudocode in a slightly different context: rc = stat("/tmp/toastbrot", &st); if (rc == -1 && errno == ENOENT) { rc = open("/tmp/toastbrot", O_CREAT | O_RDWR, 0666); if (rc != -1) { write(rc, "will we kill /etc/shadow", sizeof("will we kill /etc/shadow")); close(rc); } } and the answer to this question is: The guy who wrote this cannot imagine that it would be possible. But it is. > There is no requirement for atomicity. You can't just make up requirements because > they seem reasonable to you. And there is also no requirement that the implementation doesn't use the 'file database created during booting' in the way I outlined above EXCEPT that this would also be a broken implementation because of the TOCTOU-race. Coming to think of it, it should also be okay to let mkdir fail randomly with EEXIST since the result is again identical: mkdir will or won't fail for some reason which has no specific relation to the state of the filesystem at the time the request was executed whatsoever.