]> git.sesse.net Git - bcachefs-tools-debian/blob - bcache-super-show.c
Fix offsets, cache and backing are two different cases.
[bcachefs-tools-debian] / bcache-super-show.c
1 #define _FILE_OFFSET_BITS       64
2 #define __USE_FILE_OFFSET64
3 #define _XOPEN_SOURCE 500
4
5 #include <errno.h>
6 #include <fcntl.h>
7 #include <inttypes.h>
8 #include <linux/fs.h>
9 #include <stdbool.h>
10 #include <stdint.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <sys/ioctl.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <unistd.h>
18 #include <uuid/uuid.h>
19
20 #include "bcache.h"
21
22
23 static void usage()
24 {
25         fprintf(stderr, "Usage: bcache-super-show [-f] <device>\n");
26 }
27
28
29 int main(int argc, char **argv)
30 {
31         bool force_csum = false;
32         int o;
33         extern char *optarg;
34         struct cache_sb sb;
35         char uuid[40];
36         uint64_t expected_csum;
37
38         while ((o = getopt(argc, argv, "f")) != EOF)
39                 switch (o) {
40                         case 'f':
41                                 force_csum = 1;
42                                 break;
43
44                         default:
45                                 usage();
46                                 exit(1);
47                 }
48
49         argv += optind;
50         argc -= optind;
51
52         if (argc != 1) {
53                 usage();
54                 exit(1);
55         }
56
57         int fd = open(argv[0], O_RDONLY);
58         if (fd < 0) {
59                 printf("Can't open dev %s: %s\n", argv[0], strerror(errno));
60                 exit(2);
61         }
62
63         if (pread(fd, &sb, sizeof(sb), 4096) != sizeof(sb)) {
64                 fprintf(stderr, "Couldn't read\n");
65                 exit(2);
66         }
67
68         printf("sb.magic\t\t");
69         if (! memcmp(sb.magic, bcache_magic, 16)) {
70                 printf("ok\n");
71         } else {
72                 printf("bad magic\n");
73                 fprintf(stderr, "Invalid superblock (bad magic)\n");
74                 exit(2);
75         }
76
77         printf("sb.first_sector\t\t%" PRIu64, sb.offset);
78         if (sb.offset == SB_SECTOR) {
79                 printf(" [match]\n");
80         } else {
81                 printf(" [expected %ds]\n", SB_SECTOR);
82                 fprintf(stderr, "Invalid superblock (bad sector)\n");
83                 exit(2);
84         }
85
86         printf("sb.csum\t\t\t0x%" PRIx64, sb.csum);
87         expected_csum = csum_set(&sb);
88         if (sb.csum == expected_csum) {
89                 printf(" [match]\n");
90         } else {
91                 printf(" [expected %" PRIX64 "]\n", expected_csum);
92                 if (! force_csum) {
93                         fprintf(stderr, "Corrupt superblock (bad csum)\n");
94                         exit(2);
95                 }
96         }
97
98         printf("sb.version\t\t%" PRIu64, sb.version);
99         switch (sb.version) {
100                 case 0:
101                         printf(" [cache device]\n");
102                         break;
103
104                 case CACHE_BACKING_DEV: // 1
105                         printf(" [backing device]\n");
106                         break;
107
108                 case 3:
109                         printf(" [backing device with offset]\n");
110                         // XXX Kernel side bcache.h says different, and implements neither
111                         return 0; //break;
112
113                 default:
114                         printf(" [unknown]\n");
115                         // exit code?
116                         return 0;
117         }
118
119         putchar('\n');
120
121         uuid_unparse(sb.uuid, uuid);
122         printf("dev.uuid\t\t%s\n", uuid);
123
124         printf(
125                         "dev.sectors_per_block\t%u\n"
126                         "dev.sectors_per_bucket\t%u\n"
127                         "dev.bucket_count\t%ju\n"
128                         "dev.cache_count\t\t%u\n", // expect version == 0 ? 1 : 0
129                         sb.block_size,
130                         sb.bucket_size,
131                         sb.nbuckets,
132                         sb.nr_this_dev);
133
134         if (sb.version == 0) {
135                 printf(
136                                 "dev.cache.first_bucket\t%u\n"
137                                 "dev.cache.first_sector\t%u\n",
138                                 sb.first_bucket,
139                                 sb.bucket_size * sb.first_bucket);
140         } else if (sb.version == CACHE_BACKING_DEV) {
141                 printf(
142                                 "dev.data.first_sector\t%u\n",
143                                 BDEV_DATA_START);
144         }
145         putchar('\n');
146
147         uuid_unparse(sb.set_uuid, uuid);
148         printf("cset.uuid\t\t%s\n", uuid);
149
150         printf("cset.cache_count\t%u\n\n", sb.nr_in_set);
151
152         return 0;
153 }