projects
/
firefly-linux-kernel-4.4.55.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
SUNRPC: RPC client should retry with different versions of rpcbind
[firefly-linux-kernel-4.4.55.git]
/
fs
/
dcache.c
diff --git
a/fs/dcache.c
b/fs/dcache.c
index a1ff91eef10810c50583962ae671f07e14737bf6..d68631f18df122824a0d36a307c647f15931c7bd 100644
(file)
--- a/
fs/dcache.c
+++ b/
fs/dcache.c
@@
-43,7
+43,7
@@
static __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock);
EXPORT_SYMBOL(dcache_lock);
EXPORT_SYMBOL(dcache_lock);
-static
kmem_cache_t
*dentry_cache __read_mostly;
+static
struct kmem_cache
*dentry_cache __read_mostly;
#define DNAME_INLINE_LEN (sizeof(struct dentry)-offsetof(struct dentry,d_iname))
#define DNAME_INLINE_LEN (sizeof(struct dentry)-offsetof(struct dentry,d_iname))
@@
-68,15
+68,19
@@
struct dentry_stat_t dentry_stat = {
.age_limit = 45,
};
.age_limit = 45,
};
-static void
d_callback(struct rcu_head *head
)
+static void
__d_free(struct dentry *dentry
)
{
{
- struct dentry * dentry = container_of(head, struct dentry, d_u.d_rcu);
-
if (dname_external(dentry))
kfree(dentry->d_name.name);
kmem_cache_free(dentry_cache, dentry);
}
if (dname_external(dentry))
kfree(dentry->d_name.name);
kmem_cache_free(dentry_cache, dentry);
}
+static void d_callback(struct rcu_head *head)
+{
+ struct dentry * dentry = container_of(head, struct dentry, d_u.d_rcu);
+ __d_free(dentry);
+}
+
/*
* no dcache_lock, please. The caller must decrement dentry_stat.nr_dentry
* inside dcache_lock.
/*
* no dcache_lock, please. The caller must decrement dentry_stat.nr_dentry
* inside dcache_lock.
@@
-85,7
+89,11
@@
static void d_free(struct dentry *dentry)
{
if (dentry->d_op && dentry->d_op->d_release)
dentry->d_op->d_release(dentry);
{
if (dentry->d_op && dentry->d_op->d_release)
dentry->d_op->d_release(dentry);
- call_rcu(&dentry->d_u.d_rcu, d_callback);
+ /* if dentry was never inserted into hash, immediate free is OK */
+ if (dentry->d_hash.pprev == NULL)
+ __d_free(dentry);
+ else
+ call_rcu(&dentry->d_u.d_rcu, d_callback);
}
/*
}
/*
@@
-478,11
+486,12
@@
static void prune_dcache(int count, struct super_block *sb)
up_read(s_umount);
}
spin_unlock(&dentry->d_lock);
up_read(s_umount);
}
spin_unlock(&dentry->d_lock);
- /*
Cannot remove the first dentry, and it isn't appropriate
- *
to move it to the head of the list, so give up, and try
- *
later
+ /*
+ *
Insert dentry at the head of the list as inserting at the
+ *
tail leads to a cycle.
*/
*/
- break;
+ list_add(&dentry->d_lru, &dentry_unused);
+ dentry_stat.nr_unused++;
}
spin_unlock(&dcache_lock);
}
}
spin_unlock(&dcache_lock);
}
@@
-556,6
+565,7
@@
repeat:
static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
{
struct dentry *parent;
static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
{
struct dentry *parent;
+ unsigned detached = 0;
BUG_ON(!IS_ROOT(dentry));
BUG_ON(!IS_ROOT(dentry));
@@
-620,7
+630,7
@@
static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
atomic_dec(&parent->d_count);
list_del(&dentry->d_u.d_child);
atomic_dec(&parent->d_count);
list_del(&dentry->d_u.d_child);
- de
ntry_stat.nr_dentry--; /* For d_free, below */
+ de
tached++;
inode = dentry->d_inode;
if (inode) {
inode = dentry->d_inode;
if (inode) {
@@
-638,7
+648,7
@@
static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
* otherwise we ascend to the parent and move to the
* next sibling if there is one */
if (!parent)
* otherwise we ascend to the parent and move to the
* next sibling if there is one */
if (!parent)
-
return
;
+
goto out
;
dentry = parent;
dentry = parent;
@@
-647,6
+657,11
@@
static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
dentry = list_entry(dentry->d_subdirs.next,
struct dentry, d_u.d_child);
}
dentry = list_entry(dentry->d_subdirs.next,
struct dentry, d_u.d_child);
}
+out:
+ /* several dentries were freed, need to correct nr_dentry */
+ spin_lock(&dcache_lock);
+ dentry_stat.nr_dentry -= detached;
+ spin_unlock(&dcache_lock);
}
/*
}
/*
@@
-2065,10
+2080,10
@@
static void __init dcache_init(unsigned long mempages)
}
/* SLAB cache for __getname() consumers */
}
/* SLAB cache for __getname() consumers */
-
kmem_cache_t
*names_cachep __read_mostly;
+
struct kmem_cache
*names_cachep __read_mostly;
/* SLAB cache for file structures */
/* SLAB cache for file structures */
-
kmem_cache_t
*filp_cachep __read_mostly;
+
struct kmem_cache
*filp_cachep __read_mostly;
EXPORT_SYMBOL(d_genocide);
EXPORT_SYMBOL(d_genocide);