#include <linux/syscalls.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/fdtable.h>
#include <linux/fs.h>
#include <linux/fsnotify.h>
#include <linux/slab.h>
#include <linux/swap.h>
#include <linux/bootmem.h>
#include <linux/fs_struct.h>
+#include <linux/hardirq.h>
#include "internal.h"
int sysctl_vfs_cache_pressure __read_mostly = 100;
if (dentry)
goto repeat;
}
+EXPORT_SYMBOL(dput);
/**
* d_invalidate - invalidate a dentry
spin_unlock(&dcache_lock);
return 0;
}
+EXPORT_SYMBOL(d_invalidate);
/* This should be called _only_ with dcache_lock held */
{
return __dget_locked(dentry);
}
+EXPORT_SYMBOL(dget_locked);
/**
* d_find_alias - grab a hashed alias of inode
}
return de;
}
+EXPORT_SYMBOL(d_find_alias);
/*
* Try to kill dentries associated with this inode.
}
spin_unlock(&dcache_lock);
}
+EXPORT_SYMBOL(d_prune_aliases);
/*
* Throw away a dentry - free the inode, dput the parent. This requires that
if ((flags & DCACHE_REFERENCED)
&& (dentry->d_flags & DCACHE_REFERENCED)) {
dentry->d_flags &= ~DCACHE_REFERENCED;
- list_move_tail(&dentry->d_lru, &referenced);
+ list_move(&dentry->d_lru, &referenced);
spin_unlock(&dentry->d_lock);
} else {
list_move_tail(&dentry->d_lru, &tmp);
{
__shrink_dcache_sb(sb, NULL, 0);
}
+EXPORT_SYMBOL(shrink_dcache_sb);
/*
* destroy a single subtree of dentries for unmount
spin_unlock(&dcache_lock);
return 1;
}
+EXPORT_SYMBOL(have_submounts);
/*
* Search the dentry child list for the specified parent,
while ((found = select_parent(parent)) != 0)
__shrink_dcache_sb(sb, &found, 0);
}
+EXPORT_SYMBOL(shrink_dcache_parent);
/*
* Scan `nr' dentries and return the number which remain.
return dentry;
}
+EXPORT_SYMBOL(d_alloc);
struct dentry *d_alloc_name(struct dentry *parent, const char *name)
{
q.hash = full_name_hash(q.name, q.len);
return d_alloc(parent, &q);
}
+EXPORT_SYMBOL(d_alloc_name);
/* the caller must hold dcache_lock */
static void __d_instantiate(struct dentry *dentry, struct inode *inode)
spin_unlock(&dcache_lock);
security_d_instantiate(entry, inode);
}
+EXPORT_SYMBOL(d_instantiate);
/**
* d_instantiate_unique - instantiate a non-aliased dentry
}
return res;
}
+EXPORT_SYMBOL(d_alloc_root);
static inline struct hlist_head *d_hash(struct dentry *parent,
unsigned long hash)
BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED));
spin_unlock(&dcache_lock);
security_d_instantiate(new, inode);
- d_rehash(dentry);
d_move(new, dentry);
iput(inode);
} else {
d_add(dentry, inode);
return new;
}
+EXPORT_SYMBOL(d_splice_alias);
/**
* d_add_ci - lookup or allocate new dentry with case-exact name
iput(inode);
return ERR_PTR(error);
}
+EXPORT_SYMBOL(d_add_ci);
/**
* d_lookup - search for a dentry
} while (read_seqretry(&rename_lock, seq));
return dentry;
}
+EXPORT_SYMBOL(d_lookup);
struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
{
out:
return 0;
}
+EXPORT_SYMBOL(d_validate);
/*
* When a file is deleted, we have two options:
fsnotify_nameremove(dentry, isdir);
}
+EXPORT_SYMBOL(d_delete);
static void __d_rehash(struct dentry * entry, struct hlist_head *list)
{
spin_unlock(&entry->d_lock);
spin_unlock(&dcache_lock);
}
+EXPORT_SYMBOL(d_rehash);
/*
* When switching names, the actual string doesn't strictly have to
d_move_locked(dentry, target);
spin_unlock(&dcache_lock);
}
+EXPORT_SYMBOL(d_move);
/**
* d_ancestor - search for an ancestor
spin_unlock(&dcache_lock);
BUG();
}
+EXPORT_SYMBOL_GPL(d_materialise_unique);
static int prepend(char **buffer, int *buflen, const char *str, int namelen)
{
spin_lock(&vfsmount_lock);
prepend(&end, &buflen, "\0", 1);
- if (!IS_ROOT(dentry) && d_unhashed(dentry) &&
+ if (d_unlinked(dentry) &&
(prepend(&end, &buflen, " (deleted)", 10) != 0))
goto Elong;
path_put(&root);
return res;
}
+EXPORT_SYMBOL(d_path);
/*
* Helper function for dentry_operations.d_dname() members
spin_lock(&dcache_lock);
prepend(&end, &buflen, "\0", 1);
- if (!IS_ROOT(dentry) && d_unhashed(dentry) &&
+ if (d_unlinked(dentry) &&
(prepend(&end, &buflen, "//deleted", 9) != 0))
goto Elong;
if (buflen < 1)
read_unlock(¤t->fs->lock);
error = -ENOENT;
- /* Has the current directory has been unlinked? */
spin_lock(&dcache_lock);
- if (IS_ROOT(pwd.dentry) || !d_unhashed(pwd.dentry)) {
+ if (!d_unlinked(pwd.dentry)) {
unsigned long len;
struct path tmp = root;
char * cwd;
int result;
unsigned long seq;
- /* FIXME: This is old behavior, needed? Please check callers. */
if (new_dentry == old_dentry)
return 1;
return result;
}
+int path_is_under(struct path *path1, struct path *path2)
+{
+ struct vfsmount *mnt = path1->mnt;
+ struct dentry *dentry = path1->dentry;
+ int res;
+ spin_lock(&vfsmount_lock);
+ if (mnt != path2->mnt) {
+ for (;;) {
+ if (mnt->mnt_parent == mnt) {
+ spin_unlock(&vfsmount_lock);
+ return 0;
+ }
+ if (mnt->mnt_parent == path2->mnt)
+ break;
+ mnt = mnt->mnt_parent;
+ }
+ dentry = mnt->mnt_mountpoint;
+ }
+ res = is_subdir(dentry, path2->dentry);
+ spin_unlock(&vfsmount_lock);
+ return res;
+}
+EXPORT_SYMBOL(path_is_under);
+
void d_genocide(struct dentry *root)
{
struct dentry *this_parent = root;
}
return ino;
}
+EXPORT_SYMBOL(find_inode_number);
static __initdata unsigned long dhash_entries;
static int __init set_dhash_entries(char *str)
/* SLAB cache for __getname() consumers */
struct kmem_cache *names_cachep __read_mostly;
+EXPORT_SYMBOL(names_cachep);
EXPORT_SYMBOL(d_genocide);
bdev_cache_init();
chrdev_init();
}
-
-EXPORT_SYMBOL(d_alloc);
-EXPORT_SYMBOL(d_alloc_root);
-EXPORT_SYMBOL(d_delete);
-EXPORT_SYMBOL(d_find_alias);
-EXPORT_SYMBOL(d_instantiate);
-EXPORT_SYMBOL(d_invalidate);
-EXPORT_SYMBOL(d_lookup);
-EXPORT_SYMBOL(d_move);
-EXPORT_SYMBOL_GPL(d_materialise_unique);
-EXPORT_SYMBOL(d_path);
-EXPORT_SYMBOL(d_prune_aliases);
-EXPORT_SYMBOL(d_rehash);
-EXPORT_SYMBOL(d_splice_alias);
-EXPORT_SYMBOL(d_add_ci);
-EXPORT_SYMBOL(d_validate);
-EXPORT_SYMBOL(dget_locked);
-EXPORT_SYMBOL(dput);
-EXPORT_SYMBOL(find_inode_number);
-EXPORT_SYMBOL(have_submounts);
-EXPORT_SYMBOL(names_cachep);
-EXPORT_SYMBOL(shrink_dcache_parent);
-EXPORT_SYMBOL(shrink_dcache_sb);