From d0501a245c7f6c8bf399594d9b331d915580d36f Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 17 Sep 2003 00:49:19 +0000 Subject: Update. 2003-09-16 Ulrich Drepper * sysdeps/unix/sysv/linux/Dist: Remove internal_statvfs.c. * sysdeps/unix/sysv/linux/Makefile [subdir=io] (sysdep_routines): Add internal_statvfs. * sysdeps/unix/sysv/linux/fstatvfs.c: Call __internal_statvfs instead of including "internal_statvfs.c". * sysdeps/unix/sysv/linux/statvfs.c: Likewise. * sysdeps/unix/sysv/linux/internal_statvfs.c: Make it a real function. Add code to avoid the stat calls on all the reported mount points when we can determine mismatch in advance. * sysdeps/unix/sysv/linux/linux_fsinfo.h: Add AUTOFS_SUPER_MAGIC and USBDEVFS_SUPER_MAGIC. 2003-09-16 Jakub Jelinek * posix/Versions (sched_getaffinity, sched_setaffinity): Change from GLIBC_2.3.2 to GLIBC_2.3.3 symbol version. 2003-09-16 Bruno Haible * intl/tst-gettext2.sh: Set GCONV_PATH and LOCPATH only after invoking msgfmt, not before. --- sysdeps/unix/sysv/linux/Dist | 1 - sysdeps/unix/sysv/linux/Makefile | 2 +- sysdeps/unix/sysv/linux/fstatvfs.c | 16 ++-- sysdeps/unix/sysv/linux/internal_statvfs.c | 114 +++++++++++++++++++++++++---- sysdeps/unix/sysv/linux/linux_fsinfo.h | 6 ++ sysdeps/unix/sysv/linux/statvfs.c | 17 ++--- 6 files changed, 120 insertions(+), 36 deletions(-) (limited to 'sysdeps/unix') diff --git a/sysdeps/unix/sysv/linux/Dist b/sysdeps/unix/sysv/linux/Dist index 1cd482c1ff..219b3d80f9 100644 --- a/sysdeps/unix/sysv/linux/Dist +++ b/sysdeps/unix/sysv/linux/Dist @@ -11,7 +11,6 @@ kernel-features.h kernel_sigaction.h kernel_stat.h kernel_termios.h -internal_statvfs.c ldd-rewrite.sed lddlibc4.c linux_fsinfo.h diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 2d781d2f74..c67376d1f8 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -137,7 +137,7 @@ CFLAGS-ypclnt.c = -DUSE_BINDINGDIR=1 endif ifeq ($(subdir),io) -sysdep_routines += xstatconv +sysdep_routines += xstatconv internal_statvfs endif ifeq ($(subdir),elf) diff --git a/sysdeps/unix/sysv/linux/fstatvfs.c b/sysdeps/unix/sysv/linux/fstatvfs.c index 0bfce16309..0dd56c1046 100644 --- a/sysdeps/unix/sysv/linux/fstatvfs.c +++ b/sysdeps/unix/sysv/linux/fstatvfs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1998, 1999, 2000, 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1998. @@ -17,16 +17,14 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include -#include -#include -#include -#include -#include +#include #include #include #include +extern void __internal_statvfs (const char *name, struct statvfs *buf, + struct statfs *fsbuf, struct stat64 *st); + int fstatvfs (int fd, struct statvfs *buf) @@ -38,8 +36,8 @@ fstatvfs (int fd, struct statvfs *buf) if (__fstatfs (fd, &fsbuf) < 0) return -1; -#define STAT(st) fstat64 (fd, st) -#include "internal_statvfs.c" + /* Convert the result. */ + __internal_statvfs (NULL, buf, &fsbuf, fstat64 (fd, &st) == -1 ? NULL : &st); /* We signal success if the statfs call succeeded. */ return 0; diff --git a/sysdeps/unix/sysv/linux/internal_statvfs.c b/sysdeps/unix/sysv/linux/internal_statvfs.c index 9317cef90d..172113d496 100644 --- a/sysdeps/unix/sysv/linux/internal_statvfs.c +++ b/sysdeps/unix/sysv/linux/internal_statvfs.c @@ -17,29 +17,46 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "linux_fsinfo.h" + + +void +__internal_statvfs (const char *name, struct statvfs *buf, + struct statfs *fsbuf, struct stat64 *st) +{ /* Now fill in the fields we have information for. */ - buf->f_bsize = fsbuf.f_bsize; + buf->f_bsize = fsbuf->f_bsize; /* Linux has the f_frsize size only in later version of the kernel. If the value is not filled in use f_bsize. */ - buf->f_frsize = fsbuf.f_frsize ?: fsbuf.f_bsize; - buf->f_blocks = fsbuf.f_blocks; - buf->f_bfree = fsbuf.f_bfree; - buf->f_bavail = fsbuf.f_bavail; - buf->f_files = fsbuf.f_files; - buf->f_ffree = fsbuf.f_ffree; - if (sizeof (buf->f_fsid) == sizeof (fsbuf.f_fsid)) - buf->f_fsid = (fsbuf.f_fsid.__val[0] - | ((unsigned long int) fsbuf.f_fsid.__val[1] + buf->f_frsize = fsbuf->f_frsize ?: fsbuf->f_bsize; + buf->f_blocks = fsbuf->f_blocks; + buf->f_bfree = fsbuf->f_bfree; + buf->f_bavail = fsbuf->f_bavail; + buf->f_files = fsbuf->f_files; + buf->f_ffree = fsbuf->f_ffree; + if (sizeof (buf->f_fsid) == sizeof (fsbuf->f_fsid)) + buf->f_fsid = (fsbuf->f_fsid.__val[0] + | ((unsigned long int) fsbuf->f_fsid.__val[1] << (8 * (sizeof (buf->f_fsid) - - sizeof (fsbuf.f_fsid.__val[0]))))); + - sizeof (fsbuf->f_fsid.__val[0]))))); else /* We cannot help here. The statvfs element is not large enough to contain both words of the statfs f_fsid field. */ - buf->f_fsid = fsbuf.f_fsid.__val[0]; + buf->f_fsid = fsbuf->f_fsid.__val[0]; #ifdef _STATVFSBUF_F_UNUSED buf->__f_unused = 0; #endif - buf->f_namemax = fsbuf.f_namelen; + buf->f_namemax = fsbuf->f_namelen; memset (buf->__f_spare, '\0', 6 * sizeof (int)); /* What remains to do is to fill the fields f_favail and f_flag. */ @@ -52,10 +69,40 @@ file. The way we can test for matching filesystem is using the device number. */ buf->f_flag = 0; - if (STAT (&st) >= 0) + if (st != NULL) { struct mntent mntbuf; FILE *mtab; + const char *fsname = NULL; + const char *fsname2 = NULL; + bool success = false; + + /* Map the filesystem type we got from the statfs call to a string. */ + switch (fsbuf->f_type) + { + case EXT2_SUPER_MAGIC: + fsname = "ext3"; + fsname2 = "ext2"; + break; + case DEVPTS_SUPER_MAGIC: + fsname= "devpts"; + break; + case SHMFS_SUPER_MAGIC: + fsname = "tmpfs"; + break; + case PROC_SUPER_MAGIC: + fsname = "proc"; + break; + case USBDEVFS_SUPER_MAGIC: + fsname = "usbdevfs"; + break; + case AUTOFS_SUPER_MAGIC: + fsname = "autofs"; + break; + case NFS_SUPER_MAGIC: + fsname = "nfs"; + break; + } mtab = __setmntent ("/proc/mounts", "r"); if (mtab == NULL) @@ -68,13 +115,25 @@ /* No locking needed. */ (void) __fsetlocking (mtab, FSETLOCKING_BYCALLER); + again: while (__getmntent_r (mtab, &mntbuf, tmpbuf, sizeof (tmpbuf))) { - struct stat64 fsst; + /* In a first round we look for a given mount point, if + we have a name. */ + if (name != NULL && strcmp (name, mntbuf.mnt_dir) != 0) + continue; + /* We need to look at the entry only if the filesystem + name matches. If we have a filesystem name. */ + else if (fsname != NULL + && strcmp (fsname, mntbuf.mnt_type) != 0 + && (fsname2 == NULL + || strcmp (fsname2, mntbuf.mnt_type) != 0)) + continue; /* Find out about the device the current entry is for. */ + struct stat64 fsst; if (stat64 (mntbuf.mnt_dir, &fsst) >= 0 - && st.st_dev == fsst.st_dev) + && st->st_dev == fsst.st_dev) { /* Bingo, we found the entry for the device FD is on. Now interpret the option string. */ @@ -100,11 +159,34 @@ buf->f_flag |= ST_NODIRATIME; /* We can stop looking for more entries. */ + success = true; break; } } + /* Maybe the kernel names for the filesystems changed or the + statvfs call got a name which was not the mount point. + Check again, this time without checking for name matches + first. */ + if (! success) + { + if (name != NULL) + /* Try without a mount point name. */ + name = NULL; + else if (fsname != NULL) + /* Try without a filesystem name. */ + fsname = fsname2 = NULL; + + /* It is not strictly allowed to use rewind here. But + this code is part of the implementation so it is + acceptable. */ + rewind (mtab); + + goto again; + } /* Close the file. */ __endmntent (mtab); + } } +} diff --git a/sysdeps/unix/sysv/linux/linux_fsinfo.h b/sysdeps/unix/sysv/linux/linux_fsinfo.h index 41dbbde55c..13c3856266 100644 --- a/sysdeps/unix/sysv/linux/linux_fsinfo.h +++ b/sysdeps/unix/sysv/linux/linux_fsinfo.h @@ -31,6 +31,9 @@ /* Constants that identify the `affs' filesystem. */ #define AFFS_SUPER_MAGIC 0xadff +/* Constants that identify the `autofs' filesystem. */ +#define AUTOFS_SUPER_MAGIC 0x187 + /* Constants that identify the `bfs' filesystem. */ #define BFS_MAGIC 0x1BADFACE @@ -94,6 +97,9 @@ /* Constants that identify the `proc' filesystem. */ #define PROC_SUPER_MAGIC 0x9fa0 +/* Constant that identifies the `usbdevfs' filesystem. */ +#define USBDEVFS_SUPER_MAGIC 0x9fa2 + /* Constants that identify the `qnx4' filesystem. */ #define QNX4_SUPER_MAGIC 0x002f diff --git a/sysdeps/unix/sysv/linux/statvfs.c b/sysdeps/unix/sysv/linux/statvfs.c index 5eef62c5f6..51d4f4fd0c 100644 --- a/sysdeps/unix/sysv/linux/statvfs.c +++ b/sysdeps/unix/sysv/linux/statvfs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 2000, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1998, 2000, 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1998. @@ -17,16 +17,14 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include -#include -#include -#include -#include -#include +#include #include #include #include +extern void __internal_statvfs (const char *name, struct statvfs *buf, + struct statfs *fsbuf, struct stat64 *st); + int statvfs (const char *file, struct statvfs *buf) @@ -38,8 +36,9 @@ statvfs (const char *file, struct statvfs *buf) if (__statfs (file, &fsbuf) < 0) return -1; -#define STAT(st) stat64 (file, st) -#include "internal_statvfs.c" + /* Convert the result. */ + __internal_statvfs (file, buf, &fsbuf, + stat64 (file, &st) == -1 ? NULL : &st); /* We signal success if the statfs call succeeded. */ return 0; -- cgit v1.2.3