Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 8: The Virtual Filesystem


Recall that the hash table is implemented in keeping with the classical pattern. The functiond_hashfrom
fs/dcache.cis used to determine the hash position of adentryobject.

Handling of the LRU list is a bit trickier. The list is headed by the global variabledentry_unused,andthe
objects it contains are linked by thed_lruelement ofstruct dentry.

dentryobjects are placed on the LRU list when their usage counter (d_count) has reached 0 — this
indicates that no application is actively using the object. New entries are always placed at the beginning
of the list. In other words, the further back an entry is in the list, the older it is — the classic LRU principle.
Theprune_dcachefunction is invoked from time to time, for instance, when a filesystem is unmounted
or when the kernel needs more memory. Old objects are removed and memory is freed. Note that it can
temporarily happen thatdentryobjects are on the unused list although they are in active use and their
usage count is bigger than zero. This is because the kernel does some optimizations: When adentrythat
was on the unused list comes back into use, it is not immediately taken off the unused list since this saves
some locking and thus increases performance. Operations likeprune_dcache, which are costly anyway,
make up for this: When they encounter an object with positive usage count, they just remove it from the
list, but do not free it.

Because LRU list objects are still simultaneously present in the hash table, they can be found by lookup
operations searching for the entry they represent. Once an entry is found, the object is removed from the
LRU list because it is now in active use. The usage counter is also incremented.

Filesystem Operations


Thedentry_operationsstructure holds function pointers to various filesystem-specific operations that
can be performed ondentryobjects. The structure is defined as follows:

<dcache.h>
struct dentry_operations {
int (*d_revalidate)(struct dentry *, struct nameidata *);
int (*d_hash) (struct dentry *, struct qstr *);
int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
int (*d_delete)(struct dentry *);
void (*d_release)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
char *(*d_dname)(struct dentry *, char *, int);
};

❑ d_iputreleases an inode from adentryobject no longer in use (in the default implementation,
the usage counter is decremented, and the inode is removed from the various lists once the
counter reaches 0).

❑ d_deleteis invoked after the last reference has been removed (whend_countreaches 0).

❑ d_releaseis invoked before adentryobject is finally deleted. The two default implementations
ford_releaseandd_deletedo nothing.

❑ d_hashcalculates hash values that can be used to place objects in the dentry hash table.

❑ d_comparecompares the filenames of twodentrys. Whereas VFS performs a simple string com-
parison, filesystems can override this behavior to suit their own requirements. For example, the
filenames in the FAT implementation are not case-sensitive. As no distinction is made between
Free download pdf