diff --git a/fs/ceph/Kconfig b/fs/ceph/Kconfig
index 7249d70e1a43..203fb5d1cdd4 100644
--- a/fs/ceph/Kconfig
+++ b/fs/ceph/Kconfig
@@ -50,3 +50,16 @@ config CEPH_FS_SECURITY_LABEL
 
 	  If you are not using a security module that requires using
 	  extended attributes for file security labels, say N.
+
+config CEPH_FS_DEBUG
+	bool "Ceph client debugging"
+	depends on CEPH_FS
+	default n
+	help
+	  If you say Y here, this option enables additional pre-
condition
+	  and post-condition checks in functions. Also it could enable
+	  BUG_ON() instead of returning the error code. This option
could
+	  save more messages in system log and execute additional
computation.
+
+	  If you are going to debug the code, then chose Y here.
+	  If unsure, say N.
diff --git a/include/linux/ceph/messenger.h
b/include/linux/ceph/messenger.h
index 1717cc57cdac..acfab9052046 100644
--- a/include/linux/ceph/messenger.h
+++ b/include/linux/ceph/messenger.h
@@ -532,7 +532,7 @@ u32 ceph_get_global_seq(struct ceph_messenger
*msgr, u32 gt);
 void ceph_con_discard_sent(struct ceph_connection *con, u64 ack_seq);
 void ceph_con_discard_requeued(struct ceph_connection *con, u64
reconnect_seq);
 
-void ceph_msg_data_cursor_init(struct ceph_msg_data_cursor *cursor,
+int ceph_msg_data_cursor_init(struct ceph_msg_data_cursor *cursor,
 			       struct ceph_msg *msg, size_t length);
 struct page *ceph_msg_data_next(struct ceph_msg_data_cursor *cursor,
 				size_t *page_offset, size_t *length);
diff --git a/net/ceph/Kconfig b/net/ceph/Kconfig
index c5c4eef3a9ff..4248661669bd 100644
--- a/net/ceph/Kconfig
+++ b/net/ceph/Kconfig
@@ -45,3 +45,16 @@ config CEPH_LIB_USE_DNS_RESOLVER
 	  Documentation/networking/dns_resolver.rst
 
 	  If unsure, say N.
+
+config CEPH_LIB_DEBUG
+	bool "Ceph core library debugging"
+	depends on CEPH_LIB
+	default n
+	help
+	  If you say Y here, this option enables additional pre-
condition
+	  and post-condition checks in functions. Also it could enable
+	  BUG_ON() instead of returning the error code. This option
could
+	  save more messages in system log and execute additional
computation.
+
+	  If you are going to debug the code, then chose Y here.
+	  If unsure, say N.
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index d1b5705dc0c6..42db34345572 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -1063,18 +1063,30 @@ static void __ceph_msg_data_cursor_init(struct
ceph_msg_data_cursor *cursor)
 	cursor->need_crc = true;
 }
 
-void ceph_msg_data_cursor_init(struct ceph_msg_data_cursor *cursor,
-			       struct ceph_msg *msg, size_t length)
+int ceph_msg_data_cursor_init(struct ceph_msg_data_cursor *cursor,
+			      struct ceph_msg *msg, size_t length)
 {
+#ifdef CONFIG_CEPH_LIB_DEBUG
 	BUG_ON(!length);
 	BUG_ON(length > msg->data_length);
 	BUG_ON(!msg->num_data_items);
+#else
+	if (!length)
+		return -EINVAL;
+
+	if (length > msg->data_length)
+		return -EINVAL;
+
+	if (!msg->num_data_items)
+		return -EINVAL;
+#endif /* CONFIG_CEPH_LIB_DEBUG */
 
 	cursor->total_resid = length;
 	cursor->data = msg->data;
 	cursor->sr_resid = 0;
 
 	__ceph_msg_data_cursor_init(cursor);
+	return 0;
 }
 
 /*
diff --git a/net/ceph/messenger_v1.c b/net/ceph/messenger_v1.c
index 0cb61c76b9b8..bc2f3a43d572 100644
--- a/net/ceph/messenger_v1.c
+++ b/net/ceph/messenger_v1.c
@@ -157,12 +157,12 @@ static size_t sizeof_footer(struct
ceph_connection *con)
 	    sizeof(struct ceph_msg_footer_old);
 }
 
-static void prepare_message_data(struct ceph_msg *msg, u32 data_len)
+static int prepare_message_data(struct ceph_msg *msg, u32 data_len)
 {
 	/* Initialize data cursor if it's not a sparse read */
 	u64 len = msg->sparse_read_total ? : data_len;
 
-	ceph_msg_data_cursor_init(&msg->cursor, msg, len);
+	return ceph_msg_data_cursor_init(&msg->cursor, msg, len);
 }
 
 /*
@@ -192,10 +192,11 @@ static void prepare_write_message_footer(struct
ceph_connection *con)
 /*
  * Prepare headers for the next outgoing message.
  */
-static void prepare_write_message(struct ceph_connection *con)
+static int prepare_write_message(struct ceph_connection *con)
 {
 	struct ceph_msg *m;
 	u32 crc;
+	int ret;
 
 	con_out_kvec_reset(con);
 	con->v1.out_msg_done = false;
@@ -251,7 +252,10 @@ static void prepare_write_message(struct
ceph_connection *con)
 	/* is there a data payload? */
 	con->out_msg->footer.data_crc = 0;
 	if (m->data_length) {
-		prepare_message_data(con->out_msg, m->data_length);
+		ret = prepare_message_data(con->out_msg, m-
>data_length);
+		if (ret)
+			return ret;
+
 		con->v1.out_more = 1;  /* data + footer will follow */
 	} else {
 		/* no, queue up footer too and be done */
@@ -259,6 +263,7 @@ static void prepare_write_message(struct
ceph_connection *con)
 	}
 
 	ceph_con_flag_set(con, CEPH_CON_F_WRITE_PENDING);
+	return 0;
 }
 
 /*
@@ -1230,8 +1235,11 @@ static int read_partial_message(struct
ceph_connection *con)
 
 		/* prepare for data payload, if any */
 
-		if (data_len)
-			prepare_message_data(con->in_msg, data_len);
+		if (data_len) {
+			ret = prepare_message_data(con->in_msg,
data_len);
+			if (ret)
+				return ret;
+		}
 	}
 
 	/* front */
@@ -1546,8 +1554,11 @@ int ceph_con_v1_try_write(struct ceph_connection
*con)
 		}
 		/* is anything else pending? */
 		if (!list_empty(&con->out_queue)) {
-			prepare_write_message(con);
-			goto more;
+			ret = prepare_write_message(con);
+			if (ret)
+				goto out;
+			else
+				goto more;
 		}
 		if (con->in_seq > con->in_seq_acked) {
 			prepare_write_ack(con);
diff --git a/net/ceph/messenger_v2.c b/net/ceph/messenger_v2.c
index bd608ffa0627..0904821c8dfa 100644
--- a/net/ceph/messenger_v2.c
+++ b/net/ceph/messenger_v2.c
@@ -1026,7 +1026,10 @@ static int setup_message_sgs(struct sg_table
*sgt, struct ceph_msg *msg,
 			if (need_padding(dlen))
 				sg_cnt++;
 		} else {
-			ceph_msg_data_cursor_init(&cursor, msg, dlen);
+			ret = ceph_msg_data_cursor_init(&cursor, msg,
dlen);
+			if (ret)
+				return ret;
+
 			sg_cnt += calc_sg_cnt_cursor(&cursor);
