block: Introduce blk_set_allow_write_beyond_eof()
authorKevin Wolf <kwolf@redhat.com>
Tue, 8 Mar 2016 15:39:49 +0000 (16:39 +0100)
committerKevin Wolf <kwolf@redhat.com>
Mon, 14 Mar 2016 15:46:43 +0000 (16:46 +0100)
We check that the guest can't write beyond the end of its disk, but for
other internal users it can make sense to allow growing a file.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
block/block-backend.c
include/sysemu/block-backend.h

index ebdf78a11cfcaf721028b5f6eb0deef5daf2fb05..03e71b43687fbba0fdc1390e0f0fd6fae68c51a0 100644 (file)
@@ -50,6 +50,8 @@ struct BlockBackend {
     bool iostatus_enabled;
     BlockDeviceIoStatus iostatus;
 
+    bool allow_write_beyond_eof;
+
     NotifierList remove_bs_notifiers, insert_bs_notifiers;
 };
 
@@ -579,6 +581,11 @@ void blk_iostatus_set_err(BlockBackend *blk, int error)
     }
 }
 
+void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow)
+{
+    blk->allow_write_beyond_eof = allow;
+}
+
 static int blk_check_byte_request(BlockBackend *blk, int64_t offset,
                                   size_t size)
 {
@@ -592,17 +599,19 @@ static int blk_check_byte_request(BlockBackend *blk, int64_t offset,
         return -ENOMEDIUM;
     }
 
-    len = blk_getlength(blk);
-    if (len < 0) {
-        return len;
-    }
-
     if (offset < 0) {
         return -EIO;
     }
 
-    if (offset > len || len - offset < size) {
-        return -EIO;
+    if (!blk->allow_write_beyond_eof) {
+        len = blk_getlength(blk);
+        if (len < 0) {
+            return len;
+        }
+
+        if (offset > len || len - offset < size) {
+            return -EIO;
+        }
     }
 
     return 0;
index 66c5cf22e1e749bc7e41dd4121c6895588a28627..00d69baa079df64495d974897f0a51f9b358b2d0 100644 (file)
@@ -78,6 +78,7 @@ void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs);
 
 void blk_hide_on_behalf_of_hmp_drive_del(BlockBackend *blk);
 
+void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow);
 void blk_iostatus_enable(BlockBackend *blk);
 bool blk_iostatus_is_enabled(const BlockBackend *blk);
 BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk);