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