]> git.sesse.net Git - bcachefs-tools-debian/blob - bcache.c
bcacheadm: add capacity command
[bcachefs-tools-debian] / bcache.c
1 #define _GNU_SOURCE
2
3 #include <ctype.h>
4 #include <errno.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <stdint.h>
8 #include <fcntl.h>
9 #include <inttypes.h>
10 #include <getopt.h>
11 #include <limits.h>
12 #include <linux/fs.h>
13 #include <stdbool.h>
14 #include <string.h>
15 #include <sys/ioctl.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <dirent.h>
19 #include <unistd.h>
20 #include <uuid/uuid.h>
21 #include <blkid.h>
22
23 #include "bcache.h"
24
25 #define __KERNEL__
26 #include <linux/bcache-ioctl.h>
27 #undef __KERNEL__
28
29 const char * const cache_state[] = {
30         "active",
31         "ro",
32         "failed",
33         "spare",
34         NULL
35 };
36
37 const char * const replacement_policies[] = {
38         "lru",
39         "fifo",
40         "random",
41         NULL
42 };
43
44 const char * const csum_types[] = {
45         "none",
46         "crc32c",
47         "crc64",
48         NULL
49 };
50
51 const char * const bdev_cache_mode[] = {
52         "writethrough",
53         "writeback",
54         "writearound",
55         "none",
56         NULL
57 };
58
59 const char * const bdev_state[] = {
60         "detached",
61         "clean",
62         "dirty",
63         "inconsistent",
64         NULL
65 };
66
67 char *skip_spaces(const char *str)
68 {
69         while (isspace(*str))
70                 ++str;
71         return (char *)str;
72 }
73
74 char *strim(char *s)
75 {
76         size_t size;
77         char *end;
78
79         s = skip_spaces(s);
80         size = strlen(s);
81         if (!size)
82                 return s;
83
84         end = s + size - 1;
85         while (end >= s && isspace(*end))
86                 end--;
87         *(end + 1) = '\0';
88
89         return s;
90 }
91
92 ssize_t read_string_list(const char *buf, const char * const list[])
93 {
94         size_t i;
95         char *s, *d = strdup(buf);
96         if (!d)
97                 return -ENOMEM;
98
99         s = strim(d);
100
101         for (i = 0; list[i]; i++)
102                 if (!strcmp(list[i], s))
103                         break;
104
105         free(d);
106
107         if (!list[i])
108                 return -EINVAL;
109
110         return i;
111 }
112
113 ssize_t read_string_list_or_die(const char *opt, const char * const list[],
114                                 const char *msg)
115 {
116         ssize_t v = read_string_list(opt, list);
117         if (v < 0) {
118                 fprintf(stderr, "Bad %s %s\n", msg, opt);
119                 exit(EXIT_FAILURE);
120
121         }
122
123         return v;
124 }
125
126 void print_string_list(const char * const list[], size_t selected)
127 {
128         size_t i;
129
130         for (i = 0; list[i]; i++) {
131                 if (i)
132                         putchar(' ');
133                 printf(i == selected ? "[%s] ": "%s", list[i]);
134         }
135 }
136
137 /*
138  * This is the CRC-32C table
139  * Generated with:
140  * width = 32 bits
141  * poly = 0x1EDC6F41
142  * reflect input bytes = true
143  * reflect output bytes = true
144  */
145
146 static const u32 crc32c_table[256] = {
147         0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
148         0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
149         0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
150         0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
151         0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
152         0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
153         0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
154         0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
155         0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
156         0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
157         0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
158         0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
159         0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
160         0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
161         0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
162         0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
163         0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
164         0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
165         0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
166         0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
167         0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
168         0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
169         0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
170         0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
171         0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
172         0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
173         0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
174         0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
175         0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
176         0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
177         0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
178         0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
179         0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
180         0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
181         0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
182         0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
183         0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
184         0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
185         0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
186         0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
187         0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
188         0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
189         0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
190         0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
191         0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
192         0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
193         0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
194         0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
195         0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
196         0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
197         0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
198         0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
199         0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
200         0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
201         0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
202         0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
203         0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
204         0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
205         0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
206         0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
207         0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
208         0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
209         0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
210         0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
211 };
212
213 /*
214  * Steps through buffer one byte at at time, calculates reflected
215  * crc using table.
216  */
217
218 static u32 crc32c(u32 crc, unsigned char const *data, size_t length)
219 {
220         while (length--)
221                 crc =
222                     crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8);
223         return crc;
224 }
225
226 /*
227  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group (Any
228  * use permitted, subject to terms of PostgreSQL license; see.)
229
230  * If we have a 64-bit integer type, then a 64-bit CRC looks just like the
231  * usual sort of implementation. (See Ross Williams' excellent introduction
232  * A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS, available from
233  * ftp://ftp.rocksoft.com/papers/crc_v3.txt or several other net sites.)
234  * If we have no working 64-bit type, then fake it with two 32-bit registers.
235  *
236  * The present implementation is a normal (not "reflected", in Williams'
237  * terms) 64-bit CRC, using initial all-ones register contents and a final
238  * bit inversion. The chosen polynomial is borrowed from the DLT1 spec
239  * (ECMA-182, available from http://www.ecma.ch/ecma1/STAND/ECMA-182.HTM):
240  *
241  * x^64 + x^62 + x^57 + x^55 + x^54 + x^53 + x^52 + x^47 + x^46 + x^45 +
242  * x^40 + x^39 + x^38 + x^37 + x^35 + x^33 + x^32 + x^31 + x^29 + x^27 +
243  * x^24 + x^23 + x^22 + x^21 + x^19 + x^17 + x^13 + x^12 + x^10 + x^9 +
244  * x^7 + x^4 + x + 1
245 */
246
247 static const uint64_t crc_table[256] = {
248         0x0000000000000000ULL, 0x42F0E1EBA9EA3693ULL, 0x85E1C3D753D46D26ULL,
249         0xC711223CFA3E5BB5ULL, 0x493366450E42ECDFULL, 0x0BC387AEA7A8DA4CULL,
250         0xCCD2A5925D9681F9ULL, 0x8E224479F47CB76AULL, 0x9266CC8A1C85D9BEULL,
251         0xD0962D61B56FEF2DULL, 0x17870F5D4F51B498ULL, 0x5577EEB6E6BB820BULL,
252         0xDB55AACF12C73561ULL, 0x99A54B24BB2D03F2ULL, 0x5EB4691841135847ULL,
253         0x1C4488F3E8F96ED4ULL, 0x663D78FF90E185EFULL, 0x24CD9914390BB37CULL,
254         0xE3DCBB28C335E8C9ULL, 0xA12C5AC36ADFDE5AULL, 0x2F0E1EBA9EA36930ULL,
255         0x6DFEFF5137495FA3ULL, 0xAAEFDD6DCD770416ULL, 0xE81F3C86649D3285ULL,
256         0xF45BB4758C645C51ULL, 0xB6AB559E258E6AC2ULL, 0x71BA77A2DFB03177ULL,
257         0x334A9649765A07E4ULL, 0xBD68D2308226B08EULL, 0xFF9833DB2BCC861DULL,
258         0x388911E7D1F2DDA8ULL, 0x7A79F00C7818EB3BULL, 0xCC7AF1FF21C30BDEULL,
259         0x8E8A101488293D4DULL, 0x499B3228721766F8ULL, 0x0B6BD3C3DBFD506BULL,
260         0x854997BA2F81E701ULL, 0xC7B97651866BD192ULL, 0x00A8546D7C558A27ULL,
261         0x4258B586D5BFBCB4ULL, 0x5E1C3D753D46D260ULL, 0x1CECDC9E94ACE4F3ULL,
262         0xDBFDFEA26E92BF46ULL, 0x990D1F49C77889D5ULL, 0x172F5B3033043EBFULL,
263         0x55DFBADB9AEE082CULL, 0x92CE98E760D05399ULL, 0xD03E790CC93A650AULL,
264         0xAA478900B1228E31ULL, 0xE8B768EB18C8B8A2ULL, 0x2FA64AD7E2F6E317ULL,
265         0x6D56AB3C4B1CD584ULL, 0xE374EF45BF6062EEULL, 0xA1840EAE168A547DULL,
266         0x66952C92ECB40FC8ULL, 0x2465CD79455E395BULL, 0x3821458AADA7578FULL,
267         0x7AD1A461044D611CULL, 0xBDC0865DFE733AA9ULL, 0xFF3067B657990C3AULL,
268         0x711223CFA3E5BB50ULL, 0x33E2C2240A0F8DC3ULL, 0xF4F3E018F031D676ULL,
269         0xB60301F359DBE0E5ULL, 0xDA050215EA6C212FULL, 0x98F5E3FE438617BCULL,
270         0x5FE4C1C2B9B84C09ULL, 0x1D14202910527A9AULL, 0x93366450E42ECDF0ULL,
271         0xD1C685BB4DC4FB63ULL, 0x16D7A787B7FAA0D6ULL, 0x5427466C1E109645ULL,
272         0x4863CE9FF6E9F891ULL, 0x0A932F745F03CE02ULL, 0xCD820D48A53D95B7ULL,
273         0x8F72ECA30CD7A324ULL, 0x0150A8DAF8AB144EULL, 0x43A04931514122DDULL,
274         0x84B16B0DAB7F7968ULL, 0xC6418AE602954FFBULL, 0xBC387AEA7A8DA4C0ULL,
275         0xFEC89B01D3679253ULL, 0x39D9B93D2959C9E6ULL, 0x7B2958D680B3FF75ULL,
276         0xF50B1CAF74CF481FULL, 0xB7FBFD44DD257E8CULL, 0x70EADF78271B2539ULL,
277         0x321A3E938EF113AAULL, 0x2E5EB66066087D7EULL, 0x6CAE578BCFE24BEDULL,
278         0xABBF75B735DC1058ULL, 0xE94F945C9C3626CBULL, 0x676DD025684A91A1ULL,
279         0x259D31CEC1A0A732ULL, 0xE28C13F23B9EFC87ULL, 0xA07CF2199274CA14ULL,
280         0x167FF3EACBAF2AF1ULL, 0x548F120162451C62ULL, 0x939E303D987B47D7ULL,
281         0xD16ED1D631917144ULL, 0x5F4C95AFC5EDC62EULL, 0x1DBC74446C07F0BDULL,
282         0xDAAD56789639AB08ULL, 0x985DB7933FD39D9BULL, 0x84193F60D72AF34FULL,
283         0xC6E9DE8B7EC0C5DCULL, 0x01F8FCB784FE9E69ULL, 0x43081D5C2D14A8FAULL,
284         0xCD2A5925D9681F90ULL, 0x8FDAB8CE70822903ULL, 0x48CB9AF28ABC72B6ULL,
285         0x0A3B7B1923564425ULL, 0x70428B155B4EAF1EULL, 0x32B26AFEF2A4998DULL,
286         0xF5A348C2089AC238ULL, 0xB753A929A170F4ABULL, 0x3971ED50550C43C1ULL,
287         0x7B810CBBFCE67552ULL, 0xBC902E8706D82EE7ULL, 0xFE60CF6CAF321874ULL,
288         0xE224479F47CB76A0ULL, 0xA0D4A674EE214033ULL, 0x67C58448141F1B86ULL,
289         0x253565A3BDF52D15ULL, 0xAB1721DA49899A7FULL, 0xE9E7C031E063ACECULL,
290         0x2EF6E20D1A5DF759ULL, 0x6C0603E6B3B7C1CAULL, 0xF6FAE5C07D3274CDULL,
291         0xB40A042BD4D8425EULL, 0x731B26172EE619EBULL, 0x31EBC7FC870C2F78ULL,
292         0xBFC9838573709812ULL, 0xFD39626EDA9AAE81ULL, 0x3A28405220A4F534ULL,
293         0x78D8A1B9894EC3A7ULL, 0x649C294A61B7AD73ULL, 0x266CC8A1C85D9BE0ULL,
294         0xE17DEA9D3263C055ULL, 0xA38D0B769B89F6C6ULL, 0x2DAF4F0F6FF541ACULL,
295         0x6F5FAEE4C61F773FULL, 0xA84E8CD83C212C8AULL, 0xEABE6D3395CB1A19ULL,
296         0x90C79D3FEDD3F122ULL, 0xD2377CD44439C7B1ULL, 0x15265EE8BE079C04ULL,
297         0x57D6BF0317EDAA97ULL, 0xD9F4FB7AE3911DFDULL, 0x9B041A914A7B2B6EULL,
298         0x5C1538ADB04570DBULL, 0x1EE5D94619AF4648ULL, 0x02A151B5F156289CULL,
299         0x4051B05E58BC1E0FULL, 0x87409262A28245BAULL, 0xC5B073890B687329ULL,
300         0x4B9237F0FF14C443ULL, 0x0962D61B56FEF2D0ULL, 0xCE73F427ACC0A965ULL,
301         0x8C8315CC052A9FF6ULL, 0x3A80143F5CF17F13ULL, 0x7870F5D4F51B4980ULL,
302         0xBF61D7E80F251235ULL, 0xFD913603A6CF24A6ULL, 0x73B3727A52B393CCULL,
303         0x31439391FB59A55FULL, 0xF652B1AD0167FEEAULL, 0xB4A25046A88DC879ULL,
304         0xA8E6D8B54074A6ADULL, 0xEA16395EE99E903EULL, 0x2D071B6213A0CB8BULL,
305         0x6FF7FA89BA4AFD18ULL, 0xE1D5BEF04E364A72ULL, 0xA3255F1BE7DC7CE1ULL,
306         0x64347D271DE22754ULL, 0x26C49CCCB40811C7ULL, 0x5CBD6CC0CC10FAFCULL,
307         0x1E4D8D2B65FACC6FULL, 0xD95CAF179FC497DAULL, 0x9BAC4EFC362EA149ULL,
308         0x158E0A85C2521623ULL, 0x577EEB6E6BB820B0ULL, 0x906FC95291867B05ULL,
309         0xD29F28B9386C4D96ULL, 0xCEDBA04AD0952342ULL, 0x8C2B41A1797F15D1ULL,
310         0x4B3A639D83414E64ULL, 0x09CA82762AAB78F7ULL, 0x87E8C60FDED7CF9DULL,
311         0xC51827E4773DF90EULL, 0x020905D88D03A2BBULL, 0x40F9E43324E99428ULL,
312         0x2CFFE7D5975E55E2ULL, 0x6E0F063E3EB46371ULL, 0xA91E2402C48A38C4ULL,
313         0xEBEEC5E96D600E57ULL, 0x65CC8190991CB93DULL, 0x273C607B30F68FAEULL,
314         0xE02D4247CAC8D41BULL, 0xA2DDA3AC6322E288ULL, 0xBE992B5F8BDB8C5CULL,
315         0xFC69CAB42231BACFULL, 0x3B78E888D80FE17AULL, 0x7988096371E5D7E9ULL,
316         0xF7AA4D1A85996083ULL, 0xB55AACF12C735610ULL, 0x724B8ECDD64D0DA5ULL,
317         0x30BB6F267FA73B36ULL, 0x4AC29F2A07BFD00DULL, 0x08327EC1AE55E69EULL,
318         0xCF235CFD546BBD2BULL, 0x8DD3BD16FD818BB8ULL, 0x03F1F96F09FD3CD2ULL,
319         0x41011884A0170A41ULL, 0x86103AB85A2951F4ULL, 0xC4E0DB53F3C36767ULL,
320         0xD8A453A01B3A09B3ULL, 0x9A54B24BB2D03F20ULL, 0x5D45907748EE6495ULL,
321         0x1FB5719CE1045206ULL, 0x919735E51578E56CULL, 0xD367D40EBC92D3FFULL,
322         0x1476F63246AC884AULL, 0x568617D9EF46BED9ULL, 0xE085162AB69D5E3CULL,
323         0xA275F7C11F7768AFULL, 0x6564D5FDE549331AULL, 0x279434164CA30589ULL,
324         0xA9B6706FB8DFB2E3ULL, 0xEB46918411358470ULL, 0x2C57B3B8EB0BDFC5ULL,
325         0x6EA7525342E1E956ULL, 0x72E3DAA0AA188782ULL, 0x30133B4B03F2B111ULL,
326         0xF7021977F9CCEAA4ULL, 0xB5F2F89C5026DC37ULL, 0x3BD0BCE5A45A6B5DULL,
327         0x79205D0E0DB05DCEULL, 0xBE317F32F78E067BULL, 0xFCC19ED95E6430E8ULL,
328         0x86B86ED5267CDBD3ULL, 0xC4488F3E8F96ED40ULL, 0x0359AD0275A8B6F5ULL,
329         0x41A94CE9DC428066ULL, 0xCF8B0890283E370CULL, 0x8D7BE97B81D4019FULL,
330         0x4A6ACB477BEA5A2AULL, 0x089A2AACD2006CB9ULL, 0x14DEA25F3AF9026DULL,
331         0x562E43B4931334FEULL, 0x913F6188692D6F4BULL, 0xD3CF8063C0C759D8ULL,
332         0x5DEDC41A34BBEEB2ULL, 0x1F1D25F19D51D821ULL, 0xD80C07CD676F8394ULL,
333         0x9AFCE626CE85B507ULL
334 };
335
336 static uint64_t bch_crc64_update(uint64_t crc, const void *_data, size_t len)
337 {
338         const unsigned char *data = _data;
339
340         while (len--) {
341                 int i = ((int) (crc >> 56) ^ *data++) & 0xFF;
342                 crc = crc_table[i] ^ (crc << 8);
343         }
344
345         return crc;
346 }
347
348 static uint64_t bch_checksum_update(unsigned type, uint64_t crc, const void *data, size_t len)
349 {
350         switch (type) {
351         case BCH_CSUM_NONE:
352                 return 0;
353         case BCH_CSUM_CRC32C:
354                 return crc32c(crc, data, len);
355         case BCH_CSUM_CRC64:
356                 return bch_crc64_update(crc, data, len);
357         default:
358                 fprintf(stderr, "Unknown checksum type %u\n", type);
359                 exit(EXIT_FAILURE);
360         }
361 }
362
363 uint64_t bch_checksum(unsigned type, const void *data, size_t len)
364 {
365         uint64_t crc = 0xffffffffffffffffULL;
366
367         crc = bch_checksum_update(type, crc, data, len);
368
369         return crc ^ 0xffffffffffffffffULL;
370 }
371
372 uint64_t getblocks(int fd)
373 {
374         uint64_t ret;
375         struct stat statbuf;
376         if (fstat(fd, &statbuf)) {
377                 perror("getblocks: stat error\n");
378                 exit(EXIT_FAILURE);
379         }
380         ret = statbuf.st_size / 512;
381         if (S_ISBLK(statbuf.st_mode))
382                 if (ioctl(fd, BLKGETSIZE, &ret)) {
383                         perror("ioctl error getting blksize");
384                         exit(EXIT_FAILURE);
385                 }
386         return ret;
387 }
388
389 uint64_t hatoi(const char *s)
390 {
391         char *e;
392         long long i = strtoll(s, &e, 10);
393         switch (*e) {
394                 case 't':
395                 case 'T':
396                         i *= 1024;
397                 case 'g':
398                 case 'G':
399                         i *= 1024;
400                 case 'm':
401                 case 'M':
402                         i *= 1024;
403                 case 'k':
404                 case 'K':
405                         i *= 1024;
406         }
407         return i;
408 }
409
410 unsigned hatoi_validate(const char *s, const char *msg)
411 {
412         uint64_t v = hatoi(s);
413
414         if (v & (v - 1)) {
415                 fprintf(stderr, "%s must be a power of two\n", msg);
416                 exit(EXIT_FAILURE);
417         }
418
419         v /= 512;
420
421         if (v > USHRT_MAX) {
422                 fprintf(stderr, "%s too large\n", msg);
423                 exit(EXIT_FAILURE);
424         }
425
426         if (!v) {
427                 fprintf(stderr, "%s too small\n", msg);
428                 exit(EXIT_FAILURE);
429         }
430
431         return v;
432 }
433
434 static void do_write_sb(int fd, struct cache_sb *sb)
435 {
436         char zeroes[SB_START] = {0};
437         size_t bytes = ((void *) bset_bkey_last(sb)) - (void *) sb;
438
439         /* Zero start of disk */
440         if (pwrite(fd, zeroes, SB_START, 0) != SB_START) {
441                 perror("write error trying to zero start of disk\n");
442                 exit(EXIT_FAILURE);
443         }
444         /* Write superblock */
445         if (pwrite(fd, sb, bytes, SB_START) != bytes) {
446                 perror("write error trying to write superblock\n");
447                 exit(EXIT_FAILURE);
448         }
449
450         fsync(fd);
451         close(fd);
452 }
453
454 void write_backingdev_sb(int fd, unsigned block_size, unsigned *bucket_sizes,
455                                 bool writeback, uint64_t data_offset,
456                                 const char *label,
457                                 uuid_le set_uuid)
458 {
459         char uuid_str[40], set_uuid_str[40];
460         struct cache_sb sb;
461
462         memset(&sb, 0, sizeof(struct cache_sb));
463
464         sb.offset       = SB_SECTOR;
465         sb.version      = BCACHE_SB_VERSION_BDEV;
466         sb.magic        = BCACHE_MAGIC;
467         uuid_generate(sb.uuid.b);
468         sb.set_uuid     = set_uuid;
469         sb.bucket_size  = bucket_sizes[0];
470         sb.block_size   = block_size;
471
472         uuid_unparse(sb.uuid.b, uuid_str);
473         uuid_unparse(sb.set_uuid.b, set_uuid_str);
474         if (label)
475                 memcpy(sb.label, label, SB_LABEL_SIZE);
476
477         SET_BDEV_CACHE_MODE(&sb, writeback
478                             ? CACHE_MODE_WRITEBACK
479                             : CACHE_MODE_WRITETHROUGH);
480
481         if (data_offset != BDEV_DATA_START_DEFAULT) {
482                 sb.version = BCACHE_SB_VERSION_BDEV_WITH_OFFSET;
483                 sb.data_offset = data_offset;
484         }
485
486         sb.csum = csum_set(&sb, BCH_CSUM_CRC64);
487
488         printf("UUID:                   %s\n"
489                "Set UUID:               %s\n"
490                "version:                %u\n"
491                "block_size:             %u\n"
492                "data_offset:            %ju\n",
493                uuid_str, set_uuid_str,
494                (unsigned) sb.version,
495                sb.block_size,
496                data_offset);
497
498         do_write_sb(fd, &sb);
499 }
500
501 int dev_open(const char *dev, bool wipe_bcache)
502 {
503         struct cache_sb sb;
504         blkid_probe pr;
505         int fd;
506         char err[MAX_PATH];
507
508         if ((fd = open(dev, O_RDWR|O_EXCL)) == -1) {
509                 sprintf(err, "Can't open dev %s: %s\n", dev, strerror(errno));
510                 goto err;
511         }
512
513         if (pread(fd, &sb, sizeof(sb), SB_START) != sizeof(sb)) {
514                 sprintf(err, "Failed to read superblock");
515                 goto err;
516         }
517
518         if (!memcmp(&sb.magic, &BCACHE_MAGIC, 16) && !wipe_bcache) {
519                 sprintf(err, "Already a bcache device on %s, "
520                         "overwrite with --wipe-bcache\n", dev);
521                 goto err;
522         }
523
524         if (!(pr = blkid_new_probe())) {
525                 sprintf(err, "Failed to create a new probe");
526                 goto err;
527         }
528         if (blkid_probe_set_device(pr, fd, 0, 0)) {
529                 sprintf(err, "failed to set probe to device");
530                 goto err;
531         }
532         /* enable ptable probing; superblock probing is enabled by default */
533         if (blkid_probe_enable_partitions(pr, true)) {
534                 sprintf(err, "Failed to enable partitions on probe");
535                 goto err;
536         }
537         if (!blkid_do_probe(pr)) {
538                 /* XXX wipefs doesn't know how to remove partition tables */
539                 sprintf(err, "Device %s already has a non-bcache superblock, "
540                         "remove it using wipefs and wipefs -a\n", dev);
541                 goto err;
542         }
543
544         return fd;
545
546         err:
547                 fprintf(stderr, "dev_open failed with: %s", err);
548                 exit(EXIT_FAILURE);
549 }
550
551 static unsigned min_bucket_size(int num_bucket_sizes, unsigned *bucket_sizes)
552 {
553         int i;
554         unsigned min = bucket_sizes[0];
555
556         for (i = 0; i < num_bucket_sizes; i++)
557                 min = bucket_sizes[i] < min ? bucket_sizes[i] : min;
558
559         return min;
560 }
561
562 static unsigned node_size(unsigned bucket_size) {
563
564         if (bucket_size <= 256)
565                 return bucket_size;
566         else if (bucket_size <= 512)
567                 return bucket_size / 2;
568         else
569                 return bucket_size / 4;
570 }
571
572 void write_cache_sbs(int *fds, struct cache_sb *sb,
573                             unsigned block_size, unsigned *bucket_sizes,
574                                 int num_bucket_sizes)
575 {
576         char uuid_str[40], set_uuid_str[40];
577         size_t i;
578         unsigned min_size = min_bucket_size(num_bucket_sizes, bucket_sizes);
579
580         sb->offset      = SB_SECTOR;
581         sb->version     = BCACHE_SB_VERSION_CDEV_V3;
582         sb->magic       = BCACHE_MAGIC;
583         sb->block_size  = block_size;
584         sb->keys        = bch_journal_buckets_offset(sb);
585
586         /*
587          * don't have a userspace crc32c implementation handy, just always use
588          * crc64
589          */
590         SET_CACHE_SB_CSUM_TYPE(sb, BCH_CSUM_CRC64);
591
592         for (i = 0; i < sb->nr_in_set; i++) {
593                 struct cache_member *m = sb->members + i;
594
595                 if (num_bucket_sizes <= 1)
596                         sb->bucket_size = bucket_sizes[0];
597                 else
598                         sb->bucket_size = bucket_sizes[i];
599                 SET_CACHE_BTREE_NODE_SIZE(sb, node_size(min_size));
600
601                 sb->uuid = m->uuid;
602                 sb->nbuckets            = getblocks(fds[i]) / sb->bucket_size;
603                 sb->nr_this_dev         = i;
604                 sb->first_bucket        = (23 / sb->bucket_size) + 1;
605
606                 if (sb->nbuckets < 1 << 7) {
607                         fprintf(stderr, "Not enough buckets: %llu, need %u\n",
608                                 sb->nbuckets, 1 << 7);
609                         exit(EXIT_FAILURE);
610                 }
611
612                 sb->csum = csum_set(sb, CACHE_SB_CSUM_TYPE(sb));
613
614                 uuid_unparse(sb->uuid.b, uuid_str);
615                 uuid_unparse(sb->set_uuid.b, set_uuid_str);
616                 printf("UUID:                   %s\n"
617                        "Set UUID:               %s\n"
618                        "version:                %u\n"
619                        "nbuckets:               %llu\n"
620                        "block_size:             %u\n"
621                        "bucket_size:            %u\n"
622                        "nr_in_set:              %u\n"
623                        "nr_this_dev:            %u\n"
624                        "first_bucket:           %u\n",
625                        uuid_str, set_uuid_str,
626                        (unsigned) sb->version,
627                        sb->nbuckets,
628                        sb->block_size,
629                        sb->bucket_size,
630                        sb->nr_in_set,
631                        sb->nr_this_dev,
632                        sb->first_bucket);
633
634                 do_write_sb(fds[i], sb);
635         }
636 }
637
638 void next_cache_device(struct cache_sb *sb,
639                               unsigned replication_set,
640                               int tier,
641                               unsigned replacement_policy,
642                               bool discard)
643 {
644         struct cache_member *m = sb->members + sb->nr_in_set;
645
646         SET_CACHE_REPLICATION_SET(m, replication_set);
647         SET_CACHE_TIER(m, tier);
648         SET_CACHE_REPLACEMENT(m, replacement_policy);
649         SET_CACHE_DISCARD(m, discard);
650         uuid_generate(m->uuid.b);
651
652         sb->nr_in_set++;
653 }
654
655 unsigned get_blocksize(const char *path)
656 {
657         struct stat statbuf;
658
659         if (stat(path, &statbuf)) {
660                 fprintf(stderr, "Error statting %s: %s\n",
661                         path, strerror(errno));
662                 exit(EXIT_FAILURE);
663         }
664
665         if (S_ISBLK(statbuf.st_mode)) {
666                 /* check IO limits:
667                  * BLKALIGNOFF: alignment_offset
668                  * BLKPBSZGET: physical_block_size
669                  * BLKSSZGET: logical_block_size
670                  * BLKIOMIN: minimum_io_size
671                  * BLKIOOPT: optimal_io_size
672                  *
673                  * It may be tempting to use physical_block_size,
674                  * or even minimum_io_size.
675                  * But to be as transparent as possible,
676                  * we want to use logical_block_size.
677                  */
678                 unsigned int logical_block_size;
679                 int fd = open(path, O_RDONLY);
680
681                 if (fd < 0) {
682                         fprintf(stderr, "open(%s) failed: %m\n", path);
683                         exit(EXIT_FAILURE);
684                 }
685                 if (ioctl(fd, BLKSSZGET, &logical_block_size)) {
686                         fprintf(stderr, "ioctl(%s, BLKSSZGET) failed: %m\n", path);
687                         exit(EXIT_FAILURE);
688                 }
689                 close(fd);
690                 return logical_block_size / 512;
691
692         }
693         /* else: not a block device.
694          * Why would we even want to write a bcache super block there? */
695
696         return statbuf.st_blksize / 512;
697 }
698
699 long strtoul_or_die(const char *p, size_t max, const char *msg)
700 {
701         errno = 0;
702         long v = strtol(p, NULL, 10);
703         if (errno || v < 0 || v >= max) {
704                 fprintf(stderr, "Invalid %s %zi\n", msg, v);
705                 exit(EXIT_FAILURE);
706         }
707
708         return v;
709 }
710
711 static void print_encode(char *in)
712 {
713     char *pos;
714         for (pos = in; *pos; pos++)
715                 if (isalnum(*pos) || strchr(".-_", *pos))
716                         putchar(*pos);
717                 else
718                         printf("%%%x", *pos);
719 }
720
721 static void show_uuid_only(struct cache_sb *sb, char *dev_uuid) {
722         uuid_unparse(sb->uuid.b, dev_uuid);
723 }
724
725 static void show_super_common(struct cache_sb *sb, bool force_csum)
726 {
727         char uuid[40];
728         char label[SB_LABEL_SIZE + 1];
729         uint64_t expected_csum;
730
731         printf("sb.magic\t\t");
732         if (!memcmp(&sb->magic, &BCACHE_MAGIC, sizeof(sb->magic))) {
733                 printf("ok\n");
734         } else {
735                 printf("bad magic\n");
736                 fprintf(stderr, "Invalid superblock (bad magic)\n");
737                 exit(2);
738         }
739
740         printf("sb.first_sector\t\t%ju", (uint64_t) sb->offset);
741         if (sb->offset == SB_SECTOR) {
742                 printf(" [match]\n");
743         } else {
744                 printf(" [expected %ds]\n", SB_SECTOR);
745                 fprintf(stderr, "Invalid superblock (bad sector)\n");
746                 exit(2);
747         }
748
749         printf("sb.csum\t\t\t%ju", (uint64_t) sb->csum);
750         expected_csum = csum_set(sb,
751                                  sb->version < BCACHE_SB_VERSION_CDEV_V3
752                                  ? BCH_CSUM_CRC64
753                                  : CACHE_SB_CSUM_TYPE(sb));
754         if (sb->csum == expected_csum) {
755                 printf(" [match]\n");
756         } else {
757                 printf(" [expected %" PRIX64 "]\n", expected_csum);
758                 if (!force_csum) {
759                         fprintf(stderr, "Corrupt superblock (bad csum)\n");
760                         exit(2);
761                 }
762         }
763
764         printf("sb.version\t\t%ju", (uint64_t) sb->version);
765         switch (sb->version) {
766                 // These are handled the same by the kernel
767                 case BCACHE_SB_VERSION_CDEV:
768                 case BCACHE_SB_VERSION_CDEV_WITH_UUID:
769                         printf(" [cache device]\n");
770                         break;
771
772                 // The second adds data offset support
773                 case BCACHE_SB_VERSION_BDEV:
774                 case BCACHE_SB_VERSION_BDEV_WITH_OFFSET:
775                         printf(" [backing device]\n");
776                         break;
777
778                 default:
779                         printf(" [unknown]\n");
780                         // exit code?
781                         exit(EXIT_SUCCESS);
782         }
783
784         putchar('\n');
785
786         strncpy(label, (char *) sb->label, SB_LABEL_SIZE);
787         label[SB_LABEL_SIZE] = '\0';
788         printf("dev.label\t\t");
789         if (*label)
790                 print_encode(label);
791         else
792                 printf("(empty)");
793         putchar('\n');
794
795         uuid_unparse(sb->uuid.b, uuid);
796         printf("dev.uuid\t\t%s\n", uuid);
797
798         uuid_unparse(sb->set_uuid.b, uuid);
799         printf("cset.uuid\t\t%s\n", uuid);
800 }
801
802 void show_super_backingdev(struct cache_sb *sb, bool force_csum)
803 {
804         uint64_t first_sector;
805
806         show_super_common(sb, force_csum);
807
808         if (sb->version == BCACHE_SB_VERSION_BDEV) {
809                 first_sector = BDEV_DATA_START_DEFAULT;
810         } else {
811                 if (sb->keys == 1 || sb->d[0]) {
812                         fprintf(stderr,
813                                 "Possible experimental format detected, bailing\n");
814                         exit(3);
815                 }
816                 first_sector = sb->data_offset;
817         }
818
819         printf("dev.data.first_sector\t%ju\n"
820                "dev.data.cache_mode\t%s"
821                "dev.data.cache_state\t%s\n",
822                first_sector,
823                bdev_cache_mode[BDEV_CACHE_MODE(sb)],
824                bdev_state[BDEV_STATE(sb)]);
825 }
826
827 static void show_cache_member(struct cache_sb *sb, unsigned i)
828 {
829         struct cache_member *m = ((struct cache_member *) sb->d) + i;
830
831         printf("cache.state\t%s\n",             cache_state[CACHE_STATE(m)]);
832
833         printf("cache.tier\t%llu\n",            CACHE_TIER(m));
834
835         printf("cache.replication_set\t%llu\n", CACHE_REPLICATION_SET(m));
836         printf("cache.cur_meta_replicas\t%llu\n", REPLICATION_SET_CUR_META_REPLICAS(m));
837         printf("cache.cur_data_replicas\t%llu\n", REPLICATION_SET_CUR_DATA_REPLICAS(m));
838
839         printf("cache.has_metadata\t%llu\n",    CACHE_HAS_METADATA(m));
840         printf("cache.has_data\t%llu\n",        CACHE_HAS_DATA(m));
841
842         printf("cache.replacement\t%s\n",       replacement_policies[CACHE_REPLACEMENT(m)]);
843         printf("cache.discard\t%llu\n",         CACHE_DISCARD(m));
844 }
845
846 void show_super_cache(struct cache_sb *sb, bool force_csum)
847 {
848         show_super_common(sb, force_csum);
849
850         printf("dev.sectors_per_block\t%u\n"
851                "dev.sectors_per_bucket\t%u\n",
852                sb->block_size,
853                sb->bucket_size);
854
855         // total_sectors includes the superblock;
856         printf("dev.cache.first_sector\t%u\n"
857                "dev.cache.cache_sectors\t%llu\n"
858                "dev.cache.total_sectors\t%llu\n"
859                "dev.cache.ordered\t%s\n"
860                "dev.cache.pos\t\t%u\n"
861                "dev.cache.setsize\t\t%u\n",
862                sb->bucket_size * sb->first_bucket,
863                sb->bucket_size * (sb->nbuckets - sb->first_bucket),
864                sb->bucket_size * sb->nbuckets,
865                CACHE_SYNC(sb) ? "yes" : "no",
866                sb->nr_this_dev,
867                sb->nr_in_set);
868
869         show_cache_member(sb, sb->nr_this_dev);
870 }
871
872 static int __sysfs_attr_type(char *attr, const char **attr_arr) {
873         int i, j;
874         for(i = 0; attr_arr[i] != NULL; i++)
875                 if(!strcmp(attr, attr_arr[i]))
876                         return 1;
877         return 0;
878 }
879
880 enum sysfs_attr sysfs_attr_type(char *attr) {
881         int ret;
882         if(__sysfs_attr_type(attr, set_attrs))
883                 return SET_ATTR;
884         if(__sysfs_attr_type(attr, cache_attrs))
885                 return CACHE_ATTR;
886         if(__sysfs_attr_type(attr, internal_attrs))
887                 return INTERNAL_ATTR;
888
889         printf("No attribute called %s, try --list to see options\n", attr);
890
891         return -1;
892 }
893
894 static void __sysfs_attr_list(const char **attr_arr) {
895         int i, j;
896         for (i = 0; attr_arr[i] != NULL; i++)
897                 printf("%s\n", attr_arr[i]);
898 }
899
900 void sysfs_attr_list() {
901         __sysfs_attr_list(set_attrs);
902         __sysfs_attr_list(cache_attrs);
903         __sysfs_attr_list(internal_attrs);
904 }
905
906 struct cache_sb *query_dev(char *dev, bool force_csum,
907                 bool print_sb, bool uuid_only, char *dev_uuid)
908 {
909         struct cache_sb sb_stack, *sb = &sb_stack;
910         size_t bytes = sizeof(*sb);
911
912         int fd = open(dev, O_RDONLY);
913         if (fd < 0) {
914                 printf("Can't open dev %s: %s\n", dev, strerror(errno));
915                 return NULL;
916         }
917
918         if (pread(fd, sb, bytes, SB_START) != bytes) {
919                 fprintf(stderr, "Couldn't read\n");
920                 return NULL;
921         }
922
923         if (sb->keys) {
924                 bytes = sizeof(*sb) + sb->keys * sizeof(uint64_t);
925                 sb = malloc(bytes);
926
927                 if (pread(fd, sb, bytes, SB_START) != bytes) {
928                         fprintf(stderr, "Couldn't read\n");
929                         return NULL;
930                 }
931         }
932
933         if(uuid_only) {
934                 show_uuid_only(sb, dev_uuid);
935                 return sb;
936         }
937
938         if(print_sb) {
939                 if (!SB_IS_BDEV(sb))
940                         show_super_cache(sb, force_csum);
941                 else
942                         show_super_backingdev(sb, force_csum);
943         }
944
945         return sb;
946 }
947
948 static char *dev_name(const char *ugly_path) {
949         char buf[32];
950         int i, end = strlen(ugly_path);
951
952         //Chop off "/bcache", then look for the next '/' from the end
953         for (i = end - 8; ; i--)
954                 if(ugly_path[i] == '/')
955                         break;
956
957         strcpy(buf, ugly_path + i);
958         buf[end - i - 7] = 0;
959
960         // Is the dev guaranteed to be in /dev?
961         // This is needed for finding the superblock with a query-dev
962         return strdup(buf);
963 }
964
965 static void list_cacheset_devs(char *cset_dir, char *cset_name, bool parse_dev_name) {
966         int i = 0;
967         DIR *cachedir;
968         struct stat cache_stat;
969         char intbuf[4];
970         char entry[MAX_PATH];
971
972         snprintf(entry, MAX_PATH, "%s/%s/cache0", cset_dir, cset_name);
973         snprintf(intbuf, 4, "%d", i);
974
975         while(true) {
976                 char buf[MAX_PATH];
977                 int len;
978                 char *tmp;
979
980                 if((cachedir = opendir(entry)) == NULL)
981                         break;
982
983                 if(stat(entry, &cache_stat))
984                         break;
985
986                 if((len = readlink(entry, buf, sizeof(buf) - 1)) != -1) {
987                         buf[len] = '\0';
988                         if(parse_dev_name) {
989                                 tmp = dev_name(buf);
990                                 printf("/dev%s\n", tmp);
991                                 free(tmp);
992                         } else {
993                                 printf("\t%s\n", buf);
994                         }
995                 }
996
997                 /* remove i from end and append i++ */
998                 entry[strlen(entry)-strlen(intbuf)] = 0;
999                 i++;
1000                 snprintf(intbuf, 4, "%d", i);
1001                 strcat(entry, intbuf);
1002         }
1003 }
1004
1005 char *find_matching_uuid(char *stats_dir, char *subdir, const char *stats_dev_uuid) {
1006         /* Do a query-dev --uuid only to get the uuid
1007          * repeat on each dev until we find a matching one
1008          * append that cache# to subdir and return
1009          */
1010
1011         int i = 0;
1012         DIR *cachedir;
1013         struct stat cache_stat;
1014         char intbuf[4];
1015         char entry[MAX_PATH];
1016         char *err = NULL;
1017
1018         snprintf(entry, MAX_PATH, "%s%s", stats_dir, subdir);
1019         snprintf(intbuf, 4, "%d", i);
1020         strcat(entry, intbuf);
1021
1022         while(true) {
1023                 char buf[MAX_PATH];
1024                 int len;
1025
1026                 if((cachedir = opendir(entry)) == NULL)
1027                         break;
1028
1029                 if(stat(entry, &cache_stat))
1030                         break;
1031
1032                 if((len = readlink(entry, buf, sizeof(buf) - 1)) != -1) {
1033                         char dev_uuid[40];
1034                         buf[len] = '\0';
1035                         int i, end = strlen(buf);
1036                         char tmp[32], devname[32];
1037                         struct cache_sb *sb;
1038
1039                         /* Chop off "/bcache", then look for the
1040                          * next '/' from the end
1041                          */
1042                         for (i = end - 8; ; i--)
1043                                 if(buf[i] == '/')
1044                                         break;
1045
1046                         strcpy(tmp, buf + i);
1047                         tmp[end - i - 7] = 0;
1048                         strcpy(devname, "/dev");
1049                         strcat(devname, tmp);
1050
1051                         err = "Unable to open superblock";
1052                         sb = query_dev(devname, false, false, true, dev_uuid);
1053                         if(!sb)
1054                                 return err;
1055
1056                         if(!strcmp(stats_dev_uuid, dev_uuid)) {
1057                                 strcat(subdir, intbuf);
1058                                 return NULL;
1059                         }
1060                 }
1061
1062                 /* remove i from end and append i++ */
1063                 entry[strlen(entry)-strlen(intbuf)] = 0;
1064                 i++;
1065                 snprintf(intbuf, 4, "%d", i);
1066                 strcat(entry, intbuf);
1067         }
1068
1069
1070         err = "dev uuid doesn't exist in cache_set";
1071         return err;
1072 }
1073
1074 char *list_cachesets(char *cset_dir, bool list_devs)
1075 {
1076         struct dirent *ent;
1077         DIR *dir;
1078         char *err = NULL;
1079
1080         dir = opendir(cset_dir);
1081         if (!dir) {
1082                 err = "Failed to open cacheset dir";
1083                 goto err;
1084         }
1085
1086         while ((ent = readdir(dir)) != NULL) {
1087                 struct stat statbuf;
1088                 char entry[MAX_PATH];
1089
1090                 if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
1091                         continue;
1092
1093                 snprintf(entry, MAX_PATH, "%s/%s", cset_dir, ent->d_name);
1094                 if(stat(entry, &statbuf) == -1) {
1095                         err = "Failed to stat cacheset subdir";
1096                         goto err;
1097                 }
1098
1099                 if (S_ISDIR(statbuf.st_mode)) {
1100                         printf("%s\n", ent->d_name);
1101
1102                         if(list_devs) {
1103                                 list_cacheset_devs(cset_dir, ent->d_name, true);
1104                         }
1105                 }
1106         }
1107
1108 err:
1109         closedir(dir);
1110         return err;
1111 }
1112
1113 char *register_bcache(char *const *devs)
1114 {
1115         int ret, bcachefd;
1116         char *err = NULL;
1117
1118         bcachefd = open("/dev/bcache", O_RDWR);
1119         if (bcachefd < 0) {
1120                 err = "Can't open bcache device";
1121                 goto err;
1122         }
1123
1124         ret = ioctl(bcachefd, BCH_IOCTL_REGISTER, devs);
1125         if (ret < 0) {
1126                 char tmp[64];
1127                 snprintf(tmp, 64, "ioctl register error: %s\n",
1128                                 strerror(ret));
1129                 err = strdup(tmp);
1130                 goto err;
1131         }
1132
1133 err:
1134         if (bcachefd)
1135                 close(bcachefd);
1136         return err;
1137 }
1138
1139 char *unregister_bcache(char *const *devs)
1140 {
1141         int ret, bcachefd;
1142         char *err = NULL;
1143
1144         bcachefd = open("/dev/bcache", O_RDWR);
1145         if (bcachefd < 0) {
1146                 err = "Can't open bcache device";
1147                 goto err;
1148         }
1149
1150         ret = ioctl(bcachefd, BCH_IOCTL_UNREGISTER, devs);
1151         if (ret < 0) {
1152                 char tmp[64];
1153                 snprintf(tmp, 64, "ioctl unregister error: %s\n",
1154                                 strerror(ret));
1155                 err = strdup(tmp);
1156                 goto err;
1157         }
1158
1159 err:
1160         close(bcachefd);
1161         return err;
1162 }
1163
1164 char *add_devices(char *const *devs, char *uuid)
1165 {
1166         int ret, bcachefd;
1167         char *err = NULL;
1168
1169         bcachefd = open("/dev/bcache", O_RDWR);
1170         if (bcachefd < 0) {
1171                 err = "Can't open bcache device";
1172                 goto err;
1173         }
1174
1175         struct bch_ioctl_add_disks ia;
1176         ia.devs = devs;
1177         ia.uuid = uuid;
1178
1179         ret = ioctl(bcachefd, BCH_IOCTL_ADD_DISKS, &ia);
1180         if (ret < 0) {
1181                 char tmp[128];
1182                 snprintf(tmp, 128, "ioctl add disk error: %s\n",
1183                                 strerror(ret));
1184                 err = strdup(tmp);
1185         }
1186
1187 err:
1188         close(bcachefd);
1189         return err;
1190 }
1191
1192 char *remove_device(const char *dev, bool force)
1193 {
1194         int ret, bcachefd;
1195         char *err = NULL;
1196
1197         bcachefd = open("/dev/bcache", O_RDWR);
1198         if (bcachefd < 0) {
1199                 err = "Can't open bcache device";
1200                 goto err;
1201         }
1202
1203         struct bch_ioctl_rm_disk ir;
1204         ir.dev = dev;
1205         ir.force = force ? 1 : 0;
1206
1207         ret = ioctl(bcachefd, BCH_IOCTL_RM_DISK, &ir);
1208         if (ret < 0) {
1209                 char tmp[128];
1210                 snprintf(tmp, 128, "ioctl add disk error: %s\n",
1211                                 strerror(ret));
1212                 err = strdup(tmp);
1213         }
1214
1215 err:
1216         close(bcachefd);
1217         return err;
1218 }
1219
1220 char *probe(char *dev, int udev)
1221 {
1222         struct cache_sb sb;
1223         char uuid[40];
1224         blkid_probe pr;
1225         char *err = NULL;
1226
1227         int fd = open(dev, O_RDONLY);
1228         if (fd == -1) {
1229                 err = "Got file descriptor -1 trying to open dev";
1230                 goto err;
1231         }
1232
1233         if (!(pr = blkid_new_probe())) {
1234                 err = "Failed trying to get a blkid for new probe";
1235                 goto err;
1236         }
1237
1238         if (blkid_probe_set_device(pr, fd, 0, 0)) {
1239                 err = "Failed blkid probe set device";
1240                 goto err;
1241         }
1242
1243         /* probe partitions too */
1244         if (blkid_probe_enable_partitions(pr, true)) {
1245                 err = "Enable probe partitions";
1246                 goto err;
1247         }
1248
1249         /* bail if anything was found
1250          * probe-bcache isn't needed once blkid recognizes bcache */
1251         if (!blkid_do_probe(pr)) {
1252                 err = "blkid recognizes bcache";
1253                 goto err;
1254         }
1255
1256         if (pread(fd, &sb, sizeof(sb), SB_START) != sizeof(sb)) {
1257                 err = "Failed to read superblock";
1258                 goto err;
1259         }
1260
1261         if (memcmp(&sb.magic, &BCACHE_MAGIC, sizeof(sb.magic))) {
1262                 err = "Bcache magic incorrect";
1263                 goto err;
1264         }
1265
1266         uuid_unparse(sb.uuid.b, uuid);
1267
1268         if (udev)
1269                 printf("ID_FS_UUID=%s\n"
1270                        "ID_FS_UUID_ENC=%s\n"
1271                        "ID_FS_TYPE=bcache\n",
1272                        uuid, uuid);
1273         else
1274                 printf("%s: UUID=\"\" TYPE=\"bcache\"\n", uuid);
1275
1276         return 0;
1277
1278 err:
1279         return err;
1280 }
1281
1282 char *read_stat_dir(DIR *dir, char *stats_dir, char *stat_name, char *ret)
1283 {
1284         struct stat statbuf;
1285         char entry[MAX_PATH];
1286         char *err = NULL;
1287
1288         snprintf(entry, MAX_PATH, "%s/%s", stats_dir, stat_name);
1289         if(stat(entry, &statbuf) == -1) {
1290                 char tmp[MAX_PATH];
1291                 snprintf(tmp, MAX_PATH, "Failed to stat %s\n", entry);
1292                 err = strdup(tmp);
1293                 goto err;
1294         }
1295
1296         if (S_ISREG(statbuf.st_mode)) {
1297                 char buf[MAX_PATH];
1298                 FILE *fp = NULL;
1299
1300                 fp = fopen(entry, "r");
1301                 if(!fp) {
1302                         /* If we can't open the file, this is probably because
1303                          * of permissions, just move to the next file */
1304                         return NULL;
1305                 }
1306
1307                 while(fgets(ret, MAX_PATH, fp));
1308                 fclose(fp);
1309         }
1310 err:
1311         return err;
1312 }
1313
1314 char *bcache_get_capacity(const char *cset_dir, const char *capacity_uuid,
1315                 bool show_devs)
1316 {
1317         char *err = NULL;
1318         char bucket_size_path[MAX_PATH];
1319         char nbuckets_path[MAX_PATH];
1320         char avail_buckets_path[MAX_PATH];
1321         char cache_path[MAX_PATH];
1322
1323         double bucket_sizes[MAX_DEVS];
1324         double nbuckets[MAX_DEVS];
1325         double avail_buckets[MAX_DEVS];
1326         char *dev_names[MAX_DEVS];
1327         int dev_count = 0, i;
1328         char intbuf[4];
1329         double total_cap = 0, total_free = 0;
1330         int precision = 2;
1331
1332         snprintf(intbuf, 4, "%d", i);
1333         snprintf(bucket_size_path, MAX_PATH, "%s/%s/%s/%s", cset_dir,
1334                         capacity_uuid, "cache0", "bucket_size_bytes");
1335         snprintf(nbuckets_path, MAX_PATH, "%s/%s/%s/%s", cset_dir,
1336                         capacity_uuid, "cache0", "nbuckets");
1337         snprintf(avail_buckets_path, MAX_PATH, "%s/%s/%s/%s", cset_dir,
1338                         capacity_uuid, "cache0", "available_buckets");
1339         snprintf(cache_path, MAX_PATH, "%s/%s/%s", cset_dir, capacity_uuid,
1340                         "cache0");
1341
1342         while(true) {
1343                 char buf[MAX_PATH];
1344                 int len;
1345                 DIR *cache_dir;
1346
1347                 if((cache_dir = opendir(cache_path)) == NULL)
1348                         break;
1349
1350                 err = read_stat_dir(cache_dir, cache_path,
1351                                 "bucket_size_bytes", buf);
1352                 if (err)
1353                         goto err;
1354                 else
1355                         bucket_sizes[dev_count] = atof(buf);
1356
1357                 err = read_stat_dir(cache_dir, cache_path,
1358                                 "nbuckets", buf);
1359                 if (err)
1360                         goto err;
1361                 else
1362                         nbuckets[dev_count] = atof(buf);
1363
1364                 err = read_stat_dir(cache_dir, cache_path,
1365                                 "available_buckets", buf);
1366                 if (err)
1367                         goto err;
1368                 else
1369                         avail_buckets[dev_count] = atof(buf);
1370
1371                 if((len = readlink(cache_path, buf, sizeof(buf) - 1)) != -1) {
1372                         buf[len] = '\0';
1373                         dev_names[dev_count] = dev_name(buf);
1374                 }
1375
1376                 /* remove i/stat and append i++/stat */
1377                 bucket_size_path[strlen(cache_path) - strlen(intbuf)] = 0;
1378                 nbuckets_path[strlen(cache_path) - strlen(intbuf)] = 0;
1379                 avail_buckets_path[strlen(cache_path) - strlen(intbuf)] = 0;
1380                 cache_path[strlen(cache_path) - strlen(intbuf)] = 0;
1381
1382                 dev_count++;
1383
1384                 snprintf(intbuf, 4, "%d", dev_count);
1385                 strcat(cache_path, intbuf);
1386                 strcat(bucket_size_path, intbuf);
1387                 strcat(nbuckets_path, intbuf);
1388                 strcat(avail_buckets_path, intbuf);
1389         }
1390
1391         printf("%-15s%-25s%-25s\n", "Device Name", "Capacity (512 Blocks)", "Free (512 Blocks)");
1392
1393         if (show_devs) {
1394                 for (i = 0; i < dev_count; i++) {
1395                         printf("%s%-11s%-25.*f%-25.*f\n", "/dev", dev_names[i],
1396                                 precision,
1397                                 (bucket_sizes[i] * nbuckets[i]) / 512,
1398                                 precision,
1399                                 (bucket_sizes[i] * avail_buckets[i]) / 512);
1400                 }
1401         }
1402
1403         for (i = 0; i < dev_count; i++) {
1404                 total_cap += (bucket_sizes[i] * nbuckets[i]) / 512;
1405                 total_free += (bucket_sizes[i] * avail_buckets[i]) / 512;
1406
1407         }
1408
1409         printf("%-15s%-25.*f%-25.*f\n", "Total", precision, total_cap,
1410                         precision, total_free);
1411
1412 err:
1413         for (i = 0; i < dev_count; i++)
1414                 if (dev_names[i])
1415                         free(dev_names[i]);
1416         return err;
1417 }