1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <stdlib.h>
6 
7 #ifdef __Fuchsia__
8 #include <zircon/device/block.h>
9 #endif
10 
11 namespace fs {
12 
13 #ifdef __Fuchsia__
14 
fvm_reset_volume_slices(int fd)15 zx_status_t fvm_reset_volume_slices(int fd) {
16     query_request_t request;
17     query_response_t response;
18 
19     request.count = 1;
20     request.vslice_start[0] = 1;
21 
22     while (true) {
23         ssize_t r = ioctl_block_fvm_vslice_query(fd, &request, &response);
24         zx_status_t status = (r <= 0) ? static_cast<zx_status_t>(r) : ZX_OK;
25         if (status == ZX_ERR_OUT_OF_RANGE) {
26             return ZX_OK;
27         }
28         if (status != ZX_OK) {
29             return status;
30         }
31         if (response.count != 1 || response.vslice_range[0].count == 0) {
32             return ZX_ERR_IO;
33         }
34 
35         // Free any slices that were allocated
36         if (response.vslice_range[0].allocated) {
37             extend_request_t shrink;
38             shrink.offset = request.vslice_start[0];
39             shrink.length = response.vslice_range[0].count;
40 
41             r = ioctl_block_fvm_shrink(fd, &shrink);
42             status = (r <= 0) ? static_cast<zx_status_t>(r) : ZX_OK;
43             if (status != ZX_OK) {
44                 return status;
45             }
46         }
47 
48         // Move to the next portion of the block address space
49         request.vslice_start[0] += response.vslice_range[0].count;
50     }
51 }
52 
53 #endif
54 
55 } // namespace fs
56