15 #include <sys/ioctl.h>
16 #include <sys/types.h>
20 #include <uuid/uuid.h>
26 #include <linux/bcache-ioctl.h>
29 const char * const cache_state[] = {
37 const char * const replacement_policies[] = {
44 const char * const csum_types[] = {
51 const char * const bdev_cache_mode[] = {
59 const char * const bdev_state[] = {
67 const char * const set_attrs[] = {
69 "btree_scan_ratelimit",
70 "bucket_reserve_percent",
71 "cache_reserve_percent",
73 "congested_read_threshold_us",
74 "congested_write_threshold_us",
77 "foreground_target_percent",
81 "sector_reserve_percent",
86 const char * const cache_attrs[] = {
87 "cache_replacement_policy",
94 const char * const internal_attrs[] = {
95 "btree_shrinker_disabled",
97 "foreground_write_rate",
103 char *skip_spaces(const char *str)
105 while (isspace(*str))
121 while (end >= s && isspace(*end))
128 ssize_t read_string_list(const char *buf, const char * const list[])
131 char *s, *d = strdup(buf);
137 for (i = 0; list[i]; i++)
138 if (!strcmp(list[i], s))
149 ssize_t read_string_list_or_die(const char *opt, const char * const list[],
152 ssize_t v = read_string_list(opt, list);
154 fprintf(stderr, "Bad %s %s\n", msg, opt);
162 void print_string_list(const char * const list[], size_t selected)
166 for (i = 0; list[i]; i++) {
169 printf(i == selected ? "[%s] ": "%s", list[i]);
174 * This is the CRC-32C table
178 * reflect input bytes = true
179 * reflect output bytes = true
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
250 * Steps through buffer one byte at at time, calculates reflected
254 static u32 crc32c(u32 crc, unsigned char const *data, size_t length)
258 crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8);
263 * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group (Any
264 * use permitted, subject to terms of PostgreSQL license; see.)
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.
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):
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 +
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
372 static uint64_t bch_crc64_update(uint64_t crc, const void *_data, size_t len)
374 const unsigned char *data = _data;
377 int i = ((int) (crc >> 56) ^ *data++) & 0xFF;
378 crc = crc_table[i] ^ (crc << 8);
384 static uint64_t bch_checksum_update(unsigned type, uint64_t crc, const void *data, size_t len)
389 case BCH_CSUM_CRC32C:
390 return crc32c(crc, data, len);
392 return bch_crc64_update(crc, data, len);
394 fprintf(stderr, "Unknown checksum type %u\n", type);
399 uint64_t bch_checksum(unsigned type, const void *data, size_t len)
401 uint64_t crc = 0xffffffffffffffffULL;
403 crc = bch_checksum_update(type, crc, data, len);
405 return crc ^ 0xffffffffffffffffULL;
408 uint64_t getblocks(int fd)
412 if (fstat(fd, &statbuf)) {
413 perror("getblocks: stat error\n");
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");
425 uint64_t hatoi(const char *s)
428 long long i = strtoll(s, &e, 10);
446 unsigned hatoi_validate(const char *s, const char *msg)
448 uint64_t v = hatoi(s);
451 fprintf(stderr, "%s must be a power of two\n", msg);
458 fprintf(stderr, "%s too large\n", msg);
463 fprintf(stderr, "%s too small\n", msg);
470 static void do_write_sb(int fd, struct cache_sb *sb)
472 char zeroes[SB_START] = {0};
473 size_t bytes = ((void *) __bset_bkey_last(sb)) - (void *) sb;
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");
480 /* Write superblock */
481 if (pwrite(fd, sb, bytes, SB_START) != bytes) {
482 perror("write error trying to write superblock\n");
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)
494 char uuid_str[40], set_uuid_str[40];
497 memset(&sb, 0, sizeof(struct cache_sb));
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;
507 uuid_unparse(sb.disk_uuid.b, uuid_str);
508 uuid_unparse(sb.user_uuid.b, set_uuid_str);
510 memcpy(sb.label, label, SB_LABEL_SIZE);
512 SET_BDEV_CACHE_MODE(&sb, mode);
514 if (data_offset != BDEV_DATA_START_DEFAULT) {
515 sb.version = BCACHE_SB_VERSION_BDEV_WITH_OFFSET;
516 sb.bdev_data_offset = data_offset;
519 sb.csum = csum_set(&sb, BCH_CSUM_CRC64);
525 "data_offset: %ju\n",
526 uuid_str, set_uuid_str,
527 (unsigned) sb.version,
531 do_write_sb(fd, &sb);
534 int dev_open(const char *dev, bool wipe_bcache)
541 if ((fd = open(dev, O_RDWR|O_EXCL)) == -1) {
542 sprintf(err, "Can't open dev %s: %s\n", dev, strerror(errno));
546 if (pread(fd, &sb, sizeof(sb), SB_START) != sizeof(sb)) {
547 sprintf(err, "Failed to read superblock");
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);
557 if (!(pr = blkid_new_probe())) {
558 sprintf(err, "Failed to create a new probe");
561 if (blkid_probe_set_device(pr, fd, 0, 0)) {
562 sprintf(err, "failed to set probe to device");
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");
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);
580 fprintf(stderr, "dev_open failed with: %s", err);
584 void write_cache_sbs(int *fds, struct cache_sb *sb,
585 unsigned block_size, unsigned *bucket_sizes,
586 int num_bucket_sizes, unsigned btree_node_size)
588 char uuid_str[40], set_uuid_str[40];
591 if (!btree_node_size) {
592 btree_node_size = 512;
594 for (i = 0; i < num_bucket_sizes; i++)
595 btree_node_size = min(btree_node_size,
599 sb->offset = SB_SECTOR;
600 sb->version = BCACHE_SB_VERSION_CDEV_V3;
601 sb->magic = BCACHE_MAGIC;
602 sb->block_size = block_size;
603 sb->u64s = bch_journal_buckets_offset(sb);
606 * don't have a userspace crc32c implementation handy, just always use
609 SET_CACHE_SB_CSUM_TYPE(sb, BCH_CSUM_CRC64);
611 for (i = 0; i < sb->nr_in_set; i++) {
612 struct cache_member *m = sb->members + i;
614 if (num_bucket_sizes <= 1) {
615 m->bucket_size = bucket_sizes[0];
617 if (!bucket_sizes[i]) {
618 printf("No bucket size specified for cache %zu,"
619 " using the default of %u",
621 m->bucket_size = bucket_sizes[0];
623 m->bucket_size = bucket_sizes[i];
627 m->nbuckets = getblocks(fds[i]) / m->bucket_size;
628 m->first_bucket = (23 / m->bucket_size) + 1;
630 if (m->nbuckets < 1 << 7) {
631 fprintf(stderr, "Not enough buckets: %llu, need %u\n",
632 m->nbuckets, 1 << 7);
637 for (i = 0; i < sb->nr_in_set; i++) {
638 struct cache_member *m = sb->members + i;
640 SET_CACHE_BTREE_NODE_SIZE(sb, btree_node_size);
643 sb->disk_uuid = m->uuid;
646 sb->csum = csum_set(sb, CACHE_SB_CSUM_TYPE(sb));
648 uuid_unparse(sb->disk_uuid.b, uuid_str);
649 uuid_unparse(sb->user_uuid.b, set_uuid_str);
658 "first_bucket: %u\n",
659 uuid_str, set_uuid_str,
660 (unsigned) sb->version,
668 do_write_sb(fds[i], sb);
672 void next_cache_device(struct cache_sb *sb,
673 unsigned replication_set,
675 unsigned replacement_policy,
678 struct cache_member *m = sb->members + sb->nr_in_set;
680 SET_CACHE_REPLICATION_SET(m, replication_set);
681 SET_CACHE_TIER(m, tier);
682 SET_CACHE_REPLACEMENT(m, replacement_policy);
683 SET_CACHE_DISCARD(m, discard);
684 uuid_generate(m->uuid.b);
689 unsigned get_blocksize(const char *path)
693 if (stat(path, &statbuf)) {
694 fprintf(stderr, "Error statting %s: %s\n",
695 path, strerror(errno));
699 if (S_ISBLK(statbuf.st_mode)) {
701 * BLKALIGNOFF: alignment_offset
702 * BLKPBSZGET: physical_block_size
703 * BLKSSZGET: logical_block_size
704 * BLKIOMIN: minimum_io_size
705 * BLKIOOPT: optimal_io_size
707 * It may be tempting to use physical_block_size,
708 * or even minimum_io_size.
709 * But to be as transparent as possible,
710 * we want to use logical_block_size.
712 unsigned int logical_block_size;
713 int fd = open(path, O_RDONLY);
716 fprintf(stderr, "open(%s) failed: %m\n", path);
719 if (ioctl(fd, BLKSSZGET, &logical_block_size)) {
720 fprintf(stderr, "ioctl(%s, BLKSSZGET) failed: %m\n", path);
724 return logical_block_size / 512;
727 /* else: not a block device.
728 * Why would we even want to write a bcache super block there? */
730 return statbuf.st_blksize / 512;
733 long strtoul_or_die(const char *p, size_t max, const char *msg)
736 long v = strtol(p, NULL, 10);
737 if (errno || v < 0 || v >= max) {
738 fprintf(stderr, "Invalid %s %zi\n", msg, v);
745 static void print_encode(char *in)
748 for (pos = in; *pos; pos++)
749 if (isalnum(*pos) || strchr(".-_", *pos))
752 printf("%%%x", *pos);
755 static void show_uuid_only(struct cache_sb *sb, char *dev_uuid) {
756 uuid_unparse(sb->disk_uuid.b, dev_uuid);
759 static void show_super_common(struct cache_sb *sb, bool force_csum)
762 char label[SB_LABEL_SIZE + 1];
763 uint64_t expected_csum;
765 printf("sb.magic\t\t");
766 if (!memcmp(&sb->magic, &BCACHE_MAGIC, sizeof(sb->magic))) {
769 printf("bad magic\n");
770 fprintf(stderr, "Invalid superblock (bad magic)\n");
774 printf("sb.first_sector\t\t%ju", (uint64_t) sb->offset);
775 if (sb->offset == SB_SECTOR) {
776 printf(" [match]\n");
778 printf(" [expected %ds]\n", SB_SECTOR);
779 fprintf(stderr, "Invalid superblock (bad sector)\n");
783 printf("sb.csum\t\t\t%ju", (uint64_t) sb->csum);
784 expected_csum = csum_set(sb,
785 sb->version < BCACHE_SB_VERSION_CDEV_V3
787 : CACHE_SB_CSUM_TYPE(sb));
788 if (sb->csum == expected_csum) {
789 printf(" [match]\n");
791 printf(" [expected %" PRIX64 "]\n", expected_csum);
793 fprintf(stderr, "Corrupt superblock (bad csum)\n");
798 printf("sb.version\t\t%ju", (uint64_t) sb->version);
799 switch (sb->version) {
800 // These are handled the same by the kernel
801 case BCACHE_SB_VERSION_CDEV:
802 case BCACHE_SB_VERSION_CDEV_WITH_UUID:
803 printf(" [cache device]\n");
806 // The second adds data offset support
807 case BCACHE_SB_VERSION_BDEV:
808 case BCACHE_SB_VERSION_BDEV_WITH_OFFSET:
809 printf(" [backing device]\n");
813 printf(" [unknown]\n");
820 strncpy(label, (char *) sb->label, SB_LABEL_SIZE);
821 label[SB_LABEL_SIZE] = '\0';
822 printf("dev.label\t\t");
829 uuid_unparse(sb->disk_uuid.b, uuid);
830 printf("dev.uuid\t\t%s\n", uuid);
832 uuid_unparse(sb->user_uuid.b, uuid);
833 printf("cset.uuid\t\t%s\n", uuid);
835 uuid_unparse(sb->set_uuid.b, uuid);
836 printf("internal.uuid\t%s\n", uuid);
840 void show_super_backingdev(struct cache_sb *sb, bool force_csum)
842 uint64_t first_sector;
844 show_super_common(sb, force_csum);
846 if (sb->version == BCACHE_SB_VERSION_BDEV) {
847 first_sector = BDEV_DATA_START_DEFAULT;
849 first_sector = sb->bdev_data_offset;
852 printf("dev.data.first_sector\t%ju\n"
853 "dev.data.cache_mode\t%s"
854 "dev.data.cache_state\t%s\n",
856 bdev_cache_mode[BDEV_CACHE_MODE(sb)],
857 bdev_state[BDEV_STATE(sb)]);
860 void show_super_cache(struct cache_sb *sb, bool force_csum)
862 struct cache_member *m = sb->members + sb->nr_this_dev;
865 show_super_common(sb, force_csum);
867 uuid_unparse(m->uuid.b, uuid);
868 printf("dev.cache.uuid\t%s\n", uuid);
870 printf("dev.sectors_per_block\t%u\n"
871 "dev.sectors_per_bucket\t%u\n",
875 // total_sectors includes the superblock;
876 printf("dev.cache.first_sector\t%u\n"
877 "dev.cache.cache_sectors\t%llu\n"
878 "dev.cache.total_sectors\t%llu\n"
879 "dev.cache.ordered\t%s\n"
880 "dev.cache.pos\t\t%u\n"
881 "dev.cache.setsize\t\t%u\n",
882 m->bucket_size * m->first_bucket,
883 m->bucket_size * (m->nbuckets - m->first_bucket),
884 m->bucket_size * m->nbuckets,
885 CACHE_SYNC(sb) ? "yes" : "no",
889 printf("cache.state\t%s\n", cache_state[CACHE_STATE(m)]);
891 printf("cache.tier\t%llu\n", CACHE_TIER(m));
893 printf("cache.replication_set\t%llu\n", CACHE_REPLICATION_SET(m));
895 printf("cache.has_metadata\t%llu\n", CACHE_HAS_METADATA(m));
896 printf("cache.has_data\t%llu\n", CACHE_HAS_DATA(m));
898 printf("cache.replacement\t%s\n", replacement_policies[CACHE_REPLACEMENT(m)]);
899 printf("cache.discard\t%llu\n", CACHE_DISCARD(m));
902 static int __sysfs_attr_type(const char *attr, const char * const *attr_arr)
904 for (unsigned i = 0; attr_arr[i] != NULL; i++)
905 if(!strcmp(attr, attr_arr[i]))
910 enum sysfs_attr sysfs_attr_type(const char *attr)
912 if(__sysfs_attr_type(attr, set_attrs))
914 if(__sysfs_attr_type(attr, cache_attrs))
916 if(__sysfs_attr_type(attr, internal_attrs))
917 return INTERNAL_ATTR;
919 printf("No attribute called %s, try --list to see options\n", attr);
924 static void __sysfs_attr_list(const char * const *attr_arr)
926 for (unsigned i = 0; attr_arr[i] != NULL; i++)
927 printf("%s\n", attr_arr[i]);
930 void sysfs_attr_list()
932 __sysfs_attr_list(set_attrs);
933 __sysfs_attr_list(cache_attrs);
934 __sysfs_attr_list(internal_attrs);
937 struct cache_sb *query_dev(char *dev, bool force_csum,
938 bool print_sb, bool uuid_only, char *dev_uuid)
941 struct cache_sb *sb = aligned_alloc(bytes, bytes);
943 int fd = open(dev, O_RDONLY|O_DIRECT);
945 printf("Can't open dev %s: %s\n", dev, strerror(errno));
950 int ret = pread(fd, sb, bytes, SB_START);
952 fprintf(stderr, "Couldn't read superblock: %s\n",
957 } else if (bytes > sizeof(sb) + sb->u64s * sizeof(u64)) {
958 /* We read the whole superblock */
963 * otherwise double the size of our dest
968 sb = aligned_alloc(4096, bytes);
974 show_uuid_only(sb, dev_uuid);
980 show_super_cache(sb, force_csum);
982 show_super_backingdev(sb, force_csum);
988 char *dev_name(const char *ugly_path) {
990 int i, end = strlen(ugly_path);
992 //Chop off "/bcache", then look for the next '/' from the end
993 for (i = end - 8; ; i--)
994 if(ugly_path[i] == '/')
997 strcpy(buf, ugly_path + i);
998 buf[end - i - 7] = 0;
1000 // Is the dev guaranteed to be in /dev?
1001 // This is needed for finding the superblock with a query-dev
1005 static void list_cacheset_devs(char *cset_dir, char *cset_name, bool parse_dev_name)
1007 DIR *cachedir, *dir;
1008 struct stat cache_stat;
1009 char entry[MAX_PATH];
1011 snprintf(entry, MAX_PATH, "%s/%s", cset_dir, cset_name);
1013 if((dir = opendir(entry)) != NULL) {
1014 while((ent = readdir(dir)) != NULL) {
1020 * We are looking for all cache# directories
1021 * do a strlen < 9 to skip over other entries
1022 * that also start with "cache"
1024 if(strncmp(ent->d_name, "cache", 5) ||
1025 !(strlen(ent->d_name) < 9))
1028 snprintf(entry, MAX_PATH, "%s/%s/%s",
1033 if((cachedir = opendir(entry)) == NULL)
1036 if(stat(entry, &cache_stat))
1039 if((len = readlink(entry, buf, sizeof(buf) - 1)) !=
1042 if(parse_dev_name) {
1043 tmp = dev_name(buf);
1044 printf("/dev%s\n", tmp);
1047 printf("\t%s\n", buf);
1054 char *find_matching_uuid(char *stats_dir, char *subdir, const char *stats_dev_uuid)
1056 /* Do a query-dev --uuid only to get the uuid
1057 * repeat on each dev until we find a matching one
1058 * append that cache# to subdir and return
1063 struct stat cache_stat;
1065 char entry[MAX_PATH];
1068 snprintf(entry, MAX_PATH, "%s%s", stats_dir, subdir);
1069 snprintf(intbuf, 4, "%d", i);
1070 strcat(entry, intbuf);
1076 if((cachedir = opendir(entry)) == NULL)
1079 if(stat(entry, &cache_stat))
1082 if((len = readlink(entry, buf, sizeof(buf) - 1)) != -1) {
1085 int i, end = strlen(buf);
1086 char tmp[32], devname[32];
1087 struct cache_sb *sb;
1089 /* Chop off "/bcache", then look for the
1090 * next '/' from the end
1092 for (i = end - 8; ; i--)
1096 strcpy(tmp, buf + i);
1097 tmp[end - i - 7] = 0;
1098 strcpy(devname, "/dev");
1099 strcat(devname, tmp);
1101 err = "Unable to open superblock";
1102 sb = query_dev(devname, false, false, true, dev_uuid);
1108 if(!strcmp(stats_dev_uuid, dev_uuid)) {
1109 strcat(subdir, intbuf);
1114 /* remove i from end and append i++ */
1115 entry[strlen(entry)-strlen(intbuf)] = 0;
1117 snprintf(intbuf, 4, "%d", i);
1118 strcat(entry, intbuf);
1122 err = "dev uuid doesn't exist in cache_set";
1126 char *list_cachesets(char *cset_dir, bool list_devs)
1132 dir = opendir(cset_dir);
1134 err = "Failed to open cacheset dir";
1138 while ((ent = readdir(dir)) != NULL) {
1139 struct stat statbuf;
1140 char entry[MAX_PATH];
1142 if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
1145 snprintf(entry, MAX_PATH, "%s/%s", cset_dir, ent->d_name);
1146 if(stat(entry, &statbuf) == -1) {
1147 err = "Failed to stat cacheset subdir";
1151 if (S_ISDIR(statbuf.st_mode)) {
1152 printf("%s\n", ent->d_name);
1155 list_cacheset_devs(cset_dir, ent->d_name, true);
1165 char *register_bcache(char *const *devs)
1170 bcachefd = open("/dev/bcache", O_RDWR);
1172 err = "Can't open bcache device";
1176 ret = ioctl(bcachefd, BCH_IOCTL_REGISTER, devs);
1179 snprintf(tmp, 64, "ioctl register error: %s\n",
1191 char *unregister_bcache(char *const *devs)
1196 bcachefd = open("/dev/bcache_extent0", O_RDWR);
1198 err = "Can't open bcache device";
1202 ret = ioctl(bcachefd, BCH_IOCTL_STOP);
1205 snprintf(tmp, 64, "ioctl unregister error: %s\n",
1216 char *add_devices(char *const *devs)
1221 bcachefd = open("/dev/bcache_extent0", O_RDWR);
1223 err = "Can't open bcache device";
1227 struct bch_ioctl_add_disks ia;
1230 ret = ioctl(bcachefd, BCH_IOCTL_ADD_DISKS, &ia);
1233 snprintf(tmp, 128, "ioctl add disk error: %s\n",
1243 char *remove_device(const char *dev, bool force)
1248 bcachefd = open("/dev/bcache_extent0", O_RDWR);
1250 err = "Can't open bcache device";
1254 struct bch_ioctl_rm_disk ir;
1256 ir.force = force ? 1 : 0;
1258 ret = ioctl(bcachefd, BCH_IOCTL_RM_DISK, &ir);
1261 snprintf(tmp, 128, "ioctl add disk error: %s\n",
1271 char *device_set_failed(const char *dev_uuid) {
1275 struct bch_ioctl_disk_failed df;
1277 bcachefd = open("/dev/bcache_extent0", O_RDWR);
1279 err = "Can't open bcache device";
1283 uuid_parse(dev_uuid, dev.b);
1286 ret = ioctl(bcachefd, BCH_IOCTL_SET_DISK_FAILED, &df);
1289 snprintf(tmp, 128, "ioctl set disk failed error %s\n",
1299 char *probe(char *dev, int udev)
1306 int fd = open(dev, O_RDONLY);
1308 err = "Got file descriptor -1 trying to open dev";
1312 if (!(pr = blkid_new_probe())) {
1313 err = "Failed trying to get a blkid for new probe";
1317 if (blkid_probe_set_device(pr, fd, 0, 0)) {
1318 err = "Failed blkid probe set device";
1322 /* probe partitions too */
1323 if (blkid_probe_enable_partitions(pr, true)) {
1324 err = "Enable probe partitions";
1328 /* bail if anything was found
1329 * probe-bcache isn't needed once blkid recognizes bcache */
1330 if (!blkid_do_probe(pr)) {
1331 err = "blkid recognizes bcache";
1335 if (pread(fd, &sb, sizeof(sb), SB_START) != sizeof(sb)) {
1336 err = "Failed to read superblock";
1340 if (memcmp(&sb.magic, &BCACHE_MAGIC, sizeof(sb.magic))) {
1341 err = "Bcache magic incorrect";
1345 uuid_unparse(sb.disk_uuid.b, uuid);
1348 printf("ID_FS_UUID=%s\n"
1349 "ID_FS_UUID_ENC=%s\n"
1350 "ID_FS_TYPE=bcache\n",
1353 printf("%s: UUID=\"\" TYPE=\"bcache\"\n", uuid);
1361 char *read_stat_dir(DIR *dir, char *stats_dir, char *stat_name, char *ret)
1363 struct stat statbuf;
1364 char entry[MAX_PATH];
1367 snprintf(entry, MAX_PATH, "%s/%s", stats_dir, stat_name);
1368 if(stat(entry, &statbuf) == -1) {
1370 snprintf(tmp, MAX_PATH, "Failed to stat %s\n", entry);
1375 if (S_ISREG(statbuf.st_mode)) {
1378 fp = fopen(entry, "r");
1380 /* If we can't open the file, this is probably because
1381 * of permissions, just move to the next file */
1385 while(fgets(ret, MAX_PATH, fp));
1392 char *bcache_get_capacity(const char *cset_dir, const char *capacity_uuid,
1396 char bucket_size_path[MAX_PATH];
1397 char nbuckets_path[MAX_PATH];
1398 char avail_buckets_path[MAX_PATH];
1399 char cache_path[MAX_PATH];
1401 double bucket_sizes[MAX_DEVS];
1402 double nbuckets[MAX_DEVS];
1403 double avail_buckets[MAX_DEVS];
1404 char *dev_names[MAX_DEVS];
1405 int dev_count = 0, i;
1406 double total_cap = 0, total_free = 0;
1415 snprintf(bucket_size_path, sizeof(bucket_size_path), "%s/%s/%s%d/%s", cset_dir,
1416 capacity_uuid, "cache", dev_count, "bucket_size_bytes");
1417 snprintf(nbuckets_path, sizeof(nbuckets_path), "%s/%s/%s%d/%s", cset_dir,
1418 capacity_uuid, "cache", dev_count, "nbuckets");
1419 snprintf(avail_buckets_path, sizeof(avail_buckets_path), "%s/%s/%s%d/%s", cset_dir,
1420 capacity_uuid, "cache", dev_count, "available_buckets");
1421 snprintf(cache_path, sizeof(cache_path), "%s/%s/%s%d", cset_dir, capacity_uuid,
1422 "cache", dev_count);
1424 if((cache_dir = opendir(cache_path)) == NULL)
1427 err = read_stat_dir(cache_dir, cache_path,
1428 "bucket_size_bytes", buf);
1432 bucket_sizes[dev_count] = atof(buf);
1434 err = read_stat_dir(cache_dir, cache_path,
1439 nbuckets[dev_count] = atof(buf);
1441 err = read_stat_dir(cache_dir, cache_path,
1442 "available_buckets", buf);
1446 avail_buckets[dev_count] = atof(buf);
1448 if((len = readlink(cache_path, buf, sizeof(buf) - 1)) != -1) {
1450 dev_names[dev_count] = dev_name(buf);
1456 printf("%-15s%-25s%-25s\n", "Device Name", "Capacity (512 Blocks)", "Free (512 Blocks)");
1459 for (i = 0; i < dev_count; i++) {
1460 printf("%s%-11s%-25.*f%-25.*f\n", "/dev", dev_names[i],
1462 (bucket_sizes[i] * nbuckets[i]) / 512,
1464 (bucket_sizes[i] * avail_buckets[i]) / 512);
1468 for (i = 0; i < dev_count; i++) {
1469 total_cap += (bucket_sizes[i] * nbuckets[i]) / 512;
1470 total_free += (bucket_sizes[i] * avail_buckets[i]) / 512;
1474 printf("%-15s%-25.*f%-25.*f\n", "Total", precision, total_cap,
1475 precision, total_free);
1478 for (i = 0; i < dev_count; i++)