1 #include </usr/include/dirent.h>
8 #include <sys/sysmacros.h>
12 #include <attr/xattr.h>
14 #include <linux/fiemap.h>
16 #include <linux/stat.h>
18 #include <uuid/uuid.h>
22 #include "libbcachefs.h"
24 #include <linux/dcache.h>
25 #include <linux/generic-radix-tree.h>
26 #include <linux/xattr.h>
27 #include "btree_update.h"
37 static char *dev_t_to_path(dev_t dev)
39 char link[PATH_MAX], *p;
42 char *sysfs_dev = mprintf("/sys/dev/block/%u:%u",
43 major(dev), minor(dev));
44 ret = readlink(sysfs_dev, link, sizeof(link));
47 if (ret < 0 || ret >= sizeof(link))
48 die("readlink error while looking up block device: %m");
52 p = strrchr(link, '/');
54 die("error looking up device name");
57 return mprintf("/dev/%s", p);
60 static bool path_is_fs_root(char *path)
62 char *line = NULL, *p, *mount;
67 f = fopen("/proc/self/mountinfo", "r");
69 die("Error getting mount information");
71 while (getline(&line, &n, f) != -1) {
74 strsep(&p, " "); /* mount id */
75 strsep(&p, " "); /* parent id */
76 strsep(&p, " "); /* dev */
77 strsep(&p, " "); /* root */
78 mount = strsep(&p, " ");
81 if (mount && !strcmp(path, mount))
92 static void mark_unreserved_space(struct bch_fs *c, ranges extents)
94 struct bch_dev *ca = c->devs[0];
95 struct hole_iter iter;
98 for_each_hole(iter, extents, bucket_to_sector(ca, ca->mi.nbuckets) << 9, i) {
99 struct bucket_mark new;
102 if (i.start == i.end)
105 b = sector_to_bucket(ca, i.start >> 9);
107 bucket_cmpxchg(&ca->buckets[b], new, new.nouse = 1);
109 } while (bucket_to_sector(ca, b) << 9 < i.end);
113 static void update_inode(struct bch_fs *c,
114 struct bch_inode_unpacked *inode)
116 struct bkey_inode_buf packed;
119 bch2_inode_pack(&packed, inode);
120 ret = bch2_btree_update(c, BTREE_ID_INODES, &packed.inode.k_i, NULL);
122 die("error creating file: %s", strerror(-ret));
125 static void create_dirent(struct bch_fs *c,
126 struct bch_inode_unpacked *parent,
127 const char *name, u64 inum, mode_t mode)
129 struct bch_hash_info parent_hash_info = bch2_hash_info_init(c, parent);
130 struct qstr qname = { { { .len = strlen(name), } }, .name = name };
132 int ret = bch2_dirent_create(c, parent->inum, &parent_hash_info,
133 mode_to_type(mode), &qname,
134 inum, NULL, BCH_HASH_SET_MUST_CREATE);
136 die("error creating file: %s", strerror(-ret));
142 static void create_link(struct bch_fs *c,
143 struct bch_inode_unpacked *parent,
144 const char *name, u64 inum, mode_t mode)
146 struct bch_inode_unpacked inode;
147 int ret = bch2_inode_find_by_inum(c, inum, &inode);
149 die("error looking up hardlink: %s", strerror(-ret));
152 update_inode(c, &inode);
154 create_dirent(c, parent, name, inum, mode);
157 static struct bch_inode_unpacked create_file(struct bch_fs *c,
158 struct bch_inode_unpacked *parent,
160 uid_t uid, gid_t gid,
161 mode_t mode, dev_t rdev)
163 struct bch_inode_unpacked new_inode;
164 struct bkey_inode_buf packed;
167 bch2_inode_init(c, &new_inode, uid, gid, mode, rdev);
168 bch2_inode_pack(&packed, &new_inode);
170 ret = bch2_inode_create(c, &packed.inode.k_i, BLOCKDEV_INODE_MAX, 0,
171 &c->unused_inode_hint);
173 die("error creating file: %s", strerror(-ret));
175 new_inode.inum = packed.inode.k.p.inode;
176 create_dirent(c, parent, name, new_inode.inum, mode);
181 #define for_each_xattr_handler(handlers, handler) \
183 for ((handler) = *(handlers)++; \
185 (handler) = *(handlers)++)
187 static const struct xattr_handler *xattr_resolve_name(const char **name)
189 const struct xattr_handler **handlers = bch2_xattr_handlers;
190 const struct xattr_handler *handler;
192 for_each_xattr_handler(handlers, handler) {
195 n = strcmp_prefix(*name, xattr_prefix(handler));
197 if (!handler->prefix ^ !*n) {
200 return ERR_PTR(-EINVAL);
206 return ERR_PTR(-EOPNOTSUPP);
209 static void copy_times(struct bch_fs *c, struct bch_inode_unpacked *dst,
212 dst->i_atime = timespec_to_bch2_time(c, src->st_atim);
213 dst->i_mtime = timespec_to_bch2_time(c, src->st_mtim);
214 dst->i_ctime = timespec_to_bch2_time(c, src->st_ctim);
217 static void copy_xattrs(struct bch_fs *c, struct bch_inode_unpacked *dst,
220 struct bch_hash_info hash_info = bch2_hash_info_init(c, dst);
222 char attrs[XATTR_LIST_MAX];
223 ssize_t attrs_size = llistxattr(src, attrs, sizeof(attrs));
225 die("listxattr error: %m");
227 for (const char *next, *attr = attrs;
228 attr < attrs + attrs_size;
230 next = attr + strlen(attr) + 1;
232 char val[XATTR_SIZE_MAX];
233 ssize_t val_size = lgetxattr(src, attr, val, sizeof(val));
236 die("error getting xattr val: %m");
238 const struct xattr_handler *h = xattr_resolve_name(&attr);
240 int ret = __bch2_xattr_set(c, dst->inum, &hash_info, attr,
241 val, val_size, 0, h->flags, NULL);
243 die("error creating xattr: %s", strerror(-ret));
247 static void write_data(struct bch_fs *c,
248 struct bch_inode_unpacked *dst_inode,
249 u64 dst_offset, void *buf, size_t len)
251 struct disk_reservation res;
252 struct bch_write_op op;
253 struct bch_write_bio bio;
257 BUG_ON(dst_offset & (block_bytes(c) - 1));
258 BUG_ON(len & (block_bytes(c) - 1));
260 closure_init_stack(&cl);
262 bio_init(&bio.bio, &bv, 1);
263 bio.bio.bi_iter.bi_size = len;
264 bch2_bio_map(&bio.bio, buf);
266 int ret = bch2_disk_reservation_get(c, &res, len >> 9, 0);
268 die("error reserving space in new filesystem: %s", strerror(-ret));
270 bch2_write_op_init(&op, c, &bio, res, c->write_points,
271 POS(dst_inode->inum, dst_offset >> 9), NULL, 0);
272 closure_call(&op.cl, bch2_write, NULL, &cl);
275 dst_inode->i_sectors += len >> 9;
278 static char buf[1 << 20] __aligned(PAGE_SIZE);
280 static void copy_data(struct bch_fs *c,
281 struct bch_inode_unpacked *dst_inode,
282 int src_fd, u64 start, u64 end)
284 while (start < end) {
285 unsigned len = min_t(u64, end - start, sizeof(buf));
287 xpread(src_fd, buf, len, start);
288 write_data(c, dst_inode, start, buf, len);
293 static void link_data(struct bch_fs *c, struct bch_inode_unpacked *dst,
294 u64 logical, u64 physical, u64 length)
296 struct bch_dev *ca = c->devs[0];
298 BUG_ON(logical & (block_bytes(c) - 1));
299 BUG_ON(physical & (block_bytes(c) - 1));
300 BUG_ON(length & (block_bytes(c) - 1));
306 BUG_ON(physical + length > bucket_to_sector(ca, ca->mi.nbuckets));
309 struct bkey_i_extent *e;
311 u64 b = sector_to_bucket(ca, physical >> 9);
312 struct disk_reservation res;
316 sectors = min(ca->mi.bucket_size -
317 (physical & (ca->mi.bucket_size - 1)),
320 e = bkey_extent_init(&k.k);
321 e->k.p.inode = dst->inum;
322 e->k.p.offset = logical + sectors;
324 extent_ptr_append(e, (struct bch_extent_ptr) {
327 .gen = ca->buckets[b].mark.gen,
330 ret = bch2_disk_reservation_get(c, &res, sectors,
331 BCH_DISK_RESERVATION_NOFAIL);
333 die("error reserving space in new filesystem: %s",
336 bch2_check_mark_super(c, extent_i_to_s_c(e), false);
338 ret = bch2_btree_insert(c, BTREE_ID_EXTENTS, &e->k_i,
339 &res, NULL, NULL, 0);
341 die("btree insert error %s", strerror(-ret));
343 bch2_disk_reservation_put(c, &res);
345 dst->i_sectors += sectors;
352 static void copy_link(struct bch_fs *c, struct bch_inode_unpacked *dst,
355 ssize_t ret = readlink(src, buf, sizeof(buf));
357 die("readlink error: %m");
359 write_data(c, dst, 0, buf, round_up(ret, block_bytes(c)));
362 static void copy_file(struct bch_fs *c, struct bch_inode_unpacked *dst,
363 int src, char *src_path, ranges *extents)
365 struct fiemap_iter iter;
366 struct fiemap_extent e;
368 fiemap_for_each(src, iter, e)
369 if (e.fe_flags & FIEMAP_EXTENT_UNKNOWN) {
374 fiemap_for_each(src, iter, e) {
375 if ((e.fe_logical & (block_bytes(c) - 1)) ||
376 (e.fe_length & (block_bytes(c) - 1)))
377 die("Unaligned extent in %s - can't handle", src_path);
379 if (e.fe_flags & (FIEMAP_EXTENT_UNKNOWN|
380 FIEMAP_EXTENT_ENCODED|
381 FIEMAP_EXTENT_NOT_ALIGNED|
382 FIEMAP_EXTENT_DATA_INLINE)) {
385 round_down(e.fe_logical, block_bytes(c)),
386 round_up(e.fe_logical + e.fe_length,
391 if (e.fe_physical < 1 << 20) {
394 round_down(e.fe_logical, block_bytes(c)),
395 round_up(e.fe_logical + e.fe_length,
400 if ((e.fe_physical & (block_bytes(c) - 1)))
401 die("Unaligned extent in %s - can't handle", src_path);
403 range_add(extents, e.fe_physical, e.fe_length);
404 link_data(c, dst, e.fe_logical, e.fe_physical, e.fe_length);
408 struct copy_fs_state {
412 GENRADIX(u64) hardlinks;
416 static void copy_dir(struct copy_fs_state *s,
418 struct bch_inode_unpacked *dst,
419 int src_fd, const char *src_path)
421 DIR *dir = fdopendir(src_fd);
424 while ((errno = 0), (d = readdir(dir))) {
425 struct bch_inode_unpacked inode;
429 die("chdir error: %m");
432 xfstatat(src_fd, d->d_name, AT_SYMLINK_NOFOLLOW);
434 if (!strcmp(d->d_name, ".") ||
435 !strcmp(d->d_name, "..") ||
436 stat.st_ino == s->bcachefs_inum)
439 char *child_path = mprintf("%s/%s", src_path, d->d_name);
441 if (stat.st_dev != s->dev)
442 die("%s does not have correct st_dev!", child_path);
444 u64 *dst_inum = S_ISREG(stat.st_mode)
445 ? genradix_ptr_alloc(&s->hardlinks, stat.st_ino, GFP_KERNEL)
448 if (dst_inum && *dst_inum) {
449 create_link(c, dst, d->d_name, *dst_inum, S_IFREG);
453 inode = create_file(c, dst, d->d_name,
454 stat.st_uid, stat.st_gid,
455 stat.st_mode, stat.st_rdev);
458 *dst_inum = inode.inum;
460 copy_times(c, &inode, &stat);
461 copy_xattrs(c, &inode, d->d_name);
465 switch (mode_to_type(stat.st_mode)) {
467 fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
468 copy_dir(s, c, &inode, fd, child_path);
472 inode.i_size = stat.st_size;
474 fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
475 copy_file(c, &inode, fd, child_path, &s->extents);
479 inode.i_size = stat.st_size;
481 copy_link(c, &inode, d->d_name);
488 /* nothing else to copy for these: */
494 update_inode(c, &inode);
500 die("readdir error: %m");
503 static ranges reserve_new_fs_space(const char *file_path, unsigned block_size,
504 u64 size, u64 *bcachefs_inum, dev_t dev,
508 ? open(file_path, O_RDWR|O_CREAT, 0600)
509 : open(file_path, O_RDWR|O_CREAT|O_EXCL, 0600);
511 die("Error creating %s for bcachefs metadata: %m",
514 struct stat statbuf = xfstat(fd);
516 if (statbuf.st_dev != dev)
517 die("bcachefs file has incorrect device");
519 *bcachefs_inum = statbuf.st_ino;
521 if (fallocate(fd, 0, 0, size))
522 die("Error reserving space for bcachefs metadata: %m");
526 struct fiemap_iter iter;
527 struct fiemap_extent e;
528 ranges extents = { NULL };
530 fiemap_for_each(fd, iter, e) {
531 if (e.fe_flags & (FIEMAP_EXTENT_UNKNOWN|
532 FIEMAP_EXTENT_ENCODED|
533 FIEMAP_EXTENT_NOT_ALIGNED|
534 FIEMAP_EXTENT_DATA_INLINE))
535 die("Unable to continue: metadata file not fully mapped");
537 if ((e.fe_physical & (block_size - 1)) ||
538 (e.fe_length & (block_size - 1)))
539 die("Unable to continue: unaligned extents in metadata file");
541 range_add(&extents, e.fe_physical, e.fe_length);
545 ranges_sort_merge(&extents);
549 static void reserve_old_fs_space(struct bch_fs *c,
550 struct bch_inode_unpacked *root_inode,
553 struct bch_dev *ca = c->devs[0];
554 struct bch_inode_unpacked dst;
555 struct hole_iter iter;
558 dst = create_file(c, root_inode, "old_migrated_filesystem",
559 0, 0, S_IFREG|0400, 0);
560 dst.i_size = bucket_to_sector(ca, ca->mi.nbuckets) << 9;
562 ranges_sort_merge(extents);
564 for_each_hole(iter, *extents, bucket_to_sector(ca, ca->mi.nbuckets) << 9, i)
565 link_data(c, &dst, i.start, i.start, i.end - i.start);
567 update_inode(c, &dst);
570 static void copy_fs(struct bch_fs *c, int src_fd, const char *src_path,
571 u64 bcachefs_inum, ranges *extents)
575 struct bch_inode_unpacked root_inode;
576 int ret = bch2_inode_find_by_inum(c, BCACHE_ROOT_INO, &root_inode);
578 die("error looking up root directory: %s", strerror(-ret));
581 die("chdir error: %m");
583 struct stat stat = xfstat(src_fd);
584 copy_times(c, &root_inode, &stat);
585 copy_xattrs(c, &root_inode, ".");
587 struct copy_fs_state s = {
588 .bcachefs_inum = bcachefs_inum,
594 copy_dir(&s, c, &root_inode, src_fd, src_path);
596 reserve_old_fs_space(c, &root_inode, &s.extents);
598 update_inode(c, &root_inode);
600 darray_free(s.extents);
601 genradix_free(&s.hardlinks);
604 static void find_superblock_space(ranges extents, struct dev_opts *dev)
608 darray_foreach(i, extents) {
609 u64 start = round_up(max(256ULL << 10, i->start),
610 dev->bucket_size << 9);
611 u64 end = round_down(i->end,
612 dev->bucket_size << 9);
614 if (start + (128 << 10) <= end) {
615 dev->sb_offset = start >> 9;
616 dev->sb_end = dev->sb_offset + 256;
621 die("Couldn't find a valid location for superblock");
624 static void migrate_usage(void)
626 puts("bcachefs migrate - migrate an existing filesystem to bcachefs\n"
627 "Usage: bcachefs migrate [OPTION]...\n"
630 " -f fs Root of filesystem to migrate(s)\n"
631 " --encrypted Enable whole filesystem encryption (chacha20/poly1305)\n"
632 " --no_passphrase Don't encrypt master encryption key\n"
633 " -F Force, even if metadata file already exists\n"
634 " -h Display this help and exit\n"
635 "Report bugs to <linux-bcache@vger.kernel.org>");
638 static const struct option migrate_opts[] = {
639 { "encrypted", no_argument, NULL, 'e' },
640 { "no_passphrase", no_argument, NULL, 'p' },
644 int cmd_migrate(int argc, char *argv[])
646 struct format_opts format_opts = format_opts_default();
647 char *fs_path = NULL;
649 bool no_passphrase = false, force = false;
652 while ((opt = getopt_long(argc, argv, "f:Fh",
653 migrate_opts, NULL)) != -1)
659 format_opts.encrypted = true;
662 no_passphrase = true;
673 die("Please specify a filesytem to migrate");
675 if (!path_is_fs_root(fs_path))
676 die("%s is not a filysestem root", fs_path);
678 int fs_fd = xopen(fs_path, O_RDONLY|O_NOATIME);
679 struct stat stat = xfstat(fs_fd);
681 if (!S_ISDIR(stat.st_mode))
682 die("%s is not a directory", fs_path);
684 struct dev_opts dev = { 0 };
686 dev.path = dev_t_to_path(stat.st_dev);
687 dev.fd = xopen(dev.path, O_RDWR);
689 block_size = min_t(unsigned, stat.st_blksize,
690 get_blocksize(dev.path, dev.fd) << 9);
692 BUG_ON(!is_power_of_2(block_size) || block_size < 512);
693 format_opts.block_size = block_size >> 9;
696 char *file_path = mprintf("%s/bcachefs", fs_path);
698 bch2_pick_bucket_size(format_opts, &dev);
700 ranges extents = reserve_new_fs_space(file_path,
701 block_size, get_size(dev.path, dev.fd) / 5,
702 &bcachefs_inum, stat.st_dev, force);
704 find_superblock_space(extents, &dev);
706 if (format_opts.encrypted && !no_passphrase) {
707 format_opts.passphrase = read_passphrase("Enter passphrase: ");
709 if (isatty(STDIN_FILENO)) {
711 read_passphrase("Enter same passphrase again: ");
713 if (strcmp(format_opts.passphrase, pass2)) {
714 memzero_explicit(format_opts.passphrase,
715 strlen(format_opts.passphrase));
716 memzero_explicit(pass2, strlen(pass2));
717 die("Passphrases do not match");
720 memzero_explicit(pass2, strlen(pass2));
725 struct bch_sb *sb = bch2_format(format_opts, &dev, 1);
726 u64 sb_offset = le64_to_cpu(sb->layout.sb_offset[0]);
728 if (format_opts.passphrase)
729 bch2_add_key(sb, format_opts.passphrase);
733 printf("Creating new filesystem on %s in space reserved at %s\n"
735 " mount -t bcachefs -o sb=%llu %s dir\n"
737 "After verifying that the new filesystem is correct, to create a\n"
738 "superblock at the default offset and finish the migration run\n"
739 " bcachefs migrate_superblock -d %s -o %llu\n"
741 "The new filesystem will have a file at /old_migrated_filestem\n"
742 "referencing all disk space that might be used by the existing\n"
743 "filesystem. That file can be deleted once the old filesystem is\n"
744 "no longer needed (and should be deleted prior to running\n"
745 "bcachefs migrate_superblock)\n",
746 dev.path, file_path, sb_offset, dev.path,
747 dev.path, sb_offset);
749 struct bch_opts opts = bch2_opts_empty();
750 struct bch_fs *c = NULL;
751 char *path[1] = { dev.path };
758 err = bch2_fs_open(path, 1, opts, &c);
760 die("Error opening new filesystem: %s", err);
762 mark_unreserved_space(c, extents);
764 err = bch2_fs_start(c);
766 die("Error starting new filesystem: %s", err);
768 copy_fs(c, fs_fd, fs_path, bcachefs_inum, &extents);
772 printf("Migrate complete, running fsck:\n");
773 opts.nostart = false;
774 opts.nochanges = true;
776 err = bch2_fs_open(path, 1, opts, &c);
778 die("Error opening new filesystem: %s", err);
781 printf("fsck complete\n");
785 static void migrate_superblock_usage(void)
787 puts("bcachefs migrate_superblock - create default superblock after migrating\n"
788 "Usage: bcachefs migrate_superblock [OPTION]...\n"
791 " -d device Device to create superblock for\n"
792 " -o offset Offset of existing superblock\n"
793 " -h Display this help and exit\n"
794 "Report bugs to <linux-bcache@vger.kernel.org>");
797 int cmd_migrate_superblock(int argc, char *argv[])
803 while ((opt = getopt(argc, argv, "d:o:h")) != -1)
809 ret = kstrtou64(optarg, 10, &offset);
811 die("Invalid offset");
814 migrate_superblock_usage();
819 die("Please specify a device");
822 die("Please specify offset of existing superblock");
824 int fd = xopen(dev, O_RDWR);
825 struct bch_sb *sb = __bch2_super_read(fd, offset);
827 if (sb->layout.nr_superblocks >= ARRAY_SIZE(sb->layout.sb_offset))
828 die("Can't add superblock: no space left in superblock layout");
830 for (unsigned i = 0; i < sb->layout.nr_superblocks; i++)
831 if (le64_to_cpu(sb->layout.sb_offset[i]) == BCH_SB_SECTOR)
832 die("Superblock layout already has default superblock");
834 memmove(&sb->layout.sb_offset[1],
835 &sb->layout.sb_offset[0],
836 sb->layout.nr_superblocks * sizeof(u64));
837 sb->layout.nr_superblocks++;
839 sb->layout.sb_offset[0] = cpu_to_le64(BCH_SB_SECTOR);
841 bch2_super_write(fd, sb);