[PATCH 2/2] rbd: skip empty blocks during import

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Check for empty blocks while importing an image.

When a read block only consists of zeroes, the import is simply
skipping the write. This way you non-sparse images will become sparse
rbd images.

Signed-off-by: Christian Brunner <chb@xxxxxx>
---
 src/rbd.cc |   44 ++++++++++++++++++++++++++------------------
 1 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/src/rbd.cc b/src/rbd.cc
index 0476cc5..d2b5b5a 100644
--- a/src/rbd.cc
+++ b/src/rbd.cc
@@ -513,7 +513,7 @@ static int do_import(librbd::RBD &rbd, librados::IoCtx& io_ctx,
       while (cur_seg) {
         bufferptr p(cur_seg);
         //cerr << "reading " << cur_seg << " bytes at offset " << file_pos << std::endl;
-	ssize_t rval;
+	ssize_t rval, i;
 	if(extent == 0 && fiemap->fm_extents[extent].fe_logical == 0) {
 	  rval = TEMP_FAILURE_RETRY(::read(fd, p.c_str(), cur_seg));
 	} else {
@@ -529,23 +529,31 @@ static int do_import(librbd::RBD &rbd, librados::IoCtx& io_ctx,
           r = 0;
           goto done;
         }
-        bufferlist bl;
-        bl.append(p);
-        librbd::RBD::AioCompletion *completion = new librbd::RBD::AioCompletion(NULL, NULL);
-        if (!completion) {
-          r = -ENOMEM;
-          goto done;
-        }
-        r = image.aio_write(file_pos, len, bl, completion);
-        if (r < 0)
-          goto done;
-	completion->wait_for_complete();
-	r = completion->get_return_value();
-	completion->release();
-        if (r < 0) {
-          cerr << "error writing to image block" << std::endl;
-          goto done;
-        }
+
+	/* Skip empty blocks */
+	char *pcstr = p.c_str();
+        for (i=0 ; i < len; i++) {
+	  if (pcstr[i] != 0) {
+            bufferlist bl;
+            bl.append(p);
+	    librbd::RBD::AioCompletion *completion = new librbd::RBD::AioCompletion(NULL, NULL);
+	    if (!completion) {
+	      r = -ENOMEM;
+              goto done;
+	    }
+	    r = image.aio_write(file_pos, len, bl, completion);
+	    if (r < 0)
+	      goto done;
+	    completion->wait_for_complete();
+	    r = completion->get_return_value();
+	    completion->release();
+	    if (r < 0) {
+	      cerr << "error writing to image block" << std::endl;
+	      goto done;
+	    }
+	    break;
+	  }
+	}
 
         file_pos += len;
         cur_seg -= len;
-- 
1.7.1


--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [CEPH Users]     [Ceph Large]     [Information on CEPH]     [Linux BTRFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux