CephFS inode trimming fix from Zheng, marked for stable.
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQEcBAABCAAGBQJaM/Y/AAoJEEp/3jgCEfOLSu0H/iFhQS+7rnyPcb3P8/YR785H IMPNWv8hg4UU6MDWC3lIliAPypAkaMLuEKOZvBRsLCW5esbOTlCP7w4bmO/YCI66 DF0JfA4AV5yXIVMAtjP2EK3sFz0eCrK6S3XP3cT+x3K5qI6zwNN3Yvj78NFcvCOz IBgxrlhpu7/DfBsorhKEAEHXaYE+NKJNlcGBIisvM0BNC9dcm7ufTkP7pP6mRJC0 GjjYqh8HMe45AvvIaE7o976M1GKexEDNsncHM8VlxuwkC5hz0SNAg73J7iwcDfUe hqfLeHcvTOrPQ0oB4Xz0Nh6cJ7tIv3gYZ941awhmH6XZCWgZhrBaLyipIenXEHM= =xpe2 -----END PGP SIGNATURE----- Merge tag 'ceph-for-4.15-rc4' of git://github.com/ceph/ceph-client Pull ceph fix from Ilya Dryomov: "CephFS inode trimming fix from Zheng, marked for stable" * tag 'ceph-for-4.15-rc4' of git://github.com/ceph/ceph-client: ceph: drop negative child dentries before try pruning inode's alias
This commit is contained in:
Коммит
dd3d66b838
|
@ -1440,6 +1440,29 @@ static int __close_session(struct ceph_mds_client *mdsc,
|
|||
return request_close_session(mdsc, session);
|
||||
}
|
||||
|
||||
static bool drop_negative_children(struct dentry *dentry)
|
||||
{
|
||||
struct dentry *child;
|
||||
bool all_negative = true;
|
||||
|
||||
if (!d_is_dir(dentry))
|
||||
goto out;
|
||||
|
||||
spin_lock(&dentry->d_lock);
|
||||
list_for_each_entry(child, &dentry->d_subdirs, d_child) {
|
||||
if (d_really_is_positive(child)) {
|
||||
all_negative = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock(&dentry->d_lock);
|
||||
|
||||
if (all_negative)
|
||||
shrink_dcache_parent(dentry);
|
||||
out:
|
||||
return all_negative;
|
||||
}
|
||||
|
||||
/*
|
||||
* Trim old(er) caps.
|
||||
*
|
||||
|
@ -1490,16 +1513,27 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg)
|
|||
if ((used | wanted) & ~oissued & mine)
|
||||
goto out; /* we need these caps */
|
||||
|
||||
session->s_trim_caps--;
|
||||
if (oissued) {
|
||||
/* we aren't the only cap.. just remove us */
|
||||
__ceph_remove_cap(cap, true);
|
||||
session->s_trim_caps--;
|
||||
} else {
|
||||
struct dentry *dentry;
|
||||
/* try dropping referring dentries */
|
||||
spin_unlock(&ci->i_ceph_lock);
|
||||
d_prune_aliases(inode);
|
||||
dout("trim_caps_cb %p cap %p pruned, count now %d\n",
|
||||
inode, cap, atomic_read(&inode->i_count));
|
||||
dentry = d_find_any_alias(inode);
|
||||
if (dentry && drop_negative_children(dentry)) {
|
||||
int count;
|
||||
dput(dentry);
|
||||
d_prune_aliases(inode);
|
||||
count = atomic_read(&inode->i_count);
|
||||
if (count == 1)
|
||||
session->s_trim_caps--;
|
||||
dout("trim_caps_cb %p cap %p pruned, count now %d\n",
|
||||
inode, cap, count);
|
||||
} else {
|
||||
dput(dentry);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче