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
11namespace fs {
12
13#ifdef __Fuchsia__
14
15zx_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