10 #include <sys/ioctl.h>
12 #include <sys/types.h>
16 #include <uuid/uuid.h>
18 #include "ccan/crc/crc.h"
24 u64 rounddown_pow_of_two(u64 n)
48 char *skip_spaces(const char *str)
66 while (end >= s && isspace(*end))
73 /* Argument parsing stuff: */
75 long strtoul_or_die(const char *p, size_t max, const char *msg)
78 long v = strtol(p, NULL, 10);
79 if (errno || v < 0 || v >= max)
80 die("Invalid %s %zi", msg, v);
85 u64 hatoi(const char *s)
88 long long i = strtoll(s, &e, 10);
106 unsigned hatoi_validate(const char *s, const char *msg)
111 die("%s must be a power of two", msg);
116 die("%s too large\n", msg);
119 die("%s too small\n", msg);
124 unsigned nr_args(char * const *args)
128 for (i = 0; args[i]; i++)
134 /* File parsing (i.e. sysfs) */
136 char *read_file_str(int dirfd, const char *path)
138 int fd = openat(dirfd, path, O_RDONLY);
141 die("Unable to open %s\n", path);
144 if (fstat(fd, &statbuf) < 0)
145 die("fstat error\n");
147 char *buf = malloc(statbuf.st_size + 1);
149 int len = read(fd, buf, statbuf.st_size);
151 die("read error while reading from file %s\n", path);
154 if (len && buf[len - 1] == '\n')
162 u64 read_file_u64(int dirfd, const char *path)
164 char *buf = read_file_str(dirfd, path);
165 u64 ret = strtoll(buf, NULL, 10);
171 /* String list options: */
173 ssize_t read_string_list(const char *buf, const char * const list[])
176 char *s, *d = strdup(buf);
182 for (i = 0; list[i]; i++)
183 if (!strcmp(list[i], s))
194 ssize_t read_string_list_or_die(const char *opt, const char * const list[],
197 ssize_t v = read_string_list(opt, list);
199 die("Bad %s %s", msg, opt);
204 void print_string_list(const char * const list[], size_t selected)
208 for (i = 0; list[i]; i++) {
211 printf(i == selected ? "[%s] ": "%s", list[i]);
215 /* Returns size of file or block device, in units of 512 byte sectors: */
216 u64 get_size(const char *path, int fd)
219 if (fstat(fd, &statbuf))
220 die("Error statting %s: %s", path, strerror(errno));
222 if (!S_ISBLK(statbuf.st_mode))
223 return statbuf.st_size >> 9;
226 if (ioctl(fd, BLKGETSIZE64, &ret))
227 die("Error getting block device size on %s: %s\n",
228 path, strerror(errno));
233 /* Returns blocksize in units of 512 byte sectors: */
234 unsigned get_blocksize(const char *path, int fd)
237 if (fstat(fd, &statbuf))
238 die("Error statting %s: %s", path, strerror(errno));
240 if (!S_ISBLK(statbuf.st_mode))
241 return statbuf.st_blksize >> 9;
244 if (ioctl(fd, BLKPBSZGET, &ret))
245 die("Error getting blocksize on %s: %s\n",
246 path, strerror(errno));
251 /* Open a block device, do magic blkid stuff: */
252 int dev_open(const char *dev)
257 if ((fd = open(dev, O_RDWR|O_EXCL)) == -1)
258 die("Can't open dev %s: %s\n", dev, strerror(errno));
260 if (!(pr = blkid_new_probe()))
261 die("Failed to create a new probe");
262 if (blkid_probe_set_device(pr, fd, 0, 0))
263 die("failed to set probe to device");
265 /* enable ptable probing; superblock probing is enabled by default */
266 if (blkid_probe_enable_partitions(pr, true))
267 die("Failed to enable partitions on probe");
269 if (!blkid_do_probe(pr))
270 /* XXX wipefs doesn't know how to remove partition tables */
271 die("Device %s already has a non-bcache superblock, "
272 "remove it using wipefs and wipefs -a\n", dev);
280 * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group (Any
281 * use permitted, subject to terms of PostgreSQL license; see.)
283 * If we have a 64-bit integer type, then a 64-bit CRC looks just like the
284 * usual sort of implementation. (See Ross Williams' excellent introduction
285 * A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS, available from
286 * ftp://ftp.rocksoft.com/papers/crc_v3.txt or several other net sites.)
287 * If we have no working 64-bit type, then fake it with two 32-bit registers.
289 * The present implementation is a normal (not "reflected", in Williams'
290 * terms) 64-bit CRC, using initial all-ones register contents and a final
291 * bit inversion. The chosen polynomial is borrowed from the DLT1 spec
292 * (ECMA-182, available from http://www.ecma.ch/ecma1/STAND/ECMA-182.HTM):
294 * x^64 + x^62 + x^57 + x^55 + x^54 + x^53 + x^52 + x^47 + x^46 + x^45 +
295 * x^40 + x^39 + x^38 + x^37 + x^35 + x^33 + x^32 + x^31 + x^29 + x^27 +
296 * x^24 + x^23 + x^22 + x^21 + x^19 + x^17 + x^13 + x^12 + x^10 + x^9 +
300 static const u64 crc_table[256] = {
301 0x0000000000000000ULL, 0x42F0E1EBA9EA3693ULL, 0x85E1C3D753D46D26ULL,
302 0xC711223CFA3E5BB5ULL, 0x493366450E42ECDFULL, 0x0BC387AEA7A8DA4CULL,
303 0xCCD2A5925D9681F9ULL, 0x8E224479F47CB76AULL, 0x9266CC8A1C85D9BEULL,
304 0xD0962D61B56FEF2DULL, 0x17870F5D4F51B498ULL, 0x5577EEB6E6BB820BULL,
305 0xDB55AACF12C73561ULL, 0x99A54B24BB2D03F2ULL, 0x5EB4691841135847ULL,
306 0x1C4488F3E8F96ED4ULL, 0x663D78FF90E185EFULL, 0x24CD9914390BB37CULL,
307 0xE3DCBB28C335E8C9ULL, 0xA12C5AC36ADFDE5AULL, 0x2F0E1EBA9EA36930ULL,
308 0x6DFEFF5137495FA3ULL, 0xAAEFDD6DCD770416ULL, 0xE81F3C86649D3285ULL,
309 0xF45BB4758C645C51ULL, 0xB6AB559E258E6AC2ULL, 0x71BA77A2DFB03177ULL,
310 0x334A9649765A07E4ULL, 0xBD68D2308226B08EULL, 0xFF9833DB2BCC861DULL,
311 0x388911E7D1F2DDA8ULL, 0x7A79F00C7818EB3BULL, 0xCC7AF1FF21C30BDEULL,
312 0x8E8A101488293D4DULL, 0x499B3228721766F8ULL, 0x0B6BD3C3DBFD506BULL,
313 0x854997BA2F81E701ULL, 0xC7B97651866BD192ULL, 0x00A8546D7C558A27ULL,
314 0x4258B586D5BFBCB4ULL, 0x5E1C3D753D46D260ULL, 0x1CECDC9E94ACE4F3ULL,
315 0xDBFDFEA26E92BF46ULL, 0x990D1F49C77889D5ULL, 0x172F5B3033043EBFULL,
316 0x55DFBADB9AEE082CULL, 0x92CE98E760D05399ULL, 0xD03E790CC93A650AULL,
317 0xAA478900B1228E31ULL, 0xE8B768EB18C8B8A2ULL, 0x2FA64AD7E2F6E317ULL,
318 0x6D56AB3C4B1CD584ULL, 0xE374EF45BF6062EEULL, 0xA1840EAE168A547DULL,
319 0x66952C92ECB40FC8ULL, 0x2465CD79455E395BULL, 0x3821458AADA7578FULL,
320 0x7AD1A461044D611CULL, 0xBDC0865DFE733AA9ULL, 0xFF3067B657990C3AULL,
321 0x711223CFA3E5BB50ULL, 0x33E2C2240A0F8DC3ULL, 0xF4F3E018F031D676ULL,
322 0xB60301F359DBE0E5ULL, 0xDA050215EA6C212FULL, 0x98F5E3FE438617BCULL,
323 0x5FE4C1C2B9B84C09ULL, 0x1D14202910527A9AULL, 0x93366450E42ECDF0ULL,
324 0xD1C685BB4DC4FB63ULL, 0x16D7A787B7FAA0D6ULL, 0x5427466C1E109645ULL,
325 0x4863CE9FF6E9F891ULL, 0x0A932F745F03CE02ULL, 0xCD820D48A53D95B7ULL,
326 0x8F72ECA30CD7A324ULL, 0x0150A8DAF8AB144EULL, 0x43A04931514122DDULL,
327 0x84B16B0DAB7F7968ULL, 0xC6418AE602954FFBULL, 0xBC387AEA7A8DA4C0ULL,
328 0xFEC89B01D3679253ULL, 0x39D9B93D2959C9E6ULL, 0x7B2958D680B3FF75ULL,
329 0xF50B1CAF74CF481FULL, 0xB7FBFD44DD257E8CULL, 0x70EADF78271B2539ULL,
330 0x321A3E938EF113AAULL, 0x2E5EB66066087D7EULL, 0x6CAE578BCFE24BEDULL,
331 0xABBF75B735DC1058ULL, 0xE94F945C9C3626CBULL, 0x676DD025684A91A1ULL,
332 0x259D31CEC1A0A732ULL, 0xE28C13F23B9EFC87ULL, 0xA07CF2199274CA14ULL,
333 0x167FF3EACBAF2AF1ULL, 0x548F120162451C62ULL, 0x939E303D987B47D7ULL,
334 0xD16ED1D631917144ULL, 0x5F4C95AFC5EDC62EULL, 0x1DBC74446C07F0BDULL,
335 0xDAAD56789639AB08ULL, 0x985DB7933FD39D9BULL, 0x84193F60D72AF34FULL,
336 0xC6E9DE8B7EC0C5DCULL, 0x01F8FCB784FE9E69ULL, 0x43081D5C2D14A8FAULL,
337 0xCD2A5925D9681F90ULL, 0x8FDAB8CE70822903ULL, 0x48CB9AF28ABC72B6ULL,
338 0x0A3B7B1923564425ULL, 0x70428B155B4EAF1EULL, 0x32B26AFEF2A4998DULL,
339 0xF5A348C2089AC238ULL, 0xB753A929A170F4ABULL, 0x3971ED50550C43C1ULL,
340 0x7B810CBBFCE67552ULL, 0xBC902E8706D82EE7ULL, 0xFE60CF6CAF321874ULL,
341 0xE224479F47CB76A0ULL, 0xA0D4A674EE214033ULL, 0x67C58448141F1B86ULL,
342 0x253565A3BDF52D15ULL, 0xAB1721DA49899A7FULL, 0xE9E7C031E063ACECULL,
343 0x2EF6E20D1A5DF759ULL, 0x6C0603E6B3B7C1CAULL, 0xF6FAE5C07D3274CDULL,
344 0xB40A042BD4D8425EULL, 0x731B26172EE619EBULL, 0x31EBC7FC870C2F78ULL,
345 0xBFC9838573709812ULL, 0xFD39626EDA9AAE81ULL, 0x3A28405220A4F534ULL,
346 0x78D8A1B9894EC3A7ULL, 0x649C294A61B7AD73ULL, 0x266CC8A1C85D9BE0ULL,
347 0xE17DEA9D3263C055ULL, 0xA38D0B769B89F6C6ULL, 0x2DAF4F0F6FF541ACULL,
348 0x6F5FAEE4C61F773FULL, 0xA84E8CD83C212C8AULL, 0xEABE6D3395CB1A19ULL,
349 0x90C79D3FEDD3F122ULL, 0xD2377CD44439C7B1ULL, 0x15265EE8BE079C04ULL,
350 0x57D6BF0317EDAA97ULL, 0xD9F4FB7AE3911DFDULL, 0x9B041A914A7B2B6EULL,
351 0x5C1538ADB04570DBULL, 0x1EE5D94619AF4648ULL, 0x02A151B5F156289CULL,
352 0x4051B05E58BC1E0FULL, 0x87409262A28245BAULL, 0xC5B073890B687329ULL,
353 0x4B9237F0FF14C443ULL, 0x0962D61B56FEF2D0ULL, 0xCE73F427ACC0A965ULL,
354 0x8C8315CC052A9FF6ULL, 0x3A80143F5CF17F13ULL, 0x7870F5D4F51B4980ULL,
355 0xBF61D7E80F251235ULL, 0xFD913603A6CF24A6ULL, 0x73B3727A52B393CCULL,
356 0x31439391FB59A55FULL, 0xF652B1AD0167FEEAULL, 0xB4A25046A88DC879ULL,
357 0xA8E6D8B54074A6ADULL, 0xEA16395EE99E903EULL, 0x2D071B6213A0CB8BULL,
358 0x6FF7FA89BA4AFD18ULL, 0xE1D5BEF04E364A72ULL, 0xA3255F1BE7DC7CE1ULL,
359 0x64347D271DE22754ULL, 0x26C49CCCB40811C7ULL, 0x5CBD6CC0CC10FAFCULL,
360 0x1E4D8D2B65FACC6FULL, 0xD95CAF179FC497DAULL, 0x9BAC4EFC362EA149ULL,
361 0x158E0A85C2521623ULL, 0x577EEB6E6BB820B0ULL, 0x906FC95291867B05ULL,
362 0xD29F28B9386C4D96ULL, 0xCEDBA04AD0952342ULL, 0x8C2B41A1797F15D1ULL,
363 0x4B3A639D83414E64ULL, 0x09CA82762AAB78F7ULL, 0x87E8C60FDED7CF9DULL,
364 0xC51827E4773DF90EULL, 0x020905D88D03A2BBULL, 0x40F9E43324E99428ULL,
365 0x2CFFE7D5975E55E2ULL, 0x6E0F063E3EB46371ULL, 0xA91E2402C48A38C4ULL,
366 0xEBEEC5E96D600E57ULL, 0x65CC8190991CB93DULL, 0x273C607B30F68FAEULL,
367 0xE02D4247CAC8D41BULL, 0xA2DDA3AC6322E288ULL, 0xBE992B5F8BDB8C5CULL,
368 0xFC69CAB42231BACFULL, 0x3B78E888D80FE17AULL, 0x7988096371E5D7E9ULL,
369 0xF7AA4D1A85996083ULL, 0xB55AACF12C735610ULL, 0x724B8ECDD64D0DA5ULL,
370 0x30BB6F267FA73B36ULL, 0x4AC29F2A07BFD00DULL, 0x08327EC1AE55E69EULL,
371 0xCF235CFD546BBD2BULL, 0x8DD3BD16FD818BB8ULL, 0x03F1F96F09FD3CD2ULL,
372 0x41011884A0170A41ULL, 0x86103AB85A2951F4ULL, 0xC4E0DB53F3C36767ULL,
373 0xD8A453A01B3A09B3ULL, 0x9A54B24BB2D03F20ULL, 0x5D45907748EE6495ULL,
374 0x1FB5719CE1045206ULL, 0x919735E51578E56CULL, 0xD367D40EBC92D3FFULL,
375 0x1476F63246AC884AULL, 0x568617D9EF46BED9ULL, 0xE085162AB69D5E3CULL,
376 0xA275F7C11F7768AFULL, 0x6564D5FDE549331AULL, 0x279434164CA30589ULL,
377 0xA9B6706FB8DFB2E3ULL, 0xEB46918411358470ULL, 0x2C57B3B8EB0BDFC5ULL,
378 0x6EA7525342E1E956ULL, 0x72E3DAA0AA188782ULL, 0x30133B4B03F2B111ULL,
379 0xF7021977F9CCEAA4ULL, 0xB5F2F89C5026DC37ULL, 0x3BD0BCE5A45A6B5DULL,
380 0x79205D0E0DB05DCEULL, 0xBE317F32F78E067BULL, 0xFCC19ED95E6430E8ULL,
381 0x86B86ED5267CDBD3ULL, 0xC4488F3E8F96ED40ULL, 0x0359AD0275A8B6F5ULL,
382 0x41A94CE9DC428066ULL, 0xCF8B0890283E370CULL, 0x8D7BE97B81D4019FULL,
383 0x4A6ACB477BEA5A2AULL, 0x089A2AACD2006CB9ULL, 0x14DEA25F3AF9026DULL,
384 0x562E43B4931334FEULL, 0x913F6188692D6F4BULL, 0xD3CF8063C0C759D8ULL,
385 0x5DEDC41A34BBEEB2ULL, 0x1F1D25F19D51D821ULL, 0xD80C07CD676F8394ULL,
386 0x9AFCE626CE85B507ULL
389 static u64 bch_crc64_update(u64 crc, const void *_data, size_t len)
391 const unsigned char *data = _data;
394 int i = ((int) (crc >> 56) ^ *data++) & 0xFF;
395 crc = crc_table[i] ^ (crc << 8);
401 static u64 bch_checksum_update(unsigned type, u64 crc, const void *data, size_t len)
406 case BCH_CSUM_CRC32C:
407 return crc32c(crc, data, len);
409 return bch_crc64_update(crc, data, len);
411 die("Unknown checksum type %u", type);
415 u64 bch_checksum(unsigned type, const void *data, size_t len)
417 u64 crc = 0xffffffffffffffffULL;
419 crc = bch_checksum_update(type, crc, data, len);
421 return crc ^ 0xffffffffffffffffULL;
424 /* Global control device: */
425 int bcachectl_open(void)
427 int fd = open("/dev/bcache-ctl", O_RDWR);
429 die("Can't open bcache device: %s", strerror(errno));
434 /* Filesystem handles (ioctl, sysfs dir): */
436 #define SYSFS_BASE "/sys/fs/bcache/"
438 struct bcache_handle bcache_fs_open(const char *path)
440 struct bcache_handle ret;
443 if (!uuid_parse(path, tmp)) {
444 /* It's a UUID, look it up in sysfs: */
446 char *sysfs = alloca(strlen(SYSFS_BASE) + strlen(path) + 1);
447 sprintf(sysfs, "%s%s", SYSFS_BASE, path);
449 ret.sysfs = opendir(sysfs);
451 die("Unable to open %s\n", path);
453 char *minor = read_file_str(dirfd(ret.sysfs), "minor");
454 char *ctl = alloca(20 + strlen(minor));
456 sprintf(ctl, "/dev/bcache%s-ctl", minor);
459 ret.fd = open(ctl, O_RDWR);
461 die("Error opening control device: %s\n",
466 ret.fd = open(path, O_RDONLY);
468 die("Error opening %s: %s\n",
469 path, strerror(errno));
471 struct bch_ioctl_query_uuid uuid;
472 if (ioctl(ret.fd, BCH_IOCTL_QUERY_UUID, &uuid))
473 die("ioctl error (not a bcache fs?): %s\n",
477 uuid_unparse(uuid.uuid.b, uuid_str);
479 char *sysfs = alloca(strlen(SYSFS_BASE) + strlen(uuid_str) + 1);
480 sprintf(sysfs, "%s%s", SYSFS_BASE, uuid_str);
482 ret.sysfs = opendir(sysfs);
484 die("Unable to open sysfs dir %s: %s\n",
485 sysfs, strerror(errno));