ceph: take reference on mds request r_unsafe_dir
authorSage Weil <sage@newdream.net>
Wed, 18 May 2011 23:12:12 +0000 (16:12 -0700)
committerSage Weil <sage@newdream.net>
Thu, 19 May 2011 18:20:07 +0000 (11:20 -0700)
We put ourselves on an inode list for the parent directory of metadata
operations so that an fsync on the directory will wait for metadata updates
to commit to disk.  We weren't holding a reference to that directory,
however, and under certain workloads (fsstress in this case) the directory
can go away.

Signed-off-by: Sage Weil <sage@newdream.net>
fs/ceph/mds_client.c

index d0fae4ce9ba55b704ccedadbfd3f298e3a00cfb4..ebce88ab3982c7ce51411bf8d20d271253cbcb54 100644 (file)
@@ -578,6 +578,7 @@ static void __register_request(struct ceph_mds_client *mdsc,
        if (dir) {
                struct ceph_inode_info *ci = ceph_inode(dir);
 
+               ihold(dir);
                spin_lock(&ci->i_unsafe_lock);
                req->r_unsafe_dir = dir;
                list_add_tail(&req->r_unsafe_dir_item, &ci->i_unsafe_dirops);
@@ -598,6 +599,9 @@ static void __unregister_request(struct ceph_mds_client *mdsc,
                spin_lock(&ci->i_unsafe_lock);
                list_del_init(&req->r_unsafe_dir_item);
                spin_unlock(&ci->i_unsafe_lock);
+
+               iput(req->r_unsafe_dir);
+               req->r_unsafe_dir = NULL;
        }
 
        ceph_mdsc_put_request(req);