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