@@ -806,6 +806,9 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc,
806806{
807807 struct ceph_mds_session * s ;
808808
809+ if (READ_ONCE (mdsc -> fsc -> mount_state ) == CEPH_MOUNT_FENCE_IO )
810+ return ERR_PTR (- EIO );
811+
809812 if (mds >= mdsc -> mdsmap -> possible_max_rank )
810813 return ERR_PTR (- EINVAL );
811814
@@ -1478,6 +1481,9 @@ static int __open_session(struct ceph_mds_client *mdsc,
14781481 int mstate ;
14791482 int mds = session -> s_mds ;
14801483
1484+ if (READ_ONCE (mdsc -> fsc -> mount_state ) == CEPH_MOUNT_FENCE_IO )
1485+ return - EIO ;
1486+
14811487 /* wait for mds to go active? */
14821488 mstate = ceph_mdsmap_get_state (mdsc -> mdsmap , mds );
14831489 dout ("open_session to mds%d (%s)\n" , mds ,
@@ -2860,6 +2866,11 @@ static void __do_request(struct ceph_mds_client *mdsc,
28602866 return ;
28612867 }
28622868
2869+ if (READ_ONCE (mdsc -> fsc -> mount_state ) == CEPH_MOUNT_FENCE_IO ) {
2870+ dout ("do_request metadata corrupted\n" );
2871+ err = - EIO ;
2872+ goto finish ;
2873+ }
28632874 if (req -> r_timeout &&
28642875 time_after_eq (jiffies , req -> r_started + req -> r_timeout )) {
28652876 dout ("do_request timed out\n" );
@@ -3245,6 +3256,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
32453256 u64 tid ;
32463257 int err , result ;
32473258 int mds = session -> s_mds ;
3259+ bool close_sessions = false;
32483260
32493261 if (msg -> front .iov_len < sizeof (* head )) {
32503262 pr_err ("mdsc_handle_reply got corrupt (short) reply\n" );
@@ -3351,10 +3363,17 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
33513363 realm = NULL ;
33523364 if (rinfo -> snapblob_len ) {
33533365 down_write (& mdsc -> snap_rwsem );
3354- ceph_update_snap_trace (mdsc , rinfo -> snapblob ,
3366+ err = ceph_update_snap_trace (mdsc , rinfo -> snapblob ,
33553367 rinfo -> snapblob + rinfo -> snapblob_len ,
33563368 le32_to_cpu (head -> op ) == CEPH_MDS_OP_RMSNAP ,
33573369 & realm );
3370+ if (err ) {
3371+ up_write (& mdsc -> snap_rwsem );
3372+ close_sessions = true;
3373+ if (err == - EIO )
3374+ ceph_msg_dump (msg );
3375+ goto out_err ;
3376+ }
33583377 downgrade_write (& mdsc -> snap_rwsem );
33593378 } else {
33603379 down_read (& mdsc -> snap_rwsem );
@@ -3412,6 +3431,10 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
34123431 req -> r_end_latency , err );
34133432out :
34143433 ceph_mdsc_put_request (req );
3434+
3435+ /* Defer closing the sessions after s_mutex lock being released */
3436+ if (close_sessions )
3437+ ceph_mdsc_close_sessions (mdsc );
34153438 return ;
34163439}
34173440
@@ -5011,7 +5034,7 @@ static bool done_closing_sessions(struct ceph_mds_client *mdsc, int skipped)
50115034}
50125035
50135036/*
5014- * called after sb is ro.
5037+ * called after sb is ro or when metadata corrupted .
50155038 */
50165039void ceph_mdsc_close_sessions (struct ceph_mds_client * mdsc )
50175040{
@@ -5301,7 +5324,8 @@ static void mds_peer_reset(struct ceph_connection *con)
53015324 struct ceph_mds_client * mdsc = s -> s_mdsc ;
53025325
53035326 pr_warn ("mds%d closed our session\n" , s -> s_mds );
5304- send_mds_reconnect (mdsc , s );
5327+ if (READ_ONCE (mdsc -> fsc -> mount_state ) != CEPH_MOUNT_FENCE_IO )
5328+ send_mds_reconnect (mdsc , s );
53055329}
53065330
53075331static void mds_dispatch (struct ceph_connection * con , struct ceph_msg * msg )
0 commit comments