]> git.sesse.net Git - bcachefs-tools-debian/blob - cmd_migrate.c
Update bcachefs sources to 2e70771b8d
[bcachefs-tools-debian] / cmd_migrate.c
1 #include </usr/include/dirent.h>
2 #include <errno.h>
3 #include <fcntl.h>
4 #include <getopt.h>
5 #include <string.h>
6 #include <sys/ioctl.h>
7 #include <sys/stat.h>
8 #include <sys/sysmacros.h>
9 #include <sys/types.h>
10 #include <sys/vfs.h>
11 #include <unistd.h>
12 #include <attr/xattr.h>
13
14 #include <linux/fiemap.h>
15 #include <linux/fs.h>
16 #include <linux/stat.h>
17
18 #include <uuid/uuid.h>
19
20 #include "cmds.h"
21 #include "crypto.h"
22 #include "libbcachefs.h"
23
24 #include <linux/dcache.h>
25 #include <linux/generic-radix-tree.h>
26 #include <linux/xattr.h>
27 #include "btree_update.h"
28 #include "buckets.h"
29 #include "dirent.h"
30 #include "fs.h"
31 #include "inode.h"
32 #include "io.h"
33 #include "str_hash.h"
34 #include "super.h"
35 #include "xattr.h"
36
37 static char *dev_t_to_path(dev_t dev)
38 {
39         char link[PATH_MAX], *p;
40         int ret;
41
42         char *sysfs_dev = mprintf("/sys/dev/block/%u:%u",
43                                   major(dev), minor(dev));
44         ret = readlink(sysfs_dev, link, sizeof(link));
45         free(sysfs_dev);
46
47         if (ret < 0 || ret >= sizeof(link))
48                 die("readlink error while looking up block device: %m");
49
50         link[ret] = '\0';
51
52         p = strrchr(link, '/');
53         if (!p)
54                 die("error looking up device name");
55         p++;
56
57         return mprintf("/dev/%s", p);
58 }
59
60 static bool path_is_fs_root(char *path)
61 {
62         char *line = NULL, *p, *mount;
63         size_t n = 0;
64         FILE *f;
65         bool ret = true;
66
67         f = fopen("/proc/self/mountinfo", "r");
68         if (!f)
69                 die("Error getting mount information");
70
71         while (getline(&line, &n, f) != -1) {
72                 p = line;
73
74                 strsep(&p, " "); /* mount id */
75                 strsep(&p, " "); /* parent id */
76                 strsep(&p, " "); /* dev */
77                 strsep(&p, " "); /* root */
78                 mount = strsep(&p, " ");
79                 strsep(&p, " ");
80
81                 if (mount && !strcmp(path, mount))
82                         goto found;
83         }
84
85         ret = false;
86 found:
87         fclose(f);
88         free(line);
89         return ret;
90 }
91
92 static void mark_unreserved_space(struct bch_fs *c, ranges extents)
93 {
94         struct bch_dev *ca = c->devs[0];
95         struct hole_iter iter;
96         struct range i;
97
98         for_each_hole(iter, extents, bucket_to_sector(ca, ca->mi.nbuckets) << 9, i) {
99                 struct bucket_mark new;
100                 u64 b;
101
102                 if (i.start == i.end)
103                         return;
104
105                 b = sector_to_bucket(ca, i.start >> 9);
106                 do {
107                         bucket_cmpxchg(&ca->buckets[b], new, new.nouse = 1);
108                         b++;
109                 } while (bucket_to_sector(ca, b) << 9 < i.end);
110         }
111 }
112
113 static void update_inode(struct bch_fs *c,
114                          struct bch_inode_unpacked *inode)
115 {
116         struct bkey_inode_buf packed;
117         int ret;
118
119         bch2_inode_pack(&packed, inode);
120         ret = bch2_btree_update(c, BTREE_ID_INODES, &packed.inode.k_i, NULL);
121         if (ret)
122                 die("error creating file: %s", strerror(-ret));
123 }
124
125 static void create_dirent(struct bch_fs *c,
126                           struct bch_inode_unpacked *parent,
127                           const char *name, u64 inum, mode_t mode)
128 {
129         struct bch_hash_info parent_hash_info = bch2_hash_info_init(c, parent);
130         struct qstr qname = { { { .len = strlen(name), } }, .name = name };
131
132         int ret = bch2_dirent_create(c, parent->inum, &parent_hash_info,
133                                      mode_to_type(mode), &qname,
134                                      inum, NULL, BCH_HASH_SET_MUST_CREATE);
135         if (ret)
136                 die("error creating file: %s", strerror(-ret));
137
138         if (S_ISDIR(mode))
139                 parent->i_nlink++;
140 }
141
142 static void create_link(struct bch_fs *c,
143                         struct bch_inode_unpacked *parent,
144                         const char *name, u64 inum, mode_t mode)
145 {
146         struct bch_inode_unpacked inode;
147         int ret = bch2_inode_find_by_inum(c, inum, &inode);
148         if (ret)
149                 die("error looking up hardlink: %s", strerror(-ret));
150
151         inode.i_nlink++;
152         update_inode(c, &inode);
153
154         create_dirent(c, parent, name, inum, mode);
155 }
156
157 static struct bch_inode_unpacked create_file(struct bch_fs *c,
158                                              struct bch_inode_unpacked *parent,
159                                              const char *name,
160                                              uid_t uid, gid_t gid,
161                                              mode_t mode, dev_t rdev)
162 {
163         struct bch_inode_unpacked new_inode;
164         struct bkey_inode_buf packed;
165         int ret;
166
167         bch2_inode_init(c, &new_inode, uid, gid, mode, rdev);
168         bch2_inode_pack(&packed, &new_inode);
169
170         ret = bch2_inode_create(c, &packed.inode.k_i, BLOCKDEV_INODE_MAX, 0,
171                                 &c->unused_inode_hint);
172         if (ret)
173                 die("error creating file: %s", strerror(-ret));
174
175         new_inode.inum = packed.inode.k.p.inode;
176         create_dirent(c, parent, name, new_inode.inum, mode);
177
178         return new_inode;
179 }
180
181 #define for_each_xattr_handler(handlers, handler)               \
182         if (handlers)                                           \
183                 for ((handler) = *(handlers)++;                 \
184                         (handler) != NULL;                      \
185                         (handler) = *(handlers)++)
186
187 static const struct xattr_handler *xattr_resolve_name(const char **name)
188 {
189         const struct xattr_handler **handlers = bch2_xattr_handlers;
190         const struct xattr_handler *handler;
191
192         for_each_xattr_handler(handlers, handler) {
193                 const char *n;
194
195                 n = strcmp_prefix(*name, xattr_prefix(handler));
196                 if (n) {
197                         if (!handler->prefix ^ !*n) {
198                                 if (*n)
199                                         continue;
200                                 return ERR_PTR(-EINVAL);
201                         }
202                         *name = n;
203                         return handler;
204                 }
205         }
206         return ERR_PTR(-EOPNOTSUPP);
207 }
208
209 static void copy_times(struct bch_fs *c, struct bch_inode_unpacked *dst,
210                        struct stat *src)
211 {
212         dst->i_atime = timespec_to_bch2_time(c, src->st_atim);
213         dst->i_mtime = timespec_to_bch2_time(c, src->st_mtim);
214         dst->i_ctime = timespec_to_bch2_time(c, src->st_ctim);
215 }
216
217 static void copy_xattrs(struct bch_fs *c, struct bch_inode_unpacked *dst,
218                         char *src)
219 {
220         struct bch_hash_info hash_info = bch2_hash_info_init(c, dst);
221
222         char attrs[XATTR_LIST_MAX];
223         ssize_t attrs_size = llistxattr(src, attrs, sizeof(attrs));
224         if (attrs_size < 0)
225                 die("listxattr error: %m");
226
227         for (const char *next, *attr = attrs;
228              attr < attrs + attrs_size;
229              attr = next) {
230                 next = attr + strlen(attr) + 1;
231
232                 char val[XATTR_SIZE_MAX];
233                 ssize_t val_size = lgetxattr(src, attr, val, sizeof(val));
234
235                 if (val_size < 0)
236                         die("error getting xattr val: %m");
237
238                 const struct xattr_handler *h = xattr_resolve_name(&attr);
239
240                 int ret = __bch2_xattr_set(c, dst->inum, &hash_info, attr,
241                                            val, val_size, 0, h->flags, NULL);
242                 if (ret < 0)
243                         die("error creating xattr: %s", strerror(-ret));
244         }
245 }
246
247 static void write_data(struct bch_fs *c,
248                        struct bch_inode_unpacked *dst_inode,
249                        u64 dst_offset, void *buf, size_t len)
250 {
251         struct disk_reservation res;
252         struct bch_write_op op;
253         struct bch_write_bio bio;
254         struct bio_vec bv;
255         struct closure cl;
256
257         BUG_ON(dst_offset       & (block_bytes(c) - 1));
258         BUG_ON(len              & (block_bytes(c) - 1));
259
260         closure_init_stack(&cl);
261
262         bio_init(&bio.bio, &bv, 1);
263         bio.bio.bi_iter.bi_size = len;
264         bch2_bio_map(&bio.bio, buf);
265
266         int ret = bch2_disk_reservation_get(c, &res, len >> 9, 0);
267         if (ret)
268                 die("error reserving space in new filesystem: %s", strerror(-ret));
269
270         bch2_write_op_init(&op, c, &bio, res, c->write_points,
271                            POS(dst_inode->inum, dst_offset >> 9), NULL, 0);
272         closure_call(&op.cl, bch2_write, NULL, &cl);
273         closure_sync(&cl);
274
275         dst_inode->i_sectors += len >> 9;
276 }
277
278 static char buf[1 << 20] __aligned(PAGE_SIZE);
279
280 static void copy_data(struct bch_fs *c,
281                       struct bch_inode_unpacked *dst_inode,
282                       int src_fd, u64 start, u64 end)
283 {
284         while (start < end) {
285                 unsigned len = min_t(u64, end - start, sizeof(buf));
286
287                 xpread(src_fd, buf, len, start);
288                 write_data(c, dst_inode, start, buf, len);
289                 start += len;
290         }
291 }
292
293 static void link_data(struct bch_fs *c, struct bch_inode_unpacked *dst,
294                       u64 logical, u64 physical, u64 length)
295 {
296         struct bch_dev *ca = c->devs[0];
297
298         BUG_ON(logical  & (block_bytes(c) - 1));
299         BUG_ON(physical & (block_bytes(c) - 1));
300         BUG_ON(length   & (block_bytes(c) - 1));
301
302         logical         >>= 9;
303         physical        >>= 9;
304         length          >>= 9;
305
306         BUG_ON(physical + length > bucket_to_sector(ca, ca->mi.nbuckets));
307
308         while (length) {
309                 struct bkey_i_extent *e;
310                 BKEY_PADDED(k) k;
311                 u64 b = sector_to_bucket(ca, physical >> 9);
312                 struct disk_reservation res;
313                 unsigned sectors;
314                 int ret;
315
316                 sectors = min(ca->mi.bucket_size -
317                               (physical & (ca->mi.bucket_size - 1)),
318                               length);
319
320                 e = bkey_extent_init(&k.k);
321                 e->k.p.inode    = dst->inum;
322                 e->k.p.offset   = logical + sectors;
323                 e->k.size       = sectors;
324                 extent_ptr_append(e, (struct bch_extent_ptr) {
325                                         .offset = physical,
326                                         .dev = 0,
327                                         .gen = ca->buckets[b].mark.gen,
328                                   });
329
330                 ret = bch2_disk_reservation_get(c, &res, sectors,
331                                                 BCH_DISK_RESERVATION_NOFAIL);
332                 if (ret)
333                         die("error reserving space in new filesystem: %s",
334                             strerror(-ret));
335
336                 bch2_check_mark_super(c, &e->k_i, false);
337
338                 ret = bch2_btree_insert(c, BTREE_ID_EXTENTS, &e->k_i,
339                                         &res, NULL, NULL, 0);
340                 if (ret)
341                         die("btree insert error %s", strerror(-ret));
342
343                 bch2_disk_reservation_put(c, &res);
344
345                 dst->i_sectors  += sectors;
346                 logical         += sectors;
347                 physical        += sectors;
348                 length          -= sectors;
349         }
350 }
351
352 static void copy_link(struct bch_fs *c, struct bch_inode_unpacked *dst,
353                       char *src)
354 {
355         ssize_t ret = readlink(src, buf, sizeof(buf));
356         if (ret < 0)
357                 die("readlink error: %m");
358
359         write_data(c, dst, 0, buf, round_up(ret, block_bytes(c)));
360 }
361
362 static void copy_file(struct bch_fs *c, struct bch_inode_unpacked *dst,
363                       int src, char *src_path, ranges *extents)
364 {
365         struct fiemap_iter iter;
366         struct fiemap_extent e;
367
368         fiemap_for_each(src, iter, e)
369                 if (e.fe_flags & FIEMAP_EXTENT_UNKNOWN) {
370                         fsync(src);
371                         break;
372                 }
373
374         fiemap_for_each(src, iter, e) {
375                 if ((e.fe_logical       & (block_bytes(c) - 1)) ||
376                     (e.fe_length        & (block_bytes(c) - 1)))
377                         die("Unaligned extent in %s - can't handle", src_path);
378
379                 if (e.fe_flags & (FIEMAP_EXTENT_UNKNOWN|
380                                   FIEMAP_EXTENT_ENCODED|
381                                   FIEMAP_EXTENT_NOT_ALIGNED|
382                                   FIEMAP_EXTENT_DATA_INLINE)) {
383                         copy_data(c, dst,
384                                   src,
385                                   round_down(e.fe_logical, block_bytes(c)),
386                                   round_up(e.fe_logical + e.fe_length,
387                                            block_bytes(c)));
388                         continue;
389                 }
390
391                 if (e.fe_physical < 1 << 20) {
392                         copy_data(c, dst,
393                                   src,
394                                   round_down(e.fe_logical, block_bytes(c)),
395                                   round_up(e.fe_logical + e.fe_length,
396                                            block_bytes(c)));
397                         continue;
398                 }
399
400                 if ((e.fe_physical      & (block_bytes(c) - 1)))
401                         die("Unaligned extent in %s - can't handle", src_path);
402
403                 range_add(extents, e.fe_physical, e.fe_length);
404                 link_data(c, dst, e.fe_logical, e.fe_physical, e.fe_length);
405         }
406 }
407
408 struct copy_fs_state {
409         u64                     bcachefs_inum;
410         dev_t                   dev;
411
412         GENRADIX(u64)           hardlinks;
413         ranges                  extents;
414 };
415
416 static void copy_dir(struct copy_fs_state *s,
417                      struct bch_fs *c,
418                      struct bch_inode_unpacked *dst,
419                      int src_fd, const char *src_path)
420 {
421         DIR *dir = fdopendir(src_fd);
422         struct dirent *d;
423
424         while ((errno = 0), (d = readdir(dir))) {
425                 struct bch_inode_unpacked inode;
426                 int fd;
427
428                 if (fchdir(src_fd))
429                         die("chdir error: %m");
430
431                 struct stat stat =
432                         xfstatat(src_fd, d->d_name, AT_SYMLINK_NOFOLLOW);
433
434                 if (!strcmp(d->d_name, ".") ||
435                     !strcmp(d->d_name, "..") ||
436                     stat.st_ino == s->bcachefs_inum)
437                         continue;
438
439                 char *child_path = mprintf("%s/%s", src_path, d->d_name);
440
441                 if (stat.st_dev != s->dev)
442                         die("%s does not have correct st_dev!", child_path);
443
444                 u64 *dst_inum = S_ISREG(stat.st_mode)
445                         ? genradix_ptr_alloc(&s->hardlinks, stat.st_ino, GFP_KERNEL)
446                         : NULL;
447
448                 if (dst_inum && *dst_inum) {
449                         create_link(c, dst, d->d_name, *dst_inum, S_IFREG);
450                         goto next;
451                 }
452
453                 inode = create_file(c, dst, d->d_name,
454                                     stat.st_uid, stat.st_gid,
455                                     stat.st_mode, stat.st_rdev);
456
457                 if (dst_inum)
458                         *dst_inum = inode.inum;
459
460                 copy_times(c, &inode, &stat);
461                 copy_xattrs(c, &inode, d->d_name);
462
463                 /* copy xattrs */
464
465                 switch (mode_to_type(stat.st_mode)) {
466                 case DT_DIR:
467                         fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
468                         copy_dir(s, c, &inode, fd, child_path);
469                         close(fd);
470                         break;
471                 case DT_REG:
472                         inode.i_size = stat.st_size;
473
474                         fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
475                         copy_file(c, &inode, fd, child_path, &s->extents);
476                         close(fd);
477                         break;
478                 case DT_LNK:
479                         inode.i_size = stat.st_size;
480
481                         copy_link(c, &inode, d->d_name);
482                         break;
483                 case DT_FIFO:
484                 case DT_CHR:
485                 case DT_BLK:
486                 case DT_SOCK:
487                 case DT_WHT:
488                         /* nothing else to copy for these: */
489                         break;
490                 default:
491                         BUG();
492                 }
493
494                 update_inode(c, &inode);
495 next:
496                 free(child_path);
497         }
498
499         if (errno)
500                 die("readdir error: %m");
501 }
502
503 static ranges reserve_new_fs_space(const char *file_path, unsigned block_size,
504                                    u64 size, u64 *bcachefs_inum, dev_t dev,
505                                    bool force)
506 {
507         int fd = force
508                 ? open(file_path, O_RDWR|O_CREAT, 0600)
509                 : open(file_path, O_RDWR|O_CREAT|O_EXCL, 0600);
510         if (fd < 0)
511                 die("Error creating %s for bcachefs metadata: %m",
512                     file_path);
513
514         struct stat statbuf = xfstat(fd);
515
516         if (statbuf.st_dev != dev)
517                 die("bcachefs file has incorrect device");
518
519         *bcachefs_inum = statbuf.st_ino;
520
521         if (fallocate(fd, 0, 0, size))
522                 die("Error reserving space for bcachefs metadata: %m");
523
524         fsync(fd);
525
526         struct fiemap_iter iter;
527         struct fiemap_extent e;
528         ranges extents = { NULL };
529
530         fiemap_for_each(fd, iter, e) {
531                 if (e.fe_flags & (FIEMAP_EXTENT_UNKNOWN|
532                                   FIEMAP_EXTENT_ENCODED|
533                                   FIEMAP_EXTENT_NOT_ALIGNED|
534                                   FIEMAP_EXTENT_DATA_INLINE))
535                         die("Unable to continue: metadata file not fully mapped");
536
537                 if ((e.fe_physical      & (block_size - 1)) ||
538                     (e.fe_length        & (block_size - 1)))
539                         die("Unable to continue: unaligned extents in metadata file");
540
541                 range_add(&extents, e.fe_physical, e.fe_length);
542         }
543         close(fd);
544
545         ranges_sort_merge(&extents);
546         return extents;
547 }
548
549 static void reserve_old_fs_space(struct bch_fs *c,
550                                  struct bch_inode_unpacked *root_inode,
551                                  ranges *extents)
552 {
553         struct bch_dev *ca = c->devs[0];
554         struct bch_inode_unpacked dst;
555         struct hole_iter iter;
556         struct range i;
557
558         dst = create_file(c, root_inode, "old_migrated_filesystem",
559                           0, 0, S_IFREG|0400, 0);
560         dst.i_size = bucket_to_sector(ca, ca->mi.nbuckets) << 9;
561
562         ranges_sort_merge(extents);
563
564         for_each_hole(iter, *extents, bucket_to_sector(ca, ca->mi.nbuckets) << 9, i)
565                 link_data(c, &dst, i.start, i.start, i.end - i.start);
566
567         update_inode(c, &dst);
568 }
569
570 static void copy_fs(struct bch_fs *c, int src_fd, const char *src_path,
571                     u64 bcachefs_inum, ranges *extents)
572 {
573         syncfs(src_fd);
574
575         struct bch_inode_unpacked root_inode;
576         int ret = bch2_inode_find_by_inum(c, BCACHE_ROOT_INO, &root_inode);
577         if (ret)
578                 die("error looking up root directory: %s", strerror(-ret));
579
580         if (fchdir(src_fd))
581                 die("chdir error: %m");
582
583         struct stat stat = xfstat(src_fd);
584         copy_times(c, &root_inode, &stat);
585         copy_xattrs(c, &root_inode, ".");
586
587         struct copy_fs_state s = {
588                 .bcachefs_inum  = bcachefs_inum,
589                 .dev            = stat.st_dev,
590                 .extents        = *extents,
591         };
592
593         /* now, copy: */
594         copy_dir(&s, c, &root_inode, src_fd, src_path);
595
596         reserve_old_fs_space(c, &root_inode, &s.extents);
597
598         update_inode(c, &root_inode);
599
600         darray_free(s.extents);
601         genradix_free(&s.hardlinks);
602 }
603
604 static void find_superblock_space(ranges extents, struct dev_opts *dev)
605 {
606         struct range *i;
607
608         darray_foreach(i, extents) {
609                 u64 start = round_up(max(256ULL << 10, i->start),
610                                      dev->bucket_size << 9);
611                 u64 end = round_down(i->end,
612                                      dev->bucket_size << 9);
613
614                 if (start + (128 << 10) <= end) {
615                         dev->sb_offset  = start >> 9;
616                         dev->sb_end     = dev->sb_offset + 256;
617                         return;
618                 }
619         }
620
621         die("Couldn't find a valid location for superblock");
622 }
623
624 static void migrate_usage(void)
625 {
626         puts("bcachefs migrate - migrate an existing filesystem to bcachefs\n"
627              "Usage: bcachefs migrate [OPTION]...\n"
628              "\n"
629              "Options:\n"
630              "  -f fs                  Root of filesystem to migrate(s)\n"
631              "      --encrypted        Enable whole filesystem encryption (chacha20/poly1305)\n"
632              "      --no_passphrase    Don't encrypt master encryption key\n"
633              "  -F                     Force, even if metadata file already exists\n"
634              "  -h                     Display this help and exit\n"
635              "Report bugs to <linux-bcache@vger.kernel.org>");
636 }
637
638 static const struct option migrate_opts[] = {
639         { "encrypted",          no_argument, NULL, 'e' },
640         { "no_passphrase",      no_argument, NULL, 'p' },
641         { NULL }
642 };
643
644 int cmd_migrate(int argc, char *argv[])
645 {
646         struct format_opts format_opts = format_opts_default();
647         char *fs_path = NULL;
648         unsigned block_size;
649         bool no_passphrase = false, force = false;
650         int opt;
651
652         while ((opt = getopt_long(argc, argv, "f:Fh",
653                                   migrate_opts, NULL)) != -1)
654                 switch (opt) {
655                 case 'f':
656                         fs_path = optarg;
657                         break;
658                 case 'e':
659                         format_opts.encrypted = true;
660                         break;
661                 case 'p':
662                         no_passphrase = true;
663                         break;
664                 case 'F':
665                         force = true;
666                         break;
667                 case 'h':
668                         migrate_usage();
669                         exit(EXIT_SUCCESS);
670                 }
671
672         if (!fs_path)
673                 die("Please specify a filesytem to migrate");
674
675         if (!path_is_fs_root(fs_path))
676                 die("%s is not a filysestem root", fs_path);
677
678         int fs_fd = xopen(fs_path, O_RDONLY|O_NOATIME);
679         struct stat stat = xfstat(fs_fd);
680
681         if (!S_ISDIR(stat.st_mode))
682                 die("%s is not a directory", fs_path);
683
684         struct dev_opts dev = { 0 };
685
686         dev.path = dev_t_to_path(stat.st_dev);
687         dev.fd = xopen(dev.path, O_RDWR);
688
689         block_size = min_t(unsigned, stat.st_blksize,
690                            get_blocksize(dev.path, dev.fd) << 9);
691
692         BUG_ON(!is_power_of_2(block_size) || block_size < 512);
693         format_opts.block_size = block_size >> 9;
694
695         u64 bcachefs_inum;
696         char *file_path = mprintf("%s/bcachefs", fs_path);
697
698         bch2_pick_bucket_size(format_opts, &dev);
699
700         ranges extents = reserve_new_fs_space(file_path,
701                                 block_size, get_size(dev.path, dev.fd) / 5,
702                                 &bcachefs_inum, stat.st_dev, force);
703
704         find_superblock_space(extents, &dev);
705
706         if (format_opts.encrypted && !no_passphrase) {
707                 format_opts.passphrase = read_passphrase("Enter passphrase: ");
708
709                 if (isatty(STDIN_FILENO)) {
710                         char *pass2 =
711                                 read_passphrase("Enter same passphrase again: ");
712
713                         if (strcmp(format_opts.passphrase, pass2)) {
714                                 memzero_explicit(format_opts.passphrase,
715                                                  strlen(format_opts.passphrase));
716                                 memzero_explicit(pass2, strlen(pass2));
717                                 die("Passphrases do not match");
718                         }
719
720                         memzero_explicit(pass2, strlen(pass2));
721                         free(pass2);
722                 }
723         }
724
725         struct bch_sb *sb = bch2_format(format_opts, &dev, 1);
726         u64 sb_offset = le64_to_cpu(sb->layout.sb_offset[0]);
727
728         if (format_opts.passphrase)
729                 bch2_add_key(sb, format_opts.passphrase);
730
731         free(sb);
732
733         printf("Creating new filesystem on %s in space reserved at %s\n"
734                "To mount, run\n"
735                "  mount -t bcachefs -o sb=%llu %s dir\n"
736                "\n"
737                "After verifying that the new filesystem is correct, to create a\n"
738                "superblock at the default offset and finish the migration run\n"
739                "  bcachefs migrate_superblock -d %s -o %llu\n"
740                "\n"
741                "The new filesystem will have a file at /old_migrated_filestem\n"
742                "referencing all disk space that might be used by the existing\n"
743                "filesystem. That file can be deleted once the old filesystem is\n"
744                "no longer needed (and should be deleted prior to running\n"
745                "bcachefs migrate_superblock)\n",
746                dev.path, file_path, sb_offset, dev.path,
747                dev.path, sb_offset);
748
749         struct bch_opts opts = bch2_opts_empty();
750         struct bch_fs *c = NULL;
751         char *path[1] = { dev.path };
752         const char *err;
753
754         opts.sb         = sb_offset;
755         opts.nostart    = true;
756         opts.noexcl     = true;
757
758         err = bch2_fs_open(path, 1, opts, &c);
759         if (err)
760                 die("Error opening new filesystem: %s", err);
761
762         mark_unreserved_space(c, extents);
763
764         err = bch2_fs_start(c);
765         if (err)
766                 die("Error starting new filesystem: %s", err);
767
768         copy_fs(c, fs_fd, fs_path, bcachefs_inum, &extents);
769
770         bch2_fs_stop(c);
771
772         printf("Migrate complete, running fsck:\n");
773         opts.nostart    = false;
774         opts.nochanges  = true;
775
776         err = bch2_fs_open(path, 1, opts, &c);
777         if (err)
778                 die("Error opening new filesystem: %s", err);
779
780         bch2_fs_stop(c);
781         printf("fsck complete\n");
782         return 0;
783 }
784
785 static void migrate_superblock_usage(void)
786 {
787         puts("bcachefs migrate_superblock - create default superblock after migrating\n"
788              "Usage: bcachefs migrate_superblock [OPTION]...\n"
789              "\n"
790              "Options:\n"
791              "  -d device     Device to create superblock for\n"
792              "  -o offset     Offset of existing superblock\n"
793              "  -h            Display this help and exit\n"
794              "Report bugs to <linux-bcache@vger.kernel.org>");
795 }
796
797 int cmd_migrate_superblock(int argc, char *argv[])
798 {
799         char *dev = NULL;
800         u64 offset = 0;
801         int opt, ret;
802
803         while ((opt = getopt(argc, argv, "d:o:h")) != -1)
804                 switch (opt) {
805                         case 'd':
806                                 dev = optarg;
807                                 break;
808                         case 'o':
809                                 ret = kstrtou64(optarg, 10, &offset);
810                                 if (ret)
811                                         die("Invalid offset");
812                                 break;
813                         case 'h':
814                                 migrate_superblock_usage();
815                                 exit(EXIT_SUCCESS);
816                 }
817
818         if (!dev)
819                 die("Please specify a device");
820
821         if (!offset)
822                 die("Please specify offset of existing superblock");
823
824         int fd = xopen(dev, O_RDWR);
825         struct bch_sb *sb = __bch2_super_read(fd, offset);
826
827         if (sb->layout.nr_superblocks >= ARRAY_SIZE(sb->layout.sb_offset))
828                 die("Can't add superblock: no space left in superblock layout");
829
830         for (unsigned i = 0; i < sb->layout.nr_superblocks; i++)
831                 if (le64_to_cpu(sb->layout.sb_offset[i]) == BCH_SB_SECTOR)
832                         die("Superblock layout already has default superblock");
833
834         memmove(&sb->layout.sb_offset[1],
835                 &sb->layout.sb_offset[0],
836                 sb->layout.nr_superblocks * sizeof(u64));
837         sb->layout.nr_superblocks++;
838
839         sb->layout.sb_offset[0] = cpu_to_le64(BCH_SB_SECTOR);
840
841         bch2_super_write(fd, sb);
842         close(fd);
843
844         return 0;
845 }