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));
894 printf("cache.cur_meta_replicas\t%llu\n", REPLICATION_SET_CUR_META_REPLICAS(m));
895 printf("cache.cur_data_replicas\t%llu\n", REPLICATION_SET_CUR_DATA_REPLICAS(m));
897 printf("cache.has_metadata\t%llu\n", CACHE_HAS_METADATA(m));
898 printf("cache.has_data\t%llu\n", CACHE_HAS_DATA(m));
900 printf("cache.replacement\t%s\n", replacement_policies[CACHE_REPLACEMENT(m)]);
901 printf("cache.discard\t%llu\n", CACHE_DISCARD(m));
904 static int __sysfs_attr_type(const char *attr, const char * const *attr_arr)
906 for (unsigned i = 0; attr_arr[i] != NULL; i++)
907 if(!strcmp(attr, attr_arr[i]))
912 enum sysfs_attr sysfs_attr_type(const char *attr)
914 if(__sysfs_attr_type(attr, set_attrs))
916 if(__sysfs_attr_type(attr, cache_attrs))
918 if(__sysfs_attr_type(attr, internal_attrs))
919 return INTERNAL_ATTR;
921 printf("No attribute called %s, try --list to see options\n", attr);
926 static void __sysfs_attr_list(const char * const *attr_arr)
928 for (unsigned i = 0; attr_arr[i] != NULL; i++)
929 printf("%s\n", attr_arr[i]);
932 void sysfs_attr_list()
934 __sysfs_attr_list(set_attrs);
935 __sysfs_attr_list(cache_attrs);
936 __sysfs_attr_list(internal_attrs);
939 struct cache_sb *query_dev(char *dev, bool force_csum,
940 bool print_sb, bool uuid_only, char *dev_uuid)
943 struct cache_sb *sb = aligned_alloc(bytes, bytes);
945 int fd = open(dev, O_RDONLY|O_DIRECT);
947 printf("Can't open dev %s: %s\n", dev, strerror(errno));
952 int ret = pread(fd, sb, bytes, SB_START);
954 fprintf(stderr, "Couldn't read superblock: %s\n",
959 } else if (bytes > sizeof(sb) + sb->u64s * sizeof(u64)) {
960 /* We read the whole superblock */
965 * otherwise double the size of our dest
970 sb = aligned_alloc(4096, bytes);
976 show_uuid_only(sb, dev_uuid);
982 show_super_cache(sb, force_csum);
984 show_super_backingdev(sb, force_csum);
990 char *dev_name(const char *ugly_path) {
992 int i, end = strlen(ugly_path);
994 //Chop off "/bcache", then look for the next '/' from the end
995 for (i = end - 8; ; i--)
996 if(ugly_path[i] == '/')
999 strcpy(buf, ugly_path + i);
1000 buf[end - i - 7] = 0;
1002 // Is the dev guaranteed to be in /dev?
1003 // This is needed for finding the superblock with a query-dev
1007 static void list_cacheset_devs(char *cset_dir, char *cset_name, bool parse_dev_name)
1009 DIR *cachedir, *dir;
1010 struct stat cache_stat;
1011 char entry[MAX_PATH];
1013 snprintf(entry, MAX_PATH, "%s/%s", cset_dir, cset_name);
1015 if((dir = opendir(entry)) != NULL) {
1016 while((ent = readdir(dir)) != NULL) {
1022 * We are looking for all cache# directories
1023 * do a strlen < 9 to skip over other entries
1024 * that also start with "cache"
1026 if(strncmp(ent->d_name, "cache", 5) ||
1027 !(strlen(ent->d_name) < 9))
1030 snprintf(entry, MAX_PATH, "%s/%s/%s",
1035 if((cachedir = opendir(entry)) == NULL)
1038 if(stat(entry, &cache_stat))
1041 if((len = readlink(entry, buf, sizeof(buf) - 1)) !=
1044 if(parse_dev_name) {
1045 tmp = dev_name(buf);
1046 printf("/dev%s\n", tmp);
1049 printf("\t%s\n", buf);
1056 char *find_matching_uuid(char *stats_dir, char *subdir, const char *stats_dev_uuid)
1058 /* Do a query-dev --uuid only to get the uuid
1059 * repeat on each dev until we find a matching one
1060 * append that cache# to subdir and return
1065 struct stat cache_stat;
1067 char entry[MAX_PATH];
1070 snprintf(entry, MAX_PATH, "%s%s", stats_dir, subdir);
1071 snprintf(intbuf, 4, "%d", i);
1072 strcat(entry, intbuf);
1078 if((cachedir = opendir(entry)) == NULL)
1081 if(stat(entry, &cache_stat))
1084 if((len = readlink(entry, buf, sizeof(buf) - 1)) != -1) {
1087 int i, end = strlen(buf);
1088 char tmp[32], devname[32];
1089 struct cache_sb *sb;
1091 /* Chop off "/bcache", then look for the
1092 * next '/' from the end
1094 for (i = end - 8; ; i--)
1098 strcpy(tmp, buf + i);
1099 tmp[end - i - 7] = 0;
1100 strcpy(devname, "/dev");
1101 strcat(devname, tmp);
1103 err = "Unable to open superblock";
1104 sb = query_dev(devname, false, false, true, dev_uuid);
1110 if(!strcmp(stats_dev_uuid, dev_uuid)) {
1111 strcat(subdir, intbuf);
1116 /* remove i from end and append i++ */
1117 entry[strlen(entry)-strlen(intbuf)] = 0;
1119 snprintf(intbuf, 4, "%d", i);
1120 strcat(entry, intbuf);
1124 err = "dev uuid doesn't exist in cache_set";
1128 char *list_cachesets(char *cset_dir, bool list_devs)
1134 dir = opendir(cset_dir);
1136 err = "Failed to open cacheset dir";
1140 while ((ent = readdir(dir)) != NULL) {
1141 struct stat statbuf;
1142 char entry[MAX_PATH];
1144 if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
1147 snprintf(entry, MAX_PATH, "%s/%s", cset_dir, ent->d_name);
1148 if(stat(entry, &statbuf) == -1) {
1149 err = "Failed to stat cacheset subdir";
1153 if (S_ISDIR(statbuf.st_mode)) {
1154 printf("%s\n", ent->d_name);
1157 list_cacheset_devs(cset_dir, ent->d_name, true);
1167 char *register_bcache(char *const *devs)
1172 bcachefd = open("/dev/bcache", O_RDWR);
1174 err = "Can't open bcache device";
1178 ret = ioctl(bcachefd, BCH_IOCTL_REGISTER, devs);
1181 snprintf(tmp, 64, "ioctl register error: %s\n",
1193 char *unregister_bcache(char *const *devs)
1198 bcachefd = open("/dev/bcache_extent0", O_RDWR);
1200 err = "Can't open bcache device";
1204 ret = ioctl(bcachefd, BCH_IOCTL_STOP);
1207 snprintf(tmp, 64, "ioctl unregister error: %s\n",
1218 char *add_devices(char *const *devs)
1223 bcachefd = open("/dev/bcache_extent0", O_RDWR);
1225 err = "Can't open bcache device";
1229 struct bch_ioctl_add_disks ia;
1232 ret = ioctl(bcachefd, BCH_IOCTL_ADD_DISKS, &ia);
1235 snprintf(tmp, 128, "ioctl add disk error: %s\n",
1245 char *remove_device(const char *dev, bool force)
1250 bcachefd = open("/dev/bcache_extent0", O_RDWR);
1252 err = "Can't open bcache device";
1256 struct bch_ioctl_rm_disk ir;
1258 ir.force = force ? 1 : 0;
1260 ret = ioctl(bcachefd, BCH_IOCTL_RM_DISK, &ir);
1263 snprintf(tmp, 128, "ioctl add disk error: %s\n",
1273 char *device_set_failed(const char *dev_uuid) {
1277 struct bch_ioctl_disk_failed df;
1279 bcachefd = open("/dev/bcache_extent0", O_RDWR);
1281 err = "Can't open bcache device";
1285 uuid_parse(dev_uuid, dev.b);
1288 ret = ioctl(bcachefd, BCH_IOCTL_SET_DISK_FAILED, &df);
1291 snprintf(tmp, 128, "ioctl set disk failed error %s\n",
1301 char *probe(char *dev, int udev)
1308 int fd = open(dev, O_RDONLY);
1310 err = "Got file descriptor -1 trying to open dev";
1314 if (!(pr = blkid_new_probe())) {
1315 err = "Failed trying to get a blkid for new probe";
1319 if (blkid_probe_set_device(pr, fd, 0, 0)) {
1320 err = "Failed blkid probe set device";
1324 /* probe partitions too */
1325 if (blkid_probe_enable_partitions(pr, true)) {
1326 err = "Enable probe partitions";
1330 /* bail if anything was found
1331 * probe-bcache isn't needed once blkid recognizes bcache */
1332 if (!blkid_do_probe(pr)) {
1333 err = "blkid recognizes bcache";
1337 if (pread(fd, &sb, sizeof(sb), SB_START) != sizeof(sb)) {
1338 err = "Failed to read superblock";
1342 if (memcmp(&sb.magic, &BCACHE_MAGIC, sizeof(sb.magic))) {
1343 err = "Bcache magic incorrect";
1347 uuid_unparse(sb.disk_uuid.b, uuid);
1350 printf("ID_FS_UUID=%s\n"
1351 "ID_FS_UUID_ENC=%s\n"
1352 "ID_FS_TYPE=bcache\n",
1355 printf("%s: UUID=\"\" TYPE=\"bcache\"\n", uuid);
1363 char *read_stat_dir(DIR *dir, char *stats_dir, char *stat_name, char *ret)
1365 struct stat statbuf;
1366 char entry[MAX_PATH];
1369 snprintf(entry, MAX_PATH, "%s/%s", stats_dir, stat_name);
1370 if(stat(entry, &statbuf) == -1) {
1372 snprintf(tmp, MAX_PATH, "Failed to stat %s\n", entry);
1377 if (S_ISREG(statbuf.st_mode)) {
1380 fp = fopen(entry, "r");
1382 /* If we can't open the file, this is probably because
1383 * of permissions, just move to the next file */
1387 while(fgets(ret, MAX_PATH, fp));
1394 char *bcache_get_capacity(const char *cset_dir, const char *capacity_uuid,
1398 char bucket_size_path[MAX_PATH];
1399 char nbuckets_path[MAX_PATH];
1400 char avail_buckets_path[MAX_PATH];
1401 char cache_path[MAX_PATH];
1403 double bucket_sizes[MAX_DEVS];
1404 double nbuckets[MAX_DEVS];
1405 double avail_buckets[MAX_DEVS];
1406 char *dev_names[MAX_DEVS];
1407 int dev_count = 0, i;
1408 double total_cap = 0, total_free = 0;
1417 snprintf(bucket_size_path, sizeof(bucket_size_path), "%s/%s/%s%d/%s", cset_dir,
1418 capacity_uuid, "cache", dev_count, "bucket_size_bytes");
1419 snprintf(nbuckets_path, sizeof(nbuckets_path), "%s/%s/%s%d/%s", cset_dir,
1420 capacity_uuid, "cache", dev_count, "nbuckets");
1421 snprintf(avail_buckets_path, sizeof(avail_buckets_path), "%s/%s/%s%d/%s", cset_dir,
1422 capacity_uuid, "cache", dev_count, "available_buckets");
1423 snprintf(cache_path, sizeof(cache_path), "%s/%s/%s%d", cset_dir, capacity_uuid,
1424 "cache", dev_count);
1426 if((cache_dir = opendir(cache_path)) == NULL)
1429 err = read_stat_dir(cache_dir, cache_path,
1430 "bucket_size_bytes", buf);
1434 bucket_sizes[dev_count] = atof(buf);
1436 err = read_stat_dir(cache_dir, cache_path,
1441 nbuckets[dev_count] = atof(buf);
1443 err = read_stat_dir(cache_dir, cache_path,
1444 "available_buckets", buf);
1448 avail_buckets[dev_count] = atof(buf);
1450 if((len = readlink(cache_path, buf, sizeof(buf) - 1)) != -1) {
1452 dev_names[dev_count] = dev_name(buf);
1458 printf("%-15s%-25s%-25s\n", "Device Name", "Capacity (512 Blocks)", "Free (512 Blocks)");
1461 for (i = 0; i < dev_count; i++) {
1462 printf("%s%-11s%-25.*f%-25.*f\n", "/dev", dev_names[i],
1464 (bucket_sizes[i] * nbuckets[i]) / 512,
1466 (bucket_sizes[i] * avail_buckets[i]) / 512);
1470 for (i = 0; i < dev_count; i++) {
1471 total_cap += (bucket_sizes[i] * nbuckets[i]) / 512;
1472 total_free += (bucket_sizes[i] * avail_buckets[i]) / 512;
1476 printf("%-15s%-25.*f%-25.*f\n", "Total", precision, total_cap,
1477 precision, total_free);
1480 for (i = 0; i < dev_count; i++)