diff options
author | Sage Weil <sage@newdream.net> | 2011-07-26 14:31:26 -0400 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2011-07-26 14:31:26 -0400 |
commit | d79698da32b317e96216236f265a9b72b78ae568 (patch) | |
tree | 97f98e83c699794d6a5d979688587fbfdbba2ba7 /fs | |
parent | 41b02e1f9bb87b07d792b64aaeb7af3d00d69cd2 (diff) |
ceph: document unlocked d_parent accesses
For the most part we don't care about racing with rename when directing
MDS requests; either the old or new parent is fine. Document that, and
do some minor cleanup.
Reviewed-by: Yehuda Sadeh <yehuda@hq.newdream.net>
Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ceph/dir.c | 2 | ||||
-rw-r--r-- | fs/ceph/mds_client.c | 13 |
2 files changed, 11 insertions, 4 deletions
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 7263f825d426..852ff8600ac9 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -506,7 +506,7 @@ int ceph_handle_snapdir(struct ceph_mds_request *req, | |||
506 | struct dentry *dentry, int err) | 506 | struct dentry *dentry, int err) |
507 | { | 507 | { |
508 | struct ceph_fs_client *fsc = ceph_sb_to_client(dentry->d_sb); | 508 | struct ceph_fs_client *fsc = ceph_sb_to_client(dentry->d_sb); |
509 | struct inode *parent = dentry->d_parent->d_inode; | 509 | struct inode *parent = dentry->d_parent->d_inode; /* we hold i_mutex */ |
510 | 510 | ||
511 | /* .snap dir? */ | 511 | /* .snap dir? */ |
512 | if (err == -ENOENT && | 512 | if (err == -ENOENT && |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 66a8939cc518..fee028b5332e 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -621,6 +621,12 @@ static void __unregister_request(struct ceph_mds_client *mdsc, | |||
621 | */ | 621 | */ |
622 | struct dentry *get_nonsnap_parent(struct dentry *dentry) | 622 | struct dentry *get_nonsnap_parent(struct dentry *dentry) |
623 | { | 623 | { |
624 | /* | ||
625 | * we don't need to worry about protecting the d_parent access | ||
626 | * here because we never renaming inside the snapped namespace | ||
627 | * except to resplice to another snapdir, and either the old or new | ||
628 | * result is a valid result. | ||
629 | */ | ||
624 | while (!IS_ROOT(dentry) && ceph_snap(dentry->d_inode) != CEPH_NOSNAP) | 630 | while (!IS_ROOT(dentry) && ceph_snap(dentry->d_inode) != CEPH_NOSNAP) |
625 | dentry = dentry->d_parent; | 631 | dentry = dentry->d_parent; |
626 | return dentry; | 632 | return dentry; |
@@ -656,7 +662,9 @@ static int __choose_mds(struct ceph_mds_client *mdsc, | |||
656 | if (req->r_inode) { | 662 | if (req->r_inode) { |
657 | inode = req->r_inode; | 663 | inode = req->r_inode; |
658 | } else if (req->r_dentry) { | 664 | } else if (req->r_dentry) { |
659 | struct inode *dir = req->r_dentry->d_parent->d_inode; | 665 | /* ignore race with rename; old or new d_parent is okay */ |
666 | struct dentry *parent = req->r_dentry->d_parent; | ||
667 | struct inode *dir = parent->d_inode; | ||
660 | 668 | ||
661 | if (dir->i_sb != mdsc->fsc->sb) { | 669 | if (dir->i_sb != mdsc->fsc->sb) { |
662 | /* not this fs! */ | 670 | /* not this fs! */ |
@@ -664,8 +672,7 @@ static int __choose_mds(struct ceph_mds_client *mdsc, | |||
664 | } else if (ceph_snap(dir) != CEPH_NOSNAP) { | 672 | } else if (ceph_snap(dir) != CEPH_NOSNAP) { |
665 | /* direct snapped/virtual snapdir requests | 673 | /* direct snapped/virtual snapdir requests |
666 | * based on parent dir inode */ | 674 | * based on parent dir inode */ |
667 | struct dentry *dn = | 675 | struct dentry *dn = get_nonsnap_parent(parent); |
668 | get_nonsnap_parent(req->r_dentry->d_parent); | ||
669 | inode = dn->d_inode; | 676 | inode = dn->d_inode; |
670 | dout("__choose_mds using nonsnap parent %p\n", inode); | 677 | dout("__choose_mds using nonsnap parent %p\n", inode); |
671 | } else if (req->r_dentry->d_inode) { | 678 | } else if (req->r_dentry->d_inode) { |