]> git.sesse.net Git - bcachefs-tools-debian/blob - cmd_migrate.c
Increase default superblock size to 1MB
[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(c, &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, BKEY_EXTENT_VAL_U64s_MAX) 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         bch2_alloc_write(c, false);
600 }
601
602 static void find_superblock_space(ranges extents,
603                                   struct format_opts opts,
604                                   struct dev_opts *dev)
605 {
606         struct range *i;
607
608         darray_foreach(i, extents) {
609                 u64 start = round_up(max(256ULL << 10, i->start),
610                                      dev->bucket_size << 9);
611                 u64 end = round_down(i->end,
612                                      dev->bucket_size << 9);
613
614                 /* Need space for two superblocks: */
615                 if (start + (opts.superblock_size << 9) * 2 <= end) {
616                         dev->sb_offset  = start >> 9;
617                         dev->sb_end     = dev->sb_offset + opts.superblock_size * 2;
618                         return;
619                 }
620         }
621
622         die("Couldn't find a valid location for superblock");
623 }
624
625 static void migrate_usage(void)
626 {
627         puts("bcachefs migrate - migrate an existing filesystem to bcachefs\n"
628              "Usage: bcachefs migrate [OPTION]...\n"
629              "\n"
630              "Options:\n"
631              "  -f fs                  Root of filesystem to migrate(s)\n"
632              "      --encrypted        Enable whole filesystem encryption (chacha20/poly1305)\n"
633              "      --no_passphrase    Don't encrypt master encryption key\n"
634              "  -F                     Force, even if metadata file already exists\n"
635              "  -h                     Display this help and exit\n"
636              "Report bugs to <linux-bcache@vger.kernel.org>");
637 }
638
639 static const struct option migrate_opts[] = {
640         { "encrypted",          no_argument, NULL, 'e' },
641         { "no_passphrase",      no_argument, NULL, 'p' },
642         { NULL }
643 };
644
645 static int migrate_fs(const char                *fs_path,
646                       struct bch_opt_strs       fs_opt_strs,
647                       struct bch_opts           fs_opts,
648                       struct format_opts        format_opts,
649                       bool force)
650 {
651         if (!path_is_fs_root(fs_path))
652                 die("%s is not a filysestem root", fs_path);
653
654         int fs_fd = xopen(fs_path, O_RDONLY|O_NOATIME);
655         struct stat stat = xfstat(fs_fd);
656
657         if (!S_ISDIR(stat.st_mode))
658                 die("%s is not a directory", fs_path);
659
660         struct dev_opts dev = dev_opts_default();
661
662         dev.path = dev_t_to_path(stat.st_dev);
663         dev.fd = xopen(dev.path, O_RDWR);
664
665         opt_set(fs_opts, block_size, get_blocksize(dev.path, dev.fd));
666
667         char *file_path = mprintf("%s/bcachefs", fs_path);
668         printf("Creating new filesystem on %s in space reserved at %s\n",
669                dev.path, file_path);
670
671         bch2_pick_bucket_size(fs_opts, &dev);
672
673         u64 bcachefs_inum;
674         ranges extents = reserve_new_fs_space(file_path,
675                                 fs_opts.block_size << 9,
676                                 get_size(dev.path, dev.fd) / 5,
677                                 &bcachefs_inum, stat.st_dev, force);
678
679         find_superblock_space(extents, format_opts, &dev);
680
681         struct bch_sb *sb = bch2_format(fs_opt_strs,
682                                         fs_opts,format_opts, &dev, 1);
683         u64 sb_offset = le64_to_cpu(sb->layout.sb_offset[0]);
684
685         if (format_opts.passphrase)
686                 bch2_add_key(sb, format_opts.passphrase);
687
688         free(sb);
689
690         struct bch_opts opts = bch2_opts_empty();
691         struct bch_fs *c = NULL;
692         char *path[1] = { dev.path };
693
694         opt_set(opts, sb,       sb_offset);
695         opt_set(opts, nostart,  true);
696         opt_set(opts, noexcl,   true);
697
698         c = bch2_fs_open(path, 1, opts);
699         if (IS_ERR(c))
700                 die("Error opening new filesystem: %s", strerror(-PTR_ERR(c)));
701
702         mark_unreserved_space(c, extents);
703
704         int ret = bch2_fs_start(c);
705         if (ret)
706                 die("Error starting new filesystem: %s", strerror(-ret));
707
708         copy_fs(c, fs_fd, fs_path, bcachefs_inum, &extents);
709
710         bch2_fs_stop(c);
711
712         printf("Migrate complete, running fsck:\n");
713         opt_set(opts, nostart,  false);
714         opt_set(opts, nochanges, true);
715
716         c = bch2_fs_open(path, 1, opts);
717         if (IS_ERR(c))
718                 die("Error opening new filesystem: %s", strerror(-PTR_ERR(c)));
719
720         bch2_fs_stop(c);
721         printf("fsck complete\n");
722
723         printf("To mount the new filesystem, run\n"
724                "  mount -t bcachefs -o sb=%llu %s dir\n"
725                "\n"
726                "After verifying that the new filesystem is correct, to create a\n"
727                "superblock at the default offset and finish the migration run\n"
728                "  bcachefs migrate-superblock -d %s -o %llu\n"
729                "\n"
730                "The new filesystem will have a file at /old_migrated_filestem\n"
731                "referencing all disk space that might be used by the existing\n"
732                "filesystem. That file can be deleted once the old filesystem is\n"
733                "no longer needed (and should be deleted prior to running\n"
734                "bcachefs migrate-superblock)\n",
735                sb_offset, dev.path, dev.path, sb_offset);
736         return 0;
737 }
738
739 int cmd_migrate(int argc, char *argv[])
740 {
741         struct format_opts format_opts = format_opts_default();
742         char *fs_path = NULL;
743         bool no_passphrase = false, force = false;
744         int opt;
745
746         struct bch_opt_strs fs_opt_strs =
747                 bch2_cmdline_opts_get(&argc, argv, OPT_FORMAT);
748         struct bch_opts fs_opts = bch2_parse_opts(fs_opt_strs);
749
750         while ((opt = getopt_long(argc, argv, "f:Fh",
751                                   migrate_opts, NULL)) != -1)
752                 switch (opt) {
753                 case 'f':
754                         fs_path = optarg;
755                         break;
756                 case 'e':
757                         format_opts.encrypted = true;
758                         break;
759                 case 'p':
760                         no_passphrase = true;
761                         break;
762                 case 'F':
763                         force = true;
764                         break;
765                 case 'h':
766                         migrate_usage();
767                         exit(EXIT_SUCCESS);
768                 }
769
770         if (!fs_path)
771                 die("Please specify a filesystem to migrate");
772
773         if (format_opts.encrypted && !no_passphrase)
774                 format_opts.passphrase = read_passphrase_twice("Enter passphrase: ");
775
776         return migrate_fs(fs_path,
777                           fs_opt_strs,
778                           fs_opts,
779                           format_opts, force);
780 }
781
782 static void migrate_superblock_usage(void)
783 {
784         puts("bcachefs migrate-superblock - create default superblock after migrating\n"
785              "Usage: bcachefs migrate-superblock [OPTION]...\n"
786              "\n"
787              "Options:\n"
788              "  -d device     Device to create superblock for\n"
789              "  -o offset     Offset of existing superblock\n"
790              "  -h            Display this help and exit\n"
791              "Report bugs to <linux-bcache@vger.kernel.org>");
792 }
793
794 int cmd_migrate_superblock(int argc, char *argv[])
795 {
796         char *dev = NULL;
797         u64 offset = 0;
798         int opt, ret;
799
800         while ((opt = getopt(argc, argv, "d:o:h")) != -1)
801                 switch (opt) {
802                         case 'd':
803                                 dev = optarg;
804                                 break;
805                         case 'o':
806                                 ret = kstrtou64(optarg, 10, &offset);
807                                 if (ret)
808                                         die("Invalid offset");
809                                 break;
810                         case 'h':
811                                 migrate_superblock_usage();
812                                 exit(EXIT_SUCCESS);
813                 }
814
815         if (!dev)
816                 die("Please specify a device");
817
818         if (!offset)
819                 die("Please specify offset of existing superblock");
820
821         int fd = xopen(dev, O_RDWR);
822         struct bch_sb *sb = __bch2_super_read(fd, offset);
823
824         if (sb->layout.nr_superblocks >= ARRAY_SIZE(sb->layout.sb_offset))
825                 die("Can't add superblock: no space left in superblock layout");
826
827         unsigned i;
828         for (i = 0; i < sb->layout.nr_superblocks; i++)
829                 if (le64_to_cpu(sb->layout.sb_offset[i]) == BCH_SB_SECTOR)
830                         die("Superblock layout already has default superblock");
831
832         memmove(&sb->layout.sb_offset[1],
833                 &sb->layout.sb_offset[0],
834                 sb->layout.nr_superblocks * sizeof(u64));
835         sb->layout.nr_superblocks++;
836
837         sb->layout.sb_offset[0] = cpu_to_le64(BCH_SB_SECTOR);
838
839         bch2_super_write(fd, sb);
840         close(fd);
841
842         return 0;
843 }