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 */
-#define ceph_msg_has_trail(m) ((m)->t.type == CEPH_MSG_DATA_PAGELIST)
-
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_cursor {
- bool last_piece; /* now at last piece of data item */
- union {
- struct { /* pagelist */
- struct page *page; /* page from list */
- size_t offset; /* bytes from list */
- };
- };
-};
-
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_iter; /* iterator */
struct bio *bio;
- unsigned int bio_seg; /* current seg in bio */
+ size_t bio_length;
};
#endif /* CONFIG_BLOCK */
struct {
};
struct ceph_pagelist *pagelist;
};
- struct ceph_msg_data_cursor cursor; /* pagelist only */
+};
+
+struct ceph_msg_data_cursor {
+ 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 */
+ struct bio *bio; /* bio from list */
+ unsigned int vector_index; /* vector from bio */
+ unsigned int vector_offset; /* bytes from vector */
+ };
+#endif /* CONFIG_BLOCK */
+ struct { /* pages */
+ unsigned int page_offset; /* offset in page */
+ unsigned short page_index; /* index in array */
+ unsigned short page_count; /* pages in array */
+ };
+ struct { /* pagelist */
+ struct page *page; /* page from list */
+ size_t offset; /* bytes from list */
+ };
+ };
};
/*
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 */
- struct ceph_msg_data t; /* trail */
+ 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);
-extern void ceph_msg_data_set_trail(struct ceph_msg *msg,
- struct ceph_pagelist *trail);
+#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);