@@ -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.
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);
@@ -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.
@@ -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;
}
/*
@@ -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);
@@ -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);