]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
metadump: support writing discontiguous io cursors
authorDave Chinner <dchinner@redhat.com>
Mon, 3 Feb 2014 22:35:36 +0000 (09:35 +1100)
committerDave Chinner <david@fromorbit.com>
Mon, 3 Feb 2014 22:35:36 +0000 (09:35 +1100)
To handle discontiguous buffers, metadump needs to be able to handle
io cursrors that use discontiguous buffer mappings. Factor
write_buf() to extract the data copy routine and use that to
implement support for both flat and discontiguous buffer maps.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
db/metadump.c

index 4104fcbdd6597bdbd36c47910b8e00a7739ccc1c..a8bc297ec89cb785b8ef8528e22be8c55a07c94d 100644 (file)
@@ -166,12 +166,34 @@ write_index(void)
        return 0;
 }
 
+/*
+ * Return 0 for success, -errno for failure.
+ */
+static int
+write_buf_segment(
+       char            *data,
+       __int64_t       off,
+       int             len)
+{
+       int             i;
+       int             ret;
+
+       for (i = 0; i < len; i++, off++, data += BBSIZE) {
+               block_index[cur_index] = cpu_to_be64(off);
+               memcpy(&block_buffer[cur_index << BBSHIFT], data, BBSIZE);
+               if (++cur_index == num_indicies) {
+                       ret = write_index();
+                       if (ret)
+                               return -EIO;
+               }
+       }
+       return 0;
+}
+
 static int
 write_buf(
        iocur_t         *buf)
 {
-       char            *data;
-       __int64_t       off;
        int             i;
        int             ret;
 
@@ -191,15 +213,20 @@ write_buf(
                }
        }
 
-       for (i = 0, off = buf->bb, data = buf->data;
-                       i < buf->blen;
-                       i++, off++, data += BBSIZE) {
-               block_index[cur_index] = cpu_to_be64(off);
-               memcpy(&block_buffer[cur_index << BBSHIFT], data, BBSIZE);
-               if (++cur_index == num_indicies) {
-                       ret = write_index();
+       /* handle discontiguous buffers */
+       if (!buf->bbmap) {
+               ret = write_buf_segment(buf->data, buf->bb, buf->blen);
+               if (ret)
+                       return ret;
+       } else {
+               int     len = 0;
+               for (i = 0; i < buf->bbmap->nmaps; i++) {
+                       ret = write_buf_segment(buf->data + BBTOB(len),
+                                               buf->bbmap->b[i].bm_bn,
+                                               buf->bbmap->b[i].bm_len);
                        if (ret)
                                return ret;
+                       len += buf->bbmap->b[i].bm_len;
                }
        }
        return seenint() ? -EINTR : 0;