ldout(cct, 20) << "aio_write " << ictx << " off = " << off << " len = "
<< len << " buf = " << (void*)buf << dendl;
- if (!len)
- return 0;
-
int r = ictx_check(ictx);
if (r < 0)
return r;
// map
vector<ObjectExtent> extents;
- Striper::file_to_extents(ictx->cct, ictx->format_string, &ictx->layout, off, mylen, 0, extents);
+ if (len > 0) {
+ Striper::file_to_extents(ictx->cct, ictx->format_string,
+ &ictx->layout, off, mylen, 0, extents);
+ }
c->get();
c->init_time(ictx, AIO_TYPE_WRITE);
for (vector<ObjectExtent>::iterator p = extents.begin(); p != extents.end(); ++p) {
ldout(cct, 20) << " oid " << p->oid << " " << p->offset << "~" << p->length
<< " from " << p->buffer_extents << dendl;
-
// assemble extent
bufferlist bl;
for (vector<pair<uint64_t,uint64_t> >::iterator q = p->buffer_extents.begin();
ldout(cct, 20) << "aio_discard " << ictx << " off = " << off << " len = "
<< len << dendl;
- if (!len)
- return 0;
-
int r = ictx_check(ictx);
if (r < 0)
return r;
// map
vector<ObjectExtent> extents;
- Striper::file_to_extents(ictx->cct, ictx->format_string, &ictx->layout, off, len, 0, extents);
+ if (len > 0) {
+ Striper::file_to_extents(ictx->cct, ictx->format_string,
+ &ictx->layout, off, len, 0, extents);
+ }
c->get();
c->init_time(ictx, AIO_TYPE_DISCARD);
r = clip_io(ictx, p->first, &len);
if (r < 0)
return r;
+ if (len == 0)
+ continue;
Striper::file_to_extents(ictx->cct, ictx->format_string, &ictx->layout,
p->first, len, 0, object_extents, buffer_ofs);
ASSERT_EQ(0, destroy_one_pool_pp(pool_name, rados));
}
+TEST(LibRBD, ZeroLengthWrite)
+{
+ rados_t cluster;
+ rados_ioctx_t ioctx;
+ string pool_name = get_temp_pool_name();
+ ASSERT_EQ("", create_one_pool(pool_name, &cluster));
+ rados_ioctx_create(cluster, pool_name.c_str(), &ioctx);
+
+ rbd_image_t image;
+ int order = 0;
+ const char *name = "testimg";
+ uint64_t size = 2 << 20;
+
+ ASSERT_EQ(0, create_image(ioctx, name, size, &order));
+ ASSERT_EQ(0, rbd_open(ioctx, name, &image, NULL));
+
+ char read_data[1];
+ ASSERT_EQ(0, rbd_write(image, 0, 0, NULL));
+ ASSERT_EQ(1, rbd_read(image, 0, 1, read_data));
+ ASSERT_EQ('\0', read_data[0]);
+
+ ASSERT_EQ(0, rbd_close(image));
+
+ rados_ioctx_destroy(ioctx);
+ ASSERT_EQ(0, destroy_one_pool(pool_name, &cluster));
+}
+
+
+TEST(LibRBD, ZeroLengthDiscard)
+{
+ rados_t cluster;
+ rados_ioctx_t ioctx;
+ string pool_name = get_temp_pool_name();
+ ASSERT_EQ("", create_one_pool(pool_name, &cluster));
+ rados_ioctx_create(cluster, pool_name.c_str(), &ioctx);
+
+ rbd_image_t image;
+ int order = 0;
+ const char *name = "testimg";
+ uint64_t size = 2 << 20;
+
+ ASSERT_EQ(0, create_image(ioctx, name, size, &order));
+ ASSERT_EQ(0, rbd_open(ioctx, name, &image, NULL));
+
+ const char *data = "blah";
+ char read_data[strlen(data)];
+ ASSERT_EQ((int)strlen(data), rbd_write(image, 0, strlen(data), data));
+ ASSERT_EQ(0, rbd_discard(image, 0, 0));
+ ASSERT_EQ((int)strlen(data), rbd_read(image, 0, strlen(data), read_data));
+ ASSERT_EQ(0, memcmp(data, read_data, strlen(data)));
+
+ ASSERT_EQ(0, rbd_close(image));
+
+ rados_ioctx_destroy(ioctx);
+ ASSERT_EQ(0, destroy_one_pool(pool_name, &cluster));
+}
+
+TEST(LibRBD, ZeroLengthRead)
+{
+ rados_t cluster;
+ rados_ioctx_t ioctx;
+ string pool_name = get_temp_pool_name();
+ ASSERT_EQ("", create_one_pool(pool_name, &cluster));
+ rados_ioctx_create(cluster, pool_name.c_str(), &ioctx);
+
+ rbd_image_t image;
+ int order = 0;
+ const char *name = "testimg";
+ uint64_t size = 2 << 20;
+
+ ASSERT_EQ(0, create_image(ioctx, name, size, &order));
+ ASSERT_EQ(0, rbd_open(ioctx, name, &image, NULL));
+
+ char read_data[1];
+ ASSERT_EQ(0, rbd_read(image, 0, 0, read_data));
+
+ ASSERT_EQ(0, rbd_close(image));
+
+ rados_ioctx_destroy(ioctx);
+ ASSERT_EQ(0, destroy_one_pool(pool_name, &cluster));
+}
+
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);