public inbox for libc-hacker@sourceware.org
 help / color / mirror / Atom feed
From: Jim Meyering <jim@meyering.net>
To: Ulrich Drepper <drepper@redhat.com>
Cc: libc-hacker@sources.redhat.com
Cc: Aharon Robbins <arnold@skeeve.com>
Subject: statvfs suggestion
Date: Tue, 16 Sep 2003 09:09:00 -0000	[thread overview]
Message-ID: <85smmx5ccp.fsf_-_@pi.meyering.net> (raw)
In-Reply-To: <85isobj8b5.fsf@pi.meyering.net> (Jim Meyering's message of "Tue, 02 Sep 2003 21:31:58 +0200")

Hi Uli,

[There's no pressure at all, since the coreutils work around this problem
 simply by using statfs on glibc systems, but I feel I should at least
 report the problem.  Other applications may well be affected. ]

For some time, now the coreutils have been avoiding the use of glibc's
statvfs because it has an undesirable side-effect in some cases.
When df used statvfs, it would sometimes hang unnecessarily due to a
problem with an unrelated hard mount.  That was because statvfs stats
a directory for each entry in /proc/mounts, in order, until it finds
one with matching device number.  Of course, that would make df hang if
even one of the file systems listed in /proc/mounts before the desired
one is hard-mounted, but not available.

What do you think about changing internal_statvfs.c so that it first
reads/saves all entries from /proc/mounts without stat'ing each
corresponding directory?  Then it can stop if any mount point matches
the name of the file.

This is a relatively important optimization, not just for the case
mentioned above that would make df hang unnecessarily, but also to avoid
the potential O(N^2) stat/mount operations that you'd currently incur
when iterating with getmntent, and calling statvfs on each mount point.

Here's some actual code demonstrating the problem, but not the hang:

  $ cat statvfs-glibc-test.c
  #include <stdlib.h>
  #include <sys/statvfs.h>

  int
  main (int argc, char **argv)
  {
    struct statvfs fsd;
    exit (statvfs (argv[1], &fsd));
  }

Note that it will stat the 10 or so directories
before the desired one, while it could have stat'ed only
the selected one in this case, since the file argument, "/my",
to statvfs matches the name of a mount point:

  $ cat /proc/mounts
  rootfs / rootfs rw 0 0
  /dev2/root2 / ext3 rw 0 0
  proc /proc proc rw 0 0
  devpts /dev/pts devpts rw 0 0
  /dev/hda5 /tmp ext3 rw 0 0
  /dev/hda3 /_boot ext3 rw 0 0
  /dev/hda2 /var ext3 rw 0 0
  /dev/hda7 /u ext3 rw 0 0
  tmpfs /t tmpfs rw 0 0
  /dev/hdc2 /misc ext3 rw 0 0
  /dev/hdc3 /nobak ext3 rw 0 0
  /dev/hdc4 /my ext3 rw 0 0
  /dev/hde2 /e-root ext3 rw 0 0
  /dev/hde3 /e ext3 rw 0 0
  /dev/hdg2 /g-root ext3 rw 0 0
  /dev/hdg3 /g ext3 rw 0 0
  automount(pid475) /mnt/auto autofs rw 0 0
  usb /proc/bus/usb usbdevfs rw 0 0

  $ strace -e stat64,open ./a.out /my
  ...
  stat64("/my", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
  open("/proc/mounts", O_RDONLY)          = 3
  stat64("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
  stat64("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
  stat64("/proc", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
  stat64("/dev/pts", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
  stat64("/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=8192, ...}) = 0
  stat64("/_boot", {st_mode=S_IFDIR|0755, st_size=1024, ...}) = 0
  stat64("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
  stat64("/u", {st_mode=S_IFDIR|S_ISGID|0775, st_size=4096, ...}) = 0
  stat64("/t", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=340, ...}) = 0
  stat64("/misc", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
  stat64("/nobak", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
  stat64("/my", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0

Jim

       reply	other threads:[~2003-09-16  9:09 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <200309021423.h82ENWrV018980@skeeve.com>
     [not found] ` <85isobj8b5.fsf@pi.meyering.net>
2003-09-16  9:09   ` Jim Meyering [this message]
2003-09-17  0:51     ` Ulrich Drepper
2003-09-17 12:00       ` Jim Meyering
     [not found] <200309171137.h8HBbHW6024549@skeeve.com>
2003-09-17 15:09 ` Ulrich Drepper

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=85smmx5ccp.fsf_-_@pi.meyering.net \
    --to=jim@meyering.net \
    --cc=drepper@redhat.com \
    --cc=libc-hacker@sources.redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).