getcwd does lots of stat'ing

From: Cameron Schaus (cam@cds.realcase.com)
Date: Thu May 25 2000 - 22:27:31 EST


Why does a call to getcwd descend the direcotries until a mount point
is hit? I noticed this while profiling some code at work (this is
very expensive on nfs mounted drives). Every directory that it finds,
it runs lstat on.

Is this done in the libc implementation of getcwd, or does the kernel
system call do this? I am running 2.2.14 with Trond's nfsv3 patches
with the Debian 2.1 distribution.

The only solution to this I can think of is to not call getcwd so
much! Any other advice, or even an explanation of what is going on
would be appreciated.

Thanks,
Cam

Below is strace output showing a getcwd in action. Notice it quits
when it hits the mount point (/home).
--------------------
lstat(".", {st_mode=S_IFDIR|S_ISGID|0755, st_size=7168, ...}) = 0
lstat("/", {st_mode=S_IFDIR|0755, st_size=1024, ...}) = 0
lstat("..", {st_mode=S_IFDIR|S_ISGID|0775, st_size=1024, ...}) = 0
stat("..", {st_mode=S_IFDIR|S_ISGID|0775, st_size=1024, ...}) = 0
open("..", O_RDONLY|O_NONBLOCK) = 4
fcntl(4, F_SETFD, FD_CLOEXEC) = 0
brk(0x8177000) = 0x8177000
lseek(4, 0, SEEK_CUR) = 0
getdents(4, /* 53 entries */, 3933) = 940
lstat("../arai", {st_mode=S_IFDIR|S_ISGID|0755, st_size=2560, ...}) = 0
lstat("../bergamin", {st_mode=S_IFDIR|S_ISGID|0755, st_size=21504, ...}) = 0
lstat("../cam2", {st_mode=S_IFDIR|S_ISGID|0755, st_size=5632, ...}) = 0
lstat("../chris", {st_mode=S_IFDIR|S_ISGID|0755, st_size=3584, ...}) = 0
lstat("../curt", {st_mode=S_IFDIR|S_ISGID|0755, st_size=1536, ...}) = 0
lstat("../darren", {st_mode=S_IFDIR|S_ISGID|0755, st_size=2048, ...}) = 0
lstat("../dave", {st_mode=S_IFDIR|S_ISGID|0755, st_size=4096, ...}) = 0
lstat("../fetz", {st_mode=S_IFDIR|S_ISGID|0755, st_size=4608, ...}) = 0
lstat("../guest", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("../jason", {st_mode=S_IFDIR|S_ISGID|0755, st_size=44544, ...}) = 0
lstat("../jeff", {st_mode=S_IFDIR|S_ISGID|0755, st_size=4096, ...}) = 0
lstat("../joe", {st_mode=S_IFDIR|S_ISGID|0755, st_size=2560, ...}) = 0
lstat("../jon", {st_mode=S_IFDIR|S_ISGID|0755, st_size=2560, ...}) = 0
lstat("../kester", {st_mode=S_IFDIR|S_ISGID|0755, st_size=8192, ...}) = 0
lstat("../kevin2", {st_mode=S_IFDIR|S_ISGID|0755, st_size=3072, ...}) = 0
lstat("../nfstest", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("../paul", {st_mode=S_IFDIR|S_ISGID|0755, st_size=3072, ...}) = 0
lstat("../paul2", {st_mode=S_IFDIR|S_ISGID|0775, st_size=6656, ...}) = 0
[...]
lstat("../schaus", {st_mode=S_IFDIR|S_ISGID|0755, st_size=7168, ...}) = 0
close(4) = 0
lstat("../..", {st_mode=S_IFDIR|0755, st_size=1024, ...}) = 0
stat("../..", {st_mode=S_IFDIR|0755, st_size=1024, ...}) = 0
open("../..", O_RDONLY|O_NONBLOCK) = 4
fcntl(4, F_SETFD, FD_CLOEXEC) = 0
lseek(4, 0, SEEK_CUR) = 0
getdents(4, /* 31 entries */, 3933) = 524
lstat("../../home", {st_mode=S_IFDIR|S_ISGID|0775, st_size=1024, ...}) = 0
close(4) = 0
--------------------

-- 
Cam Schaus
cam@cds.realcase.com

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed May 31 2000 - 21:00:15 EST