From 552786c4f88164766616cdaf96b9d26a9c0325f2 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 15 Oct 2008 13:52:33 -0700 Subject: [PATCH] kclient: fix inode refcount problems in ceph_fill_trace If we fail to take i_mutex, we get the inode via ceph_get_inode, which bumps i_count. Make sure we iput() it before jumping to update_inode label. Note that d_instantiate consumes the ref, but the other paths (d_alloc_anon, d_find_alias) do not. --- src/kernel/inode.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/kernel/inode.c b/src/kernel/inode.c index ccd0093d87f09..9cb47cb1e9738 100644 --- a/src/kernel/inode.c +++ b/src/kernel/inode.c @@ -917,16 +917,16 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, mutex_unlock(&parent->d_inode->i_mutex); update_inode: + BUG_ON(dn->d_inode != in); err = ceph_fill_inode(in, &rinfo->trace_in[d+1], rinfo->trace_numd <= d ? rinfo->trace_dir[d+1]:0); if (err < 0) { derr(30, "ceph_fill_inode badness\n"); - iput(in); - in = NULL; d_delete(dn); dn = NULL; + in = NULL; break; } @@ -935,7 +935,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, /* do we diverge into a snap dir at this point in the trace? */ if (d == rinfo->trace_numi - rinfo->trace_snapdirpos - 1) { - struct inode *snapdir = ceph_get_snapdir(dn->d_inode); + struct inode *snapdir = ceph_get_snapdir(in); dput(dn); dn = d_find_alias(snapdir); if (!dn) { @@ -1003,6 +1003,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, if (existing) { if (dn) dput(dn); + iput(in); dn = existing; dout(10, " using existing %p alias %p\n", in, dn); } else { @@ -1016,6 +1017,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, dput(dn); } dn = d_alloc_anon(in); + iput(in); dout(10, " d_alloc_anon new dn %p\n", dn); } } -- 2.39.5