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