Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 373352
b: refs/heads/master
c: dd236fc
h: refs/heads/master
v: v3
  • Loading branch information
Alex Elder authored and Sage Weil committed May 2, 2013
1 parent 5ad6124 commit 9c35f48
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 27 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fe38a2b67bc6b3a60da82a23e9082256a30e39d9
refs/heads/master: dd236fcb65d7b6b80c408cb5f66aab55f4594284
8 changes: 6 additions & 2 deletions trunk/include/linux/ceph/messenger.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,12 @@ static __inline__ bool ceph_msg_data_type_valid(enum ceph_msg_data_type type)

struct ceph_msg_data_cursor {
bool last_piece; /* now at last piece of data item */
struct page *page; /* current page in pagelist */
size_t offset; /* pagelist bytes consumed */
union {
struct { /* pagelist */
struct page *page; /* page from list */
size_t offset; /* bytes from list */
};
};
};

struct ceph_msg_data {
Expand Down
117 changes: 93 additions & 24 deletions trunk/net/ceph/messenger.c
Original file line number Diff line number Diff line change
Expand Up @@ -742,21 +742,16 @@ static void iter_bio_next(struct bio **bio_iter, unsigned int *seg)
#endif

/*
* Message data is handled (sent or received) in pieces, where each
* piece resides on a single page. The network layer might not
* consume an entire piece at once. A data item's cursor keeps
* track of which piece is next to process and how much remains to
* be processed in that piece. It also tracks whether the current
* piece is the last one in the data item.
* For a pagelist, a piece is whatever remains to be consumed in the
* first page in the list, or the front of the next page.
*/
static void ceph_msg_data_cursor_init(struct ceph_msg_data *data)
static void ceph_msg_data_pagelist_cursor_init(struct ceph_msg_data *data)
{
struct ceph_msg_data_cursor *cursor = &data->cursor;
struct ceph_pagelist *pagelist;
struct page *page;

if (data->type != CEPH_MSG_DATA_PAGELIST)
return;
BUG_ON(data->type != CEPH_MSG_DATA_PAGELIST);

pagelist = data->pagelist;
BUG_ON(!pagelist);
Expand All @@ -771,15 +766,9 @@ static void ceph_msg_data_cursor_init(struct ceph_msg_data *data)
cursor->last_piece = pagelist->length <= PAGE_SIZE;
}

/*
* Return the page containing the next piece to process for a given
* data item, and supply the page offset and length of that piece.
* Indicate whether this is the last piece in this data item.
*/
static struct page *ceph_msg_data_next(struct ceph_msg_data *data,
static struct page *ceph_msg_data_pagelist_next(struct ceph_msg_data *data,
size_t *page_offset,
size_t *length,
bool *last_piece)
size_t *length)
{
struct ceph_msg_data_cursor *cursor = &data->cursor;
struct ceph_pagelist *pagelist;
Expand All @@ -793,8 +782,7 @@ static struct page *ceph_msg_data_next(struct ceph_msg_data *data,
BUG_ON(!cursor->page);
BUG_ON(cursor->offset >= pagelist->length);

*last_piece = cursor->last_piece;
if (*last_piece) {
if (cursor->last_piece) {
/* pagelist offset is always 0 */
piece_end = pagelist->length & ~PAGE_MASK;
if (!piece_end)
Expand All @@ -808,11 +796,8 @@ static struct page *ceph_msg_data_next(struct ceph_msg_data *data,
return data->cursor.page;
}

/*
* Returns true if the result moves the cursor on to the next piece
* (the next page) of the pagelist.
*/
static bool ceph_msg_data_advance(struct ceph_msg_data *data, size_t bytes)
static bool ceph_msg_data_pagelist_advance(struct ceph_msg_data *data,
size_t bytes)
{
struct ceph_msg_data_cursor *cursor = &data->cursor;
struct ceph_pagelist *pagelist;
Expand Down Expand Up @@ -844,6 +829,90 @@ static bool ceph_msg_data_advance(struct ceph_msg_data *data, size_t bytes)
return true;
}

/*
* Message data is handled (sent or received) in pieces, where each
* piece resides on a single page. The network layer might not
* consume an entire piece at once. A data item's cursor keeps
* track of which piece is next to process and how much remains to
* be processed in that piece. It also tracks whether the current
* piece is the last one in the data item.
*/
static void ceph_msg_data_cursor_init(struct ceph_msg_data *data)
{
switch (data->type) {
case CEPH_MSG_DATA_PAGELIST:
ceph_msg_data_pagelist_cursor_init(data);
break;
case CEPH_MSG_DATA_NONE:
case CEPH_MSG_DATA_PAGES:
#ifdef CONFIG_BLOCK
case CEPH_MSG_DATA_BIO:
#endif /* CONFIG_BLOCK */
default:
/* BUG(); */
break;
}
}

/*
* Return the page containing the next piece to process for a given
* data item, and supply the page offset and length of that piece.
* Indicate whether this is the last piece in this data item.
*/
static struct page *ceph_msg_data_next(struct ceph_msg_data *data,
size_t *page_offset,
size_t *length,
bool *last_piece)
{
struct page *page;

switch (data->type) {
case CEPH_MSG_DATA_PAGELIST:
page = ceph_msg_data_pagelist_next(data, page_offset, length);
break;
case CEPH_MSG_DATA_NONE:
case CEPH_MSG_DATA_PAGES:
#ifdef CONFIG_BLOCK
case CEPH_MSG_DATA_BIO:
#endif /* CONFIG_BLOCK */
default:
page = NULL;
break;
}
BUG_ON(!page);
BUG_ON(*page_offset + *length > PAGE_SIZE);
BUG_ON(!*length);
if (last_piece)
*last_piece = data->cursor.last_piece;

return page;
}

/*
* Returns true if the result moves the cursor on to the next piece
* of the data item.
*/
static bool ceph_msg_data_advance(struct ceph_msg_data *data, size_t bytes)
{
bool new_piece;

switch (data->type) {
case CEPH_MSG_DATA_PAGELIST:
new_piece = ceph_msg_data_pagelist_advance(data, bytes);
break;
case CEPH_MSG_DATA_NONE:
case CEPH_MSG_DATA_PAGES:
#ifdef CONFIG_BLOCK
case CEPH_MSG_DATA_BIO:
#endif /* CONFIG_BLOCK */
default:
BUG();
break;
}

return new_piece;
}

static void prepare_message_data(struct ceph_msg *msg,
struct ceph_msg_pos *msg_pos)
{
Expand Down

0 comments on commit 9c35f48

Please sign in to comment.