PageRenderTime 47ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/mdadm-3.2.5/bitmap.c

#
C | 449 lines | 344 code | 57 blank | 48 comment | 74 complexity | f3a7e5a160a3d18e1c54184d2113f045 MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. * mdadm - manage Linux "md" devices aka RAID arrays.
  3. *
  4. * Copyright (C) 2004 Paul Clements, SteelEye Technology, Inc.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. #include "mdadm.h"
  21. inline void sb_le_to_cpu(bitmap_super_t *sb)
  22. {
  23. sb->magic = __le32_to_cpu(sb->magic);
  24. sb->version = __le32_to_cpu(sb->version);
  25. /* uuid gets no translation */
  26. sb->events = __le64_to_cpu(sb->events);
  27. sb->events_cleared = __le64_to_cpu(sb->events_cleared);
  28. sb->state = __le32_to_cpu(sb->state);
  29. sb->chunksize = __le32_to_cpu(sb->chunksize);
  30. sb->daemon_sleep = __le32_to_cpu(sb->daemon_sleep);
  31. sb->sync_size = __le64_to_cpu(sb->sync_size);
  32. sb->write_behind = __le32_to_cpu(sb->write_behind);
  33. }
  34. inline void sb_cpu_to_le(bitmap_super_t *sb)
  35. {
  36. sb_le_to_cpu(sb); /* these are really the same thing */
  37. }
  38. mapping_t bitmap_states[] = {
  39. { "OK", 0 },
  40. { "Out of date", 2 },
  41. { NULL, -1 }
  42. };
  43. const char *bitmap_state(int state_num)
  44. {
  45. char *state = map_num(bitmap_states, state_num);
  46. return state ? state : "Unknown";
  47. }
  48. const char *human_chunksize(unsigned long bytes)
  49. {
  50. static char buf[16];
  51. char *suffixes[] = { "B", "KB", "MB", "GB", "TB", NULL };
  52. int i = 0;
  53. while (bytes >> 10) {
  54. bytes >>= 10;
  55. i++;
  56. }
  57. snprintf(buf, sizeof(buf), "%lu %s", bytes, suffixes[i]);
  58. return buf;
  59. }
  60. typedef struct bitmap_info_s {
  61. bitmap_super_t sb;
  62. unsigned long long total_bits;
  63. unsigned long long dirty_bits;
  64. } bitmap_info_t;
  65. /* count the dirty bits in the first num_bits of byte */
  66. inline int count_dirty_bits_byte(char byte, int num_bits)
  67. {
  68. int num = 0;
  69. switch (num_bits) { /* fall through... */
  70. case 8: if (byte & 128) num++;
  71. case 7: if (byte & 64) num++;
  72. case 6: if (byte & 32) num++;
  73. case 5: if (byte & 16) num++;
  74. case 4: if (byte & 8) num++;
  75. case 3: if (byte & 4) num++;
  76. case 2: if (byte & 2) num++;
  77. case 1: if (byte & 1) num++;
  78. default: break;
  79. }
  80. return num;
  81. }
  82. int count_dirty_bits(char *buf, int num_bits)
  83. {
  84. int i, num = 0;
  85. for (i=0; i < num_bits / 8; i++)
  86. num += count_dirty_bits_byte(buf[i], 8);
  87. if (num_bits % 8) /* not an even byte boundary */
  88. num += count_dirty_bits_byte(buf[i], num_bits % 8);
  89. return num;
  90. }
  91. /* calculate the size of the bitmap given the array size and bitmap chunksize */
  92. unsigned long long bitmap_bits(unsigned long long array_size,
  93. unsigned long chunksize)
  94. {
  95. return (array_size * 512 + chunksize - 1) / chunksize;
  96. }
  97. unsigned long bitmap_sectors(struct bitmap_super_s *bsb)
  98. {
  99. unsigned long long bits = bitmap_bits(__le64_to_cpu(bsb->sync_size),
  100. __le32_to_cpu(bsb->chunksize));
  101. int bits_per_sector = 8*512;
  102. return (bits + bits_per_sector - 1) / bits_per_sector;
  103. }
  104. bitmap_info_t *bitmap_fd_read(int fd, int brief)
  105. {
  106. /* Note: fd might be open O_DIRECT, so we must be
  107. * careful to align reads properly
  108. */
  109. unsigned long long total_bits = 0, read_bits = 0, dirty_bits = 0;
  110. bitmap_info_t *info;
  111. void *buf;
  112. unsigned int n, skip;
  113. if (posix_memalign(&buf, 4096, 8192) != 0) {
  114. fprintf(stderr, Name ": failed to allocate 8192 bytes\n");
  115. return NULL;
  116. }
  117. n = read(fd, buf, 8192);
  118. info = malloc(sizeof(*info));
  119. if (info == NULL) {
  120. #if __GNUC__ < 3
  121. fprintf(stderr, Name ": failed to allocate %d bytes\n",
  122. (int)sizeof(*info));
  123. #else
  124. fprintf(stderr, Name ": failed to allocate %zd bytes\n",
  125. sizeof(*info));
  126. #endif
  127. free(buf);
  128. return NULL;
  129. }
  130. if (n < sizeof(info->sb)) {
  131. fprintf(stderr, Name ": failed to read superblock of bitmap "
  132. "file: %s\n", strerror(errno));
  133. free(info);
  134. free(buf);
  135. return NULL;
  136. }
  137. memcpy(&info->sb, buf, sizeof(info->sb));
  138. skip = sizeof(info->sb);
  139. sb_le_to_cpu(&info->sb); /* convert superblock to CPU byte ordering */
  140. if (brief || info->sb.sync_size == 0 || info->sb.chunksize == 0)
  141. goto out;
  142. /* read the rest of the file counting total bits and dirty bits --
  143. * we stop when either:
  144. * 1) we hit EOF, in which case we assume the rest of the bits (if any)
  145. * are dirty
  146. * 2) we've read the full bitmap, in which case we ignore any trailing
  147. * data in the file
  148. */
  149. total_bits = bitmap_bits(info->sb.sync_size, info->sb.chunksize);
  150. while(read_bits < total_bits) {
  151. unsigned long long remaining = total_bits - read_bits;
  152. if (n == 0) {
  153. n = read(fd, buf, 8192);
  154. skip = 0;
  155. if (n <= 0)
  156. break;
  157. }
  158. if (remaining > (n-skip) * 8) /* we want the full buffer */
  159. remaining = (n-skip) * 8;
  160. dirty_bits += count_dirty_bits(buf+skip, remaining);
  161. read_bits += remaining;
  162. n = 0;
  163. }
  164. if (read_bits < total_bits) { /* file truncated... */
  165. fprintf(stderr, Name ": WARNING: bitmap file is not large "
  166. "enough for array size %llu!\n\n",
  167. (unsigned long long)info->sb.sync_size);
  168. total_bits = read_bits;
  169. }
  170. out:
  171. free(buf);
  172. info->total_bits = total_bits;
  173. info->dirty_bits = dirty_bits;
  174. return info;
  175. }
  176. bitmap_info_t *bitmap_file_read(char *filename, int brief, struct supertype **stp)
  177. {
  178. int fd;
  179. bitmap_info_t *info;
  180. struct stat stb;
  181. struct supertype *st = *stp;
  182. if (stat(filename, &stb) < 0) {
  183. fprintf(stderr, Name ": failed to find file %s: %s\n",
  184. filename, strerror(errno));
  185. return NULL;
  186. }
  187. if ((S_IFMT & stb.st_mode) == S_IFBLK) {
  188. fd = open(filename, O_RDONLY);
  189. if (fd < 0) {
  190. fprintf(stderr, Name ": failed to open bitmap file %s: %s\n",
  191. filename, strerror(errno));
  192. return NULL;
  193. }
  194. /* block device, so we are probably after an internal bitmap */
  195. if (!st) st = guess_super(fd);
  196. if (!st) {
  197. /* just look at device... */
  198. lseek(fd, 0, 0);
  199. } else if (!st->ss->locate_bitmap) {
  200. fprintf(stderr, Name ": No bitmap possible with %s metadata\n",
  201. st->ss->name);
  202. return NULL;
  203. } else
  204. st->ss->locate_bitmap(st, fd);
  205. ioctl(fd, BLKFLSBUF, 0); /* make sure we read current data */
  206. *stp = st;
  207. } else {
  208. fd = open(filename, O_RDONLY|O_DIRECT);
  209. if (fd < 0) {
  210. fprintf(stderr, Name ": failed to open bitmap file %s: %s\n",
  211. filename, strerror(errno));
  212. return NULL;
  213. }
  214. }
  215. info = bitmap_fd_read(fd, brief);
  216. close(fd);
  217. return info;
  218. }
  219. __u32 swapl(__u32 l)
  220. {
  221. char *c = (char*)&l;
  222. char t= c[0];
  223. c[0] = c[3];
  224. c[3] = t;
  225. t = c[1];
  226. c[1] = c[2];
  227. c[2] = t;
  228. return l;
  229. }
  230. int ExamineBitmap(char *filename, int brief, struct supertype *st)
  231. {
  232. /*
  233. * Read the bitmap file and display its contents
  234. */
  235. bitmap_super_t *sb;
  236. bitmap_info_t *info;
  237. int rv = 1;
  238. char buf[64];
  239. int swap;
  240. __u32 uuid32[4];
  241. info = bitmap_file_read(filename, brief, &st);
  242. if (!info)
  243. return rv;
  244. sb = &info->sb;
  245. printf(" Filename : %s\n", filename);
  246. printf(" Magic : %08x\n", sb->magic);
  247. if (sb->magic != BITMAP_MAGIC) {
  248. fprintf(stderr, Name ": invalid bitmap magic 0x%x, the bitmap file appears to be corrupted\n", sb->magic);
  249. }
  250. printf(" Version : %d\n", sb->version);
  251. if (sb->version < BITMAP_MAJOR_LO ||
  252. sb->version > BITMAP_MAJOR_HI) {
  253. fprintf(stderr, Name ": unknown bitmap version %d, either the bitmap file is corrupted or you need to upgrade your tools\n", sb->version);
  254. goto free_info;
  255. }
  256. rv = 0;
  257. if (st)
  258. swap = st->ss->swapuuid;
  259. else
  260. #if __BYTE_ORDER == BIG_ENDIAN
  261. swap = 0;
  262. #else
  263. swap = 1;
  264. #endif
  265. memcpy(uuid32, sb->uuid, 16);
  266. if (swap)
  267. printf(" UUID : %08x:%08x:%08x:%08x\n",
  268. swapl(uuid32[0]),
  269. swapl(uuid32[1]),
  270. swapl(uuid32[2]),
  271. swapl(uuid32[3]));
  272. else
  273. printf(" UUID : %08x:%08x:%08x:%08x\n",
  274. uuid32[0],
  275. uuid32[1],
  276. uuid32[2],
  277. uuid32[3]);
  278. printf(" Events : %llu\n", (unsigned long long)sb->events);
  279. printf(" Events Cleared : %llu\n", (unsigned long long)sb->events_cleared);
  280. printf(" State : %s\n", bitmap_state(sb->state));
  281. printf(" Chunksize : %s\n", human_chunksize(sb->chunksize));
  282. printf(" Daemon : %ds flush period\n", sb->daemon_sleep);
  283. if (sb->write_behind)
  284. sprintf(buf, "Allow write behind, max %d", sb->write_behind);
  285. else
  286. sprintf(buf, "Normal");
  287. printf(" Write Mode : %s\n", buf);
  288. printf(" Sync Size : %llu%s\n", (unsigned long long)sb->sync_size/2,
  289. human_size(sb->sync_size * 512));
  290. if (brief)
  291. goto free_info;
  292. printf(" Bitmap : %llu bits (chunks), %llu dirty (%2.1f%%)\n",
  293. info->total_bits, info->dirty_bits,
  294. 100.0 * info->dirty_bits / (info->total_bits?:1));
  295. free_info:
  296. free(info);
  297. return rv;
  298. }
  299. int CreateBitmap(char *filename, int force, char uuid[16],
  300. unsigned long chunksize, unsigned long daemon_sleep,
  301. unsigned long write_behind,
  302. unsigned long long array_size /* sectors */,
  303. int major)
  304. {
  305. /*
  306. * Create a bitmap file with a superblock and (optionally) a full bitmap
  307. */
  308. FILE *fp;
  309. int rv = 1;
  310. char block[512];
  311. bitmap_super_t sb;
  312. long long bytes, filesize;
  313. if (!force && access(filename, F_OK) == 0) {
  314. fprintf(stderr, Name ": bitmap file %s already exists, use --force to overwrite\n", filename);
  315. return rv;
  316. }
  317. fp = fopen(filename, "w");
  318. if (fp == NULL) {
  319. fprintf(stderr, Name ": failed to open bitmap file %s: %s\n",
  320. filename, strerror(errno));
  321. return rv;
  322. }
  323. if (chunksize == UnSet) {
  324. /* We don't want more than 2^21 chunks, as 2^11 fill up one
  325. * 4K page (2 bytes per chunk), and 2^10 address of those
  326. * fill up a 4K indexing page. 2^20 might be safer, especially
  327. * on 64bit hosts, so use that.
  328. */
  329. chunksize = DEFAULT_BITMAP_CHUNK;
  330. /* <<20 for 2^20 chunks, >>9 to convert bytes to sectors */
  331. while (array_size > ((unsigned long long)chunksize << (20-9)))
  332. chunksize <<= 1;
  333. }
  334. memset(&sb, 0, sizeof(sb));
  335. sb.magic = BITMAP_MAGIC;
  336. sb.version = major;
  337. if (uuid != NULL)
  338. memcpy(sb.uuid, uuid, 16);
  339. sb.chunksize = chunksize;
  340. sb.daemon_sleep = daemon_sleep;
  341. sb.write_behind = write_behind;
  342. sb.sync_size = array_size;
  343. sb_cpu_to_le(&sb); /* convert to on-disk byte ordering */
  344. if (fwrite(&sb, sizeof(sb), 1, fp) != 1) {
  345. fprintf(stderr, Name ": failed to write superblock to bitmap file %s: %s\n", filename, strerror(errno));
  346. goto out;
  347. }
  348. /* calculate the size of the bitmap and write it to disk */
  349. bytes = (bitmap_bits(array_size, chunksize) + 7) / 8;
  350. if (!bytes) {
  351. rv = 0;
  352. goto out;
  353. }
  354. filesize = bytes + sizeof(sb);
  355. memset(block, 0xff, sizeof(block));
  356. while (bytes > 0) {
  357. if (fwrite(block, sizeof(block), 1, fp) != 1) {
  358. fprintf(stderr, Name ": failed to write bitmap file %s: %s\n", filename, strerror(errno));
  359. goto out;
  360. }
  361. bytes -= sizeof(block);
  362. }
  363. rv = 0;
  364. fflush(fp);
  365. /* make the file be the right size (well, to the nearest byte) */
  366. if (ftruncate(fileno(fp), filesize))
  367. perror("ftrunace");
  368. out:
  369. fclose(fp);
  370. if (rv)
  371. unlink(filename); /* possibly corrupted, better get rid of it */
  372. return rv;
  373. }
  374. int bitmap_update_uuid(int fd, int *uuid, int swap)
  375. {
  376. struct bitmap_super_s bm;
  377. if (lseek(fd, 0, 0) != 0)
  378. return 1;
  379. if (read(fd, &bm, sizeof(bm)) != sizeof(bm))
  380. return 1;
  381. if (bm.magic != __cpu_to_le32(BITMAP_MAGIC))
  382. return 1;
  383. copy_uuid(bm.uuid, uuid, swap);
  384. if (lseek(fd, 0, 0) != 0)
  385. return 2;
  386. if (write(fd, &bm, sizeof(bm)) != sizeof(bm)) {
  387. lseek(fd, 0, 0);
  388. return 2;
  389. }
  390. lseek(fd, 0, 0);
  391. return 0;
  392. }