[PATCH v3 23/24] dcache: Copy documentation to struct declaration

From: Tobin C. Harding
Date: Wed Mar 27 2019 - 01:20:16 EST


Currently the documentation for the struct dentry is located
in Documentation/filesystems/vfs.txt. Having documentation far away
from the code increases the chance of docs getting stale. This is
exactly what has happened, currently docs reference the 2.6.22 kernel.

The kernel has a mechanism for documenting structures in the
source/header files, we should use it. This makes reading arguable
easier because documentation is right there with the source and also
helps prevent the docs from getting stale.

Copy documentation for struct dentry from vfs.txt and locate it with
the struct declaration. Use kernel docs in preparation for including
the struct docs into the soon to be created vfs.rst

To ease review this patch does not touch vfs.txt, this file will be
converted to RST format shortly.

Cc: Jani Nikula <jani.nikula@xxxxxxxxxxxxxxx>
Cc: Jonathan Corbet <corbet@xxxxxxx>
Signed-off-by: Tobin C. Harding <tobin@xxxxxxxxxx>
---
include/linux/dcache.h | 177 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 177 insertions(+)

diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 0643c5127e1a..442bba9dcec8 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -130,20 +130,197 @@ enum dentry_d_lock_class
DENTRY_D_LOCK_NESTED
};

+/**
+ * struct dentry_operations - Describe how a filesystem can overload the
+ * standard dentry operations.
+ *
+ * Dentries and the dcache are the domain of the VFS and the individual
+ * filesystem implementations. Device drivers have no business here.
+ * These methods may be set to %NULL, as they are either optional or the
+ * VFS uses a default.
+ *
+ * Each dentry has a pointer to its parent dentry, as well as a hash
+ * list of child dentries. Child dentries are basically like files in a
+ * directory.
+ */
struct dentry_operations {
+ /**
+ * @d_revalidate: Called when the VFS needs to revalidate a
+ * dentry. This is called whenever a name look-up finds a
+ * dentry in the dcache. Most local filesystems leave this as
+ * %NULL, because all their dentries in the dcache are valid.
+ * Network filesystems are different since things can change on
+ * the server without the client necessarily being aware of it.
+ *
+ * This function should return a positive value if the dentry is
+ * still valid, and zero or a negative error code if it isn't.
+ *
+ * d_revalidate may be called in rcu-walk mode (flags &
+ * LOOKUP_RCU). If in rcu-walk mode, the filesystem must
+ * revalidate the dentry without blocking or storing to the
+ * dentry, d_parent and d_inode should not be used without care
+ * (because they can change and, in d_inode case, even become
+ * %NULL under us).
+ *
+ * If a situation is encountered that rcu-walk
+ * cannot handle, return -ECHILD and it will be called again
+ * in ref-walk mode.
+ */
int (*d_revalidate)(struct dentry *, unsigned int);
+
+ /**
+ * @d_weak_revalidate: Called when the VFS needs to revalidate a
+ * "jumped" dentry. This is called when a path-walk ends at
+ * dentry that was not acquired by doing a lookup in the parent
+ * directory. This includes "/", "." and "..", as well as
+ * procfs-style symlinks and mountpoint traversal.
+ *
+ * In this case, we are less concerned with whether the dentry
+ * is still fully correct, but rather that the inode is still
+ * valid. As with d_revalidate, most local filesystems will set
+ * this to %NULL since their dcache entries are always valid.
+ *
+ * This function has the same return code semantics as
+ * d_revalidate.
+ *
+ * d_weak_revalidate is only called after leaving rcu-walk mode.
+ */
int (*d_weak_revalidate)(struct dentry *, unsigned int);
+
+ /**
+ * @d_hash: Called when the VFS adds a dentry to the hash table.
+ * The first dentry passed to d_hash is the parent directory
+ * that the name is to be hashed into.
+ *
+ * Same locking and synchronisation rules as d_compare regarding
+ * what is safe to dereference etc.
+ */
int (*d_hash)(const struct dentry *, struct qstr *);
+
+ /**
+ * @d_compare: Called to compare a dentry name with a given name. The first
+ * dentry is the parent of the dentry to be compared, the second is
+ * the child dentry. len and name string are properties of the dentry
+ * to be compared. qstr is the name to compare it with.
+ *
+ * Must be constant and idempotent, and should not take locks if
+ * possible, and should not or store into the dentry.
+ * Should not dereference pointers outside the dentry without
+ * lots of care (eg. d_parent, d_inode, d_name should not be used).
+ *
+ * However, our vfsmount is pinned, and RCU held, so the dentries and
+ * inodes won't disappear, neither will our sb or filesystem module.
+ * ->d_sb may be used.
+ *
+ * It is a tricky calling convention because it needs to be called under
+ * "rcu-walk", ie. without any locks or references on things.
+ */
int (*d_compare)(const struct dentry *,
unsigned int, const char *, const struct qstr *);
+
+ /**
+ * @d_delete: Called when the last reference to a dentry is
+ * dropped and the dcache is deciding whether or not to cache
+ * it. Return 1 to delete immediately, or 0 to cache the
+ * dentry. Default is %NULL which means to always cache a
+ * reachable dentry. d_delete() must be constant and idempotent.
+ */
int (*d_delete)(const struct dentry *);
+
+ /**
+ * @d_init: Called when a dentry is allocated.
+ */
int (*d_init)(struct dentry *);
+
+ /**
+ * @d_release: Called when a dentry is really deallocated.
+ */
void (*d_release)(struct dentry *);
+
+ /**
+ * @d_prune: Called by the VFS to inform the fs that this dentry
+ * is about to be unhashed and destroyed.
+ */
void (*d_prune)(struct dentry *);
+
+ /**
+ * @d_iput: Called when a dentry loses its inode (just prior to
+ * its being deallocated). The default when this is %NULL is
+ * that the VFS calls iput(). If you define this method, you
+ * must call iput() yourself.
+ */
void (*d_iput)(struct dentry *, struct inode *);
+
+ /**
+ * @d_dname: Called when the pathname of a dentry should be
+ * generated. Useful for some pseudo filesystems (sockfs,
+ * pipefs, ...) to delay pathname generation. (Instead of doing
+ * it when dentry is created, it's done only when the path is
+ * needed.). Real filesystems probably dont want to use it,
+ * because their dentries are present in global dcache hash, so
+ * their hash should be an invariant. As no lock is held,
+ * d_dname() should not try to modify the dentry itself, unless
+ * appropriate SMP safety is used. CAUTION : d_path() logic is
+ * quite tricky. The correct way to return for example "Hello"
+ * is to put it at the end of the buffer, and returns a pointer
+ * to the first char. dynamic_dname() helper function is
+ * provided to take care of this. (See vfs.rst for an example.)
+ */
char *(*d_dname)(struct dentry *, char *, int);
+
+ /**
+ * @d_automount: Called when an automount dentry is to be
+ * traversed (optional). This should create a new VFS mount
+ * record and return the record to the caller. The caller is
+ * supplied with a path parameter giving the automount directory
+ * to describe the automount target and the parent VFS mount
+ * record to provide inheritable mount parameters. %NULL should
+ * be returned if someone else managed to make the automount
+ * first. If the vfsmount creation failed, then an error code
+ * should be returned. If -EISDIR is returned, then the
+ * directory will be treated as an ordinary directory and
+ * returned to pathwalk to continue walking. If a vfsmount is
+ * returned, the caller will attempt to mount it on the
+ * mountpoint and will remove the vfsmount from its expiration
+ * list in the case of failure. The vfsmount should be returned
+ * with 2 refs on it to prevent automatic expiration - the
+ * caller will clean up the additional ref. This function is
+ * only used if DCACHE_NEED_AUTOMOUNT is set on the dentry.
+ * This is set by __d_instantiate() if S_AUTOMOUNT is set on the
+ * inode being added.
+ */
struct vfsmount *(*d_automount)(struct path *);
+
+ /**
+ * @d_manage: Called to allow the filesystem to manage the
+ * transition from a dentry (optional). This allows autofs, for
+ * example, to hold up clients waiting to explore behind a
+ * 'mountpoint' while letting the daemon go past and construct
+ * the subtree there. 0 should be returned to let the calling
+ * process continue. -EISDIR can be returned to tell pathwalk
+ * to use this directory as an ordinary directory and to ignore
+ * anything mounted on it and not to check the automount flag.
+ * Any other error code will abort pathwalk completely. If the
+ * 'rcu_walk' parameter is true, then the caller is doing a
+ * pathwalk in RCU-walk mode. Sleeping is not permitted in this
+ * mode, and the caller can be asked to leave it and call again
+ * by returning -* ECHILD. -EISDIR may also be returned to tell
+ * pathwalk to ignore d_automount or any mounts. This function
+ * is only used if DCACHE_MANAGE_TRANSIT is set on the dentry
+ * being transited from.
+ */
int (*d_manage)(const struct path *, bool);
+
+ /**
+ * @d_real: overlay/union type filesystems implement this method
+ * to return one of the underlying dentries hidden by the
+ * overlay. It is used in two different modes: Called from
+ * file_dentry() it returns the real dentry matching the inode
+ * argument. The real dentry may be from a lower layer already
+ * copied up, but still referenced from the file. This mode is
+ * selected with a non-NULL inode argument. With %NULL inode
+ * the topmost real underlying dentry is returned.
+ */
struct dentry *(*d_real)(struct dentry *, const struct inode *);
} ____cacheline_aligned;

--
2.21.0