From 47b7bca2cd8c3de7d550bbf5949e59cc17f6a513 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 16 Aug 2010 09:21:27 -0700 Subject: [PATCH] --- yaml --- r: 210048 b: refs/heads/master c: eb6bb1c5bdc6e455a9d16cb845cc65afc9b0a617 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/fs/ceph/mds_client.c | 26 ++++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index 2a4e25c6f67e..a06f779c5094 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ed326044489ed89c740c50a3df5dffc9c3b20b96 +refs/heads/master: eb6bb1c5bdc6e455a9d16cb845cc65afc9b0a617 diff --git a/trunk/fs/ceph/mds_client.c b/trunk/fs/ceph/mds_client.c index 397a47b696ce..8d1f11c7a5a2 100644 --- a/trunk/fs/ceph/mds_client.c +++ b/trunk/fs/ceph/mds_client.c @@ -560,6 +560,13 @@ static void __unregister_request(struct ceph_mds_client *mdsc, * * Called under mdsc->mutex. */ +struct dentry *get_nonsnap_parent(struct dentry *dentry) +{ + while (!IS_ROOT(dentry) && ceph_snap(dentry->d_inode) != CEPH_NOSNAP) + dentry = dentry->d_parent; + return dentry; +} + static int __choose_mds(struct ceph_mds_client *mdsc, struct ceph_mds_request *req) { @@ -590,14 +597,29 @@ static int __choose_mds(struct ceph_mds_client *mdsc, if (req->r_inode) { inode = req->r_inode; } else if (req->r_dentry) { - if (req->r_dentry->d_inode) { + struct inode *dir = req->r_dentry->d_parent->d_inode; + + if (dir->i_sb != mdsc->client->sb) { + /* not this fs! */ + inode = req->r_dentry->d_inode; + } else if (ceph_snap(dir) != CEPH_NOSNAP) { + /* direct snapped/virtual snapdir requests + * based on parent dir inode */ + struct dentry *dn = + get_nonsnap_parent(req->r_dentry->d_parent); + inode = dn->d_inode; + dout("__choose_mds using nonsnap parent %p\n", inode); + } else if (req->r_dentry->d_inode) { + /* dentry target */ inode = req->r_dentry->d_inode; } else { - inode = req->r_dentry->d_parent->d_inode; + /* dir + name */ + inode = dir; hash = req->r_dentry->d_name.hash; is_hash = true; } } + dout("__choose_mds %p is_hash=%d (%d) mode %d\n", inode, (int)is_hash, (int)hash, mode); if (!inode)