Re: [PATCH v2 2/2] cephfs: Don't d_drop() before d_splice_alias()
From: Xiubo Li
Date: Tue Nov 10 2026 - 01:59:47 EST
On Tue, Nov 10, 2026 at 07:20:24AM +1100, NeilBrown wrote:
> In two places ceph drops a dentry and then calls d_splice_alias().
> The d_drop() is no longer needed before d_splice_alias() and will
> cause problems for proposed changes to locking.
Tested with a second client creating and renaming entries, and with this
client running mkdir, creat, symlink, mknod and link over its own cached
negative dentries. With this patch, splice_dentry() now passes hashed
negative dentries to d_splice_alias()(confirmed with bpftrace), and the
results match the other client, with no duplicate dentries. A 10 minute
metadata fsstress run (create, mkdir, rename, link, unlink, getdents...)
with a second client doing readdir/stat churn was clean under KASAN
and lockdep.
The async create path in ceph_finish_async_create() was not exercised
here: my test cluster never grants the directory caps it needs.
Reviewed-by: Xiubo Li <xiubo.li@xxxxxxxxx>
Tested-by: Xiubo Li <xiubo.li@xxxxxxxxx>
Thanks
Xiubo
NeilBrown <neilb@xxxxxxxxxxx> 于2026年11月9日周一 21:25写道:
>
> From: NeilBrown <neil@xxxxxxxxxx>
>
> In two places ceph drops a dentry and then calls d_splice_alias().
> The d_drop() is no longer needed before d_splice_alias() and will
> cause problems for proposed changes to locking.
>
> Signed-off-by: NeilBrown <neil@xxxxxxxxxx>
> ---
> fs/ceph/file.c | 2 --
> fs/ceph/inode.c | 3 ---
> 2 files changed, 5 deletions(-)
>
> diff --git a/fs/ceph/file.c b/fs/ceph/file.c
> index 4a19a00be96f..159ec0bdf1fd 100644
> --- a/fs/ceph/file.c
> +++ b/fs/ceph/file.c
> @@ -770,8 +770,6 @@ static int ceph_finish_async_create(struct inode *dir, struct inode *inode,
> unlock_new_inode(inode);
> }
> if (d_in_lookup(dentry) || d_really_is_negative(dentry)) {
> - if (!d_unhashed(dentry))
> - d_drop(dentry);
> dn = d_splice_alias(inode, dentry);
> WARN_ON_ONCE(dn && dn != dentry);
> }
> diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
> index cfc438b3a446..68da14fced96 100644
> --- a/fs/ceph/inode.c
> +++ b/fs/ceph/inode.c
> @@ -1626,9 +1626,6 @@ static int splice_dentry(struct dentry **pdn, struct inode *in)
> }
> }
>
> - /* dn must be unhashed */
> - if (!d_unhashed(dn))
> - d_drop(dn);
> realdn = d_splice_alias(in, dn);
> if (IS_ERR(realdn)) {
> pr_err_client(cl, "error %ld %p inode %p ino %llx.%llx\n",
> --
> 2.50.0.107.gf914562f5916.dirty
>
>