Hello community, here is the log from the commit of package btrfsprogs for openSUSE:Factory checked in at 2015-07-19 11:45:23 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/btrfsprogs (Old) and /work/SRC/openSUSE:Factory/.btrfsprogs.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "btrfsprogs" Changes: -------- --- /work/SRC/openSUSE:Factory/btrfsprogs/btrfsprogs.changes 2015-07-05 17:58:09.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.btrfsprogs.new/btrfsprogs.changes 2015-07-19 11:45:24.000000000 +0200 @@ -1,0 +2,28 @@ +Tue Jul 14 00:00:00 CEST 2015 - dste...@suse.com + +- version 4.1.2 + - mkfs: bugfix, previous version does not create entierly correct + filesystem (has to be recreated) + +------------------------------------------------------------------- +Fri Jul 10 00:00:00 CEST 2015 - dste...@suse.com + +- version 4.1.1 + * bugfixes + - defrag: threshold overflow fix + - fsck: + - check if items fit into the leaf space + - fix wrong nbytes + - mkfs: + - create only desired block groups for single device + - preparatory work for fix on multiple devices + * enhancements + - new alias for 'device delete': 'device remove' + * other + - fix compilation on old gcc (4.3) + - documentation updates + - debug-tree: print nbytes + - test: image for corrupted nbytes + - corupt-block: let it kill nbytes + +------------------------------------------------------------------- Old: ---- btrfs-progs-v4.1.tar.gz New: ---- btrfs-progs-v4.1.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ btrfsprogs.spec ++++++ --- /var/tmp/diff_new_pack.enXCNN/_old 2015-07-19 11:45:25.000000000 +0200 +++ /var/tmp/diff_new_pack.enXCNN/_new 2015-07-19 11:45:25.000000000 +0200 @@ -17,7 +17,7 @@ Name: btrfsprogs -Version: 4.1 +Version: 4.1.2 Release: 0 Summary: Utilities for the Btrfs filesystem License: GPL-2.0 ++++++ btrfs-progs-v4.1.tar.gz -> btrfs-progs-v4.1.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/Documentation/btrfs-device.asciidoc new/btrfs-progs-v4.1.2/Documentation/btrfs-device.asciidoc --- old/btrfs-progs-v4.1/Documentation/btrfs-device.asciidoc 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/Documentation/btrfs-device.asciidoc 2015-07-14 13:45:36.000000000 +0200 @@ -74,9 +74,12 @@ -f|--force:::: force overwrite of existing filesystem on the given disk(s) -*delete* <dev> [<dev>...] <path>:: +*remove* <dev> [<dev>...] <path>:: Remove device(s) from a filesystem identified by <path>. +*delete* <dev> [<dev>...] <path>:: +Alias of remove kept for backwards compatability + *ready* <device>:: Check device to see if it has all of it's devices in cache for mounting. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/Documentation/btrfs-filesystem.asciidoc new/btrfs-progs-v4.1.2/Documentation/btrfs-filesystem.asciidoc --- old/btrfs-progs-v4.1/Documentation/btrfs-filesystem.asciidoc 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/Documentation/btrfs-filesystem.asciidoc 2015-07-14 13:45:36.000000000 +0200 @@ -49,27 +49,32 @@ If '-r' is passed, files in dir will be defragmented recursively. The start position and the number of bytes to defragment can be specified by start and len using '-s' and '-l' options below. -Any extent bigger than threshold given by '-t' option, will be considered -already defragged. -Use 0 to take the kernel default. +Extents bigger than value given by '-t' will be skipped, otherwise this value +is used as a target extent size, but is only advisory and may not be reached +if the free space is too fragmented. +Use 0 to take the kernel default, which is 256kB but may change in the future. You can also turn on compression in defragment operations. + `Options` + -v:::: be verbose --c:::: -compress file contents while defragmenting +-c[<algo>]:::: +compress file contents while defragmenting. Optional argument selects the compression +algorithm, 'zlib' (default) or 'lzo'. Currently it's not possible to select no +compression. -r:::: -defragment files recursively +defragment files recursively in given directories -f:::: -flush filesystem after defragmenting +flush data for each file before going to the next file. This will limit the amount +of dirty data to current file, otherwise the amount cumulates from several files +and may increase system load. -s <start>[kKmMgGtTpPeE]:::: defragment only from byte <start> onward -l <len>[kKmMgGtTpPeE]:::: defragment only up to <len> bytes -t <size>[kKmMgGtTpPeE]:::: -defragment only files at least <size> bytes big +target extent size, do not touch extents bigger than <size> + For <start>, <len>, <size> it is possible to append units designator: \'K', \'M', \'G', \'T', \'P', or \'E', which represent diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/Documentation/btrfs.asciidoc new/btrfs-progs-v4.1.2/Documentation/btrfs.asciidoc --- old/btrfs-progs-v4.1/Documentation/btrfs.asciidoc 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/Documentation/btrfs.asciidoc 2015-07-14 13:45:36.000000000 +0200 @@ -75,7 +75,7 @@ See `btrfs-rescue`(8) for details. *restore*:: - Manage a btrfs filesystem, including label setting/sync and so on. + + Try to restore files from a damaged btrfs filesystem. + See `btrfs-restore`(8) for details. *scrub*:: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/Documentation/mkfs.btrfs.asciidoc new/btrfs-progs-v4.1.2/Documentation/mkfs.btrfs.asciidoc --- old/btrfs-progs-v4.1/Documentation/mkfs.btrfs.asciidoc 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/Documentation/mkfs.btrfs.asciidoc 2015-07-14 13:45:36.000000000 +0200 @@ -112,7 +112,7 @@ -O|--features <feature1>[,<feature2>...]:: A list of filesystem features turned on at mkfs time. Not all features are -supported by old kernels. +supported by old kernels. To disable a feature, prefix it with '^'. + To see all features run: + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/btrfs-completion new/btrfs-progs-v4.1.2/btrfs-completion --- old/btrfs-progs-v4.1/btrfs-completion 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/btrfs-completion 2015-07-14 13:45:36.000000000 +0200 @@ -33,7 +33,7 @@ commands_subvolume='create delete list snapshot find-new get-default set-default show sync' commands_filesystem='defragment sync resize show df label usage' commands_balance='start pause cancel resume status' - commands_device='scan add delete ready stats usage' + commands_device='scan add delete remove ready stats usage' commands_scrub='start cancel resume status' commands_rescue='chunk-recover super-recover' commands_inspect_internal='inode-resolve logical-resolve subvolid-resolve rootid' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/btrfs-convert.c new/btrfs-progs-v4.1.2/btrfs-convert.c --- old/btrfs-progs-v4.1/btrfs-convert.c 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/btrfs-convert.c 2015-07-14 13:45:36.000000000 +0200 @@ -2289,6 +2289,7 @@ struct btrfs_root *image_root; struct task_ctx ctx; char features_buf[64]; + struct btrfs_mkfs_config mkfs_cfg; ret = open_ext2fs(devname, &ext2_fs); if (ret) { @@ -2337,9 +2338,17 @@ printf("\tblocksize: %u\n", blocksize); printf("\tnodesize: %u\n", nodesize); printf("\tfeatures: %s\n", features_buf); - ret = make_btrfs(fd, devname, ext2_fs->super->s_volume_name, - NULL, blocks, total_bytes, nodesize, - blocksize, blocksize, features); + + mkfs_cfg.label = ext2_fs->super->s_volume_name; + mkfs_cfg.fs_uuid = NULL; + memcpy(mkfs_cfg.blocks, blocks, sizeof(blocks)); + mkfs_cfg.num_bytes = total_bytes; + mkfs_cfg.nodesize = nodesize; + mkfs_cfg.sectorsize = blocksize; + mkfs_cfg.stripesize = blocksize; + mkfs_cfg.features = features; + + ret = make_btrfs(fd, &mkfs_cfg); if (ret) { fprintf(stderr, "unable to create initial ctree: %s\n", strerror(-ret)); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/btrfs-corrupt-block.c new/btrfs-progs-v4.1.2/btrfs-corrupt-block.c --- old/btrfs-progs-v4.1/btrfs-corrupt-block.c 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/btrfs-corrupt-block.c 2015-07-14 13:45:36.000000000 +0200 @@ -299,6 +299,7 @@ enum btrfs_inode_field { BTRFS_INODE_FIELD_ISIZE, + BTRFS_INODE_FIELD_NBYTES, BTRFS_INODE_FIELD_BAD, }; @@ -335,6 +336,8 @@ { if (!strncmp(field, "isize", FIELD_BUF_LEN)) return BTRFS_INODE_FIELD_ISIZE; + if (!strncmp(field, "nbytes", FIELD_BUF_LEN)) + return BTRFS_INODE_FIELD_NBYTES; return BTRFS_INODE_FIELD_BAD; } @@ -593,6 +596,11 @@ bogus = generate_u64(orig); btrfs_set_inode_size(path->nodes[0], ei, bogus); break; + case BTRFS_INODE_FIELD_NBYTES: + orig = btrfs_inode_nbytes(path->nodes[0], ei); + bogus = generate_u64(orig); + btrfs_set_inode_nbytes(path->nodes[0], ei, bogus); + break; default: ret = -EINVAL; break; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/cmds-check.c new/btrfs-progs-v4.1.2/cmds-check.c --- old/btrfs-progs-v4.1/cmds-check.c 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/cmds-check.c 2015-07-14 13:45:36.000000000 +0200 @@ -1918,6 +1918,39 @@ return ret; } +static int repair_inode_nbytes(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + struct inode_record *rec) +{ + struct btrfs_inode_item *ei; + struct btrfs_key key; + int ret = 0; + + key.objectid = rec->ino; + key.type = BTRFS_INODE_ITEM_KEY; + key.offset = 0; + + ret = btrfs_search_slot(trans, root, &key, path, 0, 1); + if (ret) { + if (ret > 0) + ret = -ENOENT; + goto out; + } + + /* Since ret == 0, no need to check anything */ + ei = btrfs_item_ptr(path->nodes[0], path->slots[0], + struct btrfs_inode_item); + btrfs_set_inode_nbytes(path->nodes[0], ei, rec->found_size); + btrfs_mark_buffer_dirty(path->nodes[0]); + rec->errors &= ~I_ERR_FILE_NBYTES_WRONG; + printf("reset nbytes for ino %llu root %llu\n", + rec->ino, root->root_key.objectid); +out: + btrfs_release_path(path); + return ret; +} + static int add_missing_dir_index(struct btrfs_root *root, struct cache_tree *inode_cache, struct inode_record *rec, @@ -2661,7 +2694,8 @@ I_ERR_LINK_COUNT_WRONG | I_ERR_NO_INODE_ITEM | I_ERR_FILE_EXTENT_ORPHAN | - I_ERR_FILE_EXTENT_DISCOUNT))) + I_ERR_FILE_EXTENT_DISCOUNT| + I_ERR_FILE_NBYTES_WRONG))) return rec->errors; path = btrfs_alloc_path(); @@ -2693,6 +2727,8 @@ ret = repair_inode_orphan_item(trans, root, path, rec); if (!ret && rec->errors & I_ERR_LINK_COUNT_WRONG) ret = repair_inode_nlinks(trans, root, path, rec); + if (!ret && rec->errors & I_ERR_FILE_NBYTES_WRONG) + ret = repair_inode_nbytes(trans, root, path, rec); btrfs_commit_transaction(trans, root); btrfs_free_path(path); return ret; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/cmds-device.c new/btrfs-progs-v4.1.2/cmds-device.c --- old/btrfs-progs-v4.1/cmds-device.c 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/cmds-device.c 2015-07-14 13:45:36.000000000 +0200 @@ -143,20 +143,14 @@ return !!ret; } -static const char * const cmd_rm_dev_usage[] = { - "btrfs device delete <device> [<device>...] <path>", - "Remove a device from a filesystem", - NULL -}; - -static int cmd_rm_dev(int argc, char **argv) +static int _cmd_rm_dev(int argc, char **argv, const char * const *usagestr) { char *mntpnt; int i, fdmnt, ret=0, e; DIR *dirstream = NULL; if (check_argc_min(argc, 3)) - usage(cmd_rm_dev_usage); + usage(usagestr); mntpnt = argv[argc - 1]; @@ -198,6 +192,28 @@ return !!ret; } +static const char * const cmd_rm_dev_usage[] = { + "btrfs device remove <device> [<device>...] <path>", + "Remove a device from a filesystem", + NULL +}; + +static int cmd_rm_dev(int argc, char **argv) +{ + return _cmd_rm_dev(argc, argv, cmd_rm_dev_usage); +} + +static const char * const cmd_del_dev_usage[] = { + "btrfs device delete <device> [<device>...] <path>", + "Remove a device from a filesystem", + NULL +}; + +static int cmd_del_dev(int argc, char **argv) +{ + return _cmd_rm_dev(argc, argv, cmd_del_dev_usage); +} + static const char * const cmd_scan_dev_usage[] = { "btrfs device scan [(-d|--all-devices)|<device> [<device>...]]", "Scan devices for a btrfs filesystem", @@ -590,7 +606,8 @@ const struct cmd_group device_cmd_group = { device_cmd_group_usage, device_cmd_group_info, { { "add", cmd_add_dev, cmd_add_dev_usage, NULL, 0 }, - { "delete", cmd_rm_dev, cmd_rm_dev_usage, NULL, 0 }, + { "delete", cmd_del_dev, cmd_del_dev_usage, NULL, CMD_ALIAS }, + { "remove", cmd_rm_dev, cmd_rm_dev_usage, NULL, 0 }, { "scan", cmd_scan_dev, cmd_scan_dev_usage, NULL, 0 }, { "ready", cmd_ready_dev, cmd_ready_dev_usage, NULL, 0 }, { "stats", cmd_dev_stats, cmd_dev_stats_usage, NULL, 0 }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/cmds-filesystem.c new/btrfs-progs-v4.1.2/cmds-filesystem.c --- old/btrfs-progs-v4.1/cmds-filesystem.c 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/cmds-filesystem.c 2015-07-14 13:45:36.000000000 +0200 @@ -1065,7 +1065,7 @@ "-f flush data to disk immediately after defragmenting", "-s start defragment only from byte onward", "-l len defragment only up to len bytes", - "-t size minimal size of file to be considered for defragmenting", + "-t size target extent size hint", NULL }; @@ -1127,7 +1127,7 @@ int flush = 0; u64 start = 0; u64 len = (u64)-1; - u32 thresh = 0; + u64 thresh = 0; int i; int recursive = 0; int ret = 0; @@ -1170,6 +1170,11 @@ break; case 't': thresh = parse_size(optarg); + if (thresh > (u32)-1) { + fprintf(stderr, + "WARNING: target extent size %llu too big, trimmed to %u", + thresh, (u32)-1); + } defrag_global_fancy_ioctl = 1; break; case 'r': @@ -1186,7 +1191,7 @@ memset(&defrag_global_range, 0, sizeof(range)); defrag_global_range.start = start; defrag_global_range.len = len; - defrag_global_range.extent_thresh = thresh; + defrag_global_range.extent_thresh = (u32)thresh; if (compress_type) { defrag_global_range.flags |= BTRFS_DEFRAG_RANGE_COMPRESS; defrag_global_range.compress_type = compress_type; @@ -1377,7 +1382,7 @@ { "show", cmd_show, cmd_show_usage, NULL, 0 }, { "sync", cmd_sync, cmd_sync_usage, NULL, 0 }, { "defragment", cmd_defrag, cmd_defrag_usage, NULL, 0 }, - { "balance", cmd_balance, NULL, &balance_cmd_group, 1 }, + { "balance", cmd_balance, NULL, &balance_cmd_group, CMD_HIDDEN }, { "resize", cmd_resize, cmd_resize_usage, NULL, 0 }, { "label", cmd_label, cmd_label_usage, NULL, 0 }, { "usage", cmd_filesystem_usage, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/cmds-inspect.c new/btrfs-progs-v4.1.2/cmds-inspect.c --- old/btrfs-progs-v4.1/cmds-inspect.c 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/cmds-inspect.c 2015-07-14 13:45:36.000000000 +0200 @@ -293,7 +293,7 @@ goto out; } - path[PATH_MAX] = '\0'; + path[PATH_MAX - 1] = '\0'; printf("%s\n", path); out: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/commands.h new/btrfs-progs-v4.1.2/commands.h --- old/btrfs-progs-v4.1/commands.h 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/commands.h 2015-07-14 13:45:36.000000000 +0200 @@ -17,6 +17,11 @@ #ifndef __BTRFS_COMMANDS_H__ #define __BTRFS_COMMANDS_H__ +enum { + CMD_HIDDEN = (1 << 0), /* should not be in help listings */ + CMD_ALIAS = (1 << 1), /* alias of next command in cmd_group */ +}; + struct cmd_struct { const char *token; int (*fn)(int, char **); @@ -47,8 +52,8 @@ /* should be NULL if token is not a subgroup */ const struct cmd_group *next; - /* if true don't list this token in help listings */ - int hidden; + /* CMD_* flags above */ + int flags; }; #define NULL_CMD_STRUCT {NULL, NULL, NULL, NULL, 0} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/configure new/btrfs-progs-v4.1.2/configure --- old/btrfs-progs-v4.1/configure 2015-06-22 16:49:06.000000000 +0200 +++ new/btrfs-progs-v4.1.2/configure 2015-07-14 13:46:56.000000000 +0200 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for btrfs-progs v4.1. +# Generated by GNU Autoconf 2.69 for btrfs-progs v4.1.2. # # Report bugs to <linux-bt...@vger.kernel.org>. # @@ -580,8 +580,8 @@ # Identity of this package. PACKAGE_NAME='btrfs-progs' PACKAGE_TARNAME='btrfs-progs' -PACKAGE_VERSION='v4.1' -PACKAGE_STRING='btrfs-progs v4.1' +PACKAGE_VERSION='v4.1.2' +PACKAGE_STRING='btrfs-progs v4.1.2' PACKAGE_BUGREPORT='linux-bt...@vger.kernel.org' PACKAGE_URL='http://btrfs.wiki.kernel.org' @@ -1287,7 +1287,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures btrfs-progs v4.1 to adapt to many kinds of systems. +\`configure' configures btrfs-progs v4.1.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1352,7 +1352,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of btrfs-progs v4.1:";; + short | recursive ) echo "Configuration of btrfs-progs v4.1.2:";; esac cat <<\_ACEOF @@ -1461,7 +1461,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -btrfs-progs configure v4.1 +btrfs-progs configure v4.1.2 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1830,7 +1830,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by btrfs-progs $as_me v4.1, which was +It was created by btrfs-progs $as_me v4.1.2, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -6375,7 +6375,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by btrfs-progs $as_me v4.1, which was +This file was extended by btrfs-progs $as_me v4.1.2, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -6438,7 +6438,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -btrfs-progs config.status v4.1 +btrfs-progs config.status v4.1.2 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/ctree.c new/btrfs-progs-v4.1.2/ctree.c --- old/btrfs-progs-v4.1/ctree.c 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/ctree.c 2015-07-14 13:45:36.000000000 +0200 @@ -521,6 +521,20 @@ goto fail; } } + + for (i = 0; i < nritems; i++) { + if (btrfs_item_end_nr(buf, i) > BTRFS_LEAF_DATA_SIZE(root)) { + btrfs_item_key(buf, &key, 0); + btrfs_print_key(&key); + fflush(stdout); + ret = BTRFS_TREE_BLOCK_INVALID_OFFSETS; + fprintf(stderr, "slot end outside of leaf %llu > %llu\n", + (unsigned long long)btrfs_item_end_nr(buf, i), + (unsigned long long)BTRFS_LEAF_DATA_SIZE(root)); + goto fail; + } + } + return BTRFS_TREE_BLOCK_CLEAN; fail: if (btrfs_header_owner(buf) == BTRFS_EXTENT_TREE_OBJECTID) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/ctree.h new/btrfs-progs-v4.1.2/ctree.h --- old/btrfs-progs-v4.1/ctree.h 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/ctree.h 2015-07-14 13:45:36.000000000 +0200 @@ -2275,6 +2275,8 @@ struct btrfs_inode_item *inode, u64 file_pos, u64 disk_bytenr, u64 num_bytes); +int btrfs_free_block_group(struct btrfs_trans_handle *trans, + struct btrfs_fs_info *fs_info, u64 bytenr, u64 len); /* ctree.c */ int btrfs_comp_cpu_keys(struct btrfs_key *k1, struct btrfs_key *k2); int btrfs_del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/disk-io.c new/btrfs-progs-v4.1.2/disk-io.c --- old/btrfs-progs-v4.1/disk-io.c 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/disk-io.c 2015-07-14 13:45:36.000000000 +0200 @@ -571,6 +571,8 @@ goto commit_tree; if (root == root->fs_info->tree_root) goto commit_tree; + if (root == root->fs_info->chunk_root) + goto commit_tree; free_extent_buffer(root->commit_root); root->commit_root = NULL; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/extent-tree.c new/btrfs-progs-v4.1.2/extent-tree.c --- old/btrfs-progs-v4.1/extent-tree.c 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/extent-tree.c 2015-07-14 13:45:36.000000000 +0200 @@ -1801,6 +1801,31 @@ } +static int free_space_info(struct btrfs_fs_info *fs_info, u64 flags, + u64 total_bytes, u64 bytes_used, + struct btrfs_space_info **space_info) +{ + struct btrfs_space_info *found; + + /* only support free block group which is empty */ + if (bytes_used) + return -ENOTEMPTY; + + found = __find_space_info(fs_info, flags); + if (!found) + return -ENOENT; + if (found->total_bytes < total_bytes) { + fprintf(stderr, + "WARNING: bad space info to free %llu only have %llu\n", + total_bytes, found->total_bytes); + return -EINVAL; + } + found->total_bytes -= total_bytes; + if (space_info) + *space_info = found; + return 0; +} + static int update_space_info(struct btrfs_fs_info *info, u64 flags, u64 total_bytes, u64 bytes_used, struct btrfs_space_info **space_info) @@ -3448,6 +3473,357 @@ } /* + * Just remove a block group item in extent tree + * Caller should ensure the block group is empty and all space is pinned. + * Or new tree block/data may be allocated into it. + */ +static int free_block_group_item(struct btrfs_trans_handle *trans, + struct btrfs_fs_info *fs_info, + u64 bytenr, u64 len) +{ + struct btrfs_path *path; + struct btrfs_key key; + struct btrfs_root *root = fs_info->extent_root; + int ret = 0; + + key.objectid = bytenr; + key.offset = len; + key.type = BTRFS_BLOCK_GROUP_ITEM_KEY; + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + + ret = btrfs_search_slot(trans, root, &key, path, -1, 1); + if (ret > 0) { + ret = -ENOENT; + goto out; + } + if (ret < 0) + goto out; + + ret = btrfs_del_item(trans, root, path); +out: + btrfs_free_path(path); + return ret; +} + +static int free_dev_extent_item(struct btrfs_trans_handle *trans, + struct btrfs_fs_info *fs_info, + u64 devid, u64 dev_offset) +{ + struct btrfs_root *root = fs_info->dev_root; + struct btrfs_path *path; + struct btrfs_key key; + int ret; + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + + key.objectid = devid; + key.type = BTRFS_DEV_EXTENT_KEY; + key.offset = dev_offset; + + ret = btrfs_search_slot(trans, root, &key, path, -1, 1); + if (ret < 0) + goto out; + if (ret > 0) { + ret = -ENOENT; + goto out; + } + + ret = btrfs_del_item(trans, root, path); +out: + btrfs_free_path(path); + return ret; +} + +static int free_chunk_dev_extent_items(struct btrfs_trans_handle *trans, + struct btrfs_fs_info *fs_info, + u64 chunk_offset) +{ + struct btrfs_chunk *chunk = NULL; + struct btrfs_root *root= fs_info->chunk_root; + struct btrfs_path *path; + struct btrfs_key key; + u16 num_stripes; + int i; + int ret; + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + + key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID; + key.type = BTRFS_CHUNK_ITEM_KEY; + key.offset = chunk_offset; + + ret = btrfs_search_slot(trans, root, &key, path, 0, 0); + if (ret < 0) + goto out; + if (ret > 0) { + ret = -ENOENT; + goto out; + } + chunk = btrfs_item_ptr(path->nodes[0], path->slots[0], + struct btrfs_chunk); + num_stripes = btrfs_chunk_num_stripes(path->nodes[0], chunk); + for (i = 0; i < num_stripes; i++) { + ret = free_dev_extent_item(trans, fs_info, + btrfs_stripe_devid_nr(path->nodes[0], chunk, i), + btrfs_stripe_offset_nr(path->nodes[0], chunk, i)); + if (ret < 0) + goto out; + } +out: + btrfs_free_path(path); + return ret; +} + +static int free_system_chunk_item(struct btrfs_super_block *super, + struct btrfs_key *key) +{ + struct btrfs_disk_key *disk_key; + struct btrfs_key cpu_key; + u32 array_size = btrfs_super_sys_array_size(super); + char *ptr = (char *)super->sys_chunk_array; + int cur = 0; + int ret = -ENOENT; + + while (cur < btrfs_super_sys_array_size(super)) { + struct btrfs_chunk *chunk; + u32 num_stripes; + u32 chunk_len; + + disk_key = (struct btrfs_disk_key *)(ptr + cur); + btrfs_disk_key_to_cpu(&cpu_key, disk_key); + if (cpu_key.type != BTRFS_CHUNK_ITEM_KEY) { + /* just in case */ + ret = -EIO; + goto out; + } + + chunk = (struct btrfs_chunk *)(ptr + cur + sizeof(*disk_key)); + num_stripes = btrfs_stack_chunk_num_stripes(chunk); + chunk_len = btrfs_chunk_item_size(num_stripes) + + sizeof(*disk_key); + + if (key->objectid == cpu_key.objectid && + key->offset == cpu_key.offset && + key->type == cpu_key.type) { + memmove(ptr + cur, ptr + cur + chunk_len, + array_size - cur - chunk_len); + array_size -= chunk_len; + btrfs_set_super_sys_array_size(super, array_size); + ret = 0; + goto out; + } + + cur += chunk_len; + } +out: + return ret; +} + +static int free_chunk_item(struct btrfs_trans_handle *trans, + struct btrfs_fs_info *fs_info, + u64 bytenr, u64 len) +{ + struct btrfs_path *path; + struct btrfs_key key; + struct btrfs_root *root = fs_info->chunk_root; + struct btrfs_chunk *chunk; + u64 chunk_type; + int ret; + + key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID; + key.offset = bytenr; + key.type = BTRFS_CHUNK_ITEM_KEY; + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + + ret = btrfs_search_slot(trans, root, &key, path, -1, 1); + if (ret > 0) { + ret = -ENOENT; + goto out; + } + if (ret < 0) + goto out; + chunk = btrfs_item_ptr(path->nodes[0], path->slots[0], + struct btrfs_chunk); + chunk_type = btrfs_chunk_type(path->nodes[0], chunk); + + ret = btrfs_del_item(trans, root, path); + if (ret < 0) + goto out; + + if (chunk_type & BTRFS_BLOCK_GROUP_SYSTEM) + ret = free_system_chunk_item(fs_info->super_copy, &key); +out: + btrfs_free_path(path); + return ret; +} + +static u64 get_dev_extent_len(struct map_lookup *map) +{ + int div; + + switch (map->type & BTRFS_BLOCK_GROUP_PROFILE_MASK) { + case 0: /* Single */ + case BTRFS_BLOCK_GROUP_DUP: + case BTRFS_BLOCK_GROUP_RAID1: + div = 1; + break; + case BTRFS_BLOCK_GROUP_RAID5: + div = (map->num_stripes - 1); + break; + case BTRFS_BLOCK_GROUP_RAID6: + div = (map->num_stripes - 2); + break; + case BTRFS_BLOCK_GROUP_RAID10: + div = (map->num_stripes / map->sub_stripes); + break; + default: + /* normally, read chunk security hook should handled it */ + BUG_ON(1); + } + return map->ce.size / div; +} + +/* free block group/chunk related caches */ +static int free_block_group_cache(struct btrfs_trans_handle *trans, + struct btrfs_fs_info *fs_info, + u64 bytenr, u64 len) +{ + struct btrfs_block_group_cache *cache; + struct cache_extent *ce; + struct map_lookup *map; + int ret; + int i; + u64 flags; + + /* Free block group cache first */ + cache = btrfs_lookup_block_group(fs_info, bytenr); + if (!cache) + return -ENOENT; + flags = cache->flags; + if (cache->free_space_ctl) { + btrfs_remove_free_space_cache(cache); + kfree(cache->free_space_ctl); + } + clear_extent_bits(&fs_info->block_group_cache, bytenr, bytenr + len, + (unsigned int)-1, GFP_NOFS); + ret = free_space_info(fs_info, flags, len, 0, NULL); + if (ret < 0) + goto out; + kfree(cache); + + /* Then free mapping info and dev usage info */ + ce = search_cache_extent(&fs_info->mapping_tree.cache_tree, bytenr); + if (!ce || ce->start != bytenr) { + ret = -ENOENT; + goto out; + } + map = container_of(ce, struct map_lookup, ce); + for (i = 0; i < map->num_stripes; i++) { + struct btrfs_device *device; + + device = map->stripes[i].dev; + device->bytes_used -= get_dev_extent_len(map); + ret = btrfs_update_device(trans, device); + if (ret < 0) + goto out; + } + remove_cache_extent(&fs_info->mapping_tree.cache_tree, ce); + free(map); +out: + return ret; +} + +int btrfs_free_block_group(struct btrfs_trans_handle *trans, + struct btrfs_fs_info *fs_info, u64 bytenr, u64 len) +{ + struct btrfs_root *extent_root = fs_info->extent_root; + struct btrfs_path *path; + struct btrfs_block_group_item *bgi; + struct btrfs_key key; + int ret = 0; + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + + key.objectid = bytenr; + key.type = BTRFS_BLOCK_GROUP_ITEM_KEY; + key.offset = len; + + /* Double check the block group to ensure it's empty */ + ret = btrfs_search_slot(trans, extent_root, &key, path, 0, 0); + if (ret > 0) { + ret = -ENONET; + goto out; + } + if (ret < 0) + goto out; + + bgi = btrfs_item_ptr(path->nodes[0], path->slots[0], + struct btrfs_block_group_item); + if (btrfs_disk_block_group_used(path->nodes[0], bgi)) { + fprintf(stderr, + "WARNING: block group [%llu,%llu) is not empty\n", + bytenr, bytenr + len); + ret = -EINVAL; + goto out; + } + btrfs_release_path(path); + + /* + * Now pin all space in the block group, to prevent further transaction + * allocate space from it. + * Every operation needs a transaction must be in the range. + */ + btrfs_pin_extent(fs_info, bytenr, len); + + /* delete block group item and chunk item */ + ret = free_block_group_item(trans, fs_info, bytenr, len); + if (ret < 0) { + fprintf(stderr, + "failed to free block group item for [%llu,%llu)\n", + bytenr, bytenr + len); + btrfs_unpin_extent(fs_info, bytenr, len); + goto out; + } + + ret = free_chunk_dev_extent_items(trans, fs_info, bytenr); + if (ret < 0) { + fprintf(stderr, + "failed to dev extents belongs to [%llu,%llu)\n", + bytenr, bytenr + len); + btrfs_unpin_extent(fs_info, bytenr, len); + goto out; + } + ret = free_chunk_item(trans, fs_info, bytenr, len); + if (ret < 0) { + fprintf(stderr, + "failed to free chunk for [%llu,%llu)\n", + bytenr, bytenr + len); + btrfs_unpin_extent(fs_info, bytenr, len); + goto out; + } + + /* Now release the block_group_cache */ + ret = free_block_group_cache(trans, fs_info, bytenr, len); + btrfs_unpin_extent(fs_info, bytenr, len); + +out: + btrfs_free_path(path); + return ret; +} + +/* * Fixup block accounting. The initial block accounting created by * make_block_groups isn't accuracy in this case. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/help.c new/btrfs-progs-v4.1.2/help.c --- old/btrfs-progs-v4.1/help.c 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/help.c 2015-07-14 13:45:36.000000000 +0200 @@ -35,7 +35,7 @@ if (!usagestr || !*usagestr) return -1; - fprintf(outf, "%s%s\n", (flags & USAGE_LISTING) ? " " : "usage: ", + fprintf(outf, "%s%s", (flags & USAGE_LISTING) ? " " : "usage: ", *usagestr++); /* a short one-line description (mandatory) */ @@ -43,6 +43,7 @@ return 0; else if (!*usagestr) return -2; + fputc('\n', outf); if (flags & USAGE_LISTING) pad = 8; @@ -79,11 +80,13 @@ static int usage_command_internal(const char * const *usagestr, const char *token, int full, int lst, - FILE *outf) + int alias, FILE *outf) { - unsigned int flags = USAGE_SHORT; + unsigned int flags = 0; int ret; + if (!alias) + flags |= USAGE_SHORT; if (full) flags |= USAGE_LONG | USAGE_OPTIONS; if (lst) @@ -108,7 +111,7 @@ FILE *outf = err ? stderr : stdout; int ret; - ret = usage_command_internal(usagestr, token, full, 0, outf); + ret = usage_command_internal(usagestr, token, full, 0, 0, outf); if (!ret) fputc('\n', outf); } @@ -131,7 +134,7 @@ int do_sep = 0; for (; cmd->token; cmd++) { - if (cmd->hidden) + if (cmd->flags & CMD_HIDDEN) continue; if (full && cmd != grp->commands) @@ -144,7 +147,7 @@ } usage_command_internal(cmd->usagestr, cmd->token, full, - 1, outf); + 1, cmd->flags & CMD_ALIAS, outf); continue; } @@ -176,7 +179,7 @@ fprintf(outf, "Command groups:\n"); for (cmd = grp->commands; cmd->token; cmd++) { - if (cmd->hidden) + if (cmd->flags & CMD_HIDDEN) continue; if (!cmd->next) @@ -187,7 +190,7 @@ fprintf(outf, "\nCommands:\n"); for (cmd = grp->commands; cmd->token; cmd++) { - if (cmd->hidden) + if (cmd->flags & CMD_HIDDEN) continue; if (cmd->next) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/mkfs.c new/btrfs-progs-v4.1.2/mkfs.c --- old/btrfs-progs-v4.1/mkfs.c 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/mkfs.c 2015-07-14 13:45:36.000000000 +0200 @@ -59,11 +59,10 @@ u64 system; }; -static int make_root_dir(struct btrfs_root *root, int mixed, +static int create_metadata_block_groups(struct btrfs_root *root, int mixed, struct mkfs_allocation *allocation) { struct btrfs_trans_handle *trans; - struct btrfs_key location; u64 bytes_used; u64 chunk_start = 0; u64 chunk_size = 0; @@ -117,8 +116,18 @@ root->fs_info->system_allocs = 0; btrfs_commit_transaction(trans, root); - trans = btrfs_start_transaction(root, 1); - BUG_ON(!trans); + +err: + return ret; +} + +static int create_data_block_groups(struct btrfs_trans_handle *trans, + struct btrfs_root *root, int mixed, + struct mkfs_allocation *allocation) +{ + u64 chunk_start = 0; + u64 chunk_size = 0; + int ret = 0; if (!mixed) { ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root, @@ -137,6 +146,16 @@ BUG_ON(ret); } +err: + return ret; +} + +static int make_root_dir(struct btrfs_trans_handle *trans, struct btrfs_root *root, + int mixed, struct mkfs_allocation *allocation) +{ + struct btrfs_key location; + int ret; + ret = btrfs_make_root_dir(trans, root->fs_info->tree_root, BTRFS_ROOT_TREE_DIR_OBJECTID); if (ret) @@ -159,7 +178,6 @@ if (ret) goto err; - btrfs_commit_transaction(trans, root); err: return ret; } @@ -229,8 +247,7 @@ static int create_raid_groups(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 data_profile, - int data_profile_opt, u64 metadata_profile, - int mixed, + u64 metadata_profile, int mixed, struct mkfs_allocation *allocation) { u64 num_devices = btrfs_super_num_devices(root->fs_info->super_copy); @@ -1187,7 +1204,6 @@ int discard = 1; int ssd = 0; int force_overwrite = 0; - char *source_dir = NULL; int source_dir_set = 0; u64 num_of_meta_chunks = 0; @@ -1198,6 +1214,7 @@ char fs_uuid[BTRFS_UUID_UNPARSED_SIZE] = { 0 }; u64 features = BTRFS_MKFS_DEFAULT_FEATURES; struct mkfs_allocation allocation = { 0 }; + struct btrfs_mkfs_config mkfs_cfg; while(1) { int c; @@ -1507,8 +1524,16 @@ features |= BTRFS_FEATURE_INCOMPAT_RAID56; } - ret = make_btrfs(fd, file, label, fs_uuid, blocks, dev_block_count, - nodesize, sectorsize, stripesize, features); + mkfs_cfg.label = label; + mkfs_cfg.fs_uuid = fs_uuid; + memcpy(mkfs_cfg.blocks, blocks, sizeof(blocks)); + mkfs_cfg.num_bytes = dev_block_count; + mkfs_cfg.nodesize = nodesize; + mkfs_cfg.sectorsize = sectorsize; + mkfs_cfg.stripesize = stripesize; + mkfs_cfg.features = features; + + ret = make_btrfs(fd, &mkfs_cfg); if (ret) { fprintf(stderr, "error during mkfs: %s\n", strerror(-ret)); exit(1); @@ -1522,12 +1547,29 @@ } root->fs_info->alloc_start = alloc_start; - ret = make_root_dir(root, mixed, &allocation); + ret = create_metadata_block_groups(root, mixed, &allocation); + if (ret) { + fprintf(stderr, "failed to create default block groups\n"); + exit(1); + } + + trans = btrfs_start_transaction(root, 1); + BUG_ON(!trans); + + ret = create_data_block_groups(trans, root, mixed, &allocation); + if (ret) { + fprintf(stderr, "failed to create default data block groups\n"); + exit(1); + } + + ret = make_root_dir(trans, root, mixed, &allocation); if (ret) { fprintf(stderr, "failed to setup the root directory\n"); exit(1); } + btrfs_commit_transaction(trans, root); + trans = btrfs_start_transaction(root, 1); if (is_block_device(file)) @@ -1587,8 +1629,7 @@ raid_groups: if (!source_dir_set) { ret = create_raid_groups(trans, root, data_profile, - data_profile_opt, metadata_profile, - mixed, &allocation); + metadata_profile, mixed, &allocation); BUG_ON(ret); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/print-tree.c new/btrfs-progs-v4.1.2/print-tree.c --- old/btrfs-progs-v4.1/print-tree.c 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/print-tree.c 2015-07-14 13:45:36.000000000 +0200 @@ -841,10 +841,13 @@ switch (type) { case BTRFS_INODE_ITEM_KEY: ii = btrfs_item_ptr(l, i, struct btrfs_inode_item); - printf("\t\tinode generation %llu transid %llu size %llu block group %llu mode %o links %u uid %u gid %u rdev %llu flags 0x%llx\n", + printf("\t\tinode generation %llu transid %llu size %llu nbytes %llu\n" + "\t\tblock group %llu mode %o links %u uid %u gid %u\n" + "\t\trdev %llu flags 0x%llx\n", (unsigned long long)btrfs_inode_generation(l, ii), (unsigned long long)btrfs_inode_transid(l, ii), (unsigned long long)btrfs_inode_size(l, ii), + (unsigned long long)btrfs_inode_nbytes(l, ii), (unsigned long long)btrfs_inode_block_group(l,ii), btrfs_inode_mode(l, ii), btrfs_inode_nlink(l, ii), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/send-utils.c new/btrfs-progs-v4.1.2/send-utils.c --- old/btrfs-progs-v4.1/send-utils.c 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/send-utils.c 2015-07-14 13:45:36.000000000 +0200 @@ -727,7 +727,7 @@ return 0; } -__attribute__((deprecated("please use path_cat_out"))) +__attribute__((deprecated)) char *path_cat(const char *p1, const char *p2) { int p1_len = strlen(p1); @@ -759,7 +759,7 @@ return 0; } -__attribute__((deprecated("please use path_cat3_out"))) +__attribute__((deprecated)) char *path_cat3(const char *p1, const char *p2, const char *p3) { int p1_len = strlen(p1); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/send-utils.h new/btrfs-progs-v4.1.2/send-utils.h --- old/btrfs-progs-v4.1/send-utils.h 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/send-utils.h 2015-07-14 13:45:36.000000000 +0200 @@ -93,9 +93,9 @@ * DEPRECATED: the functions path_cat and path_cat3 are unsafe and should not * be used, use the _out variants and always check the return code. */ -__attribute__((deprecated("please use path_cat_out"))) +__attribute__((deprecated)) char *path_cat(const char *p1, const char *p2); -__attribute__((deprecated("please use path_cat3_out"))) +__attribute__((deprecated)) char *path_cat3(const char *p1, const char *p2, const char *p3); int path_cat_out(char *out, const char *p1, const char *p2); Files old/btrfs-progs-v4.1/tests/fsck-tests/016-wrong-inode-nbytes/default_case.img.xz and new/btrfs-progs-v4.1.2/tests/fsck-tests/016-wrong-inode-nbytes/default_case.img.xz differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/utils.c new/btrfs-progs-v4.1.2/utils.c --- old/btrfs-progs-v4.1/utils.c 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/utils.c 2015-07-14 13:45:36.000000000 +0200 @@ -177,9 +177,7 @@ /* * @fs_uuid - if NULL, generates a UUID, returns back the new filesystem UUID */ -int make_btrfs(int fd, const char *device, const char *label, char *fs_uuid, - u64 blocks[7], u64 num_bytes, u32 nodesize, - u32 sectorsize, u32 stripesize, u64 features) +int make_btrfs(int fd, struct btrfs_mkfs_config *cfg) { struct btrfs_super_block super; struct extent_buffer *buf = NULL; @@ -200,59 +198,61 @@ u64 ref_root; u32 array_size; u32 item_size; - int skinny_metadata = !!(features & + int skinny_metadata = !!(cfg->features & BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA); + u64 num_bytes; - first_free = BTRFS_SUPER_INFO_OFFSET + sectorsize * 2 - 1; - first_free &= ~((u64)sectorsize - 1); + first_free = BTRFS_SUPER_INFO_OFFSET + cfg->sectorsize * 2 - 1; + first_free &= ~((u64)cfg->sectorsize - 1); memset(&super, 0, sizeof(super)); - num_bytes = (num_bytes / sectorsize) * sectorsize; - if (fs_uuid && *fs_uuid) { - if (uuid_parse(fs_uuid, super.fsid) != 0) { - fprintf(stderr, "could not parse UUID: %s\n", fs_uuid); + num_bytes = (cfg->num_bytes / cfg->sectorsize) * cfg->sectorsize; + if (cfg->fs_uuid && *cfg->fs_uuid) { + if (uuid_parse(cfg->fs_uuid, super.fsid) != 0) { + fprintf(stderr, "could not parse UUID: %s\n", + cfg->fs_uuid); ret = -EINVAL; goto out; } - if (!test_uuid_unique(fs_uuid)) { - fprintf(stderr, "non-unique UUID: %s\n", fs_uuid); + if (!test_uuid_unique(cfg->fs_uuid)) { + fprintf(stderr, "non-unique UUID: %s\n", cfg->fs_uuid); ret = -EBUSY; goto out; } } else { uuid_generate(super.fsid); - if (fs_uuid) - uuid_unparse(super.fsid, fs_uuid); + if (cfg->fs_uuid) + uuid_unparse(super.fsid, cfg->fs_uuid); } uuid_generate(super.dev_item.uuid); uuid_generate(chunk_tree_uuid); - btrfs_set_super_bytenr(&super, blocks[0]); + btrfs_set_super_bytenr(&super, cfg->blocks[0]); btrfs_set_super_num_devices(&super, 1); btrfs_set_super_magic(&super, BTRFS_MAGIC); btrfs_set_super_generation(&super, 1); - btrfs_set_super_root(&super, blocks[1]); - btrfs_set_super_chunk_root(&super, blocks[3]); + btrfs_set_super_root(&super, cfg->blocks[1]); + btrfs_set_super_chunk_root(&super, cfg->blocks[3]); btrfs_set_super_total_bytes(&super, num_bytes); - btrfs_set_super_bytes_used(&super, 6 * nodesize); - btrfs_set_super_sectorsize(&super, sectorsize); - btrfs_set_super_leafsize(&super, nodesize); - btrfs_set_super_nodesize(&super, nodesize); - btrfs_set_super_stripesize(&super, stripesize); + btrfs_set_super_bytes_used(&super, 6 * cfg->nodesize); + btrfs_set_super_sectorsize(&super, cfg->sectorsize); + btrfs_set_super_leafsize(&super, cfg->nodesize); + btrfs_set_super_nodesize(&super, cfg->nodesize); + btrfs_set_super_stripesize(&super, cfg->stripesize); btrfs_set_super_csum_type(&super, BTRFS_CSUM_TYPE_CRC32); btrfs_set_super_chunk_root_generation(&super, 1); btrfs_set_super_cache_generation(&super, -1); - btrfs_set_super_incompat_flags(&super, features); - if (label) - strncpy(super.label, label, BTRFS_LABEL_SIZE - 1); + btrfs_set_super_incompat_flags(&super, cfg->features); + if (cfg->label) + strncpy(super.label, cfg->label, BTRFS_LABEL_SIZE - 1); - buf = malloc(sizeof(*buf) + max(sectorsize, nodesize)); + buf = malloc(sizeof(*buf) + max(cfg->sectorsize, cfg->nodesize)); /* create the tree of root objects */ - memset(buf->data, 0, nodesize); - buf->len = nodesize; - btrfs_set_header_bytenr(buf, blocks[1]); + memset(buf->data, 0, cfg->nodesize); + buf->len = cfg->nodesize; + btrfs_set_header_bytenr(buf, cfg->blocks[1]); btrfs_set_header_nritems(buf, 4); btrfs_set_header_generation(buf, 1); btrfs_set_header_backref_rev(buf, BTRFS_MIXED_BACKREF_REV); @@ -270,10 +270,10 @@ btrfs_set_stack_inode_generation(inode_item, 1); btrfs_set_stack_inode_size(inode_item, 3); btrfs_set_stack_inode_nlink(inode_item, 1); - btrfs_set_stack_inode_nbytes(inode_item, nodesize); + btrfs_set_stack_inode_nbytes(inode_item, cfg->nodesize); btrfs_set_stack_inode_mode(inode_item, S_IFDIR | 0755); btrfs_set_root_refs(&root_item, 1); - btrfs_set_root_used(&root_item, nodesize); + btrfs_set_root_used(&root_item, cfg->nodesize); btrfs_set_root_generation(&root_item, 1); memset(&disk_key, 0, sizeof(disk_key)); @@ -281,8 +281,8 @@ btrfs_set_disk_key_offset(&disk_key, 0); nritems = 0; - itemoff = __BTRFS_LEAF_DATA_SIZE(nodesize) - sizeof(root_item); - btrfs_set_root_bytenr(&root_item, blocks[2]); + itemoff = __BTRFS_LEAF_DATA_SIZE(cfg->nodesize) - sizeof(root_item); + btrfs_set_root_bytenr(&root_item, cfg->blocks[2]); btrfs_set_disk_key_objectid(&disk_key, BTRFS_EXTENT_TREE_OBJECTID); btrfs_set_item_key(buf, &disk_key, nritems); btrfs_set_item_offset(buf, btrfs_item_nr(nritems), itemoff); @@ -293,7 +293,7 @@ nritems++; itemoff = itemoff - sizeof(root_item); - btrfs_set_root_bytenr(&root_item, blocks[4]); + btrfs_set_root_bytenr(&root_item, cfg->blocks[4]); btrfs_set_disk_key_objectid(&disk_key, BTRFS_DEV_TREE_OBJECTID); btrfs_set_item_key(buf, &disk_key, nritems); btrfs_set_item_offset(buf, btrfs_item_nr(nritems), itemoff); @@ -305,7 +305,7 @@ nritems++; itemoff = itemoff - sizeof(root_item); - btrfs_set_root_bytenr(&root_item, blocks[5]); + btrfs_set_root_bytenr(&root_item, cfg->blocks[5]); btrfs_set_disk_key_objectid(&disk_key, BTRFS_FS_TREE_OBJECTID); btrfs_set_item_key(buf, &disk_key, nritems); btrfs_set_item_offset(buf, btrfs_item_nr(nritems), itemoff); @@ -317,7 +317,7 @@ nritems++; itemoff = itemoff - sizeof(root_item); - btrfs_set_root_bytenr(&root_item, blocks[6]); + btrfs_set_root_bytenr(&root_item, cfg->blocks[6]); btrfs_set_disk_key_objectid(&disk_key, BTRFS_CSUM_TREE_OBJECTID); btrfs_set_item_key(buf, &disk_key, nritems); btrfs_set_item_offset(buf, btrfs_item_nr(nritems), itemoff); @@ -330,28 +330,28 @@ csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0); - ret = pwrite(fd, buf->data, nodesize, blocks[1]); - if (ret != nodesize) { + ret = pwrite(fd, buf->data, cfg->nodesize, cfg->blocks[1]); + if (ret != cfg->nodesize) { ret = (ret < 0 ? -errno : -EIO); goto out; } /* create the items for the extent tree */ memset(buf->data + sizeof(struct btrfs_header), 0, - nodesize - sizeof(struct btrfs_header)); + cfg->nodesize - sizeof(struct btrfs_header)); nritems = 0; - itemoff = __BTRFS_LEAF_DATA_SIZE(nodesize); + itemoff = __BTRFS_LEAF_DATA_SIZE(cfg->nodesize); for (i = 1; i < 7; i++) { item_size = sizeof(struct btrfs_extent_item); if (!skinny_metadata) item_size += sizeof(struct btrfs_tree_block_info); - BUG_ON(blocks[i] < first_free); - BUG_ON(blocks[i] < blocks[i - 1]); + BUG_ON(cfg->blocks[i] < first_free); + BUG_ON(cfg->blocks[i] < cfg->blocks[i - 1]); /* create extent item */ itemoff -= item_size; - btrfs_set_disk_key_objectid(&disk_key, blocks[i]); + btrfs_set_disk_key_objectid(&disk_key, cfg->blocks[i]); if (skinny_metadata) { btrfs_set_disk_key_type(&disk_key, BTRFS_METADATA_ITEM_KEY); @@ -359,7 +359,7 @@ } else { btrfs_set_disk_key_type(&disk_key, BTRFS_EXTENT_ITEM_KEY); - btrfs_set_disk_key_offset(&disk_key, nodesize); + btrfs_set_disk_key_offset(&disk_key, cfg->nodesize); } btrfs_set_item_key(buf, &disk_key, nritems); btrfs_set_item_offset(buf, btrfs_item_nr(nritems), @@ -376,7 +376,7 @@ /* create extent ref */ ref_root = reference_root_table[i]; - btrfs_set_disk_key_objectid(&disk_key, blocks[i]); + btrfs_set_disk_key_objectid(&disk_key, cfg->blocks[i]); btrfs_set_disk_key_offset(&disk_key, ref_root); btrfs_set_disk_key_type(&disk_key, BTRFS_TREE_BLOCK_REF_KEY); btrfs_set_item_key(buf, &disk_key, nritems); @@ -385,22 +385,22 @@ btrfs_set_item_size(buf, btrfs_item_nr(nritems), 0); nritems++; } - btrfs_set_header_bytenr(buf, blocks[2]); + btrfs_set_header_bytenr(buf, cfg->blocks[2]); btrfs_set_header_owner(buf, BTRFS_EXTENT_TREE_OBJECTID); btrfs_set_header_nritems(buf, nritems); csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0); - ret = pwrite(fd, buf->data, nodesize, blocks[2]); - if (ret != nodesize) { + ret = pwrite(fd, buf->data, cfg->nodesize, cfg->blocks[2]); + if (ret != cfg->nodesize) { ret = (ret < 0 ? -errno : -EIO); goto out; } /* create the chunk tree */ memset(buf->data + sizeof(struct btrfs_header), 0, - nodesize - sizeof(struct btrfs_header)); + cfg->nodesize - sizeof(struct btrfs_header)); nritems = 0; item_size = sizeof(*dev_item); - itemoff = __BTRFS_LEAF_DATA_SIZE(nodesize) - item_size; + itemoff = __BTRFS_LEAF_DATA_SIZE(cfg->nodesize) - item_size; /* first device 1 (there is no device 0) */ btrfs_set_disk_key_objectid(&disk_key, BTRFS_DEV_ITEMS_OBJECTID); @@ -416,9 +416,9 @@ btrfs_set_device_total_bytes(buf, dev_item, num_bytes); btrfs_set_device_bytes_used(buf, dev_item, BTRFS_MKFS_SYSTEM_GROUP_SIZE); - btrfs_set_device_io_align(buf, dev_item, sectorsize); - btrfs_set_device_io_width(buf, dev_item, sectorsize); - btrfs_set_device_sector_size(buf, dev_item, sectorsize); + btrfs_set_device_io_align(buf, dev_item, cfg->sectorsize); + btrfs_set_device_io_width(buf, dev_item, cfg->sectorsize); + btrfs_set_device_sector_size(buf, dev_item, cfg->sectorsize); btrfs_set_device_type(buf, dev_item, 0); write_extent_buffer(buf, super.dev_item.uuid, @@ -447,9 +447,9 @@ btrfs_set_chunk_owner(buf, chunk, BTRFS_EXTENT_TREE_OBJECTID); btrfs_set_chunk_stripe_len(buf, chunk, 64 * 1024); btrfs_set_chunk_type(buf, chunk, BTRFS_BLOCK_GROUP_SYSTEM); - btrfs_set_chunk_io_align(buf, chunk, sectorsize); - btrfs_set_chunk_io_width(buf, chunk, sectorsize); - btrfs_set_chunk_sector_size(buf, chunk, sectorsize); + btrfs_set_chunk_io_align(buf, chunk, cfg->sectorsize); + btrfs_set_chunk_io_width(buf, chunk, cfg->sectorsize); + btrfs_set_chunk_sector_size(buf, chunk, cfg->sectorsize); btrfs_set_chunk_num_stripes(buf, chunk, 1); btrfs_set_stripe_devid_nr(buf, chunk, 0, 1); btrfs_set_stripe_offset_nr(buf, chunk, 0, 0); @@ -472,21 +472,21 @@ ptr += item_size; btrfs_set_super_sys_array_size(&super, array_size); - btrfs_set_header_bytenr(buf, blocks[3]); + btrfs_set_header_bytenr(buf, cfg->blocks[3]); btrfs_set_header_owner(buf, BTRFS_CHUNK_TREE_OBJECTID); btrfs_set_header_nritems(buf, nritems); csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0); - ret = pwrite(fd, buf->data, nodesize, blocks[3]); - if (ret != nodesize) { + ret = pwrite(fd, buf->data, cfg->nodesize, cfg->blocks[3]); + if (ret != cfg->nodesize) { ret = (ret < 0 ? -errno : -EIO); goto out; } /* create the device tree */ memset(buf->data + sizeof(struct btrfs_header), 0, - nodesize - sizeof(struct btrfs_header)); + cfg->nodesize - sizeof(struct btrfs_header)); nritems = 0; - itemoff = __BTRFS_LEAF_DATA_SIZE(nodesize) - + itemoff = __BTRFS_LEAF_DATA_SIZE(cfg->nodesize) - sizeof(struct btrfs_dev_extent); btrfs_set_disk_key_objectid(&disk_key, 1); @@ -511,49 +511,49 @@ BTRFS_MKFS_SYSTEM_GROUP_SIZE); nritems++; - btrfs_set_header_bytenr(buf, blocks[4]); + btrfs_set_header_bytenr(buf, cfg->blocks[4]); btrfs_set_header_owner(buf, BTRFS_DEV_TREE_OBJECTID); btrfs_set_header_nritems(buf, nritems); csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0); - ret = pwrite(fd, buf->data, nodesize, blocks[4]); - if (ret != nodesize) { + ret = pwrite(fd, buf->data, cfg->nodesize, cfg->blocks[4]); + if (ret != cfg->nodesize) { ret = (ret < 0 ? -errno : -EIO); goto out; } /* create the FS root */ memset(buf->data + sizeof(struct btrfs_header), 0, - nodesize - sizeof(struct btrfs_header)); - btrfs_set_header_bytenr(buf, blocks[5]); + cfg->nodesize - sizeof(struct btrfs_header)); + btrfs_set_header_bytenr(buf, cfg->blocks[5]); btrfs_set_header_owner(buf, BTRFS_FS_TREE_OBJECTID); btrfs_set_header_nritems(buf, 0); csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0); - ret = pwrite(fd, buf->data, nodesize, blocks[5]); - if (ret != nodesize) { + ret = pwrite(fd, buf->data, cfg->nodesize, cfg->blocks[5]); + if (ret != cfg->nodesize) { ret = (ret < 0 ? -errno : -EIO); goto out; } /* finally create the csum root */ memset(buf->data + sizeof(struct btrfs_header), 0, - nodesize - sizeof(struct btrfs_header)); - btrfs_set_header_bytenr(buf, blocks[6]); + cfg->nodesize - sizeof(struct btrfs_header)); + btrfs_set_header_bytenr(buf, cfg->blocks[6]); btrfs_set_header_owner(buf, BTRFS_CSUM_TREE_OBJECTID); btrfs_set_header_nritems(buf, 0); csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0); - ret = pwrite(fd, buf->data, nodesize, blocks[6]); - if (ret != nodesize) { + ret = pwrite(fd, buf->data, cfg->nodesize, cfg->blocks[6]); + if (ret != cfg->nodesize) { ret = (ret < 0 ? -errno : -EIO); goto out; } /* and write out the super block */ - BUG_ON(sizeof(super) > sectorsize); - memset(buf->data, 0, sectorsize); + BUG_ON(sizeof(super) > cfg->sectorsize); + memset(buf->data, 0, cfg->sectorsize); memcpy(buf->data, &super, sizeof(super)); - buf->len = sectorsize; + buf->len = cfg->sectorsize; csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0); - ret = pwrite(fd, buf->data, sectorsize, blocks[0]); - if (ret != sectorsize) { + ret = pwrite(fd, buf->data, cfg->sectorsize, cfg->blocks[0]); + if (ret != cfg->sectorsize) { ret = (ret < 0 ? -errno : -EIO); goto out; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/utils.h new/btrfs-progs-v4.1.2/utils.h --- old/btrfs-progs-v4.1/utils.h 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/utils.h 2015-07-14 13:45:36.000000000 +0200 @@ -105,9 +105,18 @@ void btrfs_process_fs_features(u64 flags); void btrfs_parse_features_to_string(char *buf, u64 flags); -int make_btrfs(int fd, const char *device, const char *label, - char *fs_uuid, u64 blocks[6], u64 num_bytes, u32 nodesize, - u32 sectorsize, u32 stripesize, u64 features); +struct btrfs_mkfs_config { + char *label; + char *fs_uuid; + u64 blocks[8]; + u64 num_bytes; + u32 nodesize; + u32 sectorsize; + u32 stripesize; + u64 features; +}; + +int make_btrfs(int fd, struct btrfs_mkfs_config *cfg); int btrfs_make_root_dir(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 objectid); int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/btrfs-progs-v4.1/version.sh new/btrfs-progs-v4.1.2/version.sh --- old/btrfs-progs-v4.1/version.sh 2015-06-22 16:48:41.000000000 +0200 +++ new/btrfs-progs-v4.1.2/version.sh 2015-07-14 13:45:36.000000000 +0200 @@ -6,7 +6,7 @@ # Copyright 2008, Oracle # Released under the GNU GPLv2 -v="v4.1" +v="v4.1.2" opt=$1 ++++++ local-version-override.patch ++++++ --- /var/tmp/diff_new_pack.enXCNN/_old 2015-07-19 11:45:25.000000000 +0200 +++ /var/tmp/diff_new_pack.enXCNN/_new 2015-07-19 11:45:25.000000000 +0200 @@ -6,8 +6,8 @@ # Copyright 2008, Oracle # Released under the GNU GPLv2 --v="v4.1" -+v="v4.1+20150622" +-v="v4.1.2" ++v="v4.1.2+20150714" opt=$1