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