Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 8: The Virtual Filesystem


Implementation ofdo_lookup


do_lookupstarts from a path component and thenameidatainstance with the data of the initial directory
and returns the associated inode.

The kernel first attempts to find the inode in the dentry cache using the__d_lookupfunction described in
Section 8.3.5. Even if a matching element is found, this does not necessarily mean that it is current — the
d_revalidatefunction in thedentry_operationsof the underlying filesystem must be invoked to check
whether it is still valid. If so, it is returned as the result of the cache search. If not, a lookup operation
must be initiated in the low-level filesystem. The same operation is used when no entry is found in the
cache.

real_lookupperforms the filesystem-specific lookup action. Its work involves allocating data structures
in memory (to hold the lookup result) and, above all, invoking the filesystem-specificlookupfunction
made available by the inode operation structureinode_operations.

If the required directory exists, the result received by the kernel is a filleddentryinstance; otherwise, a
null pointer is returned. Note that Chapter 9 describesin greater detail how filesystems perform low-level
lookups.

do_lookupalso needs to take care of following mount points. If a validdentryis found in the cache,
__follow_mounttakes care of this. As discussed in Section 8.4.1, the kernel records the fact that a filesys-
tem is mounted by incrementing thed_mountedstructure element of the associateddentrys. To ensure
that mounting has the desired effect, the kernel musttake this fact into account when traversing the direc-
tory structure. This is done by invoking__follow_mount, whose implementation is surprisingly simple
(thepathstructure used as argument collects the required pointers to thevfsmountanddentryinstances
of the mount point).^22

fs/namei.c
static int __follow_mount(struct path *path)
{
int res = 0;
while (d_mountpoint(path->dentry)) {
struct vfsmount *mounted = lookup_mnt(path->mnt, path->dentry);
if (!mounted)
break;
path->mnt = mounted;
path->dentry = mounted->mnt_root;
res = 1;
}
return res;
}

How does this loop work? A check is first made to ascertain whether the currentdentryinstance is a
mount point. In this context, thed_mountpointmacro need only check whether the value ofd_mounted
is greater than 0. Thelookup_mountfunction extracts thevfsmountinstance of the mounted filesystem
from themount_hashtablediscussed in Section 8.4.1. Themnt_rootfield of the mounted filesystem is
used as the new value for thedentrystructure; all this means is that the root directory of the mounted
filesystem is used as the mount point — and this is exactly what we want to achieve.

(^22) I have omitted the required locking and reference counting operations, which would make the code less readable.

Free download pdf