On Sun, 26 Mar 2000, Jamie Lokier wrote:

> > That being the case, I'd rather that O_NONE just went away.  I
> > am unconvinced of its worth anyway.
>
> Apparently it's used by fdformat and a few other small utils.

Presumably this is so that the floppy driver can check that nobody
expects to read or write the disk while a format is in progress?
If so, I accept the need for O_NONE.

> Well, nearly all the uses for O_DEFEROPEN seem to be the same as the
> uses of O_NONE.  Being able to do safe fstat()s without opening the
> device, that sort of thing.
>
> The only difference is the current ioctl behaviour for O_NONE, and the
> fact that you can actually open an O_DEFEROPEN fd later.

But those features of O_DEFEROPEN are the only useful ones.  Other
than posssibly in the future being able to say "give me a no-priv
fd to this object if I can read _or_ write it" I think that O_NONE
is useless for race-avoidance purposes.

Basically, I want it for things like tar.  Currently, for files GNU
tar does:

lstat("./defines.h", {st_mode=S_IFREG|0664, st_size=318, ...}) = 0
open("./defines.h", O_RDONLY|O_LARGEFILE) = 6
read(6, "#define UTIL_LINUX_VERSION \"2.10"..., 318) = 318
fstat(6, {st_mode=S_IFREG|0664, st_size=318, ...}) = 0
close(6)                                = 0

which is fairly easily raceable if you make your directories big
enough.  Make a link at the right time, and tar may well have
backed up /etc/shadow but thought that it was a file that you
owned.

This:

open(path, O_RDONLY|O_DEFEROPEN)        = 6
fstat(6, ...)                           = 0
fcntl(6, F_REALLYOPEN)                  = 0
read(6, ..., N)                         = M
close(6)                                = 0

is safe (though we do need O_SYMLINK to complete the picture).

Does anyone know if/how *BSD deal with this?  I can't find anything
but GNU tar under their cvsweb services.

> But your deferred open could be made properly generic: Define F_REOPEN
> to mean reopen this fd's object with new flags.  It needn't be
> specific to O_DEFEROPEN, and probably has a few uses.  (Like just
> being able to dup a file without sharing the file pointer and locks).

I'd rather that was an _fdopen(fd, opts) than an fcntl.  But it does
look useful.

> For the fstat() and fs-specific ioctl() type of thing, the current
> ioctl behaviour for O_NONE isn't really right.  For for fdformat it is
> right.

Yep.

> Your O_DEFEROPEN actually seems like the right thing in many cases,
> like when you want to open a device file prior to fstat(), and you
> don't really want to open the device.

Yep.  I just don't understand your desire to combine the two.

> Neither the current O_NONE nor O_DEFEROPEN implement another useful
> case: provide an fd you can use fs-flag-setting ioctls on.  E.g.
> that's why you can't do chattr +i /dev/*.

I think that this is a separate issue.  Last time it was discussed,
the consensus seemed to be that dealing with flags via ioctl() is
horrible and should probably stop.

I think Linus wanted:

int fflags(int fd, flagset * set, flagset * get);

plus something like O_SYMLINK to allow flags on symlinks too.  I
assume that it's waiting on some other VFS work.

> It would be nice to provide all the useful facilities in the simplest
> possible way.  I think making O_NONE not open underlying devices but
> to permit fs ioctls which could in principle be filename based anyway,
> and F_REOPEN, gets very close to that.  fdformat is solved by simply
> providing an alternate device to open -- it works for not rewinding
> tapes so there is a precedent.

I disagree.  Some filesystems (network filesystems especially) will
need to have their own open routine called before flags are available.

My intent with O_DEFEROPEN was to permit a race-proof way to do what
could otherwise be done with pathnames.  The other facilities that
you suggest seem useful but still essentially separate.

Matthew.

Reply via email to