{
if (dentry->d_op && dentry->d_op->d_release)
dentry->d_op->d_release(dentry);
+ if (dentry->d_extra_attributes) {
+ kfree(dentry->d_extra_attributes);
+ dentry->d_extra_attributes = NULL;
+ }
call_rcu(&dentry->d_rcu, d_callback);
}
struct dentry *this = hlist_entry(lp, struct dentry, d_hash);
if (!list_empty(&this->d_lru)) {
dentry_stat.nr_unused--;
- list_del(&this->d_lru);
+ list_del_init(&this->d_lru);
}
/*
dentry->d_sb = NULL;
dentry->d_op = NULL;
dentry->d_fsdata = NULL;
+ dentry->d_extra_attributes = NULL;
dentry->d_mounted = 0;
dentry->d_cookie = NULL;
dentry->d_bucket = NULL;
/* Unhash the target: dput() will then get rid of it */
__d_drop(target);
+ /* flush any possible attributes */
+ if (dentry->d_extra_attributes) {
+ kfree(dentry->d_extra_attributes);
+ dentry->d_extra_attributes = NULL;
+ }
+ if (target->d_extra_attributes) {
+ kfree(target->d_extra_attributes);
+ target->d_extra_attributes = NULL;
+ }
+
list_del(&dentry->d_child);
list_del(&target->d_child);
*
* "buflen" should be positive. Caller holds the dcache_lock.
*/
-static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
+char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
struct dentry *root, struct vfsmount *rootmnt,
char *buffer, int buflen)
{
return ERR_PTR(-ENAMETOOLONG);
}
+EXPORT_SYMBOL_GPL(__d_path);
+
/* write full pathname into buffer and return start of pathname */
char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
char *buf, int buflen)
INIT_HLIST_HEAD(&dentry_hashtable[loop]);
}
+void flush_dentry_attributes (void)
+{
+ struct hlist_node *tmp;
+ struct dentry *dentry;
+ int i;
+
+ spin_lock(&dcache_lock);
+ for (i = 0; i <= d_hash_mask; i++)
+ hlist_for_each_entry(dentry, tmp, dentry_hashtable+i, d_hash) {
+ kfree(dentry->d_extra_attributes);
+ dentry->d_extra_attributes = NULL;
+ }
+ spin_unlock(&dcache_lock);
+}
+
+EXPORT_SYMBOL_GPL(flush_dentry_attributes);
+
static void __init dcache_init(unsigned long mempages)
{
/*