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