]> git.sesse.net Git - bcachefs-tools-debian/blob - cmd_migrate.c
Upload to unstable
[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_write.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, 0);
130         if (ret)
131                 die("error updating inode: %s", bch2_err_str(ret));
132 }
133
134 static void create_link(struct bch_fs *c,
135                         struct bch_inode_unpacked *parent,
136                         const char *name, u64 inum, mode_t mode)
137 {
138         struct qstr qstr = QSTR(name);
139         struct bch_inode_unpacked parent_u;
140         struct bch_inode_unpacked inode;
141
142         int ret = bch2_trans_do(c, NULL, NULL, 0,
143                 bch2_link_trans(trans,
144                                 (subvol_inum) { 1, parent->bi_inum }, &parent_u,
145                                 (subvol_inum) { 1, inum }, &inode, &qstr));
146         if (ret)
147                 die("error creating hardlink: %s", bch2_err_str(ret));
148 }
149
150 static struct bch_inode_unpacked create_file(struct bch_fs *c,
151                                              struct bch_inode_unpacked *parent,
152                                              const char *name,
153                                              uid_t uid, gid_t gid,
154                                              mode_t mode, dev_t rdev)
155 {
156         struct qstr qstr = QSTR(name);
157         struct bch_inode_unpacked new_inode;
158
159         bch2_inode_init_early(c, &new_inode);
160
161         int ret = bch2_trans_do(c, NULL, NULL, 0,
162                 bch2_create_trans(trans,
163                                   (subvol_inum) { 1, parent->bi_inum }, parent,
164                                   &new_inode, &qstr,
165                                   uid, gid, mode, rdev, NULL, NULL,
166                                   (subvol_inum) {}, 0));
167         if (ret)
168                 die("error creating %s: %s", name, bch2_err_str(ret));
169
170         return new_inode;
171 }
172
173 #define for_each_xattr_handler(handlers, handler)               \
174         if (handlers)                                           \
175                 for ((handler) = *(handlers)++;                 \
176                         (handler) != NULL;                      \
177                         (handler) = *(handlers)++)
178
179 static const struct xattr_handler *xattr_resolve_name(char **name)
180 {
181         const struct xattr_handler **handlers = bch2_xattr_handlers;
182         const struct xattr_handler *handler;
183
184         for_each_xattr_handler(handlers, handler) {
185                 char *n;
186
187                 n = strcmp_prefix(*name, xattr_prefix(handler));
188                 if (n) {
189                         if (!handler->prefix ^ !*n) {
190                                 if (*n)
191                                         continue;
192                                 return ERR_PTR(-EINVAL);
193                         }
194                         *name = n;
195                         return handler;
196                 }
197         }
198         return ERR_PTR(-EOPNOTSUPP);
199 }
200
201 static void copy_times(struct bch_fs *c, struct bch_inode_unpacked *dst,
202                        struct stat *src)
203 {
204         dst->bi_atime = timespec_to_bch2_time(c, src->st_atim);
205         dst->bi_mtime = timespec_to_bch2_time(c, src->st_mtim);
206         dst->bi_ctime = timespec_to_bch2_time(c, src->st_ctim);
207 }
208
209 static void copy_xattrs(struct bch_fs *c, struct bch_inode_unpacked *dst,
210                         char *src)
211 {
212         struct bch_hash_info hash_info = bch2_hash_info_init(c, dst);
213
214         char attrs[XATTR_LIST_MAX];
215         ssize_t attrs_size = llistxattr(src, attrs, sizeof(attrs));
216         if (attrs_size < 0)
217                 die("listxattr error: %m");
218
219         char *next, *attr;
220         for (attr = attrs;
221              attr < attrs + attrs_size;
222              attr = next) {
223                 next = attr + strlen(attr) + 1;
224
225                 char val[XATTR_SIZE_MAX];
226                 ssize_t val_size = lgetxattr(src, attr, val, sizeof(val));
227
228                 if (val_size < 0)
229                         die("error getting xattr val: %m");
230
231                 const struct xattr_handler *h = xattr_resolve_name(&attr);
232                 struct bch_inode_unpacked inode_u;
233
234                 int ret = bch2_trans_do(c, NULL, NULL, 0,
235                                 bch2_xattr_set(trans,
236                                                (subvol_inum) { 1, dst->bi_inum },
237                                                &inode_u, &hash_info, attr,
238                                                val, val_size, h->flags, 0));
239                 if (ret < 0)
240                         die("error creating xattr: %s", bch2_err_str(ret));
241         }
242 }
243
244 #define WRITE_DATA_BUF  (1 << 20)
245
246 static char buf[WRITE_DATA_BUF] __aligned(PAGE_SIZE);
247
248 static void write_data(struct bch_fs *c,
249                        struct bch_inode_unpacked *dst_inode,
250                        u64 dst_offset, void *buf, size_t len)
251 {
252         struct bch_write_op op;
253         struct bio_vec bv[WRITE_DATA_BUF / PAGE_SIZE];
254         struct closure cl;
255
256         BUG_ON(dst_offset       & (block_bytes(c) - 1));
257         BUG_ON(len              & (block_bytes(c) - 1));
258         BUG_ON(len > WRITE_DATA_BUF);
259
260         closure_init_stack(&cl);
261
262         bio_init(&op.wbio.bio, NULL, bv, ARRAY_SIZE(bv), 0);
263         bch2_bio_map(&op.wbio.bio, buf, len);
264
265         bch2_write_op_init(&op, c, bch2_opts_to_inode_opts(c->opts));
266         op.write_point  = writepoint_hashed(0);
267         op.nr_replicas  = 1;
268         op.subvol       = 1;
269         op.pos          = SPOS(dst_inode->bi_inum, dst_offset >> 9, U32_MAX);
270         op.flags |= BCH_WRITE_SYNC;
271
272         int ret = bch2_disk_reservation_get(c, &op.res, len >> 9,
273                                             c->opts.data_replicas, 0);
274         if (ret)
275                 die("error reserving space in new filesystem: %s", bch2_err_str(ret));
276
277         closure_call(&op.cl, bch2_write, NULL, &cl);
278
279         dst_inode->bi_sectors += len >> 9;
280 }
281
282 static void copy_data(struct bch_fs *c,
283                       struct bch_inode_unpacked *dst_inode,
284                       int src_fd, u64 start, u64 end)
285 {
286         while (start < end) {
287                 unsigned len = min_t(u64, end - start, sizeof(buf));
288                 unsigned pad = round_up(len, block_bytes(c)) - len;
289
290                 xpread(src_fd, buf, len, start);
291                 memset(buf + len, 0, pad);
292
293                 write_data(c, dst_inode, start, buf, len + pad);
294                 start += len;
295         }
296 }
297
298 static void link_data(struct bch_fs *c, struct bch_inode_unpacked *dst,
299                       u64 logical, u64 physical, u64 length)
300 {
301         struct bch_dev *ca = c->devs[0];
302
303         BUG_ON(logical  & (block_bytes(c) - 1));
304         BUG_ON(physical & (block_bytes(c) - 1));
305         BUG_ON(length   & (block_bytes(c) - 1));
306
307         logical         >>= 9;
308         physical        >>= 9;
309         length          >>= 9;
310
311         BUG_ON(physical + length > bucket_to_sector(ca, ca->mi.nbuckets));
312
313         while (length) {
314                 struct bkey_i_extent *e;
315                 BKEY_PADDED_ONSTACK(k, BKEY_EXTENT_VAL_U64s_MAX) k;
316                 u64 b = sector_to_bucket(ca, physical);
317                 struct disk_reservation res;
318                 unsigned sectors;
319                 int ret;
320
321                 sectors = min(ca->mi.bucket_size -
322                               (physical & (ca->mi.bucket_size - 1)),
323                               length);
324
325                 e = bkey_extent_init(&k.k);
326                 e->k.p.inode    = dst->bi_inum;
327                 e->k.p.offset   = logical + sectors;
328                 e->k.p.snapshot = U32_MAX;
329                 e->k.size       = sectors;
330                 bch2_bkey_append_ptr(&e->k_i, (struct bch_extent_ptr) {
331                                         .offset = physical,
332                                         .dev = 0,
333                                         .gen = *bucket_gen(ca, b),
334                                   });
335
336                 ret = bch2_disk_reservation_get(c, &res, sectors, 1,
337                                                 BCH_DISK_RESERVATION_NOFAIL);
338                 if (ret)
339                         die("error reserving space in new filesystem: %s",
340                             bch2_err_str(ret));
341
342                 ret = bch2_btree_insert(c, BTREE_ID_extents, &e->k_i, &res, 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.bdev = blkdev_get_by_path(dev.path, BLK_OPEN_READ|BLK_OPEN_WRITE, &dev, NULL);
673
674         opt_set(fs_opts, block_size, get_blocksize(dev.bdev->bd_buffered_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         dev.size        = get_size(dev.bdev->bd_buffered_fd);
681         dev.bucket_size = bch2_pick_bucket_size(fs_opts, &dev);
682         dev.nbuckets    = dev.size / dev.bucket_size;
683
684         bch2_check_bucket_size(fs_opts, &dev);
685
686         u64 bcachefs_inum;
687         ranges extents = reserve_new_fs_space(file_path,
688                                 fs_opts.block_size >> 9,
689                                 get_size(dev.bdev->bd_buffered_fd) / 5,
690                                 &bcachefs_inum, stat.st_dev, force);
691
692         find_superblock_space(extents, format_opts, &dev);
693
694         struct bch_sb *sb = bch2_format(fs_opt_strs,
695                                         fs_opts,format_opts, &dev, 1);
696         u64 sb_offset = le64_to_cpu(sb->layout.sb_offset[0]);
697
698         if (format_opts.passphrase)
699                 bch2_add_key(sb, "user", "user", format_opts.passphrase);
700
701         free(sb);
702
703         struct bch_opts opts = bch2_opts_empty();
704         struct bch_fs *c = NULL;
705         char *path[1] = { dev.path };
706
707         opt_set(opts, sb,       sb_offset);
708         opt_set(opts, nostart,  true);
709         opt_set(opts, noexcl,   true);
710         opt_set(opts, buckets_nouse, true);
711
712         c = bch2_fs_open(path, 1, opts);
713         if (IS_ERR(c))
714                 die("Error opening new filesystem: %s", bch2_err_str(PTR_ERR(c)));
715
716         mark_unreserved_space(c, extents);
717
718         int ret = bch2_fs_start(c);
719         if (ret)
720                 die("Error starting new filesystem: %s", bch2_err_str(ret));
721
722         copy_fs(c, fs_fd, fs_path, bcachefs_inum, &extents);
723
724         bch2_fs_stop(c);
725
726         printf("Migrate complete, running fsck:\n");
727         opt_set(opts, nostart,  false);
728         opt_set(opts, nochanges, true);
729
730         c = bch2_fs_open(path, 1, opts);
731         if (IS_ERR(c))
732                 die("Error opening new filesystem: %s", bch2_err_str(PTR_ERR(c)));
733
734         bch2_fs_stop(c);
735         printf("fsck complete\n");
736
737         printf("To mount the new filesystem, run\n"
738                "  mount -t bcachefs -o sb=%llu %s dir\n"
739                "\n"
740                "After verifying that the new filesystem is correct, to create a\n"
741                "superblock at the default offset and finish the migration run\n"
742                "  bcachefs migrate-superblock -d %s -o %llu\n"
743                "\n"
744                "The new filesystem will have a file at /old_migrated_filestem\n"
745                "referencing all disk space that might be used by the existing\n"
746                "filesystem. That file can be deleted once the old filesystem is\n"
747                "no longer needed (and should be deleted prior to running\n"
748                "bcachefs migrate-superblock)\n",
749                sb_offset, dev.path, dev.path, sb_offset);
750         return 0;
751 }
752
753 int cmd_migrate(int argc, char *argv[])
754 {
755         struct format_opts format_opts = format_opts_default();
756         char *fs_path = NULL;
757         bool no_passphrase = false, force = false;
758         int opt;
759
760         struct bch_opt_strs fs_opt_strs =
761                 bch2_cmdline_opts_get(&argc, argv, OPT_FORMAT);
762         struct bch_opts fs_opts = bch2_parse_opts(fs_opt_strs);
763
764         while ((opt = getopt_long(argc, argv, "f:Fh",
765                                   migrate_opts, NULL)) != -1)
766                 switch (opt) {
767                 case 'f':
768                         fs_path = optarg;
769                         break;
770                 case 'e':
771                         format_opts.encrypted = true;
772                         break;
773                 case 'p':
774                         no_passphrase = true;
775                         break;
776                 case 'F':
777                         force = true;
778                         break;
779                 case 'h':
780                         migrate_usage();
781                         exit(EXIT_SUCCESS);
782                 }
783
784         if (!fs_path)
785                 die("Please specify a filesystem to migrate");
786
787         if (format_opts.encrypted && !no_passphrase)
788                 format_opts.passphrase = read_passphrase_twice("Enter passphrase: ");
789
790         int ret = migrate_fs(fs_path,
791                              fs_opt_strs,
792                              fs_opts,
793                              format_opts, force);
794         bch2_opt_strs_free(&fs_opt_strs);
795         return ret;
796 }
797
798 static void migrate_superblock_usage(void)
799 {
800         puts("bcachefs migrate-superblock - create default superblock after migrating\n"
801              "Usage: bcachefs migrate-superblock [OPTION]...\n"
802              "\n"
803              "Options:\n"
804              "  -d device     Device to create superblock for\n"
805              "  -o offset     Offset of existing superblock\n"
806              "  -h            Display this help and exit\n"
807              "Report bugs to <linux-bcachefs@vger.kernel.org>");
808 }
809
810 int cmd_migrate_superblock(int argc, char *argv[])
811 {
812         char *dev = NULL;
813         u64 offset = 0;
814         int opt, ret;
815
816         while ((opt = getopt(argc, argv, "d:o:h")) != -1)
817                 switch (opt) {
818                         case 'd':
819                                 dev = optarg;
820                                 break;
821                         case 'o':
822                                 ret = kstrtou64(optarg, 10, &offset);
823                                 if (ret)
824                                         die("Invalid offset");
825                                 break;
826                         case 'h':
827                                 migrate_superblock_usage();
828                                 exit(EXIT_SUCCESS);
829                 }
830
831         if (!dev)
832                 die("Please specify a device");
833
834         if (!offset)
835                 die("Please specify offset of existing superblock");
836
837         int fd = xopen(dev, O_RDWR);
838         struct bch_sb *sb = __bch2_super_read(fd, offset);
839
840         if (sb->layout.nr_superblocks >= ARRAY_SIZE(sb->layout.sb_offset))
841                 die("Can't add superblock: no space left in superblock layout");
842
843         unsigned i;
844         for (i = 0; i < sb->layout.nr_superblocks; i++)
845                 if (le64_to_cpu(sb->layout.sb_offset[i]) == BCH_SB_SECTOR)
846                         die("Superblock layout already has default superblock");
847
848         memmove(&sb->layout.sb_offset[1],
849                 &sb->layout.sb_offset[0],
850                 sb->layout.nr_superblocks * sizeof(u64));
851         sb->layout.nr_superblocks++;
852
853         sb->layout.sb_offset[0] = cpu_to_le64(BCH_SB_SECTOR);
854
855         bch2_super_write(fd, sb);
856         close(fd);
857
858         return 0;
859 }