Skip to content

Commit

Permalink
Merge pull request #5764 from dachary/wip-12847-hammer
Browse files Browse the repository at this point in the history
common: do not insert emtpy ptr when rebuild emtpy bufferlist

Reviewed-by: Sage Weil <sage@redhat.com>
  • Loading branch information
Loic Dachary committed Sep 7, 2015
2 parents 5ef999e + aa00373 commit e9db807
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 50 deletions.
105 changes: 55 additions & 50 deletions src/common/buffer.cc
Expand Up @@ -1206,6 +1206,10 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;

void buffer::list::rebuild()
{
if (_len == 0) {
_buffers.clear();
return;
}
ptr nb;
if ((_len & ~CEPH_PAGE_MASK) == 0)
nb = buffer::create_page_aligned(_len);
Expand All @@ -1225,60 +1229,61 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
}
_memcopy_count += pos;
_buffers.clear();
_buffers.push_back(nb);
if (nb.length())
_buffers.push_back(nb);
}

void buffer::list::rebuild_aligned(unsigned align)
{
rebuild_aligned_size_and_memory(align, align);
}

void buffer::list::rebuild_aligned_size_and_memory(unsigned align_size,
unsigned align_memory)
{
std::list<ptr>::iterator p = _buffers.begin();
while (p != _buffers.end()) {
// keep anything that's already align and sized aligned
if (p->is_aligned(align_memory) && p->is_n_align_sized(align_size)) {
/*cout << " segment " << (void*)p->c_str()
<< " offset " << ((unsigned long)p->c_str() & (align - 1))
<< " length " << p->length()
<< " " << (p->length() & (align - 1)) << " ok" << std::endl;
*/
++p;
continue;
void buffer::list::rebuild_aligned(unsigned align)
{
rebuild_aligned_size_and_memory(align, align);
}

void buffer::list::rebuild_aligned_size_and_memory(unsigned align_size,
unsigned align_memory)
{
std::list<ptr>::iterator p = _buffers.begin();
while (p != _buffers.end()) {
// keep anything that's already align and sized aligned
if (p->is_aligned(align_memory) && p->is_n_align_sized(align_size)) {
/*cout << " segment " << (void*)p->c_str()
<< " offset " << ((unsigned long)p->c_str() & (align - 1))
<< " length " << p->length()
<< " " << (p->length() & (align - 1)) << " ok" << std::endl;
*/
++p;
continue;
}

// consolidate unaligned items, until we get something that is sized+aligned
list unaligned;
unsigned offset = 0;
do {
/*cout << " segment " << (void*)p->c_str()
<< " offset " << ((unsigned long)p->c_str() & (align - 1))
<< " length " << p->length() << " " << (p->length() & (align - 1))
<< " overall offset " << offset << " " << (offset & (align - 1))
<< " not ok" << std::endl;
*/
offset += p->length();
unaligned.push_back(*p);
_buffers.erase(p++);
} while (p != _buffers.end() &&
(!p->is_aligned(align_memory) ||
!p->is_n_align_sized(align_size) ||
(offset % align_size)));
if (!(unaligned.is_contiguous() && unaligned._buffers.front().is_aligned(align_memory))) {
ptr nb(buffer::create_aligned(unaligned._len, align_memory));
unaligned.rebuild(nb);
_memcopy_count += unaligned._len;
}
_buffers.insert(p, unaligned._buffers.front());
}

// consolidate unaligned items, until we get something that is sized+aligned
list unaligned;
unsigned offset = 0;
do {
/*cout << " segment " << (void*)p->c_str()
<< " offset " << ((unsigned long)p->c_str() & (align - 1))
<< " length " << p->length() << " " << (p->length() & (align - 1))
<< " overall offset " << offset << " " << (offset & (align - 1))
<< " not ok" << std::endl;
*/
offset += p->length();
unaligned.push_back(*p);
_buffers.erase(p++);
} while (p != _buffers.end() &&
(!p->is_aligned(align_memory) ||
!p->is_n_align_sized(align_size) ||
(offset % align_size)));
if (!(unaligned.is_contiguous() && unaligned._buffers.front().is_aligned(align_memory))) {
ptr nb(buffer::create_aligned(unaligned._len, align_memory));
unaligned.rebuild(nb);
_memcopy_count += unaligned._len;
}
_buffers.insert(p, unaligned._buffers.front());
}
}

void buffer::list::rebuild_page_aligned()
{
rebuild_aligned(CEPH_PAGE_SIZE);
}

void buffer::list::rebuild_page_aligned()
{
rebuild_aligned(CEPH_PAGE_SIZE);
}

// sort-of-like-assignment-op
void buffer::list::claim(list& bl, unsigned int flags)
Expand Down
13 changes: 13 additions & 0 deletions src/test/bufferlist.cc
Expand Up @@ -1421,6 +1421,19 @@ TEST(BufferList, rebuild) {
EXPECT_TRUE(bl.is_page_aligned());
EXPECT_EQ((unsigned)1, bl.buffers().size());
}
{
bufferlist bl;
char t1[] = "X";
bufferlist a2;
a2.append(t1, 1);
bl.rebuild();
bl.append(a2);
EXPECT_EQ((unsigned)1, bl.length());
bufferlist::iterator p = bl.begin();
char dst[1];
p.copy(1, dst);
EXPECT_EQ(0, memcmp(dst, "X", 1));
}
}

TEST(BufferList, rebuild_page_aligned) {
Expand Down

0 comments on commit e9db807

Please sign in to comment.