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: %s", strerror(errno));
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: %s", strerror(errno));
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: %s", strerror(errno));
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);
263 bio.bio.bi_max_vecs = 1;
264 bio.bio.bi_io_vec = &bv;
265 bio.bio.bi_iter.bi_size = len;
266 bch2_bio_map(&bio.bio, buf);
268 int ret = bch2_disk_reservation_get(c, &res, len >> 9, 0);
270 die("error reserving space in new filesystem: %s", strerror(-ret));
272 bch2_write_op_init(&op, c, &bio, res, c->write_points,
273 POS(dst_inode->inum, dst_offset >> 9), NULL, 0);
274 closure_call(&op.cl, bch2_write, NULL, &cl);
277 dst_inode->i_sectors += len >> 9;
280 static char buf[1 << 20] __aligned(PAGE_SIZE);
282 static void copy_data(struct bch_fs *c,
283 struct bch_inode_unpacked *dst_inode,
284 int src_fd, u64 start, u64 end)
286 while (start < end) {
287 unsigned len = min_t(u64, end - start, sizeof(buf));
289 xpread(src_fd, buf, len, start);
290 write_data(c, dst_inode, start, buf, len);
295 static void link_data(struct bch_fs *c, struct bch_inode_unpacked *dst,
296 u64 logical, u64 physical, u64 length)
298 struct bch_dev *ca = c->devs[0];
300 BUG_ON(logical & (block_bytes(c) - 1));
301 BUG_ON(physical & (block_bytes(c) - 1));
302 BUG_ON(length & (block_bytes(c) - 1));
308 BUG_ON(physical + length > bucket_to_sector(ca, ca->mi.nbuckets));
311 struct bkey_i_extent *e;
313 u64 b = sector_to_bucket(ca, physical >> 9);
314 struct disk_reservation res;
318 sectors = min(ca->mi.bucket_size -
319 (physical & (ca->mi.bucket_size - 1)),
322 e = bkey_extent_init(&k.k);
323 e->k.p.inode = dst->inum;
324 e->k.p.offset = logical + sectors;
326 extent_ptr_append(e, (struct bch_extent_ptr) {
329 .gen = ca->buckets[b].mark.gen,
332 ret = bch2_disk_reservation_get(c, &res, sectors,
333 BCH_DISK_RESERVATION_NOFAIL);
335 die("error reserving space in new filesystem: %s",
338 bch2_check_mark_super(c, &e->k_i, false);
340 ret = bch2_btree_insert(c, BTREE_ID_EXTENTS, &e->k_i,
341 &res, NULL, NULL, 0);
343 die("btree insert error %s", strerror(-ret));
345 bch2_disk_reservation_put(c, &res);
347 dst->i_sectors += sectors;
354 static void copy_link(struct bch_fs *c, struct bch_inode_unpacked *dst,
357 ssize_t ret = readlink(src, buf, sizeof(buf));
359 die("readlink error: %s", strerror(errno));
361 write_data(c, dst, 0, buf, round_up(ret, block_bytes(c)));
364 static void copy_file(struct bch_fs *c, struct bch_inode_unpacked *dst,
365 int src, char *src_path, ranges *extents)
367 struct fiemap_iter iter;
368 struct fiemap_extent e;
370 fiemap_for_each(src, iter, e)
371 if (e.fe_flags & FIEMAP_EXTENT_UNKNOWN) {
376 fiemap_for_each(src, iter, e) {
377 if ((e.fe_logical & (block_bytes(c) - 1)) ||
378 (e.fe_length & (block_bytes(c) - 1)))
379 die("Unaligned extent in %s - can't handle", src_path);
381 if (e.fe_flags & (FIEMAP_EXTENT_UNKNOWN|
382 FIEMAP_EXTENT_ENCODED|
383 FIEMAP_EXTENT_NOT_ALIGNED|
384 FIEMAP_EXTENT_DATA_INLINE)) {
387 round_down(e.fe_logical, block_bytes(c)),
388 round_up(e.fe_logical + e.fe_length,
393 if (e.fe_physical < 1 << 20) {
396 round_down(e.fe_logical, block_bytes(c)),
397 round_up(e.fe_logical + e.fe_length,
402 if ((e.fe_physical & (block_bytes(c) - 1)))
403 die("Unaligned extent in %s - can't handle", src_path);
405 range_add(extents, e.fe_physical, e.fe_length);
406 link_data(c, dst, e.fe_logical, e.fe_physical, e.fe_length);
410 struct copy_fs_state {
414 GENRADIX(u64) hardlinks;
418 static void copy_dir(struct copy_fs_state *s,
420 struct bch_inode_unpacked *dst,
421 int src_fd, const char *src_path)
423 DIR *dir = fdopendir(src_fd);
426 while ((errno = 0), (d = readdir(dir))) {
427 struct bch_inode_unpacked inode;
431 die("chdir error: %s", strerror(errno));
434 xfstatat(src_fd, d->d_name, AT_SYMLINK_NOFOLLOW);
436 if (!strcmp(d->d_name, ".") ||
437 !strcmp(d->d_name, "..") ||
438 stat.st_ino == s->bcachefs_inum)
441 char *child_path = mprintf("%s/%s", src_path, d->d_name);
443 if (stat.st_dev != s->dev)
444 die("%s does not have correct st_dev!", child_path);
446 u64 *dst_inum = S_ISREG(stat.st_mode)
447 ? genradix_ptr_alloc(&s->hardlinks, stat.st_ino, GFP_KERNEL)
450 if (dst_inum && *dst_inum) {
451 create_link(c, dst, d->d_name, *dst_inum, S_IFREG);
455 inode = create_file(c, dst, d->d_name,
456 stat.st_uid, stat.st_gid,
457 stat.st_mode, stat.st_rdev);
460 *dst_inum = inode.inum;
462 copy_times(c, &inode, &stat);
463 copy_xattrs(c, &inode, d->d_name);
467 switch (mode_to_type(stat.st_mode)) {
469 fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
470 copy_dir(s, c, &inode, fd, child_path);
474 inode.i_size = stat.st_size;
476 fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
477 copy_file(c, &inode, fd, child_path, &s->extents);
481 inode.i_size = stat.st_size;
483 copy_link(c, &inode, d->d_name);
490 /* nothing else to copy for these: */
496 update_inode(c, &inode);
502 die("readdir error: %s", strerror(errno));
505 static ranges reserve_new_fs_space(const char *file_path, unsigned block_size,
506 u64 size, u64 *bcachefs_inum, dev_t dev,
510 ? open(file_path, O_RDWR|O_CREAT, 0600)
511 : open(file_path, O_RDWR|O_CREAT|O_EXCL, 0600);
513 die("Error creating %s for bcachefs metadata: %s",
514 file_path, strerror(errno));
516 struct stat statbuf = xfstat(fd);
518 if (statbuf.st_dev != dev)
519 die("bcachefs file has incorrect device");
521 *bcachefs_inum = statbuf.st_ino;
523 if (fallocate(fd, 0, 0, size))
524 die("Error reserving space for bcachefs metadata: %s",
529 struct fiemap_iter iter;
530 struct fiemap_extent e;
531 ranges extents = { NULL };
533 fiemap_for_each(fd, iter, e) {
534 if (e.fe_flags & (FIEMAP_EXTENT_UNKNOWN|
535 FIEMAP_EXTENT_ENCODED|
536 FIEMAP_EXTENT_NOT_ALIGNED|
537 FIEMAP_EXTENT_DATA_INLINE))
538 die("Unable to continue: metadata file not fully mapped");
540 if ((e.fe_physical & (block_size - 1)) ||
541 (e.fe_length & (block_size - 1)))
542 die("Unable to continue: unaligned extents in metadata file");
544 range_add(&extents, e.fe_physical, e.fe_length);
548 ranges_sort_merge(&extents);
552 static void reserve_old_fs_space(struct bch_fs *c,
553 struct bch_inode_unpacked *root_inode,
556 struct bch_dev *ca = c->devs[0];
557 struct bch_inode_unpacked dst;
558 struct hole_iter iter;
561 dst = create_file(c, root_inode, "old_migrated_filesystem",
562 0, 0, S_IFREG|0400, 0);
563 dst.i_size = bucket_to_sector(ca, ca->mi.nbuckets) << 9;
565 ranges_sort_merge(extents);
567 for_each_hole(iter, *extents, bucket_to_sector(ca, ca->mi.nbuckets) << 9, i)
568 link_data(c, &dst, i.start, i.start, i.end - i.start);
570 update_inode(c, &dst);
573 static void copy_fs(struct bch_fs *c, int src_fd, const char *src_path,
574 u64 bcachefs_inum, ranges *extents)
578 struct bch_inode_unpacked root_inode;
579 int ret = bch2_inode_find_by_inum(c, BCACHE_ROOT_INO, &root_inode);
581 die("error looking up root directory: %s", strerror(-ret));
584 die("chdir error: %s", strerror(errno));
586 struct stat stat = xfstat(src_fd);
587 copy_times(c, &root_inode, &stat);
588 copy_xattrs(c, &root_inode, ".");
590 struct copy_fs_state s = {
591 .bcachefs_inum = bcachefs_inum,
597 copy_dir(&s, c, &root_inode, src_fd, src_path);
599 reserve_old_fs_space(c, &root_inode, &s.extents);
601 update_inode(c, &root_inode);
603 darray_free(s.extents);
604 genradix_free(&s.hardlinks);
607 static void find_superblock_space(ranges extents, struct dev_opts *dev)
611 darray_foreach(i, extents) {
612 u64 start = round_up(max(256ULL << 10, i->start),
613 dev->bucket_size << 9);
614 u64 end = round_down(i->end,
615 dev->bucket_size << 9);
617 if (start + (128 << 10) <= end) {
618 dev->sb_offset = start >> 9;
619 dev->sb_end = dev->sb_offset + 256;
624 die("Couldn't find a valid location for superblock");
627 static void migrate_usage(void)
629 puts("bcachefs migrate - migrate an existing filesystem to bcachefs\n"
630 "Usage: bcachefs migrate [OPTION]...\n"
633 " -f fs Root of filesystem to migrate(s)\n"
634 " --encrypted Enable whole filesystem encryption (chacha20/poly1305)\n"
635 " --no_passphrase Don't encrypt master encryption key\n"
636 " -F Force, even if metadata file already exists\n"
637 " -h Display this help and exit\n"
638 "Report bugs to <linux-bcache@vger.kernel.org>");
641 static const struct option migrate_opts[] = {
642 { "encrypted", no_argument, NULL, 'e' },
643 { "no_passphrase", no_argument, NULL, 'p' },
647 int cmd_migrate(int argc, char *argv[])
649 struct format_opts format_opts = format_opts_default();
650 char *fs_path = NULL;
652 bool no_passphrase = false, force = false;
655 while ((opt = getopt_long(argc, argv, "f:Fh",
656 migrate_opts, NULL)) != -1)
662 format_opts.encrypted = true;
665 no_passphrase = true;
676 die("Please specify a filesytem to migrate");
678 if (!path_is_fs_root(fs_path))
679 die("%s is not a filysestem root", fs_path);
681 int fs_fd = xopen(fs_path, O_RDONLY|O_NOATIME);
682 struct stat stat = xfstat(fs_fd);
684 if (!S_ISDIR(stat.st_mode))
685 die("%s is not a directory", fs_path);
687 struct dev_opts dev = { 0 };
689 dev.path = dev_t_to_path(stat.st_dev);
690 dev.fd = xopen(dev.path, O_RDWR);
692 block_size = min_t(unsigned, stat.st_blksize,
693 get_blocksize(dev.path, dev.fd) << 9);
695 BUG_ON(!is_power_of_2(block_size) || block_size < 512);
696 format_opts.block_size = block_size >> 9;
699 char *file_path = mprintf("%s/bcachefs", fs_path);
701 bch2_pick_bucket_size(format_opts, &dev);
703 ranges extents = reserve_new_fs_space(file_path,
704 block_size, get_size(dev.path, dev.fd) / 5,
705 &bcachefs_inum, stat.st_dev, force);
707 find_superblock_space(extents, &dev);
709 if (format_opts.encrypted && !no_passphrase) {
710 format_opts.passphrase = read_passphrase("Enter passphrase: ");
712 if (isatty(STDIN_FILENO)) {
714 read_passphrase("Enter same passphrase again: ");
716 if (strcmp(format_opts.passphrase, pass2)) {
717 memzero_explicit(format_opts.passphrase,
718 strlen(format_opts.passphrase));
719 memzero_explicit(pass2, strlen(pass2));
720 die("Passphrases do not match");
723 memzero_explicit(pass2, strlen(pass2));
728 struct bch_sb *sb = bch2_format(format_opts, &dev, 1);
729 u64 sb_offset = le64_to_cpu(sb->layout.sb_offset[0]);
731 if (format_opts.passphrase)
732 bch2_add_key(sb, format_opts.passphrase);
736 printf("Creating new filesystem on %s in space reserved at %s\n"
738 " mount -t bcachefs -o sb=%llu %s dir\n"
740 "After verifying that the new filesystem is correct, to create a\n"
741 "superblock at the default offset and finish the migration run\n"
742 " bcachefs migrate_superblock -d %s -o %llu\n"
744 "The new filesystem will have a file at /old_migrated_filestem\n"
745 "referencing all disk space that might be used by the existing\n"
746 "filesystem. That file can be deleted once the old filesystem is\n"
747 "no longer needed (and should be deleted prior to running\n"
748 "bcachefs migrate_superblock)\n",
749 dev.path, file_path, sb_offset, dev.path,
750 dev.path, sb_offset);
752 struct bch_opts opts = bch2_opts_empty();
753 struct bch_fs *c = NULL;
754 char *path[1] = { dev.path };
761 err = bch2_fs_open(path, 1, opts, &c);
763 die("Error opening new filesystem: %s", err);
765 mark_unreserved_space(c, extents);
767 err = bch2_fs_start(c);
769 die("Error starting new filesystem: %s", err);
771 copy_fs(c, fs_fd, fs_path, bcachefs_inum, &extents);
775 printf("Migrate complete, running fsck:\n");
776 opts.nostart = false;
777 opts.nochanges = true;
779 err = bch2_fs_open(path, 1, opts, &c);
781 die("Error opening new filesystem: %s", err);
784 printf("fsck complete\n");
788 static void migrate_superblock_usage(void)
790 puts("bcachefs migrate_superblock - create default superblock after migrating\n"
791 "Usage: bcachefs migrate_superblock [OPTION]...\n"
794 " -d device Device to create superblock for\n"
795 " -o offset Offset of existing superblock\n"
796 " -h Display this help and exit\n"
797 "Report bugs to <linux-bcache@vger.kernel.org>");
800 int cmd_migrate_superblock(int argc, char *argv[])
806 while ((opt = getopt(argc, argv, "d:o:h")) != -1)
812 ret = kstrtou64(optarg, 10, &offset);
814 die("Invalid offset");
817 migrate_superblock_usage();
822 die("Please specify a device");
825 die("Please specify offset of existing superblock");
827 int fd = xopen(dev, O_RDWR);
828 struct bch_sb *sb = __bch2_super_read(fd, offset);
830 if (sb->layout.nr_superblocks >= ARRAY_SIZE(sb->layout.sb_offset))
831 die("Can't add superblock: no space left in superblock layout");
833 for (unsigned i = 0; i < sb->layout.nr_superblocks; i++)
834 if (le64_to_cpu(sb->layout.sb_offset[i]) == BCH_SB_SECTOR)
835 die("Superblock layout already has default superblock");
837 memmove(&sb->layout.sb_offset[1],
838 &sb->layout.sb_offset[0],
839 sb->layout.nr_superblocks * sizeof(u64));
840 sb->layout.nr_superblocks++;
842 sb->layout.sb_offset[0] = cpu_to_le64(BCH_SB_SECTOR);
844 bch2_super_write(fd, sb);