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 error_actions[] = {
58 const char * const bdev_cache_mode[] = {
66 const char * const bdev_state[] = {
74 const char * const set_attrs[] = {
76 "btree_scan_ratelimit",
77 "bucket_reserve_percent",
78 "cache_reserve_percent",
80 "congested_read_threshold_us",
81 "congested_write_threshold_us",
84 "foreground_target_percent",
88 "sector_reserve_percent",
93 const char * const cache_attrs[] = {
94 "cache_replacement_policy",
101 const char * const internal_attrs[] = {
102 "btree_shrinker_disabled",
104 "foreground_write_rate",
110 char *skip_spaces(const char *str)
112 while (isspace(*str))
128 while (end >= s && isspace(*end))
135 ssize_t read_string_list(const char *buf, const char * const list[])
138 char *s, *d = strdup(buf);
144 for (i = 0; list[i]; i++)
145 if (!strcmp(list[i], s))
156 ssize_t read_string_list_or_die(const char *opt, const char * const list[],
159 ssize_t v = read_string_list(opt, list);
161 die("Bad %s %s", msg, opt);
166 void print_string_list(const char * const list[], size_t selected)
170 for (i = 0; list[i]; i++) {
173 printf(i == selected ? "[%s] ": "%s", list[i]);
178 * This is the CRC-32C table
182 * reflect input bytes = true
183 * reflect output bytes = true
186 static const u32 crc32c_table[256] = {
187 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
188 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
189 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
190 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
191 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
192 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
193 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
194 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
195 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
196 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
197 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
198 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
199 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
200 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
201 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
202 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
203 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
204 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
205 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
206 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
207 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
208 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
209 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
210 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
211 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
212 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
213 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
214 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
215 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
216 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
217 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
218 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
219 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
220 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
221 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
222 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
223 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
224 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
225 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
226 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
227 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
228 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
229 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
230 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
231 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
232 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
233 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
234 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
235 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
236 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
237 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
238 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
239 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
240 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
241 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
242 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
243 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
244 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
245 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
246 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
247 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
248 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
249 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
250 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
254 * Steps through buffer one byte at at time, calculates reflected
258 static u32 crc32c(u32 crc, unsigned char const *data, size_t length)
262 crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8);
267 * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group (Any
268 * use permitted, subject to terms of PostgreSQL license; see.)
270 * If we have a 64-bit integer type, then a 64-bit CRC looks just like the
271 * usual sort of implementation. (See Ross Williams' excellent introduction
272 * A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS, available from
273 * ftp://ftp.rocksoft.com/papers/crc_v3.txt or several other net sites.)
274 * If we have no working 64-bit type, then fake it with two 32-bit registers.
276 * The present implementation is a normal (not "reflected", in Williams'
277 * terms) 64-bit CRC, using initial all-ones register contents and a final
278 * bit inversion. The chosen polynomial is borrowed from the DLT1 spec
279 * (ECMA-182, available from http://www.ecma.ch/ecma1/STAND/ECMA-182.HTM):
281 * x^64 + x^62 + x^57 + x^55 + x^54 + x^53 + x^52 + x^47 + x^46 + x^45 +
282 * x^40 + x^39 + x^38 + x^37 + x^35 + x^33 + x^32 + x^31 + x^29 + x^27 +
283 * x^24 + x^23 + x^22 + x^21 + x^19 + x^17 + x^13 + x^12 + x^10 + x^9 +
287 static const uint64_t crc_table[256] = {
288 0x0000000000000000ULL, 0x42F0E1EBA9EA3693ULL, 0x85E1C3D753D46D26ULL,
289 0xC711223CFA3E5BB5ULL, 0x493366450E42ECDFULL, 0x0BC387AEA7A8DA4CULL,
290 0xCCD2A5925D9681F9ULL, 0x8E224479F47CB76AULL, 0x9266CC8A1C85D9BEULL,
291 0xD0962D61B56FEF2DULL, 0x17870F5D4F51B498ULL, 0x5577EEB6E6BB820BULL,
292 0xDB55AACF12C73561ULL, 0x99A54B24BB2D03F2ULL, 0x5EB4691841135847ULL,
293 0x1C4488F3E8F96ED4ULL, 0x663D78FF90E185EFULL, 0x24CD9914390BB37CULL,
294 0xE3DCBB28C335E8C9ULL, 0xA12C5AC36ADFDE5AULL, 0x2F0E1EBA9EA36930ULL,
295 0x6DFEFF5137495FA3ULL, 0xAAEFDD6DCD770416ULL, 0xE81F3C86649D3285ULL,
296 0xF45BB4758C645C51ULL, 0xB6AB559E258E6AC2ULL, 0x71BA77A2DFB03177ULL,
297 0x334A9649765A07E4ULL, 0xBD68D2308226B08EULL, 0xFF9833DB2BCC861DULL,
298 0x388911E7D1F2DDA8ULL, 0x7A79F00C7818EB3BULL, 0xCC7AF1FF21C30BDEULL,
299 0x8E8A101488293D4DULL, 0x499B3228721766F8ULL, 0x0B6BD3C3DBFD506BULL,
300 0x854997BA2F81E701ULL, 0xC7B97651866BD192ULL, 0x00A8546D7C558A27ULL,
301 0x4258B586D5BFBCB4ULL, 0x5E1C3D753D46D260ULL, 0x1CECDC9E94ACE4F3ULL,
302 0xDBFDFEA26E92BF46ULL, 0x990D1F49C77889D5ULL, 0x172F5B3033043EBFULL,
303 0x55DFBADB9AEE082CULL, 0x92CE98E760D05399ULL, 0xD03E790CC93A650AULL,
304 0xAA478900B1228E31ULL, 0xE8B768EB18C8B8A2ULL, 0x2FA64AD7E2F6E317ULL,
305 0x6D56AB3C4B1CD584ULL, 0xE374EF45BF6062EEULL, 0xA1840EAE168A547DULL,
306 0x66952C92ECB40FC8ULL, 0x2465CD79455E395BULL, 0x3821458AADA7578FULL,
307 0x7AD1A461044D611CULL, 0xBDC0865DFE733AA9ULL, 0xFF3067B657990C3AULL,
308 0x711223CFA3E5BB50ULL, 0x33E2C2240A0F8DC3ULL, 0xF4F3E018F031D676ULL,
309 0xB60301F359DBE0E5ULL, 0xDA050215EA6C212FULL, 0x98F5E3FE438617BCULL,
310 0x5FE4C1C2B9B84C09ULL, 0x1D14202910527A9AULL, 0x93366450E42ECDF0ULL,
311 0xD1C685BB4DC4FB63ULL, 0x16D7A787B7FAA0D6ULL, 0x5427466C1E109645ULL,
312 0x4863CE9FF6E9F891ULL, 0x0A932F745F03CE02ULL, 0xCD820D48A53D95B7ULL,
313 0x8F72ECA30CD7A324ULL, 0x0150A8DAF8AB144EULL, 0x43A04931514122DDULL,
314 0x84B16B0DAB7F7968ULL, 0xC6418AE602954FFBULL, 0xBC387AEA7A8DA4C0ULL,
315 0xFEC89B01D3679253ULL, 0x39D9B93D2959C9E6ULL, 0x7B2958D680B3FF75ULL,
316 0xF50B1CAF74CF481FULL, 0xB7FBFD44DD257E8CULL, 0x70EADF78271B2539ULL,
317 0x321A3E938EF113AAULL, 0x2E5EB66066087D7EULL, 0x6CAE578BCFE24BEDULL,
318 0xABBF75B735DC1058ULL, 0xE94F945C9C3626CBULL, 0x676DD025684A91A1ULL,
319 0x259D31CEC1A0A732ULL, 0xE28C13F23B9EFC87ULL, 0xA07CF2199274CA14ULL,
320 0x167FF3EACBAF2AF1ULL, 0x548F120162451C62ULL, 0x939E303D987B47D7ULL,
321 0xD16ED1D631917144ULL, 0x5F4C95AFC5EDC62EULL, 0x1DBC74446C07F0BDULL,
322 0xDAAD56789639AB08ULL, 0x985DB7933FD39D9BULL, 0x84193F60D72AF34FULL,
323 0xC6E9DE8B7EC0C5DCULL, 0x01F8FCB784FE9E69ULL, 0x43081D5C2D14A8FAULL,
324 0xCD2A5925D9681F90ULL, 0x8FDAB8CE70822903ULL, 0x48CB9AF28ABC72B6ULL,
325 0x0A3B7B1923564425ULL, 0x70428B155B4EAF1EULL, 0x32B26AFEF2A4998DULL,
326 0xF5A348C2089AC238ULL, 0xB753A929A170F4ABULL, 0x3971ED50550C43C1ULL,
327 0x7B810CBBFCE67552ULL, 0xBC902E8706D82EE7ULL, 0xFE60CF6CAF321874ULL,
328 0xE224479F47CB76A0ULL, 0xA0D4A674EE214033ULL, 0x67C58448141F1B86ULL,
329 0x253565A3BDF52D15ULL, 0xAB1721DA49899A7FULL, 0xE9E7C031E063ACECULL,
330 0x2EF6E20D1A5DF759ULL, 0x6C0603E6B3B7C1CAULL, 0xF6FAE5C07D3274CDULL,
331 0xB40A042BD4D8425EULL, 0x731B26172EE619EBULL, 0x31EBC7FC870C2F78ULL,
332 0xBFC9838573709812ULL, 0xFD39626EDA9AAE81ULL, 0x3A28405220A4F534ULL,
333 0x78D8A1B9894EC3A7ULL, 0x649C294A61B7AD73ULL, 0x266CC8A1C85D9BE0ULL,
334 0xE17DEA9D3263C055ULL, 0xA38D0B769B89F6C6ULL, 0x2DAF4F0F6FF541ACULL,
335 0x6F5FAEE4C61F773FULL, 0xA84E8CD83C212C8AULL, 0xEABE6D3395CB1A19ULL,
336 0x90C79D3FEDD3F122ULL, 0xD2377CD44439C7B1ULL, 0x15265EE8BE079C04ULL,
337 0x57D6BF0317EDAA97ULL, 0xD9F4FB7AE3911DFDULL, 0x9B041A914A7B2B6EULL,
338 0x5C1538ADB04570DBULL, 0x1EE5D94619AF4648ULL, 0x02A151B5F156289CULL,
339 0x4051B05E58BC1E0FULL, 0x87409262A28245BAULL, 0xC5B073890B687329ULL,
340 0x4B9237F0FF14C443ULL, 0x0962D61B56FEF2D0ULL, 0xCE73F427ACC0A965ULL,
341 0x8C8315CC052A9FF6ULL, 0x3A80143F5CF17F13ULL, 0x7870F5D4F51B4980ULL,
342 0xBF61D7E80F251235ULL, 0xFD913603A6CF24A6ULL, 0x73B3727A52B393CCULL,
343 0x31439391FB59A55FULL, 0xF652B1AD0167FEEAULL, 0xB4A25046A88DC879ULL,
344 0xA8E6D8B54074A6ADULL, 0xEA16395EE99E903EULL, 0x2D071B6213A0CB8BULL,
345 0x6FF7FA89BA4AFD18ULL, 0xE1D5BEF04E364A72ULL, 0xA3255F1BE7DC7CE1ULL,
346 0x64347D271DE22754ULL, 0x26C49CCCB40811C7ULL, 0x5CBD6CC0CC10FAFCULL,
347 0x1E4D8D2B65FACC6FULL, 0xD95CAF179FC497DAULL, 0x9BAC4EFC362EA149ULL,
348 0x158E0A85C2521623ULL, 0x577EEB6E6BB820B0ULL, 0x906FC95291867B05ULL,
349 0xD29F28B9386C4D96ULL, 0xCEDBA04AD0952342ULL, 0x8C2B41A1797F15D1ULL,
350 0x4B3A639D83414E64ULL, 0x09CA82762AAB78F7ULL, 0x87E8C60FDED7CF9DULL,
351 0xC51827E4773DF90EULL, 0x020905D88D03A2BBULL, 0x40F9E43324E99428ULL,
352 0x2CFFE7D5975E55E2ULL, 0x6E0F063E3EB46371ULL, 0xA91E2402C48A38C4ULL,
353 0xEBEEC5E96D600E57ULL, 0x65CC8190991CB93DULL, 0x273C607B30F68FAEULL,
354 0xE02D4247CAC8D41BULL, 0xA2DDA3AC6322E288ULL, 0xBE992B5F8BDB8C5CULL,
355 0xFC69CAB42231BACFULL, 0x3B78E888D80FE17AULL, 0x7988096371E5D7E9ULL,
356 0xF7AA4D1A85996083ULL, 0xB55AACF12C735610ULL, 0x724B8ECDD64D0DA5ULL,
357 0x30BB6F267FA73B36ULL, 0x4AC29F2A07BFD00DULL, 0x08327EC1AE55E69EULL,
358 0xCF235CFD546BBD2BULL, 0x8DD3BD16FD818BB8ULL, 0x03F1F96F09FD3CD2ULL,
359 0x41011884A0170A41ULL, 0x86103AB85A2951F4ULL, 0xC4E0DB53F3C36767ULL,
360 0xD8A453A01B3A09B3ULL, 0x9A54B24BB2D03F20ULL, 0x5D45907748EE6495ULL,
361 0x1FB5719CE1045206ULL, 0x919735E51578E56CULL, 0xD367D40EBC92D3FFULL,
362 0x1476F63246AC884AULL, 0x568617D9EF46BED9ULL, 0xE085162AB69D5E3CULL,
363 0xA275F7C11F7768AFULL, 0x6564D5FDE549331AULL, 0x279434164CA30589ULL,
364 0xA9B6706FB8DFB2E3ULL, 0xEB46918411358470ULL, 0x2C57B3B8EB0BDFC5ULL,
365 0x6EA7525342E1E956ULL, 0x72E3DAA0AA188782ULL, 0x30133B4B03F2B111ULL,
366 0xF7021977F9CCEAA4ULL, 0xB5F2F89C5026DC37ULL, 0x3BD0BCE5A45A6B5DULL,
367 0x79205D0E0DB05DCEULL, 0xBE317F32F78E067BULL, 0xFCC19ED95E6430E8ULL,
368 0x86B86ED5267CDBD3ULL, 0xC4488F3E8F96ED40ULL, 0x0359AD0275A8B6F5ULL,
369 0x41A94CE9DC428066ULL, 0xCF8B0890283E370CULL, 0x8D7BE97B81D4019FULL,
370 0x4A6ACB477BEA5A2AULL, 0x089A2AACD2006CB9ULL, 0x14DEA25F3AF9026DULL,
371 0x562E43B4931334FEULL, 0x913F6188692D6F4BULL, 0xD3CF8063C0C759D8ULL,
372 0x5DEDC41A34BBEEB2ULL, 0x1F1D25F19D51D821ULL, 0xD80C07CD676F8394ULL,
373 0x9AFCE626CE85B507ULL
376 static uint64_t bch_crc64_update(uint64_t crc, const void *_data, size_t len)
378 const unsigned char *data = _data;
381 int i = ((int) (crc >> 56) ^ *data++) & 0xFF;
382 crc = crc_table[i] ^ (crc << 8);
388 static uint64_t bch_checksum_update(unsigned type, uint64_t crc, const void *data, size_t len)
393 case BCH_CSUM_CRC32C:
394 return crc32c(crc, data, len);
396 return bch_crc64_update(crc, data, len);
398 die("Unknown checksum type %u", type);
402 uint64_t bch_checksum(unsigned type, const void *data, size_t len)
404 uint64_t crc = 0xffffffffffffffffULL;
406 crc = bch_checksum_update(type, crc, data, len);
408 return crc ^ 0xffffffffffffffffULL;
411 uint64_t getblocks(int fd)
415 if (fstat(fd, &statbuf)) {
416 perror("getblocks: stat error\n");
419 ret = statbuf.st_size / 512;
420 if (S_ISBLK(statbuf.st_mode))
421 if (ioctl(fd, BLKGETSIZE, &ret)) {
422 perror("ioctl error getting blksize");
428 uint64_t hatoi(const char *s)
431 long long i = strtoll(s, &e, 10);
449 unsigned hatoi_validate(const char *s, const char *msg)
451 uint64_t v = hatoi(s);
454 die("%s must be a power of two", msg);
459 die("%s too large\n", msg);
462 die("%s too small\n", msg);
467 void do_write_sb(int fd, struct cache_sb *sb)
469 char zeroes[SB_START] = {0};
470 size_t bytes = ((void *) __bset_bkey_last(sb)) - (void *) sb;
472 /* Zero start of disk */
473 if (pwrite(fd, zeroes, SB_START, 0) != SB_START) {
474 perror("write error trying to zero start of disk\n");
477 /* Write superblock */
478 if (pwrite(fd, sb, bytes, SB_START) != bytes) {
479 perror("write error trying to write superblock\n");
487 void write_backingdev_sb(int fd, unsigned block_size, unsigned mode,
488 uint64_t data_offset, const char *label,
489 uuid_le user_uuid, uuid_le set_uuid)
491 char uuid_str[40], set_uuid_str[40];
494 memset(&sb, 0, sizeof(struct cache_sb));
496 sb.offset = SB_SECTOR;
497 sb.version = BCACHE_SB_VERSION_BDEV;
498 sb.magic = BCACHE_MAGIC;
499 uuid_generate(sb.disk_uuid.b);
500 sb.user_uuid = user_uuid;
501 sb.set_uuid = set_uuid;
502 sb.block_size = block_size;
504 uuid_unparse(sb.disk_uuid.b, uuid_str);
505 uuid_unparse(sb.user_uuid.b, set_uuid_str);
507 memcpy(sb.label, label, SB_LABEL_SIZE);
509 SET_BDEV_CACHE_MODE(&sb, mode);
511 if (data_offset != BDEV_DATA_START_DEFAULT) {
512 sb.version = BCACHE_SB_VERSION_BDEV_WITH_OFFSET;
513 sb.bdev_data_offset = data_offset;
516 sb.csum = csum_set(&sb, BCH_CSUM_CRC64);
522 "data_offset: %ju\n",
523 uuid_str, set_uuid_str,
524 (unsigned) sb.version,
528 do_write_sb(fd, &sb);
531 int dev_open(const char *dev)
536 if ((fd = open(dev, O_RDWR|O_EXCL)) == -1)
537 die("Can't open dev %s: %s\n", dev, strerror(errno));
539 if (!(pr = blkid_new_probe()))
540 die("Failed to create a new probe");
541 if (blkid_probe_set_device(pr, fd, 0, 0))
542 die("failed to set probe to device");
544 /* enable ptable probing; superblock probing is enabled by default */
545 if (blkid_probe_enable_partitions(pr, true))
546 die("Failed to enable partitions on probe");
548 if (!blkid_do_probe(pr))
549 /* XXX wipefs doesn't know how to remove partition tables */
550 die("Device %s already has a non-bcache superblock, "
551 "remove it using wipefs and wipefs -a\n", dev);
556 unsigned get_blocksize(const char *path, int fd)
560 if (fstat(fd, &statbuf))
561 die("Error statting %s: %s", path, strerror(errno));
563 if (S_ISBLK(statbuf.st_mode)) {
565 * BLKALIGNOFF: alignment_offset
566 * BLKPBSZGET: physical_block_size
567 * BLKSSZGET: logical_block_size
568 * BLKIOMIN: minimum_io_size
569 * BLKIOOPT: optimal_io_size
571 * It may be tempting to use physical_block_size,
572 * or even minimum_io_size.
573 * But to be as transparent as possible,
574 * we want to use logical_block_size.
576 unsigned int logical_block_size;
577 if (ioctl(fd, BLKSSZGET, &logical_block_size))
578 die("ioctl(%s, BLKSSZGET) failed: %m", path);
580 return logical_block_size / 512;
583 /* else: not a block device.
584 * Why would we even want to write a bcache super block there? */
586 return statbuf.st_blksize / 512;
589 long strtoul_or_die(const char *p, size_t max, const char *msg)
592 long v = strtol(p, NULL, 10);
593 if (errno || v < 0 || v >= max)
594 die("Invalid %s %zi", msg, v);
599 static void print_encode(char *in)
602 for (pos = in; *pos; pos++)
603 if (isalnum(*pos) || strchr(".-_", *pos))
606 printf("%%%x", *pos);
609 static void show_uuid_only(struct cache_sb *sb, char *dev_uuid) {
610 uuid_unparse(sb->disk_uuid.b, dev_uuid);
613 static void show_super_common(struct cache_sb *sb, bool force_csum)
616 char label[SB_LABEL_SIZE + 1];
617 uint64_t expected_csum;
619 printf("sb.magic\t\t");
620 if (!memcmp(&sb->magic, &BCACHE_MAGIC, sizeof(sb->magic))) {
623 printf("bad magic\n");
624 die("Invalid superblock (bad magic)");
627 printf("sb.first_sector\t\t%ju", (uint64_t) sb->offset);
628 if (sb->offset == SB_SECTOR) {
629 printf(" [match]\n");
631 printf(" [expected %ds]\n", SB_SECTOR);
632 die("Invalid superblock (bad sector)");
635 printf("sb.csum\t\t\t%ju", (uint64_t) sb->csum);
636 expected_csum = csum_set(sb,
637 sb->version < BCACHE_SB_VERSION_CDEV_V3
639 : CACHE_SB_CSUM_TYPE(sb));
640 if (sb->csum == expected_csum) {
641 printf(" [match]\n");
643 printf(" [expected %" PRIX64 "]\n", expected_csum);
645 die("Corrupt superblock (bad csum)");
648 printf("sb.version\t\t%ju", (uint64_t) sb->version);
649 switch (sb->version) {
650 // These are handled the same by the kernel
651 case BCACHE_SB_VERSION_CDEV:
652 case BCACHE_SB_VERSION_CDEV_WITH_UUID:
653 printf(" [cache device]\n");
656 // The second adds data offset support
657 case BCACHE_SB_VERSION_BDEV:
658 case BCACHE_SB_VERSION_BDEV_WITH_OFFSET:
659 printf(" [backing device]\n");
663 printf(" [unknown]\n");
670 strncpy(label, (char *) sb->label, SB_LABEL_SIZE);
671 label[SB_LABEL_SIZE] = '\0';
672 printf("dev.label\t\t");
679 uuid_unparse(sb->disk_uuid.b, uuid);
680 printf("dev.uuid\t\t%s\n", uuid);
682 uuid_unparse(sb->user_uuid.b, uuid);
683 printf("cset.uuid\t\t%s\n", uuid);
685 uuid_unparse(sb->set_uuid.b, uuid);
686 printf("internal.uuid\t%s\n", uuid);
690 void show_super_backingdev(struct cache_sb *sb, bool force_csum)
692 uint64_t first_sector;
694 show_super_common(sb, force_csum);
696 if (sb->version == BCACHE_SB_VERSION_BDEV) {
697 first_sector = BDEV_DATA_START_DEFAULT;
699 first_sector = sb->bdev_data_offset;
702 printf("dev.data.first_sector\t%ju\n"
703 "dev.data.cache_mode\t%s"
704 "dev.data.cache_state\t%s\n",
706 bdev_cache_mode[BDEV_CACHE_MODE(sb)],
707 bdev_state[BDEV_STATE(sb)]);
710 void show_super_cache(struct cache_sb *sb, bool force_csum)
712 struct cache_member *m = sb->members + sb->nr_this_dev;
715 show_super_common(sb, force_csum);
717 uuid_unparse(m->uuid.b, uuid);
718 printf("dev.cache.uuid\t%s\n", uuid);
720 printf("dev.sectors_per_block\t%u\n"
721 "dev.sectors_per_bucket\t%u\n",
725 // total_sectors includes the superblock;
726 printf("dev.cache.first_sector\t%u\n"
727 "dev.cache.cache_sectors\t%llu\n"
728 "dev.cache.total_sectors\t%llu\n"
729 "dev.cache.ordered\t%s\n"
730 "dev.cache.pos\t\t%u\n"
731 "dev.cache.setsize\t\t%u\n",
732 m->bucket_size * m->first_bucket,
733 m->bucket_size * (m->nbuckets - m->first_bucket),
734 m->bucket_size * m->nbuckets,
735 CACHE_SYNC(sb) ? "yes" : "no",
739 printf("cache.state\t%s\n", cache_state[CACHE_STATE(m)]);
741 printf("cache.tier\t%llu\n", CACHE_TIER(m));
743 printf("cache.replication_set\t%llu\n", CACHE_REPLICATION_SET(m));
745 printf("cache.has_metadata\t%llu\n", CACHE_HAS_METADATA(m));
746 printf("cache.has_data\t%llu\n", CACHE_HAS_DATA(m));
748 printf("cache.replacement\t%s\n", replacement_policies[CACHE_REPLACEMENT(m)]);
749 printf("cache.discard\t%llu\n", CACHE_DISCARD(m));
752 static int __sysfs_attr_type(const char *attr, const char * const *attr_arr)
754 for (unsigned i = 0; attr_arr[i] != NULL; i++)
755 if(!strcmp(attr, attr_arr[i]))
760 enum sysfs_attr sysfs_attr_type(const char *attr)
762 if(__sysfs_attr_type(attr, set_attrs))
764 if(__sysfs_attr_type(attr, cache_attrs))
766 if(__sysfs_attr_type(attr, internal_attrs))
767 return INTERNAL_ATTR;
769 printf("No attribute called %s, try --list to see options\n", attr);
774 static void __sysfs_attr_list(const char * const *attr_arr)
776 for (unsigned i = 0; attr_arr[i] != NULL; i++)
777 printf("%s\n", attr_arr[i]);
780 void sysfs_attr_list()
782 __sysfs_attr_list(set_attrs);
783 __sysfs_attr_list(cache_attrs);
784 __sysfs_attr_list(internal_attrs);
787 struct cache_sb *query_dev(char *dev, bool force_csum,
788 bool print_sb, bool uuid_only, char *dev_uuid)
791 struct cache_sb *sb = aligned_alloc(bytes, bytes);
793 int fd = open(dev, O_RDONLY|O_DIRECT);
795 printf("Can't open dev %s: %s\n", dev, strerror(errno));
800 int ret = pread(fd, sb, bytes, SB_START);
802 fprintf(stderr, "Couldn't read superblock: %s\n",
807 } else if (bytes > sizeof(sb) + sb->u64s * sizeof(u64)) {
808 /* We read the whole superblock */
813 * otherwise double the size of our dest
818 sb = aligned_alloc(4096, bytes);
824 show_uuid_only(sb, dev_uuid);
830 show_super_cache(sb, force_csum);
832 show_super_backingdev(sb, force_csum);
838 char *dev_name(const char *ugly_path) {
840 int i, end = strlen(ugly_path);
842 //Chop off "/bcache", then look for the next '/' from the end
843 for (i = end - 8; ; i--)
844 if(ugly_path[i] == '/')
847 strcpy(buf, ugly_path + i);
848 buf[end - i - 7] = 0;
850 // Is the dev guaranteed to be in /dev?
851 // This is needed for finding the superblock with a query-dev
855 static void list_cacheset_devs(char *cset_dir, char *cset_name, bool parse_dev_name)
858 struct stat cache_stat;
859 char entry[MAX_PATH];
861 snprintf(entry, MAX_PATH, "%s/%s", cset_dir, cset_name);
863 if((dir = opendir(entry)) != NULL) {
864 while((ent = readdir(dir)) != NULL) {
870 * We are looking for all cache# directories
871 * do a strlen < 9 to skip over other entries
872 * that also start with "cache"
874 if(strncmp(ent->d_name, "cache", 5) ||
875 !(strlen(ent->d_name) < 9))
878 snprintf(entry, MAX_PATH, "%s/%s/%s",
883 if((cachedir = opendir(entry)) == NULL)
886 if(stat(entry, &cache_stat))
889 if((len = readlink(entry, buf, sizeof(buf) - 1)) !=
894 printf("/dev%s\n", tmp);
897 printf("\t%s\n", buf);
904 char *find_matching_uuid(char *stats_dir, char *subdir, const char *stats_dev_uuid)
906 /* Do a query-dev --uuid only to get the uuid
907 * repeat on each dev until we find a matching one
908 * append that cache# to subdir and return
913 struct stat cache_stat;
915 char entry[MAX_PATH];
918 snprintf(entry, MAX_PATH, "%s%s", stats_dir, subdir);
919 snprintf(intbuf, 4, "%d", i);
920 strcat(entry, intbuf);
926 if((cachedir = opendir(entry)) == NULL)
929 if(stat(entry, &cache_stat))
932 if((len = readlink(entry, buf, sizeof(buf) - 1)) != -1) {
935 int i, end = strlen(buf);
936 char tmp[32], devname[32];
939 /* Chop off "/bcache", then look for the
940 * next '/' from the end
942 for (i = end - 8; ; i--)
946 strcpy(tmp, buf + i);
947 tmp[end - i - 7] = 0;
948 strcpy(devname, "/dev");
949 strcat(devname, tmp);
951 err = "Unable to open superblock";
952 sb = query_dev(devname, false, false, true, dev_uuid);
958 if(!strcmp(stats_dev_uuid, dev_uuid)) {
959 strcat(subdir, intbuf);
964 /* remove i from end and append i++ */
965 entry[strlen(entry)-strlen(intbuf)] = 0;
967 snprintf(intbuf, 4, "%d", i);
968 strcat(entry, intbuf);
972 err = "dev uuid doesn't exist in cache_set";
976 char *list_cachesets(char *cset_dir, bool list_devs)
982 dir = opendir(cset_dir);
984 err = "Failed to open cacheset dir";
988 while ((ent = readdir(dir)) != NULL) {
990 char entry[MAX_PATH];
992 if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
995 snprintf(entry, MAX_PATH, "%s/%s", cset_dir, ent->d_name);
996 if(stat(entry, &statbuf) == -1) {
997 err = "Failed to stat cacheset subdir";
1001 if (S_ISDIR(statbuf.st_mode)) {
1002 printf("%s\n", ent->d_name);
1005 list_cacheset_devs(cset_dir, ent->d_name, true);
1015 char *register_bcache(char *const *devs)
1020 bcachefd = open("/dev/bcache", O_RDWR);
1022 err = "Can't open bcache device";
1026 ret = ioctl(bcachefd, BCH_IOCTL_REGISTER, devs);
1029 snprintf(tmp, 64, "ioctl register error: %s\n",
1041 char *unregister_bcache(char *const *devs)
1046 bcachefd = open("/dev/bcache_extent0", O_RDWR);
1048 err = "Can't open bcache device";
1052 ret = ioctl(bcachefd, BCH_IOCTL_STOP);
1055 snprintf(tmp, 64, "ioctl unregister error: %s\n",
1066 char *add_devices(char *const *devs)
1071 bcachefd = open("/dev/bcache_extent0", O_RDWR);
1073 err = "Can't open bcache device";
1077 struct bch_ioctl_add_disks ia;
1080 ret = ioctl(bcachefd, BCH_IOCTL_ADD_DISKS, &ia);
1083 snprintf(tmp, 128, "ioctl add disk error: %s\n",
1093 char *remove_device(const char *dev, bool force)
1098 bcachefd = open("/dev/bcache_extent0", O_RDWR);
1100 err = "Can't open bcache device";
1104 struct bch_ioctl_rm_disk ir;
1106 ir.force = force ? 1 : 0;
1108 ret = ioctl(bcachefd, BCH_IOCTL_RM_DISK, &ir);
1111 snprintf(tmp, 128, "ioctl add disk error: %s\n",
1121 char *device_set_failed(const char *dev_uuid) {
1125 struct bch_ioctl_disk_failed df;
1127 bcachefd = open("/dev/bcache_extent0", O_RDWR);
1129 err = "Can't open bcache device";
1133 uuid_parse(dev_uuid, dev.b);
1136 ret = ioctl(bcachefd, BCH_IOCTL_SET_DISK_FAILED, &df);
1139 snprintf(tmp, 128, "ioctl set disk failed error %s\n",
1149 char *probe(char *dev, int udev)
1156 int fd = open(dev, O_RDONLY);
1158 err = "Got file descriptor -1 trying to open dev";
1162 if (!(pr = blkid_new_probe())) {
1163 err = "Failed trying to get a blkid for new probe";
1167 if (blkid_probe_set_device(pr, fd, 0, 0)) {
1168 err = "Failed blkid probe set device";
1172 /* probe partitions too */
1173 if (blkid_probe_enable_partitions(pr, true)) {
1174 err = "Enable probe partitions";
1178 /* bail if anything was found
1179 * probe-bcache isn't needed once blkid recognizes bcache */
1180 if (!blkid_do_probe(pr)) {
1181 err = "blkid recognizes bcache";
1185 if (pread(fd, &sb, sizeof(sb), SB_START) != sizeof(sb)) {
1186 err = "Failed to read superblock";
1190 if (memcmp(&sb.magic, &BCACHE_MAGIC, sizeof(sb.magic))) {
1191 err = "Bcache magic incorrect";
1195 uuid_unparse(sb.disk_uuid.b, uuid);
1198 printf("ID_FS_UUID=%s\n"
1199 "ID_FS_UUID_ENC=%s\n"
1200 "ID_FS_TYPE=bcache\n",
1203 printf("%s: UUID=\"\" TYPE=\"bcache\"\n", uuid);
1211 char *read_stat_dir(DIR *dir, char *stats_dir, char *stat_name, char *ret)
1213 struct stat statbuf;
1214 char entry[MAX_PATH];
1217 snprintf(entry, MAX_PATH, "%s/%s", stats_dir, stat_name);
1218 if(stat(entry, &statbuf) == -1) {
1220 snprintf(tmp, MAX_PATH, "Failed to stat %s\n", entry);
1225 if (S_ISREG(statbuf.st_mode)) {
1228 fp = fopen(entry, "r");
1230 /* If we can't open the file, this is probably because
1231 * of permissions, just move to the next file */
1235 while(fgets(ret, MAX_PATH, fp));
1242 char *bcache_get_capacity(const char *cset_dir, const char *capacity_uuid,
1246 char bucket_size_path[MAX_PATH];
1247 char nbuckets_path[MAX_PATH];
1248 char avail_buckets_path[MAX_PATH];
1249 char cache_path[MAX_PATH];
1251 double bucket_sizes[MAX_DEVS];
1252 double nbuckets[MAX_DEVS];
1253 double avail_buckets[MAX_DEVS];
1254 char *dev_names[MAX_DEVS];
1255 int dev_count = 0, i;
1256 double total_cap = 0, total_free = 0;
1265 snprintf(bucket_size_path, sizeof(bucket_size_path), "%s/%s/%s%d/%s", cset_dir,
1266 capacity_uuid, "cache", dev_count, "bucket_size_bytes");
1267 snprintf(nbuckets_path, sizeof(nbuckets_path), "%s/%s/%s%d/%s", cset_dir,
1268 capacity_uuid, "cache", dev_count, "nbuckets");
1269 snprintf(avail_buckets_path, sizeof(avail_buckets_path), "%s/%s/%s%d/%s", cset_dir,
1270 capacity_uuid, "cache", dev_count, "available_buckets");
1271 snprintf(cache_path, sizeof(cache_path), "%s/%s/%s%d", cset_dir, capacity_uuid,
1272 "cache", dev_count);
1274 if((cache_dir = opendir(cache_path)) == NULL)
1277 err = read_stat_dir(cache_dir, cache_path,
1278 "bucket_size_bytes", buf);
1282 bucket_sizes[dev_count] = atof(buf);
1284 err = read_stat_dir(cache_dir, cache_path,
1289 nbuckets[dev_count] = atof(buf);
1291 err = read_stat_dir(cache_dir, cache_path,
1292 "available_buckets", buf);
1296 avail_buckets[dev_count] = atof(buf);
1298 if((len = readlink(cache_path, buf, sizeof(buf) - 1)) != -1) {
1300 dev_names[dev_count] = dev_name(buf);
1306 printf("%-15s%-25s%-25s\n", "Device Name", "Capacity (512 Blocks)", "Free (512 Blocks)");
1309 for (i = 0; i < dev_count; i++) {
1310 printf("%s%-11s%-25.*f%-25.*f\n", "/dev", dev_names[i],
1312 (bucket_sizes[i] * nbuckets[i]) / 512,
1314 (bucket_sizes[i] * avail_buckets[i]) / 512);
1318 for (i = 0; i < dev_count; i++) {
1319 total_cap += (bucket_sizes[i] * nbuckets[i]) / 512;
1320 total_free += (bucket_sizes[i] * avail_buckets[i]) / 512;
1324 printf("%-15s%-25.*f%-25.*f\n", "Total", precision, total_cap,
1325 precision, total_free);
1328 for (i = 0; i < dev_count; i++)