Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Anyone interested in implementing O_NOCLOBBER ?



    Date:        Thu, 16 Apr 2020 15:48:00 +0200
    From:        Joerg Sonnenberger <joerg%bec.de@localhost>
    Message-ID:  <20200416134800.GC21016%bec.de@localhost>

  | It strikes me as a lot of complexity for a limited use case.

That argument (almost identically, but with more verbosity) was made
back when the discussions on this were held (before my time watching
what was happening there).

I believe the complexity is almost 0 - the updates to the man page
would probably take more lines than the code.

Whether the use case is as limited as it seems was the subject of
some dispute - with some believing that if available, it would be
used, perhaps replacing many if not all uses of O_EXCL.

I'm not advocating this one way or the other (if I were, I'd just
implement it) but O_EXCL is referenced exactly 5 times in sys/kern/*.c

Two of those are for semaphores and message queues, and are irrelevant.

One is to stop following (if the final component) a symbolic link
when O_EXCL is set (O_NOCLOBBER specifically would not do that), which
is one of the problems with using O_EXCL for noclobber mode in sh - in any
case, no change is needed there.

The remaining two handle the cases where the path name does not, and
does, exist.   The does not case:

                        if (fmode & O_EXCL)
                                 va.va_vaflags |= VA_EXCLUSIVE;
                        error = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp,
                                           &ndp->ni_cnd, &va);

would I think become

                        if (fmode & (O_EXCL|O_NOCLOBER))
                                 va.va_vaflags |= VA_EXCLUSIVE;
                        error = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp,
                                           &ndp->ni_cnd, &va);

Where more of a change is needed is in the does exist case, which
is currently ...

                        if (fmode & O_EXCL) {
                                error = EEXIST;
                                goto bad;
                        }

which would need a new block added something like

			if ((mode & O_NOCLOBBER) && vp->v_type == VREG) {
                                error = EEXIST;
                                goto bad;
                        }

(the two blocks could be combined with a more complex test, but I prefer
to allow the compiler to make that optimisation).

I believe that's almost all there is to it.   Complex it isn't.

Elsewhere in the kernel, there's obviously the definition of O_EXCL
(and O_NOCLOBBER would need to be added) there's some device driver
use of O_EXCL (DRM and maybe more) none of which is relevant to O_NOCLOBBER,
as none of those is making regular files, there's some mention in procfs
which might need some investigation (I wooudn't have expected to be able
to create files there at all, but maybe some can be - whether files in
procfs count as regular files for this purpose I'm not sure), and related
references in union mounts and unionfs (where in both cases I'd expect
O_EXCL and O_NOCLOBBER to be treated the same for whatever special handling
they need).  There's also some linux compat mode fiddling (relevant only
if linux adds O_NOCLOBBER and we need to emulate it)  and in coda and NFS
which need looking at (the big issue is what one does when the client
supports O_NOCLOBBER and the server doesn't).   Finally O_EXCL is used
as an arg when external attributes are created - that clearly doesn't
need any mods.

O_NOCLOBBER is really just intended to be O_EXCL with the two minor
variations - it only applies to regular files, and follows the symlink
if the path named is an existing symlink.


  | PS: I would find something like O_NOATIME to be much more useful, when
  | talking about special purpose flags with non-trivial impact.

I would also find that useful, even O_NOMTIME sometimes, and if someone
would like to implement either of those (which would, I suspect, take some
real work, unlike the above) there would certainly be no objection here.

kre

ps: If you looked at the POSIX bug report, you'll see there are two
options - one of them will appear in the next edition.   Option 2 is
the one discussed here, where O_NOCLOBBER is required (which won't happen
unless there is at least one implementation - perhaps more than one would
be needed).   The other option (Option 1) is to recommend implementing
O_NOCLOBBER with a view to requiring it in the next version of the standard.
That is, they would add in the future directions section:

    A future version of this standard may add an O_NOCLOBBER flag, specified
    as follows, for use by shells when the noclobber option is set (see
    [xref to XRAT C.2.7.2]):

    O_NOCLOBBER

        If O_CREAT and O_NOCLOBBER are set, open() shall fail if the file 
        exists and is either a regular file or a symbolic link that resolves to
        [....]

(the rest of it is the same text I posted last time).   That is, that text
is going to appear in the standard, either as a future direction for the
next standard, or a requirement of the coming one.

That one of those two options be included has already been approved.




Home | Main Index | Thread Index | Old Index