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