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