]> git.sesse.net Git - bcachefs-tools-debian/blob - cmd_migrate.c
Add packaging workflow
[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
233                 int ret = bch2_trans_do(c, NULL, NULL, 0,
234                                 bch2_xattr_set(&trans,
235                                                (subvol_inum) { 1, dst->bi_inum },
236                                                &hash_info, attr,
237                                                val, val_size, h->flags, 0));
238                 if (ret < 0)
239                         die("error creating xattr: %s", bch2_err_str(ret));
240         }
241 }
242
243 #define WRITE_DATA_BUF  (1 << 20)
244
245 static char buf[WRITE_DATA_BUF] __aligned(PAGE_SIZE);
246
247 static void write_data(struct bch_fs *c,
248                        struct bch_inode_unpacked *dst_inode,
249                        u64 dst_offset, void *buf, size_t len)
250 {
251         struct bch_write_op op;
252         struct bio_vec bv[WRITE_DATA_BUF / PAGE_SIZE];
253         struct closure cl;
254
255         BUG_ON(dst_offset       & (block_bytes(c) - 1));
256         BUG_ON(len              & (block_bytes(c) - 1));
257         BUG_ON(len > WRITE_DATA_BUF);
258
259         closure_init_stack(&cl);
260
261         bio_init(&op.wbio.bio, NULL, bv, ARRAY_SIZE(bv), 0);
262         bch2_bio_map(&op.wbio.bio, buf, len);
263
264         bch2_write_op_init(&op, c, bch2_opts_to_inode_opts(c->opts));
265         op.write_point  = writepoint_hashed(0);
266         op.nr_replicas  = 1;
267         op.subvol       = 1;
268         op.pos          = SPOS(dst_inode->bi_inum, dst_offset >> 9, U32_MAX);
269         op.flags |= BCH_WRITE_SYNC;
270
271         int ret = bch2_disk_reservation_get(c, &op.res, len >> 9,
272                                             c->opts.data_replicas, 0);
273         if (ret)
274                 die("error reserving space in new filesystem: %s", bch2_err_str(ret));
275
276         closure_call(&op.cl, bch2_write, NULL, &cl);
277
278         dst_inode->bi_sectors += len >> 9;
279 }
280
281 static void copy_data(struct bch_fs *c,
282                       struct bch_inode_unpacked *dst_inode,
283                       int src_fd, u64 start, u64 end)
284 {
285         while (start < end) {
286                 unsigned len = min_t(u64, end - start, sizeof(buf));
287                 unsigned pad = round_up(len, block_bytes(c)) - len;
288
289                 xpread(src_fd, buf, len, start);
290                 memset(buf + len, 0, pad);
291
292                 write_data(c, dst_inode, start, buf, len + pad);
293                 start += len;
294         }
295 }
296
297 static void link_data(struct bch_fs *c, struct bch_inode_unpacked *dst,
298                       u64 logical, u64 physical, u64 length)
299 {
300         struct bch_dev *ca = c->devs[0];
301
302         BUG_ON(logical  & (block_bytes(c) - 1));
303         BUG_ON(physical & (block_bytes(c) - 1));
304         BUG_ON(length   & (block_bytes(c) - 1));
305
306         logical         >>= 9;
307         physical        >>= 9;
308         length          >>= 9;
309
310         BUG_ON(physical + length > bucket_to_sector(ca, ca->mi.nbuckets));
311
312         while (length) {
313                 struct bkey_i_extent *e;
314                 BKEY_PADDED_ONSTACK(k, BKEY_EXTENT_VAL_U64s_MAX) k;
315                 u64 b = sector_to_bucket(ca, physical);
316                 struct disk_reservation res;
317                 unsigned sectors;
318                 int ret;
319
320                 sectors = min(ca->mi.bucket_size -
321                               (physical & (ca->mi.bucket_size - 1)),
322                               length);
323
324                 e = bkey_extent_init(&k.k);
325                 e->k.p.inode    = dst->bi_inum;
326                 e->k.p.offset   = logical + sectors;
327                 e->k.p.snapshot = U32_MAX;
328                 e->k.size       = sectors;
329                 bch2_bkey_append_ptr(&e->k_i, (struct bch_extent_ptr) {
330                                         .offset = physical,
331                                         .dev = 0,
332                                         .gen = *bucket_gen(ca, b),
333                                   });
334
335                 ret = bch2_disk_reservation_get(c, &res, sectors, 1,
336                                                 BCH_DISK_RESERVATION_NOFAIL);
337                 if (ret)
338                         die("error reserving space in new filesystem: %s",
339                             bch2_err_str(ret));
340
341                 ret = bch2_btree_insert(c, BTREE_ID_extents, &e->k_i,
342                                         &res, NULL, 0);
343                 if (ret)
344                         die("btree insert error %s", bch2_err_str(ret));
345
346                 bch2_disk_reservation_put(c, &res);
347
348                 dst->bi_sectors += sectors;
349                 logical         += sectors;
350                 physical        += sectors;
351                 length          -= sectors;
352         }
353 }
354
355 static void copy_link(struct bch_fs *c, struct bch_inode_unpacked *dst,
356                       char *src)
357 {
358         ssize_t ret = readlink(src, buf, sizeof(buf));
359         if (ret < 0)
360                 die("readlink error: %m");
361
362         write_data(c, dst, 0, buf, round_up(ret, block_bytes(c)));
363 }
364
365 static void copy_file(struct bch_fs *c, struct bch_inode_unpacked *dst,
366                       int src_fd, u64 src_size,
367                       char *src_path, ranges *extents)
368 {
369         struct fiemap_iter iter;
370         struct fiemap_extent e;
371
372         fiemap_for_each(src_fd, iter, e)
373                 if (e.fe_flags & FIEMAP_EXTENT_UNKNOWN) {
374                         fsync(src_fd);
375                         break;
376                 }
377
378         fiemap_for_each(src_fd, iter, e) {
379                 if ((e.fe_logical       & (block_bytes(c) - 1)) ||
380                     (e.fe_length        & (block_bytes(c) - 1)))
381                         die("Unaligned extent in %s - can't handle", src_path);
382
383                 if (e.fe_flags & (FIEMAP_EXTENT_UNKNOWN|
384                                   FIEMAP_EXTENT_ENCODED|
385                                   FIEMAP_EXTENT_NOT_ALIGNED|
386                                   FIEMAP_EXTENT_DATA_INLINE)) {
387                         copy_data(c, dst, src_fd, e.fe_logical,
388                                   min(src_size - e.fe_logical,
389                                       e.fe_length));
390                         continue;
391                 }
392
393                 /*
394                  * if the data is below 1 MB, copy it so it doesn't conflict
395                  * with bcachefs's potentially larger superblock:
396                  */
397                 if (e.fe_physical < 1 << 20) {
398                         copy_data(c, dst, src_fd, e.fe_logical,
399                                   min(src_size - e.fe_logical,
400                                       e.fe_length));
401                         continue;
402                 }
403
404                 if ((e.fe_physical      & (block_bytes(c) - 1)))
405                         die("Unaligned extent in %s - can't handle", src_path);
406
407                 range_add(extents, e.fe_physical, e.fe_length);
408                 link_data(c, dst, e.fe_logical, e.fe_physical, e.fe_length);
409         }
410 }
411
412 struct copy_fs_state {
413         u64                     bcachefs_inum;
414         dev_t                   dev;
415
416         GENRADIX(u64)           hardlinks;
417         ranges                  extents;
418 };
419
420 static void copy_dir(struct copy_fs_state *s,
421                      struct bch_fs *c,
422                      struct bch_inode_unpacked *dst,
423                      int src_fd, const char *src_path)
424 {
425         DIR *dir = fdopendir(src_fd);
426         struct dirent *d;
427
428         while ((errno = 0), (d = readdir(dir))) {
429                 struct bch_inode_unpacked inode;
430                 int fd;
431
432                 if (fchdir(src_fd))
433                         die("chdir error: %m");
434
435                 struct stat stat =
436                         xfstatat(src_fd, d->d_name, AT_SYMLINK_NOFOLLOW);
437
438                 if (!strcmp(d->d_name, ".") ||
439                     !strcmp(d->d_name, "..") ||
440                     !strcmp(d->d_name, "lost+found") ||
441                     stat.st_ino == s->bcachefs_inum)
442                         continue;
443
444                 char *child_path = mprintf("%s/%s", src_path, d->d_name);
445
446                 if (stat.st_dev != s->dev)
447                         die("%s does not have correct st_dev!", child_path);
448
449                 u64 *dst_inum = S_ISREG(stat.st_mode)
450                         ? genradix_ptr_alloc(&s->hardlinks, stat.st_ino, GFP_KERNEL)
451                         : NULL;
452
453                 if (dst_inum && *dst_inum) {
454                         create_link(c, dst, d->d_name, *dst_inum, S_IFREG);
455                         goto next;
456                 }
457
458                 inode = create_file(c, dst, d->d_name,
459                                     stat.st_uid, stat.st_gid,
460                                     stat.st_mode, stat.st_rdev);
461
462                 if (dst_inum)
463                         *dst_inum = inode.bi_inum;
464
465                 copy_times(c, &inode, &stat);
466                 copy_xattrs(c, &inode, d->d_name);
467
468                 /* copy xattrs */
469
470                 switch (mode_to_type(stat.st_mode)) {
471                 case DT_DIR:
472                         fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
473                         copy_dir(s, c, &inode, fd, child_path);
474                         close(fd);
475                         break;
476                 case DT_REG:
477                         inode.bi_size = stat.st_size;
478
479                         fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
480                         copy_file(c, &inode, fd, stat.st_size,
481                                   child_path, &s->extents);
482                         close(fd);
483                         break;
484                 case DT_LNK:
485                         inode.bi_size = stat.st_size;
486
487                         copy_link(c, &inode, d->d_name);
488                         break;
489                 case DT_FIFO:
490                 case DT_CHR:
491                 case DT_BLK:
492                 case DT_SOCK:
493                 case DT_WHT:
494                         /* nothing else to copy for these: */
495                         break;
496                 default:
497                         BUG();
498                 }
499
500                 update_inode(c, &inode);
501 next:
502                 free(child_path);
503         }
504
505         if (errno)
506                 die("readdir error: %m");
507 }
508
509 static ranges reserve_new_fs_space(const char *file_path, unsigned block_size,
510                                    u64 size, u64 *bcachefs_inum, dev_t dev,
511                                    bool force)
512 {
513         int fd = force
514                 ? open(file_path, O_RDWR|O_CREAT, 0600)
515                 : open(file_path, O_RDWR|O_CREAT|O_EXCL, 0600);
516         if (fd < 0)
517                 die("Error creating %s for bcachefs metadata: %m",
518                     file_path);
519
520         struct stat statbuf = xfstat(fd);
521
522         if (statbuf.st_dev != dev)
523                 die("bcachefs file has incorrect device");
524
525         *bcachefs_inum = statbuf.st_ino;
526
527         if (fallocate(fd, 0, 0, size))
528                 die("Error reserving space for bcachefs metadata: %m");
529
530         fsync(fd);
531
532         struct fiemap_iter iter;
533         struct fiemap_extent e;
534         ranges extents = { 0 };
535
536         fiemap_for_each(fd, iter, e) {
537                 if (e.fe_flags & (FIEMAP_EXTENT_UNKNOWN|
538                                   FIEMAP_EXTENT_ENCODED|
539                                   FIEMAP_EXTENT_NOT_ALIGNED|
540                                   FIEMAP_EXTENT_DATA_INLINE))
541                         die("Unable to continue: metadata file not fully mapped");
542
543                 if ((e.fe_physical      & (block_size - 1)) ||
544                     (e.fe_length        & (block_size - 1)))
545                         die("Unable to continue: unaligned extents in metadata file");
546
547                 range_add(&extents, e.fe_physical, e.fe_length);
548         }
549         close(fd);
550
551         ranges_sort_merge(&extents);
552         return extents;
553 }
554
555 static void reserve_old_fs_space(struct bch_fs *c,
556                                  struct bch_inode_unpacked *root_inode,
557                                  ranges *extents)
558 {
559         struct bch_dev *ca = c->devs[0];
560         struct bch_inode_unpacked dst;
561         struct hole_iter iter;
562         struct range i;
563
564         dst = create_file(c, root_inode, "old_migrated_filesystem",
565                           0, 0, S_IFREG|0400, 0);
566         dst.bi_size = bucket_to_sector(ca, ca->mi.nbuckets) << 9;
567
568         ranges_sort_merge(extents);
569
570         for_each_hole(iter, *extents, bucket_to_sector(ca, ca->mi.nbuckets) << 9, i)
571                 link_data(c, &dst, i.start, i.start, i.end - i.start);
572
573         update_inode(c, &dst);
574 }
575
576 static void copy_fs(struct bch_fs *c, int src_fd, const char *src_path,
577                     u64 bcachefs_inum, ranges *extents)
578 {
579         syncfs(src_fd);
580
581         struct bch_inode_unpacked root_inode;
582         int ret = bch2_inode_find_by_inum(c, (subvol_inum) { 1, BCACHEFS_ROOT_INO },
583                                           &root_inode);
584         if (ret)
585                 die("error looking up root directory: %s", bch2_err_str(ret));
586
587         if (fchdir(src_fd))
588                 die("chdir error: %m");
589
590         struct stat stat = xfstat(src_fd);
591         copy_times(c, &root_inode, &stat);
592         copy_xattrs(c, &root_inode, ".");
593
594         struct copy_fs_state s = {
595                 .bcachefs_inum  = bcachefs_inum,
596                 .dev            = stat.st_dev,
597                 .extents        = *extents,
598         };
599
600         /* now, copy: */
601         copy_dir(&s, c, &root_inode, src_fd, src_path);
602
603         reserve_old_fs_space(c, &root_inode, &s.extents);
604
605         update_inode(c, &root_inode);
606
607         darray_exit(&s.extents);
608         genradix_free(&s.hardlinks);
609 }
610
611 static void find_superblock_space(ranges extents,
612                                   struct format_opts opts,
613                                   struct dev_opts *dev)
614 {
615         struct range *i;
616
617         darray_for_each(extents, i) {
618                 u64 start = round_up(max(256ULL << 10, i->start),
619                                      dev->bucket_size << 9);
620                 u64 end = round_down(i->end,
621                                      dev->bucket_size << 9);
622
623                 /* Need space for two superblocks: */
624                 if (start + (opts.superblock_size << 9) * 2 <= end) {
625                         dev->sb_offset  = start >> 9;
626                         dev->sb_end     = dev->sb_offset + opts.superblock_size * 2;
627                         return;
628                 }
629         }
630
631         die("Couldn't find a valid location for superblock");
632 }
633
634 static void migrate_usage(void)
635 {
636         puts("bcachefs migrate - migrate an existing filesystem to bcachefs\n"
637              "Usage: bcachefs migrate [OPTION]...\n"
638              "\n"
639              "Options:\n"
640              "  -f fs                  Root of filesystem to migrate(s)\n"
641              "      --encrypted        Enable whole filesystem encryption (chacha20/poly1305)\n"
642              "      --no_passphrase    Don't encrypt master encryption key\n"
643              "  -F                     Force, even if metadata file already exists\n"
644              "  -h                     Display this help and exit\n"
645              "Report bugs to <linux-bcachefs@vger.kernel.org>");
646 }
647
648 static const struct option migrate_opts[] = {
649         { "encrypted",          no_argument, NULL, 'e' },
650         { "no_passphrase",      no_argument, NULL, 'p' },
651         { NULL }
652 };
653
654 static int migrate_fs(const char                *fs_path,
655                       struct bch_opt_strs       fs_opt_strs,
656                       struct bch_opts           fs_opts,
657                       struct format_opts        format_opts,
658                       bool force)
659 {
660         if (!path_is_fs_root(fs_path))
661                 die("%s is not a filysestem root", fs_path);
662
663         int fs_fd = xopen(fs_path, O_RDONLY|O_NOATIME);
664         struct stat stat = xfstat(fs_fd);
665
666         if (!S_ISDIR(stat.st_mode))
667                 die("%s is not a directory", fs_path);
668
669         struct dev_opts dev = dev_opts_default();
670
671         dev.path = dev_t_to_path(stat.st_dev);
672         dev.fd = xopen(dev.path, O_RDWR);
673
674         opt_set(fs_opts, block_size, get_blocksize(dev.path, dev.fd));
675
676         char *file_path = mprintf("%s/bcachefs", fs_path);
677         printf("Creating new filesystem on %s in space reserved at %s\n",
678                dev.path, file_path);
679
680         bch2_pick_bucket_size(fs_opts, &dev);
681
682         u64 bcachefs_inum;
683         ranges extents = reserve_new_fs_space(file_path,
684                                 fs_opts.block_size >> 9,
685                                 get_size(dev.path, dev.fd) / 5,
686                                 &bcachefs_inum, stat.st_dev, force);
687
688         find_superblock_space(extents, format_opts, &dev);
689
690         struct bch_sb *sb = bch2_format(fs_opt_strs,
691                                         fs_opts,format_opts, &dev, 1);
692         u64 sb_offset = le64_to_cpu(sb->layout.sb_offset[0]);
693
694         if (format_opts.passphrase)
695                 bch2_add_key(sb, "user", "user", format_opts.passphrase);
696
697         free(sb);
698
699         struct bch_opts opts = bch2_opts_empty();
700         struct bch_fs *c = NULL;
701         char *path[1] = { dev.path };
702
703         opt_set(opts, sb,       sb_offset);
704         opt_set(opts, nostart,  true);
705         opt_set(opts, noexcl,   true);
706         opt_set(opts, buckets_nouse, true);
707
708         c = bch2_fs_open(path, 1, opts);
709         if (IS_ERR(c))
710                 die("Error opening new filesystem: %s", bch2_err_str(PTR_ERR(c)));
711
712         mark_unreserved_space(c, extents);
713
714         int ret = bch2_fs_start(c);
715         if (ret)
716                 die("Error starting new filesystem: %s", bch2_err_str(ret));
717
718         copy_fs(c, fs_fd, fs_path, bcachefs_inum, &extents);
719
720         bch2_fs_stop(c);
721
722         printf("Migrate complete, running fsck:\n");
723         opt_set(opts, nostart,  false);
724         opt_set(opts, nochanges, true);
725
726         c = bch2_fs_open(path, 1, opts);
727         if (IS_ERR(c))
728                 die("Error opening new filesystem: %s", bch2_err_str(PTR_ERR(c)));
729
730         bch2_fs_stop(c);
731         printf("fsck complete\n");
732
733         printf("To mount the new filesystem, run\n"
734                "  mount -t bcachefs -o sb=%llu %s dir\n"
735                "\n"
736                "After verifying that the new filesystem is correct, to create a\n"
737                "superblock at the default offset and finish the migration run\n"
738                "  bcachefs migrate-superblock -d %s -o %llu\n"
739                "\n"
740                "The new filesystem will have a file at /old_migrated_filestem\n"
741                "referencing all disk space that might be used by the existing\n"
742                "filesystem. That file can be deleted once the old filesystem is\n"
743                "no longer needed (and should be deleted prior to running\n"
744                "bcachefs migrate-superblock)\n",
745                sb_offset, dev.path, dev.path, sb_offset);
746         return 0;
747 }
748
749 int cmd_migrate(int argc, char *argv[])
750 {
751         struct format_opts format_opts = format_opts_default();
752         char *fs_path = NULL;
753         bool no_passphrase = false, force = false;
754         int opt;
755
756         struct bch_opt_strs fs_opt_strs =
757                 bch2_cmdline_opts_get(&argc, argv, OPT_FORMAT);
758         struct bch_opts fs_opts = bch2_parse_opts(fs_opt_strs);
759
760         while ((opt = getopt_long(argc, argv, "f:Fh",
761                                   migrate_opts, NULL)) != -1)
762                 switch (opt) {
763                 case 'f':
764                         fs_path = optarg;
765                         break;
766                 case 'e':
767                         format_opts.encrypted = true;
768                         break;
769                 case 'p':
770                         no_passphrase = true;
771                         break;
772                 case 'F':
773                         force = true;
774                         break;
775                 case 'h':
776                         migrate_usage();
777                         exit(EXIT_SUCCESS);
778                 }
779
780         if (!fs_path)
781                 die("Please specify a filesystem to migrate");
782
783         if (format_opts.encrypted && !no_passphrase)
784                 format_opts.passphrase = read_passphrase_twice("Enter passphrase: ");
785
786         int ret = migrate_fs(fs_path,
787                              fs_opt_strs,
788                              fs_opts,
789                              format_opts, force);
790         bch2_opt_strs_free(&fs_opt_strs);
791         return ret;
792 }
793
794 static void migrate_superblock_usage(void)
795 {
796         puts("bcachefs migrate-superblock - create default superblock after migrating\n"
797              "Usage: bcachefs migrate-superblock [OPTION]...\n"
798              "\n"
799              "Options:\n"
800              "  -d device     Device to create superblock for\n"
801              "  -o offset     Offset of existing superblock\n"
802              "  -h            Display this help and exit\n"
803              "Report bugs to <linux-bcachefs@vger.kernel.org>");
804 }
805
806 int cmd_migrate_superblock(int argc, char *argv[])
807 {
808         char *dev = NULL;
809         u64 offset = 0;
810         int opt, ret;
811
812         while ((opt = getopt(argc, argv, "d:o:h")) != -1)
813                 switch (opt) {
814                         case 'd':
815                                 dev = optarg;
816                                 break;
817                         case 'o':
818                                 ret = kstrtou64(optarg, 10, &offset);
819                                 if (ret)
820                                         die("Invalid offset");
821                                 break;
822                         case 'h':
823                                 migrate_superblock_usage();
824                                 exit(EXIT_SUCCESS);
825                 }
826
827         if (!dev)
828                 die("Please specify a device");
829
830         if (!offset)
831                 die("Please specify offset of existing superblock");
832
833         int fd = xopen(dev, O_RDWR);
834         struct bch_sb *sb = __bch2_super_read(fd, offset);
835
836         if (sb->layout.nr_superblocks >= ARRAY_SIZE(sb->layout.sb_offset))
837                 die("Can't add superblock: no space left in superblock layout");
838
839         unsigned i;
840         for (i = 0; i < sb->layout.nr_superblocks; i++)
841                 if (le64_to_cpu(sb->layout.sb_offset[i]) == BCH_SB_SECTOR)
842                         die("Superblock layout already has default superblock");
843
844         memmove(&sb->layout.sb_offset[1],
845                 &sb->layout.sb_offset[0],
846                 sb->layout.nr_superblocks * sizeof(u64));
847         sb->layout.nr_superblocks++;
848
849         sb->layout.sb_offset[0] = cpu_to_le64(BCH_SB_SECTOR);
850
851         bch2_super_write(fd, sb);
852         close(fd);
853
854         return 0;
855 }