From mboxrd@z Thu Jan 1 00:00:00 1970 From: laijs@cn.fujitsu.com (Lai Jiangshan) Date: Tue, 13 Jan 2009 17:08:56 +0800 Subject: [ltt-dev] [PATCH 04/13] read C-style string from ltt-relay buffer Message-ID: <496C5A28.8080609@cn.fujitsu.com> C-style string which is written to ltt-relay buffer is not in continuous memory region, we implement ltt_relay_read_cstr() read it. Signed-off-by: Lai Jiangshan --- b/ltt/ltt-relay-alloc.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/ltt-relay.h | 3 +++ 2 files changed, 47 insertions(+) diff --git a/include/linux/ltt-relay.h b/include/linux/ltt-relay.h index 1225a6a..173b557 100644 --- a/include/linux/ltt-relay.h +++ b/include/linux/ltt-relay.h @@ -146,6 +146,9 @@ extern int ltt_relay_write(struct rchan_buf *buf, size_t offset, extern int ltt_relay_read(struct rchan_buf *buf, size_t offset, void *dest, size_t len); +extern int ltt_relay_read_cstr(struct rchan_buf *buf, size_t offset, + void *dest, size_t len); + extern struct buf_page *ltt_relay_read_get_page(struct rchan_buf *buf, size_t offset); diff --git a/ltt/ltt-relay-alloc.c b/ltt/ltt-relay-alloc.c index 80e856c..4d9489d 100644 --- a/ltt/ltt-relay-alloc.c +++ b/ltt/ltt-relay-alloc.c @@ -614,6 +626,50 @@ int ltt_relay_read(struct rchan_buf *buf, size_t offset, EXPORT_SYMBOL_GPL(ltt_relay_read); /** + * ltt_relay_read_cstr : read a C-style string from ltt_relay_buffer. + * @buf : buffer + * @offset : offset within the buffer + * @dest : destination address + * @len : destination's length + * + * return string's length + */ +int ltt_relay_read_cstr(struct rchan_buf *buf, size_t offset, + void *dest, size_t len) +{ + struct buf_page *page; + ssize_t pagecpy, pagelen, strpagelen, orig_offset = offset; + char *str; + + offset &= buf->chan->alloc_size - 1; + page = buf->rpage; + for (;;) { + page = ltt_relay_cache_page(buf, &buf->rpage, page, offset); + str = (char *)page_address(page->page) + (offset & ~PAGE_MASK); + pagelen = PAGE_SIZE - (offset & ~PAGE_MASK); + strpagelen = strnlen(str, pagelen); + if (len) { + pagecpy = min_t(size_t, len, strpagelen); + memcpy(dest, str, pagecpy); + len -= pagecpy; + dest += pagecpy; + } + offset += strpagelen; + if (strpagelen < pagelen) + break; + /* + * Underlying layer should never ask for reads across + * subbuffers. + */ + WARN_ON(offset >= buf->chan->alloc_size); + } + if (len) + ((char *)dest)[0] = 0; + return offset - orig_offset; +} +EXPORT_SYMBOL_GPL(ltt_relay_read_cstr); + +/** * ltt_relay_read_get_page : Get a whole page to read from * @buf : buffer * @offset : offset within the buffer