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>
28 #include "btree_update.h"
38 static char *dev_t_to_path(dev_t dev)
40 char link[PATH_MAX], *p;
43 char *sysfs_dev = mprintf("/sys/dev/block/%u:%u",
44 major(dev), minor(dev));
45 ret = readlink(sysfs_dev, link, sizeof(link));
48 if (ret < 0 || ret >= sizeof(link))
49 die("readlink error while looking up block device: %m");
53 p = strrchr(link, '/');
55 die("error looking up device name");
58 return mprintf("/dev/%s", p);
61 static bool path_is_fs_root(char *path)
63 char *line = NULL, *p, *mount;
68 f = fopen("/proc/self/mountinfo", "r");
70 die("Error getting mount information");
72 while (getline(&line, &n, f) != -1) {
75 strsep(&p, " "); /* mount id */
76 strsep(&p, " "); /* parent id */
77 strsep(&p, " "); /* dev */
78 strsep(&p, " "); /* root */
79 mount = strsep(&p, " ");
82 if (mount && !strcmp(path, mount))
93 static void mark_unreserved_space(struct bch_fs *c, ranges extents)
95 struct bch_dev *ca = c->devs[0];
96 struct hole_iter iter;
99 for_each_hole(iter, extents, bucket_to_sector(ca, ca->mi.nbuckets) << 9, i) {
100 struct bucket_mark new;
103 if (i.start == i.end)
106 b = sector_to_bucket(ca, i.start >> 9);
108 bucket_cmpxchg(&ca->buckets[b], new, new.nouse = 1);
110 } while (bucket_to_sector(ca, b) << 9 < i.end);
114 static void update_inode(struct bch_fs *c,
115 struct bch_inode_unpacked *inode)
117 struct bkey_inode_buf packed;
120 bch2_inode_pack(&packed, inode);
121 ret = bch2_btree_update(c, BTREE_ID_INODES, &packed.inode.k_i, NULL);
123 die("error creating file: %s", strerror(-ret));
126 static void create_dirent(struct bch_fs *c,
127 struct bch_inode_unpacked *parent,
128 const char *name, u64 inum, mode_t mode)
130 struct bch_hash_info parent_hash_info = bch2_hash_info_init(c, parent);
131 struct qstr qname = { { { .len = strlen(name), } }, .name = name };
133 int ret = bch2_dirent_create(c, parent->inum, &parent_hash_info,
134 mode_to_type(mode), &qname,
135 inum, NULL, BCH_HASH_SET_MUST_CREATE);
137 die("error creating file: %s", strerror(-ret));
143 static void create_link(struct bch_fs *c,
144 struct bch_inode_unpacked *parent,
145 const char *name, u64 inum, mode_t mode)
147 struct bch_inode_unpacked inode;
148 int ret = bch2_inode_find_by_inum(c, inum, &inode);
150 die("error looking up hardlink: %s", strerror(-ret));
153 update_inode(c, &inode);
155 create_dirent(c, parent, name, inum, mode);
158 static struct bch_inode_unpacked create_file(struct bch_fs *c,
159 struct bch_inode_unpacked *parent,
161 uid_t uid, gid_t gid,
162 mode_t mode, dev_t rdev)
164 struct bch_inode_unpacked new_inode;
165 struct bkey_inode_buf packed;
168 bch2_inode_init(c, &new_inode, uid, gid, mode, rdev);
169 bch2_inode_pack(&packed, &new_inode);
171 ret = bch2_inode_create(c, &packed.inode.k_i, BLOCKDEV_INODE_MAX, 0,
172 &c->unused_inode_hint);
174 die("error creating file: %s", strerror(-ret));
176 new_inode.inum = packed.inode.k.p.inode;
177 create_dirent(c, parent, name, new_inode.inum, mode);
182 #define for_each_xattr_handler(handlers, handler) \
184 for ((handler) = *(handlers)++; \
186 (handler) = *(handlers)++)
188 static const struct xattr_handler *xattr_resolve_name(const char **name)
190 const struct xattr_handler **handlers = bch2_xattr_handlers;
191 const struct xattr_handler *handler;
193 for_each_xattr_handler(handlers, handler) {
196 n = strcmp_prefix(*name, xattr_prefix(handler));
198 if (!handler->prefix ^ !*n) {
201 return ERR_PTR(-EINVAL);
207 return ERR_PTR(-EOPNOTSUPP);
210 static void copy_times(struct bch_fs *c, struct bch_inode_unpacked *dst,
213 dst->i_atime = timespec_to_bch2_time(c, src->st_atim);
214 dst->i_mtime = timespec_to_bch2_time(c, src->st_mtim);
215 dst->i_ctime = timespec_to_bch2_time(c, src->st_ctim);
218 static void copy_xattrs(struct bch_fs *c, struct bch_inode_unpacked *dst,
221 struct bch_hash_info hash_info = bch2_hash_info_init(c, dst);
223 char attrs[XATTR_LIST_MAX];
224 ssize_t attrs_size = llistxattr(src, attrs, sizeof(attrs));
226 die("listxattr error: %m");
228 const char *next, *attr;
230 attr < attrs + attrs_size;
232 next = attr + strlen(attr) + 1;
234 char val[XATTR_SIZE_MAX];
235 ssize_t val_size = lgetxattr(src, attr, val, sizeof(val));
238 die("error getting xattr val: %m");
240 const struct xattr_handler *h = xattr_resolve_name(&attr);
242 int ret = __bch2_xattr_set(c, dst->inum, &hash_info, attr,
243 val, val_size, 0, h->flags, NULL);
245 die("error creating xattr: %s", strerror(-ret));
249 static void write_data(struct bch_fs *c,
250 struct bch_inode_unpacked *dst_inode,
251 u64 dst_offset, void *buf, size_t len)
253 struct disk_reservation res;
254 struct bch_write_op op;
258 BUG_ON(dst_offset & (block_bytes(c) - 1));
259 BUG_ON(len & (block_bytes(c) - 1));
261 closure_init_stack(&cl);
263 bio_init(&op.wbio.bio, &bv, 1);
264 op.wbio.bio.bi_iter.bi_size = len;
265 bch2_bio_map(&op.wbio.bio, buf);
267 int ret = bch2_disk_reservation_get(c, &res, len >> 9, 0);
269 die("error reserving space in new filesystem: %s", strerror(-ret));
271 bch2_write_op_init(&op, c, res, c->write_points,
272 POS(dst_inode->inum, dst_offset >> 9), NULL, 0);
273 closure_call(&op.cl, bch2_write, NULL, &cl);
276 dst_inode->i_sectors += len >> 9;
279 static char buf[1 << 20] __aligned(PAGE_SIZE);
281 static void copy_data(struct bch_fs *c,
282 struct bch_inode_unpacked *dst_inode,
283 int src_fd, u64 start, u64 end)
285 while (start < end) {
286 unsigned len = min_t(u64, end - start, sizeof(buf));
288 xpread(src_fd, buf, len, start);
289 write_data(c, dst_inode, start, buf, len);
294 static void link_data(struct bch_fs *c, struct bch_inode_unpacked *dst,
295 u64 logical, u64 physical, u64 length)
297 struct bch_dev *ca = c->devs[0];
299 BUG_ON(logical & (block_bytes(c) - 1));
300 BUG_ON(physical & (block_bytes(c) - 1));
301 BUG_ON(length & (block_bytes(c) - 1));
307 BUG_ON(physical + length > bucket_to_sector(ca, ca->mi.nbuckets));
310 struct bkey_i_extent *e;
312 u64 b = sector_to_bucket(ca, physical >> 9);
313 struct disk_reservation res;
317 sectors = min(ca->mi.bucket_size -
318 (physical & (ca->mi.bucket_size - 1)),
321 e = bkey_extent_init(&k.k);
322 e->k.p.inode = dst->inum;
323 e->k.p.offset = logical + sectors;
325 extent_ptr_append(e, (struct bch_extent_ptr) {
328 .gen = ca->buckets[b].mark.gen,
331 ret = bch2_disk_reservation_get(c, &res, sectors,
332 BCH_DISK_RESERVATION_NOFAIL);
334 die("error reserving space in new filesystem: %s",
337 bch2_check_mark_super(c, extent_i_to_s_c(e), false);
339 ret = bch2_btree_insert(c, BTREE_ID_EXTENTS, &e->k_i,
340 &res, NULL, NULL, 0);
342 die("btree insert error %s", strerror(-ret));
344 bch2_disk_reservation_put(c, &res);
346 dst->i_sectors += sectors;
353 static void copy_link(struct bch_fs *c, struct bch_inode_unpacked *dst,
356 ssize_t ret = readlink(src, buf, sizeof(buf));
358 die("readlink error: %m");
360 write_data(c, dst, 0, buf, round_up(ret, block_bytes(c)));
363 static void copy_file(struct bch_fs *c, struct bch_inode_unpacked *dst,
364 int src, char *src_path, ranges *extents)
366 struct fiemap_iter iter;
367 struct fiemap_extent e;
369 fiemap_for_each(src, iter, e)
370 if (e.fe_flags & FIEMAP_EXTENT_UNKNOWN) {
375 fiemap_for_each(src, iter, e) {
376 if ((e.fe_logical & (block_bytes(c) - 1)) ||
377 (e.fe_length & (block_bytes(c) - 1)))
378 die("Unaligned extent in %s - can't handle", src_path);
380 if (e.fe_flags & (FIEMAP_EXTENT_UNKNOWN|
381 FIEMAP_EXTENT_ENCODED|
382 FIEMAP_EXTENT_NOT_ALIGNED|
383 FIEMAP_EXTENT_DATA_INLINE)) {
386 round_down(e.fe_logical, block_bytes(c)),
387 round_up(e.fe_logical + e.fe_length,
392 if (e.fe_physical < 1 << 20) {
395 round_down(e.fe_logical, block_bytes(c)),
396 round_up(e.fe_logical + e.fe_length,
401 if ((e.fe_physical & (block_bytes(c) - 1)))
402 die("Unaligned extent in %s - can't handle", src_path);
404 range_add(extents, e.fe_physical, e.fe_length);
405 link_data(c, dst, e.fe_logical, e.fe_physical, e.fe_length);
409 struct copy_fs_state {
413 GENRADIX(u64) hardlinks;
417 static void copy_dir(struct copy_fs_state *s,
419 struct bch_inode_unpacked *dst,
420 int src_fd, const char *src_path)
422 DIR *dir = fdopendir(src_fd);
425 while ((errno = 0), (d = readdir(dir))) {
426 struct bch_inode_unpacked inode;
430 die("chdir error: %m");
433 xfstatat(src_fd, d->d_name, AT_SYMLINK_NOFOLLOW);
435 if (!strcmp(d->d_name, ".") ||
436 !strcmp(d->d_name, "..") ||
437 stat.st_ino == s->bcachefs_inum)
440 char *child_path = mprintf("%s/%s", src_path, d->d_name);
442 if (stat.st_dev != s->dev)
443 die("%s does not have correct st_dev!", child_path);
445 u64 *dst_inum = S_ISREG(stat.st_mode)
446 ? genradix_ptr_alloc(&s->hardlinks, stat.st_ino, GFP_KERNEL)
449 if (dst_inum && *dst_inum) {
450 create_link(c, dst, d->d_name, *dst_inum, S_IFREG);
454 inode = create_file(c, dst, d->d_name,
455 stat.st_uid, stat.st_gid,
456 stat.st_mode, stat.st_rdev);
459 *dst_inum = inode.inum;
461 copy_times(c, &inode, &stat);
462 copy_xattrs(c, &inode, d->d_name);
466 switch (mode_to_type(stat.st_mode)) {
468 fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
469 copy_dir(s, c, &inode, fd, child_path);
473 inode.i_size = stat.st_size;
475 fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
476 copy_file(c, &inode, fd, child_path, &s->extents);
480 inode.i_size = stat.st_size;
482 copy_link(c, &inode, d->d_name);
489 /* nothing else to copy for these: */
495 update_inode(c, &inode);
501 die("readdir error: %m");
504 static ranges reserve_new_fs_space(const char *file_path, unsigned block_size,
505 u64 size, u64 *bcachefs_inum, dev_t dev,
509 ? open(file_path, O_RDWR|O_CREAT, 0600)
510 : open(file_path, O_RDWR|O_CREAT|O_EXCL, 0600);
512 die("Error creating %s for bcachefs metadata: %m",
515 struct stat statbuf = xfstat(fd);
517 if (statbuf.st_dev != dev)
518 die("bcachefs file has incorrect device");
520 *bcachefs_inum = statbuf.st_ino;
522 if (fallocate(fd, 0, 0, size))
523 die("Error reserving space for bcachefs metadata: %m");
527 struct fiemap_iter iter;
528 struct fiemap_extent e;
529 ranges extents = { NULL };
531 fiemap_for_each(fd, iter, e) {
532 if (e.fe_flags & (FIEMAP_EXTENT_UNKNOWN|
533 FIEMAP_EXTENT_ENCODED|
534 FIEMAP_EXTENT_NOT_ALIGNED|
535 FIEMAP_EXTENT_DATA_INLINE))
536 die("Unable to continue: metadata file not fully mapped");
538 if ((e.fe_physical & (block_size - 1)) ||
539 (e.fe_length & (block_size - 1)))
540 die("Unable to continue: unaligned extents in metadata file");
542 range_add(&extents, e.fe_physical, e.fe_length);
546 ranges_sort_merge(&extents);
550 static void reserve_old_fs_space(struct bch_fs *c,
551 struct bch_inode_unpacked *root_inode,
554 struct bch_dev *ca = c->devs[0];
555 struct bch_inode_unpacked dst;
556 struct hole_iter iter;
559 dst = create_file(c, root_inode, "old_migrated_filesystem",
560 0, 0, S_IFREG|0400, 0);
561 dst.i_size = bucket_to_sector(ca, ca->mi.nbuckets) << 9;
563 ranges_sort_merge(extents);
565 for_each_hole(iter, *extents, bucket_to_sector(ca, ca->mi.nbuckets) << 9, i)
566 link_data(c, &dst, i.start, i.start, i.end - i.start);
568 update_inode(c, &dst);
571 static void copy_fs(struct bch_fs *c, int src_fd, const char *src_path,
572 u64 bcachefs_inum, ranges *extents)
576 struct bch_inode_unpacked root_inode;
577 int ret = bch2_inode_find_by_inum(c, BCACHE_ROOT_INO, &root_inode);
579 die("error looking up root directory: %s", strerror(-ret));
582 die("chdir error: %m");
584 struct stat stat = xfstat(src_fd);
585 copy_times(c, &root_inode, &stat);
586 copy_xattrs(c, &root_inode, ".");
588 struct copy_fs_state s = {
589 .bcachefs_inum = bcachefs_inum,
595 copy_dir(&s, c, &root_inode, src_fd, src_path);
597 reserve_old_fs_space(c, &root_inode, &s.extents);
599 update_inode(c, &root_inode);
601 darray_free(s.extents);
602 genradix_free(&s.hardlinks);
605 static void find_superblock_space(ranges extents, struct dev_opts *dev)
609 darray_foreach(i, extents) {
610 u64 start = round_up(max(256ULL << 10, i->start),
611 dev->bucket_size << 9);
612 u64 end = round_down(i->end,
613 dev->bucket_size << 9);
615 if (start + (128 << 10) <= end) {
616 dev->sb_offset = start >> 9;
617 dev->sb_end = dev->sb_offset + 256;
622 die("Couldn't find a valid location for superblock");
625 static void migrate_usage(void)
627 puts("bcachefs migrate - migrate an existing filesystem to bcachefs\n"
628 "Usage: bcachefs migrate [OPTION]...\n"
631 " -f fs Root of filesystem to migrate(s)\n"
632 " --encrypted Enable whole filesystem encryption (chacha20/poly1305)\n"
633 " --no_passphrase Don't encrypt master encryption key\n"
634 " -F Force, even if metadata file already exists\n"
635 " -h Display this help and exit\n"
636 "Report bugs to <linux-bcache@vger.kernel.org>");
639 static const struct option migrate_opts[] = {
640 { "encrypted", no_argument, NULL, 'e' },
641 { "no_passphrase", no_argument, NULL, 'p' },
645 int cmd_migrate(int argc, char *argv[])
647 struct format_opts format_opts = format_opts_default();
648 char *fs_path = NULL;
650 bool no_passphrase = false, force = false;
653 while ((opt = getopt_long(argc, argv, "f:Fh",
654 migrate_opts, NULL)) != -1)
660 format_opts.encrypted = true;
663 no_passphrase = true;
674 die("Please specify a filesytem to migrate");
676 if (!path_is_fs_root(fs_path))
677 die("%s is not a filysestem root", fs_path);
679 int fs_fd = xopen(fs_path, O_RDONLY|O_NOATIME);
680 struct stat stat = xfstat(fs_fd);
682 if (!S_ISDIR(stat.st_mode))
683 die("%s is not a directory", fs_path);
685 struct dev_opts dev = { 0 };
687 dev.path = dev_t_to_path(stat.st_dev);
688 dev.fd = xopen(dev.path, O_RDWR);
690 block_size = min_t(unsigned, stat.st_blksize,
691 get_blocksize(dev.path, dev.fd) << 9);
693 BUG_ON(!is_power_of_2(block_size) || block_size < 512);
694 format_opts.block_size = block_size >> 9;
697 char *file_path = mprintf("%s/bcachefs", fs_path);
699 bch2_pick_bucket_size(format_opts, &dev);
701 ranges extents = reserve_new_fs_space(file_path,
702 block_size, get_size(dev.path, dev.fd) / 5,
703 &bcachefs_inum, stat.st_dev, force);
705 find_superblock_space(extents, &dev);
707 if (format_opts.encrypted && !no_passphrase) {
708 format_opts.passphrase = read_passphrase("Enter passphrase: ");
710 if (isatty(STDIN_FILENO)) {
712 read_passphrase("Enter same passphrase again: ");
714 if (strcmp(format_opts.passphrase, pass2)) {
715 memzero_explicit(format_opts.passphrase,
716 strlen(format_opts.passphrase));
717 memzero_explicit(pass2, strlen(pass2));
718 die("Passphrases do not match");
721 memzero_explicit(pass2, strlen(pass2));
726 struct bch_sb *sb = bch2_format(format_opts, &dev, 1);
727 u64 sb_offset = le64_to_cpu(sb->layout.sb_offset[0]);
729 if (format_opts.passphrase)
730 bch2_add_key(sb, format_opts.passphrase);
734 printf("Creating new filesystem on %s in space reserved at %s\n"
736 " mount -t bcachefs -o sb=%llu %s dir\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"
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 dev.path, file_path, sb_offset, dev.path,
748 dev.path, sb_offset);
750 struct bch_opts opts = bch2_opts_empty();
751 struct bch_fs *c = NULL;
752 char *path[1] = { dev.path };
759 err = bch2_fs_open(path, 1, opts, &c);
761 die("Error opening new filesystem: %s", err);
763 mark_unreserved_space(c, extents);
765 err = bch2_fs_start(c);
767 die("Error starting new filesystem: %s", err);
769 copy_fs(c, fs_fd, fs_path, bcachefs_inum, &extents);
773 printf("Migrate complete, running fsck:\n");
774 opts.nostart = false;
775 opts.nochanges = true;
777 err = bch2_fs_open(path, 1, opts, &c);
779 die("Error opening new filesystem: %s", err);
782 printf("fsck complete\n");
786 static void migrate_superblock_usage(void)
788 puts("bcachefs migrate_superblock - create default superblock after migrating\n"
789 "Usage: bcachefs migrate_superblock [OPTION]...\n"
792 " -d device Device to create superblock for\n"
793 " -o offset Offset of existing superblock\n"
794 " -h Display this help and exit\n"
795 "Report bugs to <linux-bcache@vger.kernel.org>");
798 int cmd_migrate_superblock(int argc, char *argv[])
804 while ((opt = getopt(argc, argv, "d:o:h")) != -1)
810 ret = kstrtou64(optarg, 10, &offset);
812 die("Invalid offset");
815 migrate_superblock_usage();
820 die("Please specify a device");
823 die("Please specify offset of existing superblock");
825 int fd = xopen(dev, O_RDWR);
826 struct bch_sb *sb = __bch2_super_read(fd, offset);
828 if (sb->layout.nr_superblocks >= ARRAY_SIZE(sb->layout.sb_offset))
829 die("Can't add superblock: no space left in superblock layout");
832 for (i = 0; i < sb->layout.nr_superblocks; i++)
833 if (le64_to_cpu(sb->layout.sb_offset[i]) == BCH_SB_SECTOR)
834 die("Superblock layout already has default superblock");
836 memmove(&sb->layout.sb_offset[1],
837 &sb->layout.sb_offset[0],
838 sb->layout.nr_superblocks * sizeof(u64));
839 sb->layout.nr_superblocks++;
841 sb->layout.sb_offset[0] = cpu_to_le64(BCH_SB_SECTOR);
843 bch2_super_write(fd, sb);