inode query

Greg Freemyer greg.freemyer at gmail.com
Thu Apr 7 17:30:24 EDT 2011


On Tue, Apr 5, 2011 at 5:38 PM, Greg Freemyer <greg.freemyer at gmail.com> wrote:
> On Tue, Apr 5, 2011 at 4:41 PM, mohit verma <mohit89mlnc at gmail.com> wrote:
>>
>> hi list,
>> how can a utility like **find** command  can map an inode number to a
>> filename?
>>  i mean if we pass **find -inum inode_number  / **   , it will show us the
>>  files associated with that "inode_number". What is the underlying mechanism
>> used in all this ?
>>  I have peeped into the findutils code but it seems horrible to figure it
>> out from that code .:)
>
> strace is a lot easier than reading code for something like that.
>
> Looks to me like find is just walking the tree and calling
> newfstatat() on every file.
>
> Here's a short section from strace.  Notice in the directory walk it
> gets to charmaps.  (I think that's /usr/share/i18n/charmaps).
>
> I'd guess that based on the return from newfstatat() it decides its a
> directory, so it call getdents64()
>
> It then starts calling newfstatat() for everything in that directory.
> (Not as sexy as you hoped I suspect.)
>
>
> newfstatat(AT_FDCWD, "charmaps", {st_mode=S_IFDIR|0755, st_size=12288,
> ...}, AT_SYMLINK_NOFOLLOW) = 0
> open("charmaps", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 4
> getdents64(4, /* 229 entries */, 32768) = 8024
> getdents64(4, /* 0 entries */, 32768)   = 0
> close(4)                                = 0
> open("charmaps", O_RDONLY|O_NOFOLLOW)   = 4
> fchdir(4)                               = 0
> close(4)                                = 0
> stat(".", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0
> newfstatat(AT_FDCWD, "CP1257.gz", {st_mode=S_IFREG|0644, st_size=2813,
> ...}, AT_SYMLINK_NOFOLLOW) = 0
> newfstatat(AT_FDCWD, "EBCDIC-UK.gz", {st_mode=S_IFREG|0644,
> st_size=2129, ...}, AT_SYMLINK_NOFOLLOW) = 0
> newfstatat(AT_FDCWD, "LATIN-GREEK.gz", {st_mode=S_IFREG|0644,
> st_size=1605, ...}, AT_SYMLINK_NOFOLLOW) = 0
> newfstatat(AT_FDCWD, "NEXTSTEP.gz", {st_mode=S_IFREG|0644,
> st_size=2972, ...}, AT_SYMLINK_NOFOLLOW) = 0
> newfstatat(AT_FDCWD, "IBM903.gz", {st_mode=S_IFREG|0644, st_size=1566,
> ...}, AT_SYMLINK_NOFOLLOW) = 0
> newfstatat(AT_FDCWD, "BIG5-HKSCS.gz", {st_mode=S_IFREG|0644,
> st_size=145960, ...}, AT_SYMLINK_NOFOLLOW) = 0
> newfstatat(AT_FDCWD, "BRF.gz", {st_mode=S_IFREG|0644, st_size=1166,
> ...}, AT_SYMLINK_NOFOLLOW) = 0
> newfstatat(AT_FDCWD, "ISO-8859-9E.gz", {st_mode=S_IFREG|0644,
> st_size=3023, ...}, AT_SYMLINK_NOFOLLOW) = 0
> newfstatat(AT_FDCWD, "MSZ_7795.3.gz", {st_mode=S_IFREG|0644,
> st_size=1559, ...}, AT_SYMLINK_NOFOLLOW) = 0
> newfstatat(AT_FDCWD, "HP-ROMAN8.gz", {st_mode=S_IFREG|0644,
> st_size=3193, ...}, AT_SYMLINK_NOFOLLOW) = 0
> newfstatat(AT_FDCWD, "ISO-8859-7.gz", {st_mode=S_IFREG|0644,
> st_size=3074, ...}, AT_SYMLINK_NOFOLLOW) = 0
> newfstatat(AT_FDCWD, "DEC-MCS.gz", {st_mode=S_IFREG|0644,
> st_size=2948, ...}, AT_SYMLINK_NOFOLLOW) = 0
>
>
>
> HTH
> Greg
>

Mohit,

Here's some more precise info as you asked in a PM.

I'm testing with openSUSE 11.4 which is a pretty current release.

It's a 64-bit machine / OS.  I suspect that's important in exactly
which stat() call is used by find.

The exact command I running is
> sudo strace find /usr -inum 100 2> /tmp/strace.out

I assume you know 2> will redirect stderr.  So all of the strace
prints go to my tmp file.

Then I wait about 10 or 20 seconds and do a control-c.  That way the
search is killed in the middle and the last part of strace.out is
relative to the search part, not just some termination logic.

Then looking at /tmp/strace.out and pulling out what looks to a be
logically important chunk from the end of the file I have:

<snip a bunch of stuff.  pick up in what appears to be a directory scan>
newfstatat(AT_FDCWD, "gnome-dev-disc-dvdrw.png",
{st_mode=S_IFLNK|0777, st_size=17, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "media-floppy.png", {st_mode=S_IFREG|0644,
st_size=836, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "computer.png", {st_mode=S_IFREG|0644,
st_size=2065, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "cdrom_unmount.png", {st_mode=S_IFLNK|0777,
st_size=17, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "printer-remote.png", {st_mode=S_IFLNK|0777,
st_size=11, ...}, AT_SYMLINK_NOFOLLOW) = 0

### MY NOTE: DIRECTORY DONE. MOVE BACK TO PARENT DIR
open("..", O_RDONLY|O_NOFOLLOW)         = 4
fchdir(4)                               = 0
close(4)                                = 0

### MY NOTE: OPEN THE NEXT DIRECTORY SO IT CAN BE CRAWLED
newfstatat(AT_FDCWD, "categories", {st_mode=S_IFDIR|0755,
st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
open("categories", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 4

### MY NOTE: GET THE CONTENTS OF THE DIRECTORY
getdents64(4, /* 62 entries */, 32768)  = 2712
getdents64(4, /* 0 entries */, 32768)   = 0
close(4)                                = 0
open("categories", O_RDONLY|O_NOFOLLOW) = 4
fchdir(4)                               = 0
close(4)                                = 0
stat(".", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0

### MY NOTE: START CALLING newfstatat() on every file in the directory
newfstatat(AT_FDCWD, "xfce-utils.png", {st_mode=S_IFLNK|0777,
st_size=28, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "package_system.png", {st_mode=S_IFLNK|0777,
st_size=23, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "xfce-system-settings.png",
{st_mode=S_IFLNK|0777, st_size=22, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "applications-utilities.png",
{st_mode=S_IFREG|0644, st_size=1858, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "redhat-sound_video.png", {st_mode=S_IFLNK|0777,
st_size=27, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "preferences-desktop-peripherals.png",
{st_mode=S_IFREG|0644, st_size=2355, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "package_settings.png", {st_mode=S_IFLNK|0777,
st_size=22, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "package_games.png", {st_mode=S_IFLNK|0777,
st_size=22, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "applications-multimedia.png",
{st_mode=S_IFREG|0644, st_size=3129, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "preferences-other.png", {st_mode=S_IFREG|0644,
st_size=2355, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "applications-science.png",
{st_mode=S_IFREG|0644, st_size=2065, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "package_multimedia.png", {st_mode=S_IFLNK|0777,
st_size=27, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "applications-graphics.png",
{st_mode=S_IFREG|0644, st_size=1740, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "gnome-devel.png", {st_mode=S_IFLNK|0777,
st_size=28, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "gnome-settings.png", {st_mode=S_IFLNK|0777,
st_size=23, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "gnome-joystick.png", {st_mode=S_IFLNK|0777,
st_size=22, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "gnome-multimedia.png", {st_mode=S_IFLNK|0777,
st_size=27, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "applications-development.png",
{st_mode=S_IFREG|0644, st_size=1717, ...}, AT_SYMLINK_NOFOLLOW) =

I can't say I've ever seen newfstatat() before but based on a little
googling it seems to be a version of fstat which is natively 64-bit.

Good Luck
Greg



More information about the Kernelnewbies mailing list