aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/mds_client.c
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2011-07-26 14:31:14 -0400
committerSage Weil <sage@newdream.net>2011-07-26 14:31:14 -0400
commit41b02e1f9bb87b07d792b64aaeb7af3d00d69cd2 (patch)
tree87c9524ff96cbff2ff29d659cbefd516b553ca1f /fs/ceph/mds_client.c
parent4f1772645296a230e04f5c53e79cfb6f841ce634 (diff)
ceph: explicitly reference rename old_dentry parent dir in request
We carry a pin on the parent directory for the rename source and dest dentries. For the source it's r_locked_dir; we need to explicitly reference the old_dentry parent as well, since the dentry's d_parent may change between when the request was created and pinned and when it is freed. Reviewed-by: Yehuda Sadeh <yehuda@hq.newdream.net> Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/mds_client.c')
-rw-r--r--fs/ceph/mds_client.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 8a09cd5a659e..66a8939cc518 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -483,22 +483,26 @@ void ceph_mdsc_release_request(struct kref *kref)
483 destroy_reply_info(&req->r_reply_info); 483 destroy_reply_info(&req->r_reply_info);
484 } 484 }
485 if (req->r_inode) { 485 if (req->r_inode) {
486 ceph_put_cap_refs(ceph_inode(req->r_inode), 486 ceph_put_cap_refs(ceph_inode(req->r_inode), CEPH_CAP_PIN);
487 CEPH_CAP_PIN);
488 iput(req->r_inode); 487 iput(req->r_inode);
489 } 488 }
490 if (req->r_locked_dir) 489 if (req->r_locked_dir)
491 ceph_put_cap_refs(ceph_inode(req->r_locked_dir), 490 ceph_put_cap_refs(ceph_inode(req->r_locked_dir), CEPH_CAP_PIN);
492 CEPH_CAP_PIN);
493 if (req->r_target_inode) 491 if (req->r_target_inode)
494 iput(req->r_target_inode); 492 iput(req->r_target_inode);
495 if (req->r_dentry) 493 if (req->r_dentry)
496 dput(req->r_dentry); 494 dput(req->r_dentry);
497 if (req->r_old_dentry) { 495 if (req->r_old_dentry) {
498 ceph_put_cap_refs( 496 /*
499 ceph_inode(req->r_old_dentry->d_parent->d_inode), 497 * track (and drop pins for) r_old_dentry_dir
500 CEPH_CAP_PIN); 498 * separately, since r_old_dentry's d_parent may have
499 * changed between the dir mutex being dropped and
500 * this request being freed.
501 */
502 ceph_put_cap_refs(ceph_inode(req->r_old_dentry_dir),
503 CEPH_CAP_PIN);
501 dput(req->r_old_dentry); 504 dput(req->r_old_dentry);
505 iput(req->r_old_dentry_dir);
502 } 506 }
503 kfree(req->r_path1); 507 kfree(req->r_path1);
504 kfree(req->r_path2); 508 kfree(req->r_path2);
@@ -1931,9 +1935,8 @@ int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
1931 if (req->r_locked_dir) 1935 if (req->r_locked_dir)
1932 ceph_get_cap_refs(ceph_inode(req->r_locked_dir), CEPH_CAP_PIN); 1936 ceph_get_cap_refs(ceph_inode(req->r_locked_dir), CEPH_CAP_PIN);
1933 if (req->r_old_dentry) 1937 if (req->r_old_dentry)
1934 ceph_get_cap_refs( 1938 ceph_get_cap_refs(ceph_inode(req->r_old_dentry_dir),
1935 ceph_inode(req->r_old_dentry->d_parent->d_inode), 1939 CEPH_CAP_PIN);
1936 CEPH_CAP_PIN);
1937 1940
1938 /* issue */ 1941 /* issue */
1939 mutex_lock(&mdsc->mutex); 1942 mutex_lock(&mdsc->mutex);