]> git.sesse.net Git - bcachefs-tools-debian/blob - cmd_migrate.c
cmd_migrate: fix xattrs
[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 "libbcache.h"
23 #include "linux/bcache.h"
24
25 #include <linux/dcache.h>
26 #include <linux/generic-radix-tree.h>
27 #include <linux/xattr.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: %s", strerror(errno));
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 cache_set *c, ranges extents)
94 {
95         struct cache *ca = c->cache[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 cache_set *c,
115                          struct bch_inode_unpacked *inode)
116 {
117         struct bkey_inode_buf packed;
118         int ret;
119
120         bch_inode_pack(&packed, inode);
121         ret = bch_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 cache_set *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 = bch_hash_info_init(parent);
131         struct qstr qname = { { { .len = strlen(name), } }, .name = name };
132
133         int ret = bch_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 cache_set *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 = bch_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 cache_set *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         bch_inode_init(c, &new_inode, uid, gid, mode, rdev);
169         bch_inode_pack(&packed, &new_inode);
170
171         ret = bch_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 = bch_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 cache_set *c, struct bch_inode_unpacked *dst,
211                        struct stat *src)
212 {
213         dst->i_atime = timespec_to_bch_time(c, src->st_atim);
214         dst->i_mtime = timespec_to_bch_time(c, src->st_mtim);
215         dst->i_ctime = timespec_to_bch_time(c, src->st_ctim);
216 }
217
218 static void copy_xattrs(struct cache_set *c, struct bch_inode_unpacked *dst,
219                         char *src)
220 {
221         struct bch_hash_info hash_info = bch_hash_info_init(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: %s", strerror(errno));
227
228         for (const char *next, *attr = attrs;
229              attr < attrs + attrs_size;
230              attr = next) {
231                 next = attr + strlen(attr) + 1;
232
233                 char val[XATTR_SIZE_MAX];
234                 ssize_t val_size = lgetxattr(src, attr, val, sizeof(val));
235
236                 if (val_size < 0)
237                         die("error getting xattr val: %s", strerror(errno));
238
239                 const struct xattr_handler *h = xattr_resolve_name(&attr);
240
241                 int ret = __bch_xattr_set(c, dst->inum, &hash_info, attr,
242                                           val, val_size, 0, h->flags, NULL);
243                 if (ret < 0)
244                         die("error creating xattr: %s", strerror(-ret));
245         }
246 }
247
248 static void write_data(struct cache_set *c,
249                        struct bch_inode_unpacked *dst_inode,
250                        u64 dst_offset, void *buf, size_t len)
251 {
252         struct disk_reservation res;
253         struct bch_write_op op;
254         struct bch_write_bio bio;
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(&bio.bio);
264         bio.bio.bi_max_vecs     = 1;
265         bio.bio.bi_io_vec       = &bv;
266         bio.bio.bi_iter.bi_size = len;
267         bch_bio_map(&bio.bio, buf);
268
269         int ret = bch_disk_reservation_get(c, &res, len >> 9, 0);
270         if (ret)
271                 die("error reserving space in new filesystem: %s", strerror(-ret));
272
273         bch_write_op_init(&op, c, &bio, res, c->write_points,
274                           POS(dst_inode->inum, dst_offset >> 9), NULL, 0);
275         closure_call(&op.cl, bch_write, NULL, &cl);
276         closure_sync(&cl);
277
278         dst_inode->i_sectors += len >> 9;
279 }
280
281 static char buf[1 << 20] __aligned(PAGE_SIZE);
282
283 static void copy_data(struct cache_set *c,
284                       struct bch_inode_unpacked *dst_inode,
285                       int src_fd, u64 start, u64 end)
286 {
287         while (start < end) {
288                 unsigned len = min_t(u64, end - start, sizeof(buf));
289
290                 xpread(src_fd, buf, len, start);
291                 write_data(c, dst_inode, start, buf, len);
292                 start += len;
293         }
294 }
295
296 static void link_data(struct cache_set *c, struct bch_inode_unpacked *dst,
297                       u64 logical, u64 physical, u64 length)
298 {
299         struct cache *ca = c->cache[0];
300
301         BUG_ON(logical  & (block_bytes(c) - 1));
302         BUG_ON(physical & (block_bytes(c) - 1));
303         BUG_ON(length   & (block_bytes(c) - 1));
304
305         logical         >>= 9;
306         physical        >>= 9;
307         length          >>= 9;
308
309         BUG_ON(physical + length > bucket_to_sector(ca, ca->mi.nbuckets));
310
311         while (length) {
312                 struct bkey_i_extent *e;
313                 BKEY_PADDED(k) k;
314                 u64 b = sector_to_bucket(ca, physical >> 9);
315                 struct disk_reservation res;
316                 unsigned sectors;
317                 int ret;
318
319                 sectors = min(ca->mi.bucket_size -
320                               (physical & (ca->mi.bucket_size - 1)),
321                               length);
322
323                 e = bkey_extent_init(&k.k);
324                 e->k.p.inode    = dst->inum;
325                 e->k.p.offset   = logical + sectors;
326                 e->k.size       = sectors;
327                 extent_ptr_append(e, (struct bch_extent_ptr) {
328                                         .offset = physical,
329                                         .dev = 0,
330                                         .gen = ca->buckets[b].mark.gen,
331                                   });
332
333                 ret = bch_disk_reservation_get(c, &res, sectors,
334                                                BCH_DISK_RESERVATION_NOFAIL);
335                 if (ret)
336                         die("error reserving space in new filesystem: %s",
337                             strerror(-ret));
338
339                 ret = bch_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                 bch_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 cache_set *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: %s", strerror(errno));
359
360         write_data(c, dst, 0, buf, round_up(ret, block_bytes(c)));
361 }
362
363 static void copy_file(struct cache_set *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      & (block_bytes(c) - 1)))
393                         die("Unaligned extent in %s - can't handle", src_path);
394
395                 range_add(extents, e.fe_physical, e.fe_length);
396                 link_data(c, dst, e.fe_logical, e.fe_physical, e.fe_length);
397         }
398 }
399
400 struct copy_fs_state {
401         u64                     bcachefs_inum;
402         dev_t                   dev;
403
404         GENRADIX(u64)           hardlinks;
405         ranges                  extents;
406 };
407
408 static void copy_dir(struct copy_fs_state *s,
409                      struct cache_set *c,
410                      struct bch_inode_unpacked *dst,
411                      int src_fd, const char *src_path)
412 {
413         DIR *dir = fdopendir(src_fd);
414         struct dirent *d;
415
416         while ((errno = 0), (d = readdir(dir))) {
417                 struct bch_inode_unpacked inode;
418                 int fd;
419
420                 if (fchdir(src_fd))
421                         die("chdir error: %s", strerror(errno));
422
423                 struct stat stat =
424                         xfstatat(src_fd, d->d_name, AT_SYMLINK_NOFOLLOW);
425
426                 if (!strcmp(d->d_name, ".") ||
427                     !strcmp(d->d_name, "..") ||
428                     stat.st_ino == s->bcachefs_inum)
429                         continue;
430
431                 char *child_path = mprintf("%s/%s", src_path, d->d_name);
432
433                 if (stat.st_dev != s->dev)
434                         die("%s does not have correct st_dev!", child_path);
435
436                 u64 *dst_inum = S_ISREG(stat.st_mode)
437                         ? genradix_ptr_alloc(&s->hardlinks, stat.st_ino, GFP_KERNEL)
438                         : NULL;
439
440                 if (dst_inum && *dst_inum) {
441                         create_link(c, dst, d->d_name, *dst_inum, S_IFREG);
442                         goto next;
443                 }
444
445                 inode = create_file(c, dst, d->d_name,
446                                     stat.st_uid, stat.st_gid,
447                                     stat.st_mode, stat.st_rdev);
448
449                 if (dst_inum)
450                         *dst_inum = inode.inum;
451
452                 copy_times(c, &inode, &stat);
453                 copy_xattrs(c, &inode, d->d_name);
454
455                 /* copy xattrs */
456
457                 switch (mode_to_type(stat.st_mode)) {
458                 case DT_DIR:
459                         fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
460                         copy_dir(s, c, &inode, fd, child_path);
461                         close(fd);
462                         break;
463                 case DT_REG:
464                         inode.i_size = stat.st_size;
465
466                         fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
467                         copy_file(c, &inode, fd, child_path, &s->extents);
468                         close(fd);
469                         break;
470                 case DT_LNK:
471                         inode.i_size = stat.st_size;
472
473                         copy_link(c, &inode, d->d_name);
474                         break;
475                 case DT_FIFO:
476                 case DT_CHR:
477                 case DT_BLK:
478                 case DT_SOCK:
479                 case DT_WHT:
480                         /* nothing else to copy for these: */
481                         break;
482                 default:
483                         BUG();
484                 }
485
486                 update_inode(c, &inode);
487 next:
488                 free(child_path);
489         }
490
491         if (errno)
492                 die("readdir error: %s", strerror(errno));
493 }
494
495 static ranges reserve_new_fs_space(const char *file_path, unsigned block_size,
496                                    u64 size, u64 *bcachefs_inum, dev_t dev,
497                                    bool force)
498 {
499         int fd = force
500                 ? open(file_path, O_RDWR|O_CREAT, 0600)
501                 : open(file_path, O_RDWR|O_CREAT|O_EXCL, 0600);
502         if (fd < 0)
503                 die("Error creating %s for bcachefs metadata: %s",
504                     file_path, strerror(errno));
505
506         struct stat statbuf = xfstat(fd);
507
508         if (statbuf.st_dev != dev)
509                 die("bcachefs file has incorrect device");
510
511         *bcachefs_inum = statbuf.st_ino;
512
513         if (fallocate(fd, 0, 0, size))
514                 die("Error reserving space for bcachefs metadata: %s",
515                     strerror(errno));
516
517         fsync(fd);
518
519         struct fiemap_iter iter;
520         struct fiemap_extent e;
521         ranges extents = { NULL };
522
523         fiemap_for_each(fd, iter, e) {
524                 if (e.fe_flags & (FIEMAP_EXTENT_UNKNOWN|
525                                   FIEMAP_EXTENT_ENCODED|
526                                   FIEMAP_EXTENT_NOT_ALIGNED|
527                                   FIEMAP_EXTENT_DATA_INLINE))
528                         die("Unable to continue: metadata file not fully mapped");
529
530                 if ((e.fe_physical      & (block_size - 1)) ||
531                     (e.fe_length        & (block_size - 1)))
532                         die("Unable to continue: unaligned extents in metadata file");
533
534                 range_add(&extents, e.fe_physical, e.fe_length);
535         }
536         close(fd);
537
538         ranges_sort_merge(&extents);
539         return extents;
540 }
541
542 static void reserve_old_fs_space(struct cache_set *c,
543                                  struct bch_inode_unpacked *root_inode,
544                                  ranges *extents)
545 {
546         struct cache *ca = c->cache[0];
547         struct bch_inode_unpacked dst;
548         struct hole_iter iter;
549         struct range i;
550
551         dst = create_file(c, root_inode, "old_migrated_filesystem",
552                           0, 0, S_IFREG|0400, 0);
553         dst.i_size = bucket_to_sector(ca, ca->mi.nbuckets) << 9;
554
555         ranges_sort_merge(extents);
556
557         for_each_hole(iter, *extents, bucket_to_sector(ca, ca->mi.nbuckets) << 9, i)
558                 link_data(c, &dst, i.start, i.start, i.end - i.start);
559
560         update_inode(c, &dst);
561 }
562
563 static void copy_fs(struct cache_set *c, int src_fd, const char *src_path,
564                     u64 bcachefs_inum, ranges *extents)
565 {
566         syncfs(src_fd);
567
568         struct bch_inode_unpacked root_inode;
569         int ret = bch_inode_find_by_inum(c, BCACHE_ROOT_INO, &root_inode);
570         if (ret)
571                 die("error looking up root directory: %s", strerror(-ret));
572
573         if (fchdir(src_fd))
574                 die("chdir error: %s", strerror(errno));
575
576         struct stat stat = xfstat(src_fd);
577         copy_times(c, &root_inode, &stat);
578         copy_xattrs(c, &root_inode, ".");
579
580         struct copy_fs_state s = {
581                 .bcachefs_inum  = bcachefs_inum,
582                 .dev            = stat.st_dev,
583                 .extents        = *extents,
584         };
585
586         /* now, copy: */
587         copy_dir(&s, c, &root_inode, src_fd, src_path);
588
589         reserve_old_fs_space(c, &root_inode, &s.extents);
590
591         update_inode(c, &root_inode);
592
593         darray_free(s.extents);
594         genradix_free(&s.hardlinks);
595 }
596
597 static void find_superblock_space(ranges extents, struct dev_opts *dev)
598 {
599         struct range *i;
600         darray_foreach(i, extents) {
601                 u64 offset = max(256ULL << 10, i->start);
602
603                 if (offset + (128 << 10) <= i->end) {
604                         dev->sb_offset  = offset >> 9;
605                         dev->sb_end     = dev->sb_offset + 256;
606                         return;
607                 }
608         }
609
610         die("Couldn't find a valid location for superblock");
611 }
612
613 static void migrate_usage(void)
614 {
615         puts("bcache migrate - migrate an existing filesystem to bcachefs\n"
616              "Usage: bcache migrate [OPTION]...\n"
617              "\n"
618              "Options:\n"
619              "  -f fs                  Root of filesystem to migrate(s)\n"
620              "      --encrypted        Enable whole filesystem encryption (chacha20/poly1305)\n"
621              "      --no_passphrase    Don't encrypt master encryption key\n"
622              "  -F                     Force, even if metadata file already exists\n"
623              "  -h                     Display this help and exit\n"
624              "Report bugs to <linux-bcache@vger.kernel.org>");
625 }
626
627 static const struct option migrate_opts[] = {
628         { "encrypted",          no_argument, NULL, 'e' },
629         { "no_passphrase",      no_argument, NULL, 'p' },
630         { NULL }
631 };
632
633 int cmd_migrate(int argc, char *argv[])
634 {
635         struct format_opts format_opts = format_opts_default();
636         char *fs_path = NULL;
637         unsigned block_size;
638         bool no_passphrase = false, force = false;
639         int opt;
640
641         while ((opt = getopt_long(argc, argv, "f:Fh",
642                                   migrate_opts, NULL)) != -1)
643                 switch (opt) {
644                 case 'f':
645                         fs_path = optarg;
646                         break;
647                 case 'e':
648                         format_opts.encrypted = true;
649                         break;
650                 case 'p':
651                         no_passphrase = true;
652                         break;
653                 case 'F':
654                         force = true;
655                         break;
656                 case 'h':
657                         migrate_usage();
658                         exit(EXIT_SUCCESS);
659                 }
660
661         if (!fs_path)
662                 die("Please specify a filesytem to migrate");
663
664         if (!path_is_fs_root(fs_path))
665                 die("%s is not a filysestem root", fs_path);
666
667         int fs_fd = xopen(fs_path, O_RDONLY|O_NOATIME);
668         struct stat stat = xfstat(fs_fd);
669
670         if (!S_ISDIR(stat.st_mode))
671                 die("%s is not a directory", fs_path);
672
673         struct dev_opts dev = { 0 };
674
675         dev.path = dev_t_to_path(stat.st_dev);
676         dev.fd = xopen(dev.path, O_RDWR);
677
678         block_size = min_t(unsigned, stat.st_blksize,
679                            get_blocksize(dev.path, dev.fd) << 9);
680
681         BUG_ON(!is_power_of_2(block_size) || block_size < 512);
682         format_opts.block_size = block_size >> 9;
683
684         u64 bcachefs_inum;
685         char *file_path = mprintf("%s/bcachefs", fs_path);
686
687         ranges extents = reserve_new_fs_space(file_path,
688                                 block_size, get_size(dev.path, dev.fd) / 5,
689                                 &bcachefs_inum, stat.st_dev, force);
690
691         find_superblock_space(extents, &dev);
692
693         if (format_opts.encrypted && !no_passphrase) {
694                 format_opts.passphrase = read_passphrase("Enter passphrase: ");
695
696                 if (isatty(STDIN_FILENO)) {
697                         char *pass2 =
698                                 read_passphrase("Enter same passphrase again: ");
699
700                         if (strcmp(format_opts.passphrase, pass2)) {
701                                 memzero_explicit(format_opts.passphrase,
702                                                  strlen(format_opts.passphrase));
703                                 memzero_explicit(pass2, strlen(pass2));
704                                 die("Passphrases do not match");
705                         }
706
707                         memzero_explicit(pass2, strlen(pass2));
708                         free(pass2);
709                 }
710         }
711
712         struct bch_sb *sb = bcache_format(format_opts, &dev, 1);
713         u64 sb_offset = le64_to_cpu(sb->layout.sb_offset[0]);
714
715         if (format_opts.passphrase)
716                 add_bcache_key(sb, format_opts.passphrase);
717
718         free(sb);
719
720         printf("Creating new filesystem on %s in space reserved at %s\n"
721                "To mount, run\n"
722                "  mount -t bcache -o sb=%llu %s dir\n"
723                "\n"
724                "After verifying that the new filesystem is correct, to create a\n"
725                "superblock at the default offset and finish the migration run\n"
726                "  bcache migrate_superblock -d %s -o %llu\n"
727                "\n"
728                "The new filesystem will have a file at /old_migrated_filestem\n"
729                "referencing all disk space that might be used by the existing\n"
730                "filesystem. That file can be deleted once the old filesystem is\n"
731                "no longer needed (and should be deleted prior to running\n"
732                "bcache migrate_superblock)\n",
733                dev.path, file_path, sb_offset, dev.path,
734                dev.path, sb_offset);
735
736         struct bch_opts opts = bch_opts_empty();
737         struct cache_set *c = NULL;
738         char *path[1] = { dev.path };
739         const char *err;
740
741         opts.sb         = sb_offset;
742         opts.nostart    = true;
743         opts.noexcl     = true;
744
745         err = bch_fs_open(path, 1, opts, &c);
746         if (err)
747                 die("Error opening new filesystem: %s", err);
748
749         mark_unreserved_space(c, extents);
750
751         err = bch_fs_start(c);
752         if (err)
753                 die("Error starting new filesystem: %s", err);
754
755         copy_fs(c, fs_fd, fs_path, bcachefs_inum, &extents);
756
757         bch_fs_stop(c);
758
759         printf("Migrate complete, running fsck:\n");
760         opts.nostart    = false;
761         opts.nochanges  = true;
762         fsck_err_opt    = FSCK_ERR_NO;
763
764         err = bch_fs_open(path, 1, opts, &c);
765         if (err)
766                 die("Error opening new filesystem: %s", err);
767
768         bch_fs_stop(c);
769         printf("fsck complete\n");
770         return 0;
771 }
772
773 static void migrate_superblock_usage(void)
774 {
775         puts("bcache migrate_superblock - create default superblock after migrating\n"
776              "Usage: bcache migrate_superblock [OPTION]...\n"
777              "\n"
778              "Options:\n"
779              "  -d device     Device to create superblock for\n"
780              "  -o offset     Offset of existing superblock\n"
781              "  -h            Display this help and exit\n"
782              "Report bugs to <linux-bcache@vger.kernel.org>");
783 }
784
785 int cmd_migrate_superblock(int argc, char *argv[])
786 {
787         char *dev = NULL;
788         u64 offset = 0;
789         int opt, ret;
790
791         while ((opt = getopt(argc, argv, "d:o:h")) != -1)
792                 switch (opt) {
793                         case 'd':
794                                 dev = optarg;
795                                 break;
796                         case 'o':
797                                 ret = kstrtou64(optarg, 10, &offset);
798                                 if (ret)
799                                         die("Invalid offset");
800                                 break;
801                         case 'h':
802                                 migrate_superblock_usage();
803                                 exit(EXIT_SUCCESS);
804                 }
805
806         if (!dev)
807                 die("Please specify a device");
808
809         if (!offset)
810                 die("Please specify offset of existing superblock");
811
812         int fd = xopen(dev, O_RDWR);
813         struct bch_sb *sb = __bcache_super_read(fd, offset);
814
815         if (sb->layout.nr_superblocks >= ARRAY_SIZE(sb->layout.sb_offset))
816                 die("Can't add superblock: no space left in superblock layout");
817
818         for (unsigned i = 0; i < sb->layout.nr_superblocks; i++)
819                 if (le64_to_cpu(sb->layout.sb_offset[i]) == BCH_SB_SECTOR)
820                         die("Superblock layout already has default superblock");
821
822         memmove(&sb->layout.sb_offset[1],
823                 &sb->layout.sb_offset[0],
824                 sb->layout.nr_superblocks * sizeof(u64));
825         sb->layout.nr_superblocks++;
826
827         sb->layout.sb_offset[0] = cpu_to_le64(BCH_SB_SECTOR);
828
829         bcache_super_write(fd, sb);
830         close(fd);
831
832         return 0;
833 }