diff options
Diffstat (limited to 'fs/ceph/mds_client.c')
-rw-r--r-- | fs/ceph/mds_client.c | 34 |
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); |