source: mainline/uspace/srv/volsrv/empty.c@ edebb4a1

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since edebb4a1 was 4b6635a7, checked in by Jiri Svoboda <jiri@…>, 10 years ago

Volsrv empty partition detection.

  • Property mode set to 100644
File size: 3.6 KB
Line 
1/*
2 * Copyright (c) 2015 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup volsrv
30 * @{
31 */
32/**
33 * @file Empty partition handling
34 * @brief
35 */
36
37#include <block.h>
38#include <errno.h>
39#include <io/log.h>
40#include <loc.h>
41#include <stdlib.h>
42
43#include "empty.h"
44
45static bool mem_is_zero(void *buf, size_t size)
46{
47 uint8_t *bp;
48 size_t i;
49
50 bp = (uint8_t *)buf;
51 for (i = 0; i < size; i++) {
52 if (bp[i] != 0)
53 return false;
54 }
55
56 return true;
57}
58
59int vol_part_is_empty(service_id_t sid, bool *rempty)
60{
61 int rc;
62 bool block_inited = false;
63 void *buf = NULL;
64 aoff64_t nblocks;
65 aoff64_t n;
66 aoff64_t i;
67 size_t block_size;
68 bool empty;
69
70 rc = block_init(EXCHANGE_SERIALIZE, sid, 2048);
71 if (rc != EOK) {
72 log_msg(LOG_DEFAULT, LVL_ERROR, "Error opening "
73 "block device service %zu", sid);
74 rc = EIO;
75 goto error;
76 }
77
78 block_inited = true;
79
80 rc = block_get_bsize(sid, &block_size);
81 if (rc != EOK) {
82 log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
83 "block size.");
84 rc = EIO;
85 goto error;
86 }
87
88 rc = block_get_nblocks(sid, &nblocks);
89 if (rc != EOK) {
90 log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
91 "number of blocks.");
92 rc = EIO;
93 goto error;
94 }
95
96 /* Check first 16 kiB / 16 blocks, whichever is more */
97 n = (16384 + block_size - 1) / block_size;
98 if (n < 16)
99 n = 16;
100 /*
101 * Limit to half of the device so we do not process the same blocks
102 * twice
103 */
104 if (n > (nblocks + 1) / 2)
105 n = (nblocks + 1) / 2;
106
107 buf = calloc(block_size, 1);
108 if (buf == NULL) {
109 log_msg(LOG_DEFAULT, LVL_ERROR, "Error allocating buffer.");
110 rc = ENOMEM;
111 goto error;
112 }
113
114 empty = true;
115
116 for (i = 0; i < n; i++) {
117 rc = block_read_direct(sid, i, 1, buf);
118 if (rc != EOK) {
119 log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
120 "reading blocks.");
121 rc = EIO;
122 goto error;
123 }
124
125 if (!mem_is_zero(buf, block_size)) {
126 empty = false;
127 goto done;
128 }
129 }
130
131 for (i = 0; i < n; i++) {
132 rc = block_read_direct(sid, nblocks - n + i, 1, buf);
133 if (rc != EOK) {
134 log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
135 "reading blocks.");
136 rc = EIO;
137 goto error;
138 }
139
140 if (!mem_is_zero(buf, block_size)) {
141 empty = false;
142 goto done;
143 }
144 }
145
146done:
147 block_fini(sid);
148 free(buf);
149 *rempty = empty;
150 return EOK;
151error:
152 if (block_inited)
153 block_fini(sid);
154 if (buf != NULL)
155 free(buf);
156 return rc;
157}
158
159/** @}
160 */
Note: See TracBrowser for help on using the repository browser.