patch-2.3.99-pre4 linux/fs/dcache.c
Next file: linux/fs/devfs/base.c
Previous file: linux/fs/bad_inode.c
Back to the patch index
Back to the overall index
- Lines: 393
- Date:
Sun Apr 2 15:54:44 2000
- Orig file:
v2.3.99-pre3/linux/fs/dcache.c
- Orig date:
Mon Mar 27 08:08:29 2000
diff -u --recursive --new-file v2.3.99-pre3/linux/fs/dcache.c linux/fs/dcache.c
@@ -30,11 +30,6 @@
/* Right now the dcache depends on the kernel lock */
#define check_lock() if (!kernel_locked()) BUG()
-/* For managing the dcache */
-extern unsigned long num_physpages, page_cache_size;
-extern int inodes_stat[];
-#define nr_inodes (inodes_stat[0])
-
kmem_cache_t *dentry_cache;
/*
@@ -87,8 +82,8 @@
}
}
-/*
- * dput()
+/*
+ * dput
*
* This is complicated by the fact that we do not want to put
* dentries that are no longer on any hash chain on the unused
@@ -103,6 +98,17 @@
* on the compiler to always get this right (gcc generally doesn't).
* Real recursion would eat up our stack space.
*/
+
+/*
+ * dput - release a dentry
+ * @dentry: dentry to release
+ *
+ * Release a dentry. This will drop the usage count and if appropriate
+ * call the dentry unlink method as well as removing it from the queues and
+ * releasing its resources. If the parent dentries were scheduled for release
+ * they too may now get deleted.
+ */
+
void dput(struct dentry *dentry)
{
int count;
@@ -166,11 +172,16 @@
BUG();
}
-/*
+/**
+ * d_invalidate - invalidate a dentry
+ * @dentry: dentry to invalidate
+ *
* Try to invalidate the dentry if it turns out to be
* possible. If there are other dentries that can be
- * reached through this one we can't delete it.
+ * reached through this one we can't delete it and we
+ * return -EBUSY. On success we return 0.
*/
+
int d_invalidate(struct dentry * dentry)
{
check_lock();
@@ -225,12 +236,19 @@
dput(parent);
}
-/*
+/**
+ * prune_dcache - shrink the dcache
+ * @count: number of entries to try and free
+ *
* Shrink the dcache. This is done when we need
* more memory, or simply when we need to unmount
* something (at which point we need to unuse
* all dentries).
+ *
+ * This function may fail to free any resources if
+ * all the dentries are in use.
*/
+
void prune_dcache(int count)
{
check_lock();
@@ -264,6 +282,16 @@
* each dput(), but since the target dentries are all at
* the end, it's really just a single traversal.
*/
+
+/**
+ * shrink_dcache_sb - shrink dcache for a superblock
+ * @sb: superblock
+ *
+ * Shrink the dcache for the specified super block. This
+ * is used to free the dcache before unmounting a file
+ * system
+ */
+
void shrink_dcache_sb(struct super_block * sb)
{
struct list_head *tmp, *next;
@@ -307,11 +335,17 @@
}
}
-/*
+/**
+ * is_root_busy - check if a root dentry could be freed
+ * @root: Dentry to work down from
+ *
* Check whether a root dentry would be in use if all of its
* child dentries were freed. This allows a non-destructive
* test for unmounting a device.
+ *
+ * Return non zero if the root is still busy.
*/
+
int is_root_busy(struct dentry *root)
{
struct dentry *this_parent = root;
@@ -353,12 +387,21 @@
* We descend to the next level whenever the d_subdirs
* list is non-empty and continue searching.
*/
+
+/**
+ * have_submounts - check for mounts over a dentry
+ * @parent: dentry to check.
+ *
+ * Return true if the parent or its subdirectories contain
+ * a mount point
+ */
+
int have_submounts(struct dentry *parent)
{
struct dentry *this_parent = parent;
struct list_head *next;
- if (parent->d_mounts != parent)
+ if (d_mountpoint(parent))
return 1;
repeat:
next = this_parent->d_subdirs.next;
@@ -368,7 +411,7 @@
struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
next = tmp->next;
/* Have we found a mount point ? */
- if (dentry->d_mounts != dentry)
+ if (d_mountpoint(dentry))
return 1;
if (!list_empty(&dentry->d_subdirs)) {
this_parent = dentry;
@@ -440,9 +483,13 @@
return found;
}
-/*
+/**
+ * shrink_dcache_parent - prune dcache
+ * @parent: parent of entries to prune
+ *
* Prune the dcache to remove unused children of the parent dentry.
*/
+
void shrink_dcache_parent(struct dentry * parent)
{
int found;
@@ -482,6 +529,16 @@
#define NAME_ALLOC_LEN(len) ((len+16) & ~15)
+/**
+ * d_alloc - allocate a dcache entry
+ * @parent: parent of entry to allocate
+ * @name: qstr of the name
+ *
+ * Allocates a dentry. It returns NULL if there is insufficient memory
+ * available. On a success the dentry is returned. The name passed in is
+ * copied and the copy passed in may be reused after this call.
+ */
+
struct dentry * d_alloc(struct dentry * parent, const struct qstr *name)
{
char * str;
@@ -530,7 +587,11 @@
return dentry;
}
-/*
+/**
+ * d_instantiate - fill in inode information for a dentry
+ * @entry: dentry to complete
+ * @inode: inode to attacheto this dentry
+ *
* Fill in inode information in the entry.
*
* This turns negative dentries into productive full members
@@ -540,6 +601,7 @@
* (or otherwise set) by the caller to indicate that it is now
* in use by the dcache..
*/
+
void d_instantiate(struct dentry *entry, struct inode * inode)
{
if (inode)
@@ -547,6 +609,15 @@
entry->d_inode = inode;
}
+/**
+ * d_alloc_root - allocate root dentry
+ * @root_inode: inode to allocate the root for
+ *
+ * Allocate a root ('/') dentry for the inode given. The inode is
+ * instantiated and returned. NULL is returned if there is insufficient
+ * memory or the inode passed is NULL.
+ */
+
struct dentry * d_alloc_root(struct inode * root_inode)
{
struct dentry *res = NULL;
@@ -569,6 +640,17 @@
return dentry_hashtable + (hash & D_HASHMASK);
}
+/**
+ * d_lookup - search for a dentry
+ * @parent: parent dentry
+ * @name: qstr of name we wish to find
+ *
+ * Searches the children of the parent dentry for the name in question. If
+ * the dentry is found its reference count is incremented and the dentry
+ * is returned. The caller must use d_put to free the entry when it has
+ * finished using it. NULL is returned on failure.
+ */
+
struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
{
unsigned int len = name->len;
@@ -602,16 +684,23 @@
return NULL;
}
-/*
- * An insecure source has sent us a dentry, here we verify it.
+/**
+ * d_validate - verify dentry provided from insecure source
+ * @dentry: The dentry alleged to be valid
+ * @dparent: The parent dentry
+ * @hash: Hash of the dentry
+ * @len: Length of the name
*
+ * An insecure source has sent us a dentry, here we verify it.
* This is used by ncpfs in its readdir implementation.
+ * Zero is returned in the dentry is invalid.
*
- * NOTE! Do _not_ dereference the pointers before we have
+ * NOTE: This function does _not_ dereference the pointers before we have
* validated them. We can test the pointer values, but we
* must not actually use them until we have found a valid
* copy of the pointer in kernel space..
*/
+
int d_validate(struct dentry *dentry, struct dentry *dparent,
unsigned int hash, unsigned int len)
{
@@ -659,12 +748,19 @@
* it from the hash queues and waiting for
* it to be deleted later when it has no users
*/
+
+/**
+ * d_delete - delete a dentry
+ * @dentry: The dentry to delete
+ *
+ * Turn the dentry into a negative dentry if possible, otherwise
+ * remove it from the hash queues so it can be deleted later
+ */
+
void d_delete(struct dentry * dentry)
{
check_lock();
- check_lock();
-
/*
* Are we the only user?
*/
@@ -680,6 +776,13 @@
d_drop(dentry);
}
+/**
+ * d_rehash - add an entry back to the hash
+ * @entry: dentry to add to the hash
+ *
+ * Adds a dentry to the hash according to its name
+ */
+
void d_rehash(struct dentry * entry)
{
struct dentry * parent = entry->d_parent;
@@ -733,6 +836,16 @@
* the fact that any list-entry can be a head of the list.
* Think about it.
*/
+
+/**
+ * d_move - move a dentry
+ * @dentry: entry to move
+ * @target: new dentry
+ *
+ * Update the dcache to reflect the move of a file name. Negative
+ * dcache entries should not be moved in this way.
+ */
+
void d_move(struct dentry * dentry, struct dentry * target)
{
check_lock();
@@ -762,14 +875,24 @@
list_add(&dentry->d_child, &dentry->d_parent->d_subdirs);
}
-/*
+/**
+ * d_path - return the path of a dentry
+ * @dentry: dentry to report
+ * @buffer: buffer to return value in
+ * @buflen: buffer length
+ *
+ * Convert a dentry into an ascii path name. If the entry has been deleted
+ * the string ' (deleted)' is appended. Note that this is ambiguous. Returns
+ * the buffer.
+ *
* "buflen" should be PAGE_SIZE or more.
*/
-char * d_path(struct dentry *dentry, char *buffer, int buflen)
+char * __d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
+ struct dentry *root, struct vfsmount *rootmnt,
+ char *buffer, int buflen)
{
char * end = buffer+buflen;
char * retval;
- struct dentry * root = current->fs->root;
*--end = '\0';
buflen--;
@@ -839,7 +962,7 @@
char * cwd;
lock_kernel();
- cwd = d_path(pwd, page, PAGE_SIZE);
+ cwd = d_path(pwd, current->fs->pwdmnt, page, PAGE_SIZE);
unlock_kernel();
error = -ERANGE;
@@ -860,6 +983,16 @@
*
* Trivially implemented using the dcache structure
*/
+
+/**
+ * is_subdir - is new dentry a subdirectory of old_dentry
+ * @new_dentry: new dentry
+ * @old_dentry: old dentry
+ *
+ * Returns 1 if new_dentry is a subdirectory of the parent (at any depth).
+ * Returns 0 otherwise.
+ */
+
int is_subdir(struct dentry * new_dentry, struct dentry * old_dentry)
{
int result;
@@ -879,14 +1012,20 @@
return result;
}
-/*
+/**
+ * find_inode_number - check for dentry with name
+ * @dir: directory to check
+ * @name: Name to find.
+ *
* Check whether a dentry already exists for the given name,
- * and return the inode number if it has an inode.
+ * and return the inode number if it has an inode. Otherwise
+ * 0 is returned.
*
* This routine is used to post-process directory listings for
* filesystems using synthetic inode numbers, and is necessary
* to keep getcwd() working.
*/
+
ino_t find_inode_number(struct dentry *dir, struct qstr *name)
{
struct dentry * dentry;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)