From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4821 invoked by alias); 16 Sep 2003 09:09:13 -0000 Mailing-List: contact libc-hacker-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sources.redhat.com Received: (qmail 4798 invoked from network); 16 Sep 2003 09:09:12 -0000 Received: from unknown (HELO elf.meyering.net) (62.212.115.149) by sources.redhat.com with SMTP; 16 Sep 2003 09:09:12 -0000 Received: by elf.meyering.net (Acme Bit-Twister, from userid 1002) id EBD593FBA; Tue, 16 Sep 2003 11:09:10 +0200 (CEST) To: Ulrich Drepper Cc: libc-hacker@sources.redhat.com Cc: Aharon Robbins Subject: statvfs suggestion In-Reply-To: <85isobj8b5.fsf@pi.meyering.net> (Jim Meyering's message of "Tue, 02 Sep 2003 21:31:58 +0200") References: <200309021423.h82ENWrV018980@skeeve.com> <85isobj8b5.fsf@pi.meyering.net> From: Jim Meyering Date: Tue, 16 Sep 2003 09:09:00 -0000 Message-ID: <85smmx5ccp.fsf_-_@pi.meyering.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2003-09/txt/msg00056.txt.bz2 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 #include 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