1. 28 10月, 2011 1 次提交
    • A
      vfs: do (nearly) lockless generic_file_llseek · ef3d0fd2
      Andi Kleen 提交于
      The i_mutex lock use of generic _file_llseek hurts.  Independent processes
      accessing the same file synchronize over a single lock, even though
      they have no need for synchronization at all.
      
      Under high utilization this can cause llseek to scale very poorly on larger
      systems.
      
      This patch does some rethinking of the llseek locking model:
      
      First the 64bit f_pos is not necessarily atomic without locks
      on 32bit systems. This can already cause races with read() today.
      This was discussed on linux-kernel in the past and deemed acceptable.
      The patch does not change that.
      
      Let's look at the different seek variants:
      
      SEEK_SET: Doesn't really need any locking.
      If there's a race one writer wins, the other loses.
      
      For 32bit the non atomic update races against read()
      stay the same. Without a lock they can also happen
      against write() now.  The read() race was deemed
      acceptable in past discussions, and I think if it's
      ok for read it's ok for write too.
      
      => Don't need a lock.
      
      SEEK_END: This behaves like SEEK_SET plus it reads
      the maximum size too. Reading the maximum size would have the
      32bit atomic problem. But luckily we already have a way to read
      the maximum size without locking (i_size_read), so we
      can just use that instead.
      
      Without i_mutex there is no synchronization with write() anymore,
      however since the write() update is atomic on 64bit it just behaves
      like another racy SEEK_SET.  On non atomic 32bit it's the same
      as SEEK_SET.
      
      => Don't need a lock, but need to use i_size_read()
      
      SEEK_CUR: This has a read-modify-write race window
      on the same file. One could argue that any application
      doing unsynchronized seeks on the same file is already broken.
      But for the sake of not adding a regression here I'm
      using the file->f_lock to synchronize this. Using this
      lock is much better than the inode mutex because it doesn't
      synchronize between processes.
      
      => So still need a lock, but can use a f_lock.
      
      This patch implements this new scheme in generic_file_llseek.
      I dropped generic_file_llseek_unlocked and changed all callers.
      Signed-off-by: NAndi Kleen <ak@linux.intel.com>
      Signed-off-by: NChristoph Hellwig <hch@lst.de>
      ef3d0fd2
  2. 27 7月, 2011 1 次提交
  3. 21 7月, 2011 1 次提交
    • J
      fs: add SEEK_HOLE and SEEK_DATA flags · 982d8165
      Josef Bacik 提交于
      This just gets us ready to support the SEEK_HOLE and SEEK_DATA flags.  Turns out
      using fiemap in things like cp cause more problems than it solves, so lets try
      and give userspace an interface that doesn't suck.  We need to match solaris
      here, and the definitions are
      
      *o* If /whence/ is SEEK_HOLE, the offset of the start of the
      next hole greater than or equal to the supplied offset
      is returned. The definition of a hole is provided near
      the end of the DESCRIPTION.
      
      *o* If /whence/ is SEEK_DATA, the file pointer is set to the
      start of the next non-hole file region greater than or
      equal to the supplied offset.
      
      So in the generic case the entire file is data and there is a virtual hole at
      the end.  That means we will just return i_size for SEEK_HOLE and will return
      the same offset for SEEK_DATA.  This is how Solaris does it so we have to do it
      the same way.
      
      Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      982d8165
  4. 13 1月, 2011 1 次提交
  5. 18 11月, 2010 1 次提交
  6. 30 10月, 2010 1 次提交
  7. 26 10月, 2010 1 次提交
  8. 15 10月, 2010 2 次提交
    • A
      vfs: make no_llseek the default · 776c163b
      Arnd Bergmann 提交于
      All file operations now have an explicit .llseek
      operation pointer, so we can change the default
      action for future code.
      
      This makes changes the default from default_llseek
      to no_llseek, which always returns -ESPIPE if
      a user tries to seek on a file without a .llseek
      operation.
      
      The name of the default_llseek function remains
      unchanged, if anyone thinks we should change it,
      please speak up.
      Signed-off-by: NArnd Bergmann <arnd@arndb.de>
      Cc: Christoph Hellwig <hch@infradead.org>
      Cc: Al Viro <viro@zeniv.linux.org.uk>
      Cc: linux-fsdevel@vger.kernel.org
      776c163b
    • A
      vfs: don't use BKL in default_llseek · ab91261f
      Arnd Bergmann 提交于
      There are currently 191 users of default_llseek.
      Nine of these are in device drivers that use the
      big kernel lock. None of these ever touch
      file->f_pos outside of llseek or file_pos_write.
      
      Consequently, we never rely on the BKL
      in the default_llseek function and can
      replace that with i_mutex, which is also
      used in generic_file_llseek.
      Signed-off-by: NArnd Bergmann <arnd@arndb.de>
      ab91261f
  9. 28 7月, 2010 1 次提交
    • E
      fsnotify: pass a file instead of an inode to open, read, and write · 2a12a9d7
      Eric Paris 提交于
      fanotify, the upcoming notification system actually needs a struct path so it can
      do opens in the context of listeners, and it needs a file so it can get f_flags
      from the original process.  Close was the only operation that already was passing
      a struct file to the notification hook.  This patch passes a file for access,
      modify, and open as well as they are easily available to these hooks.
      Signed-off-by: NEric Paris <eparis@redhat.com>
      2a12a9d7
  10. 28 5月, 2010 1 次提交
  11. 25 3月, 2010 1 次提交
  12. 04 11月, 2009 1 次提交
  13. 24 9月, 2009 1 次提交
  14. 11 5月, 2009 1 次提交
  15. 05 4月, 2009 1 次提交
    • L
      Make non-compat preadv/pwritev use native register size · 601cc11d
      Linus Torvalds 提交于
      Instead of always splitting the file offset into 32-bit 'high' and 'low'
      parts, just split them into the largest natural word-size - which in C
      terms is 'unsigned long'.
      
      This allows 64-bit architectures to avoid the unnecessary 32-bit
      shifting and masking for native format (while the compat interfaces will
      obviously always have to do it).
      
      This also changes the order of 'high' and 'low' to be "low first".  Why?
      Because when we have it like this, the 64-bit system calls now don't use
      the "pos_high" argument at all, and it makes more sense for the native
      system call to simply match the user-mode prototype.
      
      This results in a much more natural calling convention, and allows the
      compiler to generate much more straightforward code.  On x86-64, we now
      generate
      
              testq   %rcx, %rcx      # pos_l
              js      .L122   #,
              movq    %rcx, -48(%rbp) # pos_l, pos
      
      from the C source
      
              loff_t pos = pos_from_hilo(pos_h, pos_l);
      	...
              if (pos < 0)
                      return -EINVAL;
      
      and the 'pos_h' register isn't even touched.  It used to generate code
      like
      
              mov     %r8d, %r8d      # pos_low, pos_low
              salq    $32, %rcx       #, tmp71
              movq    %r8, %rax       # pos_low, pos.386
              orq     %rcx, %rax      # tmp71, pos.386
              js      .L122   #,
              movq    %rax, -48(%rbp) # pos.386, pos
      
      which isn't _that_ horrible, but it does show how the natural word size
      is just a more sensible interface (same arguments will hold in the user
      level glibc wrapper function, of course, so the kernel side is just half
      of the equation!)
      
      Note: in all cases the user code wrapper can again be the same. You can
      just do
      
      	#define HALF_BITS (sizeof(unsigned long)*4)
      	__syscall(PWRITEV, fd, iov, count, offset, (offset >> HALF_BITS) >> HALF_BITS);
      
      or something like that.  That way the user mode wrapper will also be
      nicely passing in a zero (it won't actually have to do the shifts, the
      compiler will understand what is going on) for the last argument.
      
      And that is a good idea, even if nobody will necessarily ever care: if
      we ever do move to a 128-bit lloff_t, this particular system call might
      be left alone.  Of course, that will be the least of our worries if we
      really ever need to care, so this may not be worth really caring about.
      
      [ Fixed for lost 'loff_t' cast noticed by Andrew Morton ]
      Acked-by: NGerd Hoffmann <kraxel@redhat.com>
      Cc: H. Peter Anvin <hpa@zytor.com>
      Cc: Andrew Morton <akpm@linux-foundation.org>
      Cc: linux-api@vger.kernel.org
      Cc: linux-arch@vger.kernel.org
      Cc: Ingo Molnar <mingo@elte.hu>
      Cc: Ralf Baechle <ralf@linux-mips.org>>
      Cc: Al Viro <viro@zeniv.linux.org.uk>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      601cc11d
  16. 03 4月, 2009 1 次提交
    • G
      preadv/pwritev: Add preadv and pwritev system calls. · f3554f4b
      Gerd Hoffmann 提交于
      This patch adds preadv and pwritev system calls.  These syscalls are a
      pretty straightforward combination of pread and readv (same for write).
      They are quite useful for doing vectored I/O in threaded applications.
      Using lseek+readv instead opens race windows you'll have to plug with
      locking.
      
      Other systems have such system calls too, for example NetBSD, check
      here: http://www.daemon-systems.org/man/preadv.2.html
      
      The application-visible interface provided by glibc should look like
      this to be compatible to the existing implementations in the *BSD family:
      
        ssize_t preadv(int d, const struct iovec *iov, int iovcnt, off_t offset);
        ssize_t pwritev(int d, const struct iovec *iov, int iovcnt, off_t offset);
      
      This prototype has one problem though: On 32bit archs is the (64bit)
      offset argument unaligned, which the syscall ABI of several archs doesn't
      allow to do.  At least s390 needs a wrapper in glibc to handle this.  As
      we'll need a wrappers in glibc anyway I've decided to push problem to
      glibc entriely and use a syscall prototype which works without
      arch-specific wrappers inside the kernel: The offset argument is
      explicitly splitted into two 32bit values.
      
      The patch sports the actual system call implementation and the windup in
      the x86 system call tables.  Other archs follow as separate patches.
      Signed-off-by: NGerd Hoffmann <kraxel@redhat.com>
      Cc: Arnd Bergmann <arnd@arndb.de>
      Cc: Al Viro <viro@zeniv.linux.org.uk>
      Cc: <linux-api@vger.kernel.org>
      Cc: <linux-arch@vger.kernel.org>
      Cc: Ralf Baechle <ralf@linux-mips.org>
      Cc: Ingo Molnar <mingo@elte.hu>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: "H. Peter Anvin" <hpa@zytor.com>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      f3554f4b
  17. 14 1月, 2009 5 次提交
  18. 06 1月, 2009 1 次提交
    • A
      vfs: lseek(fd, 0, SEEK_CUR) race condition · 5b6f1eb9
      Alain Knaff 提交于
      This patch fixes a race condition in lseek. While it is expected that
      unpredictable behaviour may result while repositioning the offset of a
      file descriptor concurrently with reading/writing to the same file
      descriptor, this should not happen when merely *reading* the file
      descriptor's offset.
      
      Unfortunately, the only portable way in Unix to read a file
      descriptor's offset is lseek(fd, 0, SEEK_CUR); however executing this
      concurrently with read/write may mess up the position.
      
      [with fixes from akpm]
      Signed-off-by: NAlain Knaff <alain@knaff.lu>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      5b6f1eb9
  19. 23 10月, 2008 1 次提交
  20. 03 7月, 2008 1 次提交
    • A
      Remove BKL from remote_llseek v2 · 9465efc9
      Andi Kleen 提交于
      - Replace remote_llseek with generic_file_llseek_unlocked (to force compilation
      failures in all users)
      - Change all users to either use generic_file_llseek_unlocked directly or
      take the BKL around. I changed the file systems who don't use the BKL
      for anything (CIFS, GFS) to call it directly. NCPFS and SMBFS and NFS
      take the BKL, but explicitely in their own source now.
      
      I moved them all over in a single patch to avoid unbisectable sections.
      
      Open problem: 32bit kernels can corrupt fpos because its modification
      is not atomic, but they can do that anyways because there's other paths who
      modify it without BKL.
      
      Do we need a special lock for the pos/f_version = 0 checks?
      
      Trond says the NFS BKL is likely not needed, but keep it for now
      until his full audit.
      
      v2: Use generic_file_llseek_unlocked instead of remote_llseek_unlocked
          and factor duplicated code (suggested by hch)
      
      Cc: Trond.Myklebust@netapp.com
      Cc: swhiteho@redhat.com
      Cc: sfrench@samba.org
      Cc: vandrove@vc.cvut.cz
      Signed-off-by: NAndi Kleen <ak@suse.de>
      Signed-off-by: NAndi Kleen <ak@linux.intel.com>
      Signed-off-by: NJonathan Corbet <corbet@lwn.net>
      9465efc9
  21. 23 4月, 2008 1 次提交
  22. 09 2月, 2008 1 次提交
  23. 29 1月, 2008 1 次提交
  24. 25 1月, 2008 1 次提交
  25. 15 11月, 2007 1 次提交
    • A
      mark sys_open/sys_read exports unused · cb51f973
      Arjan van de Ven 提交于
      sys_open / sys_read were used in the early 1.2 days to load firmware from
      disk inside drivers.  Since 2.0 or so this was deprecated behavior, but
      several drivers still were using this.  Since a few years we have a
      request_firmware() API that implements this in a nice, consistent way.
      Only some old ISA sound drivers (pre-ALSA) still straggled along for some
      time....  however with commit c2b1239a the
      last user is now gone.
      
      This is a good thing, since using sys_open / sys_read etc for firmware is a
      very buggy to dangerous thing to do; these operations put an fd in the
      process file descriptor table....  which then can be tampered with from
      other threads for example.  For those who don't want the firmware loader,
      filp_open()/vfs_read are the better APIs to use, without this security
      issue.
      
      The patch below marks sys_open and sys_read unused now that they're
      really not used anymore, and for deletion in the 2.6.25 timeframe.
      Signed-off-by: NArjan van de Ven <arjan@linux.intel.com>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      cb51f973
  26. 10 10月, 2007 1 次提交
    • P
      Cleanup macros for distinguishing mandatory locks · a16877ca
      Pavel Emelyanov 提交于
      The combination of S_ISGID bit set and S_IXGRP bit unset is used to mark the
      inode as "mandatory lockable" and there's a macro for this check called
      MANDATORY_LOCK(inode).  However, fs/locks.c and some filesystems still perform
      the explicit i_mode checking.  Besides, Andrew pointed out, that this macro is
      buggy itself, as it dereferences the inode arg twice.
      
      Convert this macro into static inline function and switch its users to it,
      making the code shorter and more readable.
      
      The __mandatory_lock() helper is to be used in places where the IS_MANDLOCK()
      for superblock is already known to be true.
      Signed-off-by: NPavel Emelyanov <xemul@openvz.org>
      Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
      Cc: "J. Bruce Fields" <bfields@fieldses.org>
      Cc: David Howells <dhowells@redhat.com>
      Cc: Eric Van Hensbergen <ericvh@gmail.com>
      Cc: Ron Minnich <rminnich@sandia.gov>
      Cc: Latchesar Ionkov <lucho@ionkov.net>
      Cc: Steven Whitehouse <swhiteho@redhat.com>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      a16877ca
  27. 10 7月, 2007 3 次提交
  28. 09 5月, 2007 2 次提交
  29. 13 2月, 2007 1 次提交
    • E
      [PATCH] FS: speed up rw_verify_area() · 163da958
      Eric Dumazet 提交于
      oprofile hunting showed a stall in rw_verify_area(), because of triple
      indirection and potential cache misses.
      (file->f_path.dentry->d_inode->i_flock)
      
      By moving initialization of 'struct inode' pointer before the pos/count
      sanity tests, we allow the compiler and processor to perform two loads by
      anticipation, reducing stall, without prefetch() hints.  Even x86 arch has
      enough registers to not use temporary variables and not increase text size.
      
      I validated this patch running a bench and studied oprofile changes, and
      absolute perf of the test program.
      
      Results of my epoll_pipe_bench (source available on request) on a Pentium-M
      1.6 GHz machine
      
      Before :
      # ./epoll_pipe_bench -l 30 -t 20
      Avg: 436089 evts/sec read_count=8843037 write_count=8843040 21.218390 samples
      per call
      (best value out of 10 runs)
      
      After :
      # ./epoll_pipe_bench -l 30 -t 20
      Avg: 470980 evts/sec read_count=9549871 write_count=9549894 21.216694 samples
      per call
      (best value out of 10 runs)
      
      oprofile CPU_CLK_UNHALTED events gave a reduction from 5.3401 % to 2.5851 %
      for the rw_verify_area() function.
      Signed-off-by: NEric Dumazet <dada1@cosmosbay.com>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      163da958
  30. 12 2月, 2007 1 次提交
  31. 14 12月, 2006 1 次提交
  32. 09 12月, 2006 1 次提交