From mboxrd@z Thu Jan 1 00:00:00 1970 From: compudj@krystal.dyndns.org (Mathieu Desnoyers) Date: Mon, 23 Feb 2009 12:46:43 -0500 Subject: [ltt-dev] [PATCH take2 04/13] read C-style string from ltt-relay buffer In-Reply-To: <498A5D8B.3080809@cn.fujitsu.com> References: <498A5D8B.3080809@cn.fujitsu.com> Message-ID: <20090223174643.GD31815@Krystal> * Lai Jiangshan (laijs at cn.fujitsu.com) wrote: > 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 > --- > diff --git a/include/linux/ltt-relay.h b/include/linux/ltt-relay.h > index 1225a6a..437b2d9 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 e15f244..4b8e4c3 100644 > --- a/ltt/ltt-relay-alloc.c > +++ b/ltt/ltt-relay-alloc.c > @@ -614,6 +614,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; if orig_offset is >= buf->chan->alloc_size, this mask will make the return offset - orig_offset; return a huge value. It's not expected isn't it ? That should be : offset &= buf->chan->alloc_size - 1; orig_offset = offset; instead. This assumes the read will never cross subbuffers, which is ensured by the WARN_ON below. Mathieu > + 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 > > > > _______________________________________________ > ltt-dev mailing list > ltt-dev at lists.casi.polymtl.ca > http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev > -- Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68