Skip to content
  • Linus Torvalds's avatar
    vfs: mark pipes and sockets as stream-like file descriptors · d8e464ec
    Linus Torvalds authored
    In commit 3975b097
    
     ("convert stream-like files -> stream_open, even
    if they use noop_llseek") Kirill used a coccinelle script to change
    "nonseekable_open()" to "stream_open()", which changed the trivial cases
    of stream-like file descriptors to the new model with FMODE_STREAM.
    
    However, the two big cases - sockets and pipes - don't actually have
    that trivial pattern at all, and were thus never converted to
    FMODE_STREAM even though it makes lots of sense to do so.
    
    That's particularly true when looking forward to the next change:
    getting rid of FMODE_ATOMIC_POS entirely, and just using FMODE_STREAM to
    decide whether f_pos updates are needed or not.  And if they are, we'll
    always do them atomically.
    
    This came up because KCSAN (correctly) noted that the non-locked f_pos
    updates are data races: they are clearly benign for the case where we
    don't care, but it would be good to just not have that issue exist at
    all.
    
    Note that the reason we used FMODE_ATOMIC_POS originally is that only
    doing it for the minimal required case is "safer" in that it's possible
    that the f_pos locking can cause unnecessary serialization across the
    whole write() call.  And in the worst case, that kind of serialization
    can cause deadlock issues: think writers that need readers to empty the
    state using the same file descriptor.
    
    [ Note that the locking is per-file descriptor - because it protects
      "f_pos", which is obviously per-file descriptor - so it only affects
      cases where you literally use the same file descriptor to both read
      and write.
    
      So a regular pipe that has separate reading and writing file
      descriptors doesn't really have this situation even though it's the
      obvious case of "reader empties what a bit writer concurrently fills"
    
      But we want to make pipes as being stream-line anyway, because we
      don't want the unnecessary overhead of locking, and because a named
      pipe can be (ab-)used by reading and writing to the same file
      descriptor. ]
    
    There are likely a lot of other cases that might want FMODE_STREAM, and
    looking for ".llseek = no_llseek" users and other cases that don't have
    an lseek file operation at all and making them use "stream_open()" might
    be a good idea.  But pipes and sockets are likely to be the two main
    cases.
    
    Cc: Kirill Smelkov <kirr@nexedi.com>
    Cc: Eic Dumazet <edumazet@google.com>
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Cc: Alan Stern <stern@rowland.harvard.edu>
    Cc: Marco Elver <elver@google.com>
    Cc: Andrea Parri <parri.andrea@gmail.com>
    Cc: Paul McKenney <paulmck@kernel.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    d8e464ec