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;
167 bch2_inode_init(c, &new_inode, uid, gid, mode, rdev);
169 ret = bch2_inode_create(c, &new_inode, BLOCKDEV_INODE_MAX, 0,
170 &c->unused_inode_hint);
172 die("error creating file: %s", strerror(-ret));
174 create_dirent(c, parent, name, new_inode.inum, mode);
179 #define for_each_xattr_handler(handlers, handler) \
181 for ((handler) = *(handlers)++; \
183 (handler) = *(handlers)++)
185 static const struct xattr_handler *xattr_resolve_name(const char **name)
187 const struct xattr_handler **handlers = bch2_xattr_handlers;
188 const struct xattr_handler *handler;
190 for_each_xattr_handler(handlers, handler) {
193 n = strcmp_prefix(*name, xattr_prefix(handler));
195 if (!handler->prefix ^ !*n) {
198 return ERR_PTR(-EINVAL);
204 return ERR_PTR(-EOPNOTSUPP);
207 static void copy_times(struct bch_fs *c, struct bch_inode_unpacked *dst,
210 dst->i_atime = timespec_to_bch2_time(c, src->st_atim);
211 dst->i_mtime = timespec_to_bch2_time(c, src->st_mtim);
212 dst->i_ctime = timespec_to_bch2_time(c, src->st_ctim);
215 static void copy_xattrs(struct bch_fs *c, struct bch_inode_unpacked *dst,
218 struct bch_hash_info hash_info = bch2_hash_info_init(c, dst);
220 char attrs[XATTR_LIST_MAX];
221 ssize_t attrs_size = llistxattr(src, attrs, sizeof(attrs));
223 die("listxattr error: %m");
225 const char *next, *attr;
227 attr < attrs + attrs_size;
229 next = attr + strlen(attr) + 1;
231 char val[XATTR_SIZE_MAX];
232 ssize_t val_size = lgetxattr(src, attr, val, sizeof(val));
235 die("error getting xattr val: %m");
237 const struct xattr_handler *h = xattr_resolve_name(&attr);
239 int ret = __bch2_xattr_set(c, dst->inum, &hash_info, attr,
240 val, val_size, 0, h->flags, NULL);
242 die("error creating xattr: %s", strerror(-ret));
246 static void write_data(struct bch_fs *c,
247 struct bch_inode_unpacked *dst_inode,
248 u64 dst_offset, void *buf, size_t len)
250 struct disk_reservation res;
251 struct bch_write_op op;
255 BUG_ON(dst_offset & (block_bytes(c) - 1));
256 BUG_ON(len & (block_bytes(c) - 1));
258 closure_init_stack(&cl);
260 bio_init(&op.wbio.bio, &bv, 1);
261 op.wbio.bio.bi_iter.bi_size = len;
262 bch2_bio_map(&op.wbio.bio, buf);
264 int ret = bch2_disk_reservation_get(c, &res, len >> 9, 0);
266 die("error reserving space in new filesystem: %s", strerror(-ret));
268 bch2_write_op_init(&op, c, res, c->write_points,
269 POS(dst_inode->inum, dst_offset >> 9), NULL, 0);
270 closure_call(&op.cl, bch2_write, NULL, &cl);
273 dst_inode->i_sectors += len >> 9;
276 static char buf[1 << 20] __aligned(PAGE_SIZE);
278 static void copy_data(struct bch_fs *c,
279 struct bch_inode_unpacked *dst_inode,
280 int src_fd, u64 start, u64 end)
282 while (start < end) {
283 unsigned len = min_t(u64, end - start, sizeof(buf));
285 xpread(src_fd, buf, len, start);
286 write_data(c, dst_inode, start, buf, len);
291 static void link_data(struct bch_fs *c, struct bch_inode_unpacked *dst,
292 u64 logical, u64 physical, u64 length)
294 struct bch_dev *ca = c->devs[0];
296 BUG_ON(logical & (block_bytes(c) - 1));
297 BUG_ON(physical & (block_bytes(c) - 1));
298 BUG_ON(length & (block_bytes(c) - 1));
304 BUG_ON(physical + length > bucket_to_sector(ca, ca->mi.nbuckets));
307 struct bkey_i_extent *e;
309 u64 b = sector_to_bucket(ca, physical >> 9);
310 struct disk_reservation res;
314 sectors = min(ca->mi.bucket_size -
315 (physical & (ca->mi.bucket_size - 1)),
318 e = bkey_extent_init(&k.k);
319 e->k.p.inode = dst->inum;
320 e->k.p.offset = logical + sectors;
322 extent_ptr_append(e, (struct bch_extent_ptr) {
325 .gen = ca->buckets[b].mark.gen,
328 ret = bch2_disk_reservation_get(c, &res, sectors,
329 BCH_DISK_RESERVATION_NOFAIL);
331 die("error reserving space in new filesystem: %s",
334 bch2_check_mark_super(c, extent_i_to_s_c(e), false);
336 ret = bch2_btree_insert(c, BTREE_ID_EXTENTS, &e->k_i,
337 &res, NULL, NULL, 0);
339 die("btree insert error %s", strerror(-ret));
341 bch2_disk_reservation_put(c, &res);
343 dst->i_sectors += sectors;
350 static void copy_link(struct bch_fs *c, struct bch_inode_unpacked *dst,
353 ssize_t ret = readlink(src, buf, sizeof(buf));
355 die("readlink error: %m");
357 write_data(c, dst, 0, buf, round_up(ret, block_bytes(c)));
360 static void copy_file(struct bch_fs *c, struct bch_inode_unpacked *dst,
361 int src, char *src_path, ranges *extents)
363 struct fiemap_iter iter;
364 struct fiemap_extent e;
366 fiemap_for_each(src, iter, e)
367 if (e.fe_flags & FIEMAP_EXTENT_UNKNOWN) {
372 fiemap_for_each(src, iter, e) {
373 if ((e.fe_logical & (block_bytes(c) - 1)) ||
374 (e.fe_length & (block_bytes(c) - 1)))
375 die("Unaligned extent in %s - can't handle", src_path);
377 if (e.fe_flags & (FIEMAP_EXTENT_UNKNOWN|
378 FIEMAP_EXTENT_ENCODED|
379 FIEMAP_EXTENT_NOT_ALIGNED|
380 FIEMAP_EXTENT_DATA_INLINE)) {
383 round_down(e.fe_logical, block_bytes(c)),
384 round_up(e.fe_logical + e.fe_length,
389 if (e.fe_physical < 1 << 20) {
392 round_down(e.fe_logical, block_bytes(c)),
393 round_up(e.fe_logical + e.fe_length,
398 if ((e.fe_physical & (block_bytes(c) - 1)))
399 die("Unaligned extent in %s - can't handle", src_path);
401 range_add(extents, e.fe_physical, e.fe_length);
402 link_data(c, dst, e.fe_logical, e.fe_physical, e.fe_length);
406 struct copy_fs_state {
410 GENRADIX(u64) hardlinks;
414 static void copy_dir(struct copy_fs_state *s,
416 struct bch_inode_unpacked *dst,
417 int src_fd, const char *src_path)
419 DIR *dir = fdopendir(src_fd);
422 while ((errno = 0), (d = readdir(dir))) {
423 struct bch_inode_unpacked inode;
427 die("chdir error: %m");
430 xfstatat(src_fd, d->d_name, AT_SYMLINK_NOFOLLOW);
432 if (!strcmp(d->d_name, ".") ||
433 !strcmp(d->d_name, "..") ||
434 stat.st_ino == s->bcachefs_inum)
437 char *child_path = mprintf("%s/%s", src_path, d->d_name);
439 if (stat.st_dev != s->dev)
440 die("%s does not have correct st_dev!", child_path);
442 u64 *dst_inum = S_ISREG(stat.st_mode)
443 ? genradix_ptr_alloc(&s->hardlinks, stat.st_ino, GFP_KERNEL)
446 if (dst_inum && *dst_inum) {
447 create_link(c, dst, d->d_name, *dst_inum, S_IFREG);
451 inode = create_file(c, dst, d->d_name,
452 stat.st_uid, stat.st_gid,
453 stat.st_mode, stat.st_rdev);
456 *dst_inum = inode.inum;
458 copy_times(c, &inode, &stat);
459 copy_xattrs(c, &inode, d->d_name);
463 switch (mode_to_type(stat.st_mode)) {
465 fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
466 copy_dir(s, c, &inode, fd, child_path);
470 inode.i_size = stat.st_size;
472 fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
473 copy_file(c, &inode, fd, child_path, &s->extents);
477 inode.i_size = stat.st_size;
479 copy_link(c, &inode, d->d_name);
486 /* nothing else to copy for these: */
492 update_inode(c, &inode);
498 die("readdir error: %m");
501 static ranges reserve_new_fs_space(const char *file_path, unsigned block_size,
502 u64 size, u64 *bcachefs_inum, dev_t dev,
506 ? open(file_path, O_RDWR|O_CREAT, 0600)
507 : open(file_path, O_RDWR|O_CREAT|O_EXCL, 0600);
509 die("Error creating %s for bcachefs metadata: %m",
512 struct stat statbuf = xfstat(fd);
514 if (statbuf.st_dev != dev)
515 die("bcachefs file has incorrect device");
517 *bcachefs_inum = statbuf.st_ino;
519 if (fallocate(fd, 0, 0, size))
520 die("Error reserving space for bcachefs metadata: %m");
524 struct fiemap_iter iter;
525 struct fiemap_extent e;
526 ranges extents = { NULL };
528 fiemap_for_each(fd, iter, e) {
529 if (e.fe_flags & (FIEMAP_EXTENT_UNKNOWN|
530 FIEMAP_EXTENT_ENCODED|
531 FIEMAP_EXTENT_NOT_ALIGNED|
532 FIEMAP_EXTENT_DATA_INLINE))
533 die("Unable to continue: metadata file not fully mapped");
535 if ((e.fe_physical & (block_size - 1)) ||
536 (e.fe_length & (block_size - 1)))
537 die("Unable to continue: unaligned extents in metadata file");
539 range_add(&extents, e.fe_physical, e.fe_length);
543 ranges_sort_merge(&extents);
547 static void reserve_old_fs_space(struct bch_fs *c,
548 struct bch_inode_unpacked *root_inode,
551 struct bch_dev *ca = c->devs[0];
552 struct bch_inode_unpacked dst;
553 struct hole_iter iter;
556 dst = create_file(c, root_inode, "old_migrated_filesystem",
557 0, 0, S_IFREG|0400, 0);
558 dst.i_size = bucket_to_sector(ca, ca->mi.nbuckets) << 9;
560 ranges_sort_merge(extents);
562 for_each_hole(iter, *extents, bucket_to_sector(ca, ca->mi.nbuckets) << 9, i)
563 link_data(c, &dst, i.start, i.start, i.end - i.start);
565 update_inode(c, &dst);
568 static void copy_fs(struct bch_fs *c, int src_fd, const char *src_path,
569 u64 bcachefs_inum, ranges *extents)
573 struct bch_inode_unpacked root_inode;
574 int ret = bch2_inode_find_by_inum(c, BCACHEFS_ROOT_INO, &root_inode);
576 die("error looking up root directory: %s", strerror(-ret));
579 die("chdir error: %m");
581 struct stat stat = xfstat(src_fd);
582 copy_times(c, &root_inode, &stat);
583 copy_xattrs(c, &root_inode, ".");
585 struct copy_fs_state s = {
586 .bcachefs_inum = bcachefs_inum,
592 copy_dir(&s, c, &root_inode, src_fd, src_path);
594 reserve_old_fs_space(c, &root_inode, &s.extents);
596 update_inode(c, &root_inode);
598 darray_free(s.extents);
599 genradix_free(&s.hardlinks);
602 static void find_superblock_space(ranges extents, struct dev_opts *dev)
606 darray_foreach(i, extents) {
607 u64 start = round_up(max(256ULL << 10, i->start),
608 dev->bucket_size << 9);
609 u64 end = round_down(i->end,
610 dev->bucket_size << 9);
612 if (start + (128 << 10) <= end) {
613 dev->sb_offset = start >> 9;
614 dev->sb_end = dev->sb_offset + 256;
619 die("Couldn't find a valid location for superblock");
622 static void migrate_usage(void)
624 puts("bcachefs migrate - migrate an existing filesystem to bcachefs\n"
625 "Usage: bcachefs migrate [OPTION]...\n"
628 " -f fs Root of filesystem to migrate(s)\n"
629 " --encrypted Enable whole filesystem encryption (chacha20/poly1305)\n"
630 " --no_passphrase Don't encrypt master encryption key\n"
631 " -F Force, even if metadata file already exists\n"
632 " -h Display this help and exit\n"
633 "Report bugs to <linux-bcache@vger.kernel.org>");
636 static const struct option migrate_opts[] = {
637 { "encrypted", no_argument, NULL, 'e' },
638 { "no_passphrase", no_argument, NULL, 'p' },
642 int cmd_migrate(int argc, char *argv[])
644 struct format_opts format_opts = format_opts_default();
645 char *fs_path = NULL;
647 bool no_passphrase = false, force = false;
650 while ((opt = getopt_long(argc, argv, "f:Fh",
651 migrate_opts, NULL)) != -1)
657 format_opts.encrypted = true;
660 no_passphrase = true;
671 die("Please specify a filesytem to migrate");
673 if (!path_is_fs_root(fs_path))
674 die("%s is not a filysestem root", fs_path);
676 int fs_fd = xopen(fs_path, O_RDONLY|O_NOATIME);
677 struct stat stat = xfstat(fs_fd);
679 if (!S_ISDIR(stat.st_mode))
680 die("%s is not a directory", fs_path);
682 struct dev_opts dev = dev_opts_default();
684 dev.path = dev_t_to_path(stat.st_dev);
685 dev.fd = xopen(dev.path, O_RDWR);
687 block_size = min_t(unsigned, stat.st_blksize,
688 get_blocksize(dev.path, dev.fd) << 9);
690 BUG_ON(!is_power_of_2(block_size) || block_size < 512);
691 format_opts.block_size = block_size >> 9;
694 char *file_path = mprintf("%s/bcachefs", fs_path);
696 bch2_pick_bucket_size(format_opts, &dev);
698 ranges extents = reserve_new_fs_space(file_path,
699 block_size, get_size(dev.path, dev.fd) / 5,
700 &bcachefs_inum, stat.st_dev, force);
702 find_superblock_space(extents, &dev);
704 if (format_opts.encrypted && !no_passphrase) {
705 format_opts.passphrase = read_passphrase("Enter passphrase: ");
707 if (isatty(STDIN_FILENO)) {
709 read_passphrase("Enter same passphrase again: ");
711 if (strcmp(format_opts.passphrase, pass2)) {
712 memzero_explicit(format_opts.passphrase,
713 strlen(format_opts.passphrase));
714 memzero_explicit(pass2, strlen(pass2));
715 die("Passphrases do not match");
718 memzero_explicit(pass2, strlen(pass2));
723 struct bch_sb *sb = bch2_format(format_opts, &dev, 1);
724 u64 sb_offset = le64_to_cpu(sb->layout.sb_offset[0]);
726 if (format_opts.passphrase)
727 bch2_add_key(sb, format_opts.passphrase);
731 printf("Creating new filesystem on %s in space reserved at %s\n"
733 " mount -t bcachefs -o sb=%llu %s dir\n"
735 "After verifying that the new filesystem is correct, to create a\n"
736 "superblock at the default offset and finish the migration run\n"
737 " bcachefs migrate_superblock -d %s -o %llu\n"
739 "The new filesystem will have a file at /old_migrated_filestem\n"
740 "referencing all disk space that might be used by the existing\n"
741 "filesystem. That file can be deleted once the old filesystem is\n"
742 "no longer needed (and should be deleted prior to running\n"
743 "bcachefs migrate_superblock)\n",
744 dev.path, file_path, sb_offset, dev.path,
745 dev.path, sb_offset);
747 struct bch_opts opts = bch2_opts_empty();
748 struct bch_fs *c = NULL;
749 char *path[1] = { dev.path };
756 err = bch2_fs_open(path, 1, opts, &c);
758 die("Error opening new filesystem: %s", err);
760 mark_unreserved_space(c, extents);
762 err = bch2_fs_start(c);
764 die("Error starting new filesystem: %s", err);
766 copy_fs(c, fs_fd, fs_path, bcachefs_inum, &extents);
770 printf("Migrate complete, running fsck:\n");
771 opts.nostart = false;
772 opts.nochanges = true;
774 err = bch2_fs_open(path, 1, opts, &c);
776 die("Error opening new filesystem: %s", err);
779 printf("fsck complete\n");
783 static void migrate_superblock_usage(void)
785 puts("bcachefs migrate_superblock - create default superblock after migrating\n"
786 "Usage: bcachefs migrate_superblock [OPTION]...\n"
789 " -d device Device to create superblock for\n"
790 " -o offset Offset of existing superblock\n"
791 " -h Display this help and exit\n"
792 "Report bugs to <linux-bcache@vger.kernel.org>");
795 int cmd_migrate_superblock(int argc, char *argv[])
801 while ((opt = getopt(argc, argv, "d:o:h")) != -1)
807 ret = kstrtou64(optarg, 10, &offset);
809 die("Invalid offset");
812 migrate_superblock_usage();
817 die("Please specify a device");
820 die("Please specify offset of existing superblock");
822 int fd = xopen(dev, O_RDWR);
823 struct bch_sb *sb = __bch2_super_read(fd, offset);
825 if (sb->layout.nr_superblocks >= ARRAY_SIZE(sb->layout.sb_offset))
826 die("Can't add superblock: no space left in superblock layout");
829 for (i = 0; i < sb->layout.nr_superblocks; i++)
830 if (le64_to_cpu(sb->layout.sb_offset[i]) == BCH_SB_SECTOR)
831 die("Superblock layout already has default superblock");
833 memmove(&sb->layout.sb_offset[1],
834 &sb->layout.sb_offset[0],
835 sb->layout.nr_superblocks * sizeof(u64));
836 sb->layout.nr_superblocks++;
838 sb->layout.sb_offset[0] = cpu_to_le64(BCH_SB_SECTOR);
840 bch2_super_write(fd, sb);