• Al Viro's avatar
    struct fd: representation change · 88a2f646
    Al Viro authored
    	We want the compiler to see that fdput() on empty instance
    is a no-op.  The emptiness check is that file reference is NULL,
    while fdput() is "fput() if FDPUT_FPUT is present in flags".
    The reason why fdput() on empty instance is a no-op is something
    compiler can't see - it's that we never generate instances with
    NULL file reference combined with non-zero flags.
    
    	It's not that hard to deal with - the real primitives behind
    fdget() et.al. are returning an unsigned long value, unpacked by (inlined)
    __to_fd() into the current struct file * + int.  The lower bits are
    used to store flags, while the rest encodes the pointer.  Linus suggested
    that keeping this unsigned long around with the extractions done by inlined
    accessors should generate a sane code and that turns out to be the case.
    Namely, turning struct fd into a struct-wrapped unsinged long, with
            fd_empty(f) => unlikely(f.word == 0)
    	fd_file(f) => (struct file *)(f.word & ~3)
    	fdput(f) => if (f.word & 1) fput(fd_file(f))
    ends up with compiler doing the right thing.  The cost is the patch
    footprint, of course - we need to switch f.file to fd_file(f) all over
    the tree, and it's not doable with simple search and replace; there are
    false positives, etc.
    
    	Note that the sole member of that structure is an opaque
    unsigned long - all accesses should be done via wrappers and I don't
    want to use a name that would invite manual casts to file pointers,
    etc.  The value of that member is equal either to (unsigned long)p | flags,
    p being an address of some struct file instance, or to 0 for an empty fd.
    
    	For now the new predicate (fd_empty(f)) has no users; all the
    existing checks have form (!fd_file(f)).  We will convert to fd_empty()
    use later; here we only define it (and tell the compiler that it's
    unlikely to return true).
    
    	This commit only deals with representation change; there will
    be followups.
    Reviewed-by: default avatarChristian Brauner <brauner@kernel.org>
    Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    88a2f646
file.c 13.7 KB