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 "libbcache.h"
23 #include "linux/bcache.h"
25 #include <linux/dcache.h>
26 #include <linux/generic-radix-tree.h>
27 #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: %s", strerror(errno));
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 cache_set *c, ranges extents)
95 struct cache *ca = c->cache[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 cache_set *c,
115 struct bch_inode_unpacked *inode)
117 struct bkey_inode_buf packed;
120 bch_inode_pack(&packed, inode);
121 ret = bch_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 cache_set *c,
127 struct bch_inode_unpacked *parent,
128 const char *name, u64 inum, mode_t mode)
130 struct bch_hash_info parent_hash_info = bch_hash_info_init(parent);
131 struct qstr qname = { { { .len = strlen(name), } }, .name = name };
133 int ret = bch_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 cache_set *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 = bch_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 cache_set *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 bch_inode_init(c, &new_inode, uid, gid, mode, rdev);
169 bch_inode_pack(&packed, &new_inode);
171 ret = bch_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 = bch_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 cache_set *c, struct bch_inode_unpacked *dst,
213 dst->i_atime = timespec_to_bch_time(c, src->st_atim);
214 dst->i_mtime = timespec_to_bch_time(c, src->st_mtim);
215 dst->i_ctime = timespec_to_bch_time(c, src->st_ctim);
218 static void copy_xattrs(struct cache_set *c, struct bch_inode_unpacked *dst,
221 struct bch_hash_info hash_info = bch_hash_info_init(dst);
223 char attrs[XATTR_LIST_MAX];
224 ssize_t attrs_size = llistxattr(src, attrs, sizeof(attrs));
226 die("listxattr error: %s", strerror(errno));
228 for (const char *next, *attr = attrs;
229 attr < attrs + attrs_size;
231 next = attr + strlen(attr) + 1;
233 char val[XATTR_SIZE_MAX];
234 ssize_t val_size = lgetxattr(src, attr, val, sizeof(val));
237 die("error getting xattr val: %s", strerror(errno));
239 const struct xattr_handler *h = xattr_resolve_name(&attr);
241 int ret = __bch_xattr_set(c, dst->inum, &hash_info, attr,
242 val, val_size, 0, h->flags, NULL);
244 die("error creating xattr: %s", strerror(-ret));
248 static void write_data(struct cache_set *c,
249 struct bch_inode_unpacked *dst_inode,
250 u64 dst_offset, void *buf, size_t len)
252 struct disk_reservation res;
253 struct bch_write_op op;
254 struct bch_write_bio bio;
258 BUG_ON(dst_offset & (block_bytes(c) - 1));
259 BUG_ON(len & (block_bytes(c) - 1));
261 closure_init_stack(&cl);
264 bio.bio.bi_max_vecs = 1;
265 bio.bio.bi_io_vec = &bv;
266 bio.bio.bi_iter.bi_size = len;
267 bch_bio_map(&bio.bio, buf);
269 int ret = bch_disk_reservation_get(c, &res, len >> 9, 0);
271 die("error reserving space in new filesystem: %s", strerror(-ret));
273 bch_write_op_init(&op, c, &bio, res, c->write_points,
274 POS(dst_inode->inum, dst_offset >> 9), NULL, 0);
275 closure_call(&op.cl, bch_write, NULL, &cl);
278 dst_inode->i_sectors += len >> 9;
281 static char buf[1 << 20] __aligned(PAGE_SIZE);
283 static void copy_data(struct cache_set *c,
284 struct bch_inode_unpacked *dst_inode,
285 int src_fd, u64 start, u64 end)
287 while (start < end) {
288 unsigned len = min_t(u64, end - start, sizeof(buf));
290 xpread(src_fd, buf, len, start);
291 write_data(c, dst_inode, start, buf, len);
296 static void link_data(struct cache_set *c, struct bch_inode_unpacked *dst,
297 u64 logical, u64 physical, u64 length)
299 struct cache *ca = c->cache[0];
301 BUG_ON(logical & (block_bytes(c) - 1));
302 BUG_ON(physical & (block_bytes(c) - 1));
303 BUG_ON(length & (block_bytes(c) - 1));
309 BUG_ON(physical + length > bucket_to_sector(ca, ca->mi.nbuckets));
312 struct bkey_i_extent *e;
314 u64 b = sector_to_bucket(ca, physical >> 9);
315 struct disk_reservation res;
319 sectors = min(ca->mi.bucket_size -
320 (physical & (ca->mi.bucket_size - 1)),
323 e = bkey_extent_init(&k.k);
324 e->k.p.inode = dst->inum;
325 e->k.p.offset = logical + sectors;
327 extent_ptr_append(e, (struct bch_extent_ptr) {
330 .gen = ca->buckets[b].mark.gen,
333 ret = bch_disk_reservation_get(c, &res, sectors,
334 BCH_DISK_RESERVATION_NOFAIL);
336 die("error reserving space in new filesystem: %s",
339 ret = bch_btree_insert(c, BTREE_ID_EXTENTS, &e->k_i,
340 &res, NULL, NULL, 0);
342 die("btree insert error %s", strerror(-ret));
344 bch_disk_reservation_put(c, &res);
346 dst->i_sectors += sectors;
353 static void copy_link(struct cache_set *c, struct bch_inode_unpacked *dst,
356 ssize_t ret = readlink(src, buf, sizeof(buf));
358 die("readlink error: %s", strerror(errno));
360 write_data(c, dst, 0, buf, round_up(ret, block_bytes(c)));
363 static void copy_file(struct cache_set *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 & (block_bytes(c) - 1)))
393 die("Unaligned extent in %s - can't handle", src_path);
395 range_add(extents, e.fe_physical, e.fe_length);
396 link_data(c, dst, e.fe_logical, e.fe_physical, e.fe_length);
400 struct copy_fs_state {
404 GENRADIX(u64) hardlinks;
408 static void copy_dir(struct copy_fs_state *s,
410 struct bch_inode_unpacked *dst,
411 int src_fd, const char *src_path)
413 DIR *dir = fdopendir(src_fd);
416 while ((errno = 0), (d = readdir(dir))) {
417 struct bch_inode_unpacked inode;
421 die("chdir error: %s", strerror(errno));
424 xfstatat(src_fd, d->d_name, AT_SYMLINK_NOFOLLOW);
426 if (!strcmp(d->d_name, ".") ||
427 !strcmp(d->d_name, "..") ||
428 stat.st_ino == s->bcachefs_inum)
431 char *child_path = mprintf("%s/%s", src_path, d->d_name);
433 if (stat.st_dev != s->dev)
434 die("%s does not have correct st_dev!", child_path);
436 u64 *dst_inum = S_ISREG(stat.st_mode)
437 ? genradix_ptr_alloc(&s->hardlinks, stat.st_ino, GFP_KERNEL)
440 if (dst_inum && *dst_inum) {
441 create_link(c, dst, d->d_name, *dst_inum, S_IFREG);
445 inode = create_file(c, dst, d->d_name,
446 stat.st_uid, stat.st_gid,
447 stat.st_mode, stat.st_rdev);
450 *dst_inum = inode.inum;
452 copy_times(c, &inode, &stat);
453 copy_xattrs(c, &inode, d->d_name);
457 switch (mode_to_type(stat.st_mode)) {
459 fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
460 copy_dir(s, c, &inode, fd, child_path);
464 inode.i_size = stat.st_size;
466 fd = xopen(d->d_name, O_RDONLY|O_NOATIME);
467 copy_file(c, &inode, fd, child_path, &s->extents);
471 inode.i_size = stat.st_size;
473 copy_link(c, &inode, d->d_name);
480 /* nothing else to copy for these: */
486 update_inode(c, &inode);
492 die("readdir error: %s", strerror(errno));
495 static ranges reserve_new_fs_space(const char *file_path, unsigned block_size,
496 u64 size, u64 *bcachefs_inum, dev_t dev,
500 ? open(file_path, O_RDWR|O_CREAT, 0600)
501 : open(file_path, O_RDWR|O_CREAT|O_EXCL, 0600);
503 die("Error creating %s for bcachefs metadata: %s",
504 file_path, strerror(errno));
506 struct stat statbuf = xfstat(fd);
508 if (statbuf.st_dev != dev)
509 die("bcachefs file has incorrect device");
511 *bcachefs_inum = statbuf.st_ino;
513 if (fallocate(fd, 0, 0, size))
514 die("Error reserving space for bcachefs metadata: %s",
519 struct fiemap_iter iter;
520 struct fiemap_extent e;
521 ranges extents = { NULL };
523 fiemap_for_each(fd, iter, e) {
524 if (e.fe_flags & (FIEMAP_EXTENT_UNKNOWN|
525 FIEMAP_EXTENT_ENCODED|
526 FIEMAP_EXTENT_NOT_ALIGNED|
527 FIEMAP_EXTENT_DATA_INLINE))
528 die("Unable to continue: metadata file not fully mapped");
530 if ((e.fe_physical & (block_size - 1)) ||
531 (e.fe_length & (block_size - 1)))
532 die("Unable to continue: unaligned extents in metadata file");
534 range_add(&extents, e.fe_physical, e.fe_length);
538 ranges_sort_merge(&extents);
542 static void reserve_old_fs_space(struct cache_set *c,
543 struct bch_inode_unpacked *root_inode,
546 struct cache *ca = c->cache[0];
547 struct bch_inode_unpacked dst;
548 struct hole_iter iter;
551 dst = create_file(c, root_inode, "old_migrated_filesystem",
552 0, 0, S_IFREG|0400, 0);
553 dst.i_size = bucket_to_sector(ca, ca->mi.nbuckets) << 9;
555 ranges_sort_merge(extents);
557 for_each_hole(iter, *extents, bucket_to_sector(ca, ca->mi.nbuckets) << 9, i)
558 link_data(c, &dst, i.start, i.start, i.end - i.start);
560 update_inode(c, &dst);
563 static void copy_fs(struct cache_set *c, int src_fd, const char *src_path,
564 u64 bcachefs_inum, ranges *extents)
568 struct bch_inode_unpacked root_inode;
569 int ret = bch_inode_find_by_inum(c, BCACHE_ROOT_INO, &root_inode);
571 die("error looking up root directory: %s", strerror(-ret));
574 die("chdir error: %s", strerror(errno));
576 struct stat stat = xfstat(src_fd);
577 copy_times(c, &root_inode, &stat);
578 copy_xattrs(c, &root_inode, ".");
580 struct copy_fs_state s = {
581 .bcachefs_inum = bcachefs_inum,
587 copy_dir(&s, c, &root_inode, src_fd, src_path);
589 reserve_old_fs_space(c, &root_inode, &s.extents);
591 update_inode(c, &root_inode);
593 darray_free(s.extents);
594 genradix_free(&s.hardlinks);
597 static void find_superblock_space(ranges extents, struct dev_opts *dev)
600 darray_foreach(i, extents) {
601 u64 offset = max(256ULL << 10, i->start);
603 if (offset + (128 << 10) <= i->end) {
604 dev->sb_offset = offset >> 9;
605 dev->sb_end = dev->sb_offset + 256;
610 die("Couldn't find a valid location for superblock");
613 static void migrate_usage(void)
615 puts("bcache migrate - migrate an existing filesystem to bcachefs\n"
616 "Usage: bcache migrate [OPTION]...\n"
619 " -f fs Root of filesystem to migrate(s)\n"
620 " --encrypted Enable whole filesystem encryption (chacha20/poly1305)\n"
621 " --no_passphrase Don't encrypt master encryption key\n"
622 " -F Force, even if metadata file already exists\n"
623 " -h Display this help and exit\n"
624 "Report bugs to <linux-bcache@vger.kernel.org>");
627 static const struct option migrate_opts[] = {
628 { "encrypted", no_argument, NULL, 'e' },
629 { "no_passphrase", no_argument, NULL, 'p' },
633 int cmd_migrate(int argc, char *argv[])
635 struct format_opts format_opts = format_opts_default();
636 char *fs_path = NULL;
638 bool no_passphrase = false, force = false;
641 while ((opt = getopt_long(argc, argv, "f:Fh",
642 migrate_opts, NULL)) != -1)
648 format_opts.encrypted = true;
651 no_passphrase = true;
662 die("Please specify a filesytem to migrate");
664 if (!path_is_fs_root(fs_path))
665 die("%s is not a filysestem root", fs_path);
667 int fs_fd = xopen(fs_path, O_RDONLY|O_NOATIME);
668 struct stat stat = xfstat(fs_fd);
670 if (!S_ISDIR(stat.st_mode))
671 die("%s is not a directory", fs_path);
673 struct dev_opts dev = { 0 };
675 dev.path = dev_t_to_path(stat.st_dev);
676 dev.fd = xopen(dev.path, O_RDWR);
678 block_size = min_t(unsigned, stat.st_blksize,
679 get_blocksize(dev.path, dev.fd) << 9);
681 BUG_ON(!is_power_of_2(block_size) || block_size < 512);
682 format_opts.block_size = block_size >> 9;
685 char *file_path = mprintf("%s/bcachefs", fs_path);
687 ranges extents = reserve_new_fs_space(file_path,
688 block_size, get_size(dev.path, dev.fd) / 5,
689 &bcachefs_inum, stat.st_dev, force);
691 find_superblock_space(extents, &dev);
693 if (format_opts.encrypted && !no_passphrase) {
694 format_opts.passphrase = read_passphrase("Enter passphrase: ");
696 if (isatty(STDIN_FILENO)) {
698 read_passphrase("Enter same passphrase again: ");
700 if (strcmp(format_opts.passphrase, pass2)) {
701 memzero_explicit(format_opts.passphrase,
702 strlen(format_opts.passphrase));
703 memzero_explicit(pass2, strlen(pass2));
704 die("Passphrases do not match");
707 memzero_explicit(pass2, strlen(pass2));
712 struct bch_sb *sb = bcache_format(format_opts, &dev, 1);
713 u64 sb_offset = le64_to_cpu(sb->layout.sb_offset[0]);
715 if (format_opts.passphrase)
716 add_bcache_key(sb, format_opts.passphrase);
720 printf("Creating new filesystem on %s in space reserved at %s\n"
722 " mount -t bcache -o sb=%llu %s dir\n"
724 "After verifying that the new filesystem is correct, to create a\n"
725 "superblock at the default offset and finish the migration run\n"
726 " bcache migrate_superblock -d %s -o %llu\n"
728 "The new filesystem will have a file at /old_migrated_filestem\n"
729 "referencing all disk space that might be used by the existing\n"
730 "filesystem. That file can be deleted once the old filesystem is\n"
731 "no longer needed (and should be deleted prior to running\n"
732 "bcache migrate_superblock)\n",
733 dev.path, file_path, sb_offset, dev.path,
734 dev.path, sb_offset);
736 struct bch_opts opts = bch_opts_empty();
737 struct cache_set *c = NULL;
738 char *path[1] = { dev.path };
745 err = bch_fs_open(path, 1, opts, &c);
747 die("Error opening new filesystem: %s", err);
749 mark_unreserved_space(c, extents);
751 err = bch_fs_start(c);
753 die("Error starting new filesystem: %s", err);
755 copy_fs(c, fs_fd, fs_path, bcachefs_inum, &extents);
759 printf("Migrate complete, running fsck:\n");
760 opts.nostart = false;
761 opts.nochanges = true;
762 fsck_err_opt = FSCK_ERR_NO;
764 err = bch_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("bcache migrate_superblock - create default superblock after migrating\n"
776 "Usage: bcache 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);