u32 required_features;
};
-#define ceph_msg_has_pages(m) ((m)->p.type == CEPH_MSG_DATA_PAGES)
-#define ceph_msg_has_pagelist(m) ((m)->l.type == CEPH_MSG_DATA_PAGELIST)
-#ifdef CONFIG_BLOCK
-#define ceph_msg_has_bio(m) ((m)->b.type == CEPH_MSG_DATA_BIO)
-#endif /* CONFIG_BLOCK */
-
enum ceph_msg_data_type {
CEPH_MSG_DATA_NONE, /* message contains no data payload */
CEPH_MSG_DATA_PAGES, /* data source/destination is a page array */
}
}
+struct ceph_msg_data {
+ struct list_head links; /* ceph_msg->data */
+ enum ceph_msg_data_type type;
+ union {
+#ifdef CONFIG_BLOCK
+ struct {
+ struct bio *bio;
+ size_t bio_length;
+ };
+#endif /* CONFIG_BLOCK */
+ struct {
+ struct page **pages; /* NOT OWNER. */
+ size_t length; /* total # bytes */
+ unsigned int alignment; /* first page */
+ };
+ struct ceph_pagelist *pagelist;
+ };
+};
+
struct ceph_msg_data_cursor {
- bool last_piece; /* now at last piece of data item */
+ size_t total_resid; /* across all data items */
+ struct list_head *data_head; /* = &ceph_msg->data */
+
+ struct ceph_msg_data *data; /* current data item */
+ size_t resid; /* bytes not yet consumed */
+ bool last_piece; /* current is last piece */
+ bool need_crc; /* crc update needed */
union {
#ifdef CONFIG_BLOCK
struct { /* bio */
};
#endif /* CONFIG_BLOCK */
struct { /* pages */
- size_t resid; /* bytes from array */
unsigned int page_offset; /* offset in page */
unsigned short page_index; /* index in array */
unsigned short page_count; /* pages in array */
};
};
-struct ceph_msg_data {
- enum ceph_msg_data_type type;
- union {
-#ifdef CONFIG_BLOCK
- struct {
- struct bio *bio_iter; /* iterator */
- struct bio *bio;
- unsigned int bio_seg; /* current seg in bio */
- };
-#endif /* CONFIG_BLOCK */
- struct {
- struct page **pages; /* NOT OWNER. */
- size_t length; /* total # bytes */
- unsigned int alignment; /* first page */
- };
- struct ceph_pagelist *pagelist;
- };
- struct ceph_msg_data_cursor cursor; /* pagelist only */
-};
-
/*
* a single message. it contains a header (src, dest, message type, etc.),
* footer (crc values, mainly), a "front" message body, and possibly a
struct kvec front; /* unaligned blobs of message */
struct ceph_buffer *middle;
- /* data payload */
- struct ceph_msg_data p; /* pages */
- struct ceph_msg_data l; /* pagelist */
-#ifdef CONFIG_BLOCK
- struct ceph_msg_data b; /* bio */
-#endif /* CONFIG_BLOCK */
+ size_t data_length;
+ struct list_head data;
+ struct ceph_msg_data_cursor cursor;
struct ceph_connection *con;
struct list_head list_head; /* links for connection lists */
struct ceph_msgpool *pool;
};
-struct ceph_msg_pos {
- int page, page_pos; /* which page; offset in page */
- int data_pos; /* offset in data payload */
- bool did_page_crc; /* true if we've calculated crc for current page */
-};
-
/* ceph connection fault delay defaults, for exponential backoff */
#define BASE_DELAY_INTERVAL (HZ/2)
#define MAX_DELAY_INTERVAL (5 * 60 * HZ)
struct ceph_msg *out_msg; /* sending message (== tail of
out_sent) */
bool out_msg_done;
- struct ceph_msg_pos out_msg_pos;
struct kvec out_kvec[8], /* sending header/footer data */
*out_kvec_cur;
/* message in temps */
struct ceph_msg_header in_hdr;
struct ceph_msg *in_msg;
- struct ceph_msg_pos in_msg_pos;
u32 in_front_crc, in_middle_crc, in_data_crc; /* calculated crc */
char in_tag; /* protocol control byte */
extern void ceph_con_keepalive(struct ceph_connection *con);
-extern void ceph_msg_data_set_pages(struct ceph_msg *msg, struct page **pages,
+extern void ceph_msg_data_add_pages(struct ceph_msg *msg, struct page **pages,
size_t length, size_t alignment);
-extern void ceph_msg_data_set_pagelist(struct ceph_msg *msg,
+extern void ceph_msg_data_add_pagelist(struct ceph_msg *msg,
struct ceph_pagelist *pagelist);
-extern void ceph_msg_data_set_bio(struct ceph_msg *msg, struct bio *bio);
+#ifdef CONFIG_BLOCK
+extern void ceph_msg_data_add_bio(struct ceph_msg *msg, struct bio *bio,
+ size_t length);
+#endif /* CONFIG_BLOCK */
extern struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags,
bool can_fail);