aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/mds_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph/mds_client.c')
-rw-r--r--fs/ceph/mds_client.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 187bf214444d..603786b564be 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -414,6 +414,9 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc,
414{ 414{
415 struct ceph_mds_session *s; 415 struct ceph_mds_session *s;
416 416
417 if (mds >= mdsc->mdsmap->m_max_mds)
418 return ERR_PTR(-EINVAL);
419
417 s = kzalloc(sizeof(*s), GFP_NOFS); 420 s = kzalloc(sizeof(*s), GFP_NOFS);
418 if (!s) 421 if (!s)
419 return ERR_PTR(-ENOMEM); 422 return ERR_PTR(-ENOMEM);
@@ -1028,6 +1031,37 @@ static void remove_session_caps(struct ceph_mds_session *session)
1028{ 1031{
1029 dout("remove_session_caps on %p\n", session); 1032 dout("remove_session_caps on %p\n", session);
1030 iterate_session_caps(session, remove_session_caps_cb, NULL); 1033 iterate_session_caps(session, remove_session_caps_cb, NULL);
1034
1035 spin_lock(&session->s_cap_lock);
1036 if (session->s_nr_caps > 0) {
1037 struct super_block *sb = session->s_mdsc->fsc->sb;
1038 struct inode *inode;
1039 struct ceph_cap *cap, *prev = NULL;
1040 struct ceph_vino vino;
1041 /*
1042 * iterate_session_caps() skips inodes that are being
1043 * deleted, we need to wait until deletions are complete.
1044 * __wait_on_freeing_inode() is designed for the job,
1045 * but it is not exported, so use lookup inode function
1046 * to access it.
1047 */
1048 while (!list_empty(&session->s_caps)) {
1049 cap = list_entry(session->s_caps.next,
1050 struct ceph_cap, session_caps);
1051 if (cap == prev)
1052 break;
1053 prev = cap;
1054 vino = cap->ci->i_vino;
1055 spin_unlock(&session->s_cap_lock);
1056
1057 inode = ceph_lookup_inode(sb, vino);
1058 iput(inode);
1059
1060 spin_lock(&session->s_cap_lock);
1061 }
1062 }
1063 spin_unlock(&session->s_cap_lock);
1064
1031 BUG_ON(session->s_nr_caps > 0); 1065 BUG_ON(session->s_nr_caps > 0);
1032 BUG_ON(!list_empty(&session->s_cap_flushing)); 1066 BUG_ON(!list_empty(&session->s_cap_flushing));
1033 cleanup_cap_releases(session); 1067 cleanup_cap_releases(session);