1. 20 10月, 2007 1 次提交
  2. 09 5月, 2007 1 次提交
    • U
      utimensat implementation · 1c710c89
      Ulrich Drepper 提交于
      Implement utimensat(2) which is an extension to futimesat(2) in that it
      
      a) supports nano-second resolution for the timestamps
      b) allows to selectively ignore the atime/mtime value
      c) allows to selectively use the current time for either atime or mtime
      d) supports changing the atime/mtime of a symlink itself along the lines
         of the BSD lutimes(3) functions
      
      For this change the internally used do_utimes() functions was changed to
      accept a timespec time value and an additional flags parameter.
      
      Additionally the sys_utime function was changed to match compat_sys_utime
      which already use do_utimes instead of duplicating the work.
      
      Also, the completely missing futimensat() functionality is added.  We have
      such a function in glibc but we have to resort to using /proc/self/fd/* which
      not everybody likes (chroot etc).
      
      Test application (the syscall number will need per-arch editing):
      
      #include <errno.h>
      #include <fcntl.h>
      #include <time.h>
      #include <sys/time.h>
      #include <stddef.h>
      #include <syscall.h>
      
      #define __NR_utimensat 280
      
      #define UTIME_NOW       ((1l << 30) - 1l)
      #define UTIME_OMIT      ((1l << 30) - 2l)
      
      int
      main(void)
      {
        int status = 0;
      
        int fd = open("ttt", O_RDWR|O_CREAT|O_EXCL, 0666);
        if (fd == -1)
          error (1, errno, "failed to create test file \"ttt\"");
      
        struct stat64 st1;
        if (fstat64 (fd, &st1) != 0)
          error (1, errno, "fstat failed");
      
        struct timespec t[2];
        t[0].tv_sec = 0;
        t[0].tv_nsec = 0;
        t[1].tv_sec = 0;
        t[1].tv_nsec = 0;
        if (syscall(__NR_utimensat, AT_FDCWD, "ttt", t, 0) != 0)
          error (1, errno, "utimensat failed");
      
        struct stat64 st2;
        if (fstat64 (fd, &st2) != 0)
          error (1, errno, "fstat failed");
      
        if (st2.st_atim.tv_sec != 0 || st2.st_atim.tv_nsec != 0)
          {
            puts ("atim not reset to zero");
            status = 1;
          }
        if (st2.st_mtim.tv_sec != 0 || st2.st_mtim.tv_nsec != 0)
          {
            puts ("mtim not reset to zero");
            status = 1;
          }
        if (status != 0)
          goto out;
      
        t[0] = st1.st_atim;
        t[1].tv_sec = 0;
        t[1].tv_nsec = UTIME_OMIT;
        if (syscall(__NR_utimensat, AT_FDCWD, "ttt", t, 0) != 0)
          error (1, errno, "utimensat failed");
      
        if (fstat64 (fd, &st2) != 0)
          error (1, errno, "fstat failed");
      
        if (st2.st_atim.tv_sec != st1.st_atim.tv_sec
            || st2.st_atim.tv_nsec != st1.st_atim.tv_nsec)
          {
            puts ("atim not set");
            status = 1;
          }
        if (st2.st_mtim.tv_sec != 0 || st2.st_mtim.tv_nsec != 0)
          {
            puts ("mtim changed from zero");
            status = 1;
          }
        if (status != 0)
          goto out;
      
        t[0].tv_sec = 0;
        t[0].tv_nsec = UTIME_OMIT;
        t[1] = st1.st_mtim;
        if (syscall(__NR_utimensat, AT_FDCWD, "ttt", t, 0) != 0)
          error (1, errno, "utimensat failed");
      
        if (fstat64 (fd, &st2) != 0)
          error (1, errno, "fstat failed");
      
        if (st2.st_atim.tv_sec != st1.st_atim.tv_sec
            || st2.st_atim.tv_nsec != st1.st_atim.tv_nsec)
          {
            puts ("mtim changed from original time");
            status = 1;
          }
        if (st2.st_mtim.tv_sec != st1.st_mtim.tv_sec
            || st2.st_mtim.tv_nsec != st1.st_mtim.tv_nsec)
          {
            puts ("mtim not set");
            status = 1;
          }
        if (status != 0)
          goto out;
      
        sleep (2);
      
        t[0].tv_sec = 0;
        t[0].tv_nsec = UTIME_NOW;
        t[1].tv_sec = 0;
        t[1].tv_nsec = UTIME_NOW;
        if (syscall(__NR_utimensat, AT_FDCWD, "ttt", t, 0) != 0)
          error (1, errno, "utimensat failed");
      
        if (fstat64 (fd, &st2) != 0)
          error (1, errno, "fstat failed");
      
        struct timeval tv;
        gettimeofday(&tv,NULL);
      
        if (st2.st_atim.tv_sec <= st1.st_atim.tv_sec
            || st2.st_atim.tv_sec > tv.tv_sec)
          {
            puts ("atim not set to NOW");
            status = 1;
          }
        if (st2.st_mtim.tv_sec <= st1.st_mtim.tv_sec
            || st2.st_mtim.tv_sec > tv.tv_sec)
          {
            puts ("mtim not set to NOW");
            status = 1;
          }
      
        if (symlink ("ttt", "tttsym") != 0)
          error (1, errno, "cannot create symlink");
      
        t[0].tv_sec = 0;
        t[0].tv_nsec = 0;
        t[1].tv_sec = 0;
        t[1].tv_nsec = 0;
        if (syscall(__NR_utimensat, AT_FDCWD, "tttsym", t, AT_SYMLINK_NOFOLLOW) != 0)
          error (1, errno, "utimensat failed");
      
        if (lstat64 ("tttsym", &st2) != 0)
          error (1, errno, "lstat failed");
      
        if (st2.st_atim.tv_sec != 0 || st2.st_atim.tv_nsec != 0)
          {
            puts ("symlink atim not reset to zero");
            status = 1;
          }
        if (st2.st_mtim.tv_sec != 0 || st2.st_mtim.tv_nsec != 0)
          {
            puts ("symlink mtim not reset to zero");
            status = 1;
          }
        if (status != 0)
          goto out;
      
        t[0].tv_sec = 1;
        t[0].tv_nsec = 0;
        t[1].tv_sec = 1;
        t[1].tv_nsec = 0;
        if (syscall(__NR_utimensat, fd, NULL, t, 0) != 0)
          error (1, errno, "utimensat failed");
      
        if (fstat64 (fd, &st2) != 0)
          error (1, errno, "fstat failed");
      
        if (st2.st_atim.tv_sec != 1 || st2.st_atim.tv_nsec != 0)
          {
            puts ("atim not reset to one");
            status = 1;
          }
        if (st2.st_mtim.tv_sec != 1 || st2.st_mtim.tv_nsec != 0)
          {
            puts ("mtim not reset to one");
            status = 1;
          }
      
        if (status == 0)
           puts ("all OK");
      
       out:
        close (fd);
        unlink ("ttt");
        unlink ("tttsym");
      
        return status;
      }
      
      [akpm@linux-foundation.org: add missing i386 syscall table entry]
      Signed-off-by: NUlrich Drepper <drepper@redhat.com>
      Cc: Alexey Dobriyan <adobriyan@openvz.org>
      Cc: Michael Kerrisk <mtk-manpages@gmx.net>
      Cc: <linux-arch@vger.kernel.org>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      1c710c89
  3. 08 5月, 2007 2 次提交
  4. 11 12月, 2006 1 次提交
    • V
      [PATCH] fdtable: Make fdarray and fdsets equal in size · bbea9f69
      Vadim Lobanov 提交于
      Currently, each fdtable supports three dynamically-sized arrays of data: the
      fdarray and two fdsets.  The code allows the number of fds supported by the
      fdarray (fdtable->max_fds) to differ from the number of fds supported by each
      of the fdsets (fdtable->max_fdset).
      
      In practice, it is wasteful for these two sizes to differ: whenever we hit a
      limit on the smaller-capacity structure, we will reallocate the entire fdtable
      and all the dynamic arrays within it, so any delta in the memory used by the
      larger-capacity structure will never be touched at all.
      
      Rather than hogging this excess, we shouldn't even allocate it in the first
      place, and keep the capacities of the fdarray and the fdsets equal.  This
      patch removes fdtable->max_fdset.  As an added bonus, most of the supporting
      code becomes simpler.
      Signed-off-by: NVadim Lobanov <vlobanov@speakeasy.net>
      Cc: Christoph Hellwig <hch@lst.de>
      Cc: Al Viro <viro@zeniv.linux.org.uk>
      Cc: Dipankar Sarma <dipankar@in.ibm.com>
      Signed-off-by: NAndrew Morton <akpm@osdl.org>
      Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
      bbea9f69
  5. 09 12月, 2006 1 次提交
  6. 03 10月, 2006 1 次提交
    • D
      [PATCH] VFS: Make filldir_t and struct kstat deal in 64-bit inode numbers · afefdbb2
      David Howells 提交于
      These patches make the kernel pass 64-bit inode numbers internally when
      communicating to userspace, even on a 32-bit system.  They are required
      because some filesystems have intrinsic 64-bit inode numbers: NFS3+ and XFS
      for example.  The 64-bit inode numbers are then propagated to userspace
      automatically where the arch supports it.
      
      Problems have been seen with userspace (eg: ld.so) using the 64-bit inode
      number returned by stat64() or getdents64() to differentiate files, and
      failing because the 64-bit inode number space was compressed to 32-bits, and
      so overlaps occur.
      
      This patch:
      
      Make filldir_t take a 64-bit inode number and struct kstat carry a 64-bit
      inode number so that 64-bit inode numbers can be passed back to userspace.
      
      The stat functions then returns the full 64-bit inode number where
      available and where possible.  If it is not possible to represent the inode
      number supplied by the filesystem in the field provided by userspace, then
      error EOVERFLOW will be issued.
      
      Similarly, the getdents/readdir functions now pass the full 64-bit inode
      number to userspace where possible, returning EOVERFLOW instead when a
      directory entry is encountered that can't be properly represented.
      
      Note that this means that some inodes will not be stat'able on a 32-bit
      system with old libraries where they were before - but it does mean that
      there will be no ambiguity over what a 32-bit inode number refers to.
      
      Note similarly that directory scans may be cut short with an error on a
      32-bit system with old libraries where the scan would work before for the
      same reasons.
      
      It is judged unlikely that this situation will occur because modern glibc
      uses 64-bit capable versions of stat and getdents class functions
      exclusively, and that older systems are unlikely to encounter
      unrepresentable inode numbers anyway.
      
      [akpm: alpha build fix]
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
      Cc: Al Viro <viro@zeniv.linux.org.uk>
      Signed-off-by: NAndrew Morton <akpm@osdl.org>
      Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
      afefdbb2
  7. 02 10月, 2006 1 次提交
  8. 01 8月, 2006 1 次提交
  9. 23 6月, 2006 1 次提交
  10. 27 3月, 2006 1 次提交
  11. 19 1月, 2006 1 次提交
    • U
      [PATCH] vfs: *at functions: core · 5590ff0d
      Ulrich Drepper 提交于
      Here is a series of patches which introduce in total 13 new system calls
      which take a file descriptor/filename pair instead of a single file
      name.  These functions, openat etc, have been discussed on numerous
      occasions.  They are needed to implement race-free filesystem traversal,
      they are necessary to implement a virtual per-thread current working
      directory (think multi-threaded backup software), etc.
      
      We have in glibc today implementations of the interfaces which use the
      /proc/self/fd magic.  But this code is rather expensive.  Here are some
      results (similar to what Jim Meyering posted before).
      
      The test creates a deep directory hierarchy on a tmpfs filesystem.  Then
      rm -fr is used to remove all directories.  Without syscall support I get
      this:
      
      real    0m31.921s
      user    0m0.688s
      sys     0m31.234s
      
      With syscall support the results are much better:
      
      real    0m20.699s
      user    0m0.536s
      sys     0m20.149s
      
      The interfaces are for obvious reasons currently not much used.  But they'll
      be used.  coreutils (and Jeff's posixutils) are already using them.
      Furthermore, code like ftw/fts in libc (maybe even glob) will also start using
      them.  I expect a patch to make follow soon.  Every program which is walking
      the filesystem tree will benefit.
      Signed-off-by: NUlrich Drepper <drepper@redhat.com>
      Signed-off-by: NAlexey Dobriyan <adobriyan@gmail.com>
      Cc: Christoph Hellwig <hch@lst.de>
      Cc: Al Viro <viro@ftp.linux.org.uk>
      Acked-by: NIngo Molnar <mingo@elte.hu>
      Cc: Michael Kerrisk <mtk-manpages@gmx.net>
      Signed-off-by: NAndrew Morton <akpm@osdl.org>
      Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
      5590ff0d
  12. 18 9月, 2005 1 次提交
  13. 11 9月, 2005 1 次提交
  14. 10 9月, 2005 1 次提交
  15. 17 5月, 2005 1 次提交
  16. 01 5月, 2005 1 次提交
  17. 17 4月, 2005 1 次提交
    • L
      Linux-2.6.12-rc2 · 1da177e4
      Linus Torvalds 提交于
      Initial git repository build. I'm not bothering with the full history,
      even though we have it. We can create a separate "historical" git
      archive of that later if we want to, and in the meantime it's about
      3.2GB when imported into git - space that would just make the early
      git days unnecessarily complicated, when we don't have a lot of good
      infrastructure for it.
      
      Let it rip!
      1da177e4