• Al Viro's avatar
    lookup_open(): don't bother with fallbacks to lookup+create · 99a4a90c
    Al Viro authored
    We fall back to lookup+create (instead of atomic_open) in several cases:
    	1) we don't have write access to filesystem and O_TRUNC is
    present in the flags.  It's not something we want ->atomic_open() to
    see - it just might go ahead and truncate the file.  However, we can
    pass it the flags sans O_TRUNC - eventually do_open() will call
    handle_truncate() anyway.
    	2) we have O_CREAT | O_EXCL and we can't write to parent.
    That's going to be an error, of course, but we want to know _which_
    error should that be - might be EEXIST (if file exists), might be
    EACCES or EROFS.  Simply stripping O_CREAT (and checking if we see
    ENOENT) would suffice, if not for O_EXCL.  However, we used to have
    ->atomic_open() fully responsible for rejecting O_CREAT | O_EXCL
    on existing file and just stripping O_CREAT would've disarmed
    those checks.  With nothing downstream to catch the problem -
    FMODE_OPENED used to be "don't bother with EEXIST checks,
    ->atomic_open() has done those".  Now EEXIST checks downstream
    are skipped only if FMODE_CREATED is set - FMODE_OPENED alone
    is not enough.  That has eliminated the need to fall back onto
    lookup+create path in this case.
    	3) O_WRONLY or O_RDWR when we have no write access to
    filesystem, with nothing else objectionable.  Fallback is
    (and had always been) pointless.
    
    IOW, we don't really need that fallback; all we need in such
    cases is to trim O_TRUNC and O_CREAT properly.
    Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    99a4a90c
namei.c 120 KB