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