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 & (block_bytes(c) - 1)))
394 die("Unaligned extent in %s - can't handle", src_path);
396 range_add(extents, e.fe_physical, e.fe_length);
397 link_data(c, dst, e.fe_logical, e.fe_physical, e.fe_length);
401 struct copy_fs_state {
405 GENRADIX(u64) hardlinks;
409 static void copy_dir(struct copy_fs_state *s,
411 struct bch_inode_unpacked *dst,
412 int src_fd, const char *src_path)
414 DIR *dir = fdopendir(src_fd);
417 while ((errno = 0), (d = readdir(dir))) {
418 struct bch_inode_unpacked inode;
422 die("chdir error: %s", strerror(errno));
425 xfstatat(src_fd, d->d_name, AT_SYMLINK_NOFOLLOW);
427 if (!strcmp(d->d_name, ".") ||
428 !strcmp(d->d_name, "..") ||
429 stat.st_ino == s->bcachefs_inum)
432 char *child_path = mprintf("%s/%s", src_path, d->d_name);
434 if (stat.st_dev != s->dev)
435 die("%s does not have correct st_dev!", child_path);
437 u64 *dst_inum = S_ISREG(stat.st_mode)
438 ? genradix_ptr_alloc(&s->hardlinks, stat.st_ino, GFP_KERNEL)
441 if (dst_inum && *dst_inum) {
442 create_link(c, dst, d->d_name, *dst_inum, S_IFREG);
446 inode = create_file(c, dst, d->d_name,
447 stat.st_uid, stat.st_gid,
448 stat.st_mode, stat.st_rdev);
451 *dst_inum = inode.inum;
453 copy_times(c, &inode, &stat);
454 copy_xattrs(c, &inode, d->d_name);
458 switch (mode_to_type(stat.st_mode)) {
460 fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
461 copy_dir(s, c, &inode, fd, child_path);
465 inode.i_size = stat.st_size;
467 fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
468 copy_file(c, &inode, fd, child_path, &s->extents);
472 inode.i_size = stat.st_size;
474 copy_link(c, &inode, d->d_name);
481 /* nothing else to copy for these: */
487 update_inode(c, &inode);
493 die("readdir error: %s", strerror(errno));
496 static ranges reserve_new_fs_space(const char *file_path, unsigned block_size,
497 u64 size, u64 *bcachefs_inum, dev_t dev,
501 ? open(file_path, O_RDWR|O_CREAT, 0600)
502 : open(file_path, O_RDWR|O_CREAT|O_EXCL, 0600);
504 die("Error creating %s for bcachefs metadata: %s",
505 file_path, strerror(errno));
507 struct stat statbuf = xfstat(fd);
509 if (statbuf.st_dev != dev)
510 die("bcachefs file has incorrect device");
512 *bcachefs_inum = statbuf.st_ino;
514 if (fallocate(fd, 0, 0, size))
515 die("Error reserving space for bcachefs metadata: %s",
520 struct fiemap_iter iter;
521 struct fiemap_extent e;
522 ranges extents = { NULL };
524 fiemap_for_each(fd, iter, e) {
525 if (e.fe_flags & (FIEMAP_EXTENT_UNKNOWN|
526 FIEMAP_EXTENT_ENCODED|
527 FIEMAP_EXTENT_NOT_ALIGNED|
528 FIEMAP_EXTENT_DATA_INLINE))
529 die("Unable to continue: metadata file not fully mapped");
531 if ((e.fe_physical & (block_size - 1)) ||
532 (e.fe_length & (block_size - 1)))
533 die("Unable to continue: unaligned extents in metadata file");
535 range_add(&extents, e.fe_physical, e.fe_length);
539 ranges_sort_merge(&extents);
543 static void reserve_old_fs_space(struct bch_fs *c,
544 struct bch_inode_unpacked *root_inode,
547 struct bch_dev *ca = c->devs[0];
548 struct bch_inode_unpacked dst;
549 struct hole_iter iter;
552 dst = create_file(c, root_inode, "old_migrated_filesystem",
553 0, 0, S_IFREG|0400, 0);
554 dst.i_size = bucket_to_sector(ca, ca->mi.nbuckets) << 9;
556 ranges_sort_merge(extents);
558 for_each_hole(iter, *extents, bucket_to_sector(ca, ca->mi.nbuckets) << 9, i)
559 link_data(c, &dst, i.start, i.start, i.end - i.start);
561 update_inode(c, &dst);
564 static void copy_fs(struct bch_fs *c, int src_fd, const char *src_path,
565 u64 bcachefs_inum, ranges *extents)
569 struct bch_inode_unpacked root_inode;
570 int ret = bch2_inode_find_by_inum(c, BCACHE_ROOT_INO, &root_inode);
572 die("error looking up root directory: %s", strerror(-ret));
575 die("chdir error: %s", strerror(errno));
577 struct stat stat = xfstat(src_fd);
578 copy_times(c, &root_inode, &stat);
579 copy_xattrs(c, &root_inode, ".");
581 struct copy_fs_state s = {
582 .bcachefs_inum = bcachefs_inum,
588 copy_dir(&s, c, &root_inode, src_fd, src_path);
590 reserve_old_fs_space(c, &root_inode, &s.extents);
592 update_inode(c, &root_inode);
594 darray_free(s.extents);
595 genradix_free(&s.hardlinks);
598 static void find_superblock_space(ranges extents, struct dev_opts *dev)
601 darray_foreach(i, extents) {
602 u64 offset = max(256ULL << 10, i->start);
604 if (offset + (128 << 10) <= i->end) {
605 dev->sb_offset = offset >> 9;
606 dev->sb_end = dev->sb_offset + 256;
611 die("Couldn't find a valid location for superblock");
614 static void migrate_usage(void)
616 puts("bcachefs migrate - migrate an existing filesystem to bcachefs\n"
617 "Usage: bcachefs migrate [OPTION]...\n"
620 " -f fs Root of filesystem to migrate(s)\n"
621 " --encrypted Enable whole filesystem encryption (chacha20/poly1305)\n"
622 " --no_passphrase Don't encrypt master encryption key\n"
623 " -F Force, even if metadata file already exists\n"
624 " -h Display this help and exit\n"
625 "Report bugs to <linux-bcache@vger.kernel.org>");
628 static const struct option migrate_opts[] = {
629 { "encrypted", no_argument, NULL, 'e' },
630 { "no_passphrase", no_argument, NULL, 'p' },
634 int cmd_migrate(int argc, char *argv[])
636 struct format_opts format_opts = format_opts_default();
637 char *fs_path = NULL;
639 bool no_passphrase = false, force = false;
642 while ((opt = getopt_long(argc, argv, "f:Fh",
643 migrate_opts, NULL)) != -1)
649 format_opts.encrypted = true;
652 no_passphrase = true;
663 die("Please specify a filesytem to migrate");
665 if (!path_is_fs_root(fs_path))
666 die("%s is not a filysestem root", fs_path);
668 int fs_fd = xopen(fs_path, O_RDONLY|O_NOATIME);
669 struct stat stat = xfstat(fs_fd);
671 if (!S_ISDIR(stat.st_mode))
672 die("%s is not a directory", fs_path);
674 struct dev_opts dev = { 0 };
676 dev.path = dev_t_to_path(stat.st_dev);
677 dev.fd = xopen(dev.path, O_RDWR);
679 block_size = min_t(unsigned, stat.st_blksize,
680 get_blocksize(dev.path, dev.fd) << 9);
682 BUG_ON(!is_power_of_2(block_size) || block_size < 512);
683 format_opts.block_size = block_size >> 9;
686 char *file_path = mprintf("%s/bcachefs", fs_path);
688 ranges extents = reserve_new_fs_space(file_path,
689 block_size, get_size(dev.path, dev.fd) / 5,
690 &bcachefs_inum, stat.st_dev, force);
692 find_superblock_space(extents, &dev);
694 if (format_opts.encrypted && !no_passphrase) {
695 format_opts.passphrase = read_passphrase("Enter passphrase: ");
697 if (isatty(STDIN_FILENO)) {
699 read_passphrase("Enter same passphrase again: ");
701 if (strcmp(format_opts.passphrase, pass2)) {
702 memzero_explicit(format_opts.passphrase,
703 strlen(format_opts.passphrase));
704 memzero_explicit(pass2, strlen(pass2));
705 die("Passphrases do not match");
708 memzero_explicit(pass2, strlen(pass2));
713 struct bch_sb *sb = bcache_format(format_opts, &dev, 1);
714 u64 sb_offset = le64_to_cpu(sb->layout.sb_offset[0]);
716 if (format_opts.passphrase)
717 add_bcache_key(sb, format_opts.passphrase);
721 printf("Creating new filesystem on %s in space reserved at %s\n"
723 " mount -t bcachefs -o sb=%llu %s dir\n"
725 "After verifying that the new filesystem is correct, to create a\n"
726 "superblock at the default offset and finish the migration run\n"
727 " bcachefs migrate_superblock -d %s -o %llu\n"
729 "The new filesystem will have a file at /old_migrated_filestem\n"
730 "referencing all disk space that might be used by the existing\n"
731 "filesystem. That file can be deleted once the old filesystem is\n"
732 "no longer needed (and should be deleted prior to running\n"
733 "bcachefs migrate_superblock)\n",
734 dev.path, file_path, sb_offset, dev.path,
735 dev.path, sb_offset);
737 struct bch_opts opts = bch2_opts_empty();
738 struct bch_fs *c = NULL;
739 char *path[1] = { dev.path };
746 err = bch2_fs_open(path, 1, opts, &c);
748 die("Error opening new filesystem: %s", err);
750 mark_unreserved_space(c, extents);
752 err = bch2_fs_start(c);
754 die("Error starting new filesystem: %s", err);
756 copy_fs(c, fs_fd, fs_path, bcachefs_inum, &extents);
760 printf("Migrate complete, running fsck:\n");
761 opts.nostart = false;
762 opts.nochanges = true;
764 err = bch2_fs_open(path, 1, opts, &c);
766 die("Error opening new filesystem: %s", err);
769 printf("fsck complete\n");
773 static void migrate_superblock_usage(void)
775 puts("bcachefs migrate_superblock - create default superblock after migrating\n"
776 "Usage: bcachefs migrate_superblock [OPTION]...\n"
779 " -d device Device to create superblock for\n"
780 " -o offset Offset of existing superblock\n"
781 " -h Display this help and exit\n"
782 "Report bugs to <linux-bcache@vger.kernel.org>");
785 int cmd_migrate_superblock(int argc, char *argv[])
791 while ((opt = getopt(argc, argv, "d:o:h")) != -1)
797 ret = kstrtou64(optarg, 10, &offset);
799 die("Invalid offset");
802 migrate_superblock_usage();
807 die("Please specify a device");
810 die("Please specify offset of existing superblock");
812 int fd = xopen(dev, O_RDWR);
813 struct bch_sb *sb = __bcache_super_read(fd, offset);
815 if (sb->layout.nr_superblocks >= ARRAY_SIZE(sb->layout.sb_offset))
816 die("Can't add superblock: no space left in superblock layout");
818 for (unsigned i = 0; i < sb->layout.nr_superblocks; i++)
819 if (le64_to_cpu(sb->layout.sb_offset[i]) == BCH_SB_SECTOR)
820 die("Superblock layout already has default superblock");
822 memmove(&sb->layout.sb_offset[1],
823 &sb->layout.sb_offset[0],
824 sb->layout.nr_superblocks * sizeof(u64));
825 sb->layout.nr_superblocks++;
827 sb->layout.sb_offset[0] = cpu_to_le64(BCH_SB_SECTOR);
829 bcache_super_write(fd, sb);