aboutsummaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
Diffstat (limited to 'block')
-rw-r--r--block/export/fuse.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/block/export/fuse.c b/block/export/fuse.c
index fdda8e3..5029e70 100644
--- a/block/export/fuse.c
+++ b/block/export/fuse.c
@@ -86,8 +86,8 @@ static int fuse_export_create(BlockExport *blk_exp,
assert(blk_exp_args->type == BLOCK_EXPORT_TYPE_FUSE);
- /* For growable exports, take the RESIZE permission */
- if (args->growable) {
+ /* For growable and writable exports, take the RESIZE permission */
+ if (args->growable || blk_exp_args->writable) {
uint64_t blk_perm, blk_shared_perm;
blk_get_perm(exp->common.blk, &blk_perm, &blk_shared_perm);
@@ -392,14 +392,23 @@ static int fuse_do_truncate(const FuseExport *exp, int64_t size,
{
uint64_t blk_perm, blk_shared_perm;
BdrvRequestFlags truncate_flags = 0;
- int ret;
+ bool add_resize_perm;
+ int ret, ret_check;
+
+ /* Growable and writable exports have a permanent RESIZE permission */
+ add_resize_perm = !exp->growable && !exp->writable;
if (req_zero_write) {
truncate_flags |= BDRV_REQ_ZERO_WRITE;
}
- /* Growable exports have a permanent RESIZE permission */
- if (!exp->growable) {
+ if (add_resize_perm) {
+
+ if (!qemu_in_main_thread()) {
+ /* Changing permissions like below only works in the main thread */
+ return -EPERM;
+ }
+
blk_get_perm(exp->common.blk, &blk_perm, &blk_shared_perm);
ret = blk_set_perm(exp->common.blk, blk_perm | BLK_PERM_RESIZE,
@@ -412,9 +421,11 @@ static int fuse_do_truncate(const FuseExport *exp, int64_t size,
ret = blk_truncate(exp->common.blk, size, true, prealloc,
truncate_flags, NULL);
- if (!exp->growable) {
+ if (add_resize_perm) {
/* Must succeed, because we are only giving up the RESIZE permission */
- blk_set_perm(exp->common.blk, blk_perm, blk_shared_perm, &error_abort);
+ ret_check = blk_set_perm(exp->common.blk, blk_perm,
+ blk_shared_perm, &error_abort);
+ assert(ret_check == 0);
}
return ret;