diff options
author | Dimitri John Ledkov <xnox@ubuntu.com> | 2018-07-23 14:32:01 +0100 |
---|---|---|
committer | Dimitri John Ledkov <xnox@ubuntu.com> | 2018-07-23 14:32:01 +0100 |
commit | 3b9cf4c8cda0818e4d3f9892ece9f7d99de13b03 (patch) | |
tree | 59446f505b5bb3b31b1b3bb81af997dda68407c2 | |
parent | f22f0302575d3a167ee550470c922de82e34342b (diff) |
New upstream release.debian/4.17-1archive/debian/4.17-1
93 files changed, 1954 insertions, 1252 deletions
@@ -1,3 +1,26 @@ +btrfs-progs-4.17 (2018-06-14) + * check + * many lowmem mode improvements + * properly report qgroup mismatch errors + * check symlinks with append/immutable flags + * fi usage + * correctly calculate allocated/unallocated for raid10 + * minor output updates + * mkfs + * detect ENOSPC on thinly provisioned devices + * fix spurious EEXIST during directory traversal + * restore: fix relative path for restore target + * dump-tree: print symbolic tree names for backrefs + * send: fix regression preventing send -p with subvolumes mounted on "/" + * corrupt-tree: refactoring and command line updates + * build + * make it work with e2fsprogs < 1.42 again + * restore support for autoconf 2.63 + * detect if -std=gnu90 is supported + * other + * new tests + * cleanups + btrfs-progs-4.16.1 (2018-04-24) * remove obsolete tools: btrfs-debug-tree, btrfs-zero-log, btrfs-show-super, btrfs-calc-size diff --git a/Documentation/btrfs-balance.8.gz b/Documentation/btrfs-balance.8.gz Binary files differindex f51c43d0..02771775 100644 --- a/Documentation/btrfs-balance.8.gz +++ b/Documentation/btrfs-balance.8.gz diff --git a/Documentation/btrfs-check.8.gz b/Documentation/btrfs-check.8.gz Binary files differindex f811ae43..7a4b5d6b 100644 --- a/Documentation/btrfs-check.8.gz +++ b/Documentation/btrfs-check.8.gz diff --git a/Documentation/btrfs-convert.8.gz b/Documentation/btrfs-convert.8.gz Binary files differindex 85f9cf3e..af0b9b13 100644 --- a/Documentation/btrfs-convert.8.gz +++ b/Documentation/btrfs-convert.8.gz diff --git a/Documentation/btrfs-device.8.gz b/Documentation/btrfs-device.8.gz Binary files differindex 3daf4dbc..668dbc67 100644 --- a/Documentation/btrfs-device.8.gz +++ b/Documentation/btrfs-device.8.gz diff --git a/Documentation/btrfs-filesystem.8.gz b/Documentation/btrfs-filesystem.8.gz Binary files differindex 91f00e79..5da186b2 100644 --- a/Documentation/btrfs-filesystem.8.gz +++ b/Documentation/btrfs-filesystem.8.gz diff --git a/Documentation/btrfs-find-root.8.gz b/Documentation/btrfs-find-root.8.gz Binary files differindex 92fcc6b6..9143c5a7 100644 --- a/Documentation/btrfs-find-root.8.gz +++ b/Documentation/btrfs-find-root.8.gz diff --git a/Documentation/btrfs-image.8.gz b/Documentation/btrfs-image.8.gz Binary files differindex b765137a..7b9b34e7 100644 --- a/Documentation/btrfs-image.8.gz +++ b/Documentation/btrfs-image.8.gz diff --git a/Documentation/btrfs-inspect-internal.8.gz b/Documentation/btrfs-inspect-internal.8.gz Binary files differindex 2fdc7275..ea67330c 100644 --- a/Documentation/btrfs-inspect-internal.8.gz +++ b/Documentation/btrfs-inspect-internal.8.gz diff --git a/Documentation/btrfs-map-logical.8.gz b/Documentation/btrfs-map-logical.8.gz Binary files differindex 00d0c048..89875909 100644 --- a/Documentation/btrfs-map-logical.8.gz +++ b/Documentation/btrfs-map-logical.8.gz diff --git a/Documentation/btrfs-property.8.gz b/Documentation/btrfs-property.8.gz Binary files differindex 4a8101aa..95e8f69b 100644 --- a/Documentation/btrfs-property.8.gz +++ b/Documentation/btrfs-property.8.gz diff --git a/Documentation/btrfs-qgroup.8.gz b/Documentation/btrfs-qgroup.8.gz Binary files differindex 13feefed..b52ee493 100644 --- a/Documentation/btrfs-qgroup.8.gz +++ b/Documentation/btrfs-qgroup.8.gz diff --git a/Documentation/btrfs-quota.8.gz b/Documentation/btrfs-quota.8.gz Binary files differindex c400008e..a1be6bed 100644 --- a/Documentation/btrfs-quota.8.gz +++ b/Documentation/btrfs-quota.8.gz diff --git a/Documentation/btrfs-receive.8.gz b/Documentation/btrfs-receive.8.gz Binary files differindex 5b782a3d..0bdac0ab 100644 --- a/Documentation/btrfs-receive.8.gz +++ b/Documentation/btrfs-receive.8.gz diff --git a/Documentation/btrfs-replace.8.gz b/Documentation/btrfs-replace.8.gz Binary files differindex ca3cb8ff..754aa8b3 100644 --- a/Documentation/btrfs-replace.8.gz +++ b/Documentation/btrfs-replace.8.gz diff --git a/Documentation/btrfs-rescue.8.gz b/Documentation/btrfs-rescue.8.gz Binary files differindex 681dae38..e0100dbf 100644 --- a/Documentation/btrfs-rescue.8.gz +++ b/Documentation/btrfs-rescue.8.gz diff --git a/Documentation/btrfs-restore.8.gz b/Documentation/btrfs-restore.8.gz Binary files differindex 3a7371ce..65eaf98f 100644 --- a/Documentation/btrfs-restore.8.gz +++ b/Documentation/btrfs-restore.8.gz diff --git a/Documentation/btrfs-scrub.8.gz b/Documentation/btrfs-scrub.8.gz Binary files differindex 8aa92d8f..4a44a430 100644 --- a/Documentation/btrfs-scrub.8.gz +++ b/Documentation/btrfs-scrub.8.gz diff --git a/Documentation/btrfs-select-super.8.gz b/Documentation/btrfs-select-super.8.gz Binary files differindex d0afda32..0e025c10 100644 --- a/Documentation/btrfs-select-super.8.gz +++ b/Documentation/btrfs-select-super.8.gz diff --git a/Documentation/btrfs-send.8.gz b/Documentation/btrfs-send.8.gz Binary files differindex 0f31ed82..36fba40f 100644 --- a/Documentation/btrfs-send.8.gz +++ b/Documentation/btrfs-send.8.gz diff --git a/Documentation/btrfs-subvolume.8.gz b/Documentation/btrfs-subvolume.8.gz Binary files differindex 90e7a138..48cd18c7 100644 --- a/Documentation/btrfs-subvolume.8.gz +++ b/Documentation/btrfs-subvolume.8.gz diff --git a/Documentation/btrfs.5.gz b/Documentation/btrfs.5.gz Binary files differindex 9ead78aa..87783a00 100644 --- a/Documentation/btrfs.5.gz +++ b/Documentation/btrfs.5.gz diff --git a/Documentation/btrfs.8.gz b/Documentation/btrfs.8.gz Binary files differindex b7584036..64d35f83 100644 --- a/Documentation/btrfs.8.gz +++ b/Documentation/btrfs.8.gz diff --git a/Documentation/btrfstune.8.gz b/Documentation/btrfstune.8.gz Binary files differindex 9c403588..d9eb5bd5 100644 --- a/Documentation/btrfstune.8.gz +++ b/Documentation/btrfstune.8.gz diff --git a/Documentation/fsck.btrfs.8.gz b/Documentation/fsck.btrfs.8.gz Binary files differindex 997d4db8..ac34255c 100644 --- a/Documentation/fsck.btrfs.8.gz +++ b/Documentation/fsck.btrfs.8.gz diff --git a/Documentation/mkfs.btrfs.8.gz b/Documentation/mkfs.btrfs.8.gz Binary files differindex b0b86e15..e2fb07e8 100644 --- a/Documentation/mkfs.btrfs.8.gz +++ b/Documentation/mkfs.btrfs.8.gz @@ -63,7 +63,6 @@ ABSTOPDIR = $(shell pwd) TOPDIR := . # Common build flags -CSTD = -std=gnu90 CFLAGS = $(SUBST_CFLAGS) \ $(CSTD) \ -include config.h \ @@ -85,6 +84,7 @@ LIBBTRFSUTIL_CFLAGS = $(SUBST_CFLAGS) \ -fvisibility=hidden \ -I$(TOPDIR)/libbtrfsutil \ $(EXTRAWARN_CFLAGS) \ + $(DEBUG_CFLAGS_INTERNAL) \ $(EXTRA_CFLAGS) LDFLAGS = $(SUBST_LDFLAGS) \ diff --git a/Makefile.inc.in b/Makefile.inc.in index 52410f69..fb324614 100644 --- a/Makefile.inc.in +++ b/Makefile.inc.in @@ -4,6 +4,7 @@ export CC = @CC@ +CSTD = @BTRFS_CSTD_FLAGS@ LN_S = @LN_S@ AR = @AR@ RM = @RM@ @@ -1 +1 @@ -v4.16.1 +v4.17 @@ -155,19 +155,6 @@ static void init_pref_state(struct pref_state *prefstate) * - if you cannot add the parent or a correct key, then we will look into the * block later to set a correct key * - * delayed refs - * ============ - * backref type | shared | indirect | shared | indirect - * information | tree | tree | data | data - * --------------------+--------+----------+--------+---------- - * parent logical | y | - | - | - - * key to resolve | - | y | y | y - * tree block logical | - | - | - | - - * root for resolving | y | y | y | y - * - * - column 1: we've the parent -> done - * - column 2, 3, 4: we use the key to find the parent - * * on disk refs (inline or keyed) * ============================== * backref type | shared | indirect | shared | indirect @@ -510,7 +497,6 @@ static void __merge_refs(struct pref_state *prefstate, int mode) for (pos2 = pos1->next, n2 = pos2->next; pos2 != head; pos2 = n2, n2 = pos2->next) { struct __prelim_ref *ref2; - struct __prelim_ref *xchg; struct extent_inode_elem *eie; ref2 = list_entry(pos2, struct __prelim_ref, list); @@ -518,12 +504,13 @@ static void __merge_refs(struct pref_state *prefstate, int mode) if (mode == 1) { if (!ref_for_same_block(ref1, ref2)) continue; - if (!ref1->parent && ref2->parent) { - xchg = ref1; - ref1 = ref2; - ref2 = xchg; - } } else { + /* + * Parent == 0 means that the ref is tree block + * backref or its parent is unresolved. + */ + if (!ref1->parent || !ref2->parent) + continue; if (ref1->parent != ref2->parent) continue; } @@ -735,9 +722,9 @@ static int __add_keyed_refs(struct btrfs_fs_info *fs_info, } /* - * this adds all existing backrefs (inline backrefs, backrefs and delayed - * refs) for the given bytenr to the refs list, merges duplicates and resolves - * indirect refs to their parent bytenr. + * this adds all existing backrefs (inline backrefs, backrefs for the given + * bytenr to the refs list, merges duplicates and resolves indirect refs to + * their parent bytenr. * When roots are found, they're added to the roots list * * FIXME some caching might speed things up diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c index da0ec8c5..4fbea26c 100644 --- a/btrfs-corrupt-block.c +++ b/btrfs-corrupt-block.c @@ -114,11 +114,11 @@ static void print_usage(int ret) printf("\t-i The inode item to corrupt (must also specify the field to corrupt)\n"); printf("\t-x The file extent item to corrupt (must also specify -i for the inode and -f for the field to corrupt)\n"); printf("\t-m The metadata block to corrupt (must also specify -f for the field to corrupt)\n"); - printf("\t-K The key to corrupt in the format <num>,<num>,<num> (must also specify -f for the field)\n"); + printf("\t-K <u64,u8,u64> Corrupt the given key (must also specify -f for the field and optionally -r for the root)\n"); printf("\t-f The field in the item to corrupt\n"); - printf("\t-I An item to corrupt (must also specify the field to corrupt and a root+key for the item)\n"); - printf("\t-D Corrupt a dir item, must specify key and field\n"); - printf("\t-d Delete this item (must specify -K)\n"); + printf("\t-I <u64,u8,u64> Corrupt an item corresponding to the passed key triplet (must also specify the field to corrupt and root for the item)\n"); + printf("\t-D <u64,u8,u64> Corrupt a dir item corresponding to the passed key triplet, must also specify a field\n"); + printf("\t-d <u64,u8,u64> Delete item corresponding to passed key triplet\n"); printf("\t-r Operate on this root (only works with -d)\n"); printf("\t-C Delete a csum for the specified bytenr. When used with -b it'll delete that many bytes, otherwise it's just sectorsize\n"); exit(ret); @@ -449,7 +449,6 @@ static int corrupt_key(struct btrfs_root *root, struct btrfs_key *key, struct btrfs_trans_handle *trans; int ret; - root = root->fs_info->fs_root; if (corrupt_field == BTRFS_KEY_BAD) { fprintf(stderr, "Invalid field %s\n", field); return -EINVAL; @@ -726,7 +725,7 @@ out: static void shift_items(struct btrfs_root *root, struct extent_buffer *eb) { int nritems = btrfs_header_nritems(eb); - int shift_space = btrfs_leaf_free_space(root->fs_info, eb) / 2; + int shift_space = btrfs_leaf_free_space(eb) / 2; int slot = nritems / 2; int i = 0; unsigned int data_end = btrfs_item_offset_nr(eb, nritems - 1); @@ -1080,11 +1079,41 @@ out: return ret; } + +static void parse_key(u64 *objectid, u8 *type, u64 *offset) +{ + + int ret = sscanf(optarg, "%llu,%hhu,%llu", objectid, type, offset); + if (ret != 3) { + fprintf(stderr, "error parsing key '%s': %d\n", optarg, errno); + print_usage(1); + } +} + +static struct btrfs_root *open_root(struct btrfs_fs_info *fs_info, + u64 root_objectid) +{ + + struct btrfs_key root_key; + struct btrfs_root *root; + + root_key.objectid = root_objectid; + root_key.type = BTRFS_ROOT_ITEM_KEY; + root_key.offset = (u64)-1; + + root = btrfs_read_fs_root(fs_info, &root_key); + if (IS_ERR(root)) { + fprintf(stderr, "couldn't find root %llu\n", root_objectid); + print_usage(1); + } + + return root; +} int main(int argc, char **argv) { struct cache_tree root_cache; struct btrfs_key key; - struct btrfs_root *root; + struct btrfs_root *root, *target_root; char *dev; /* chunk offset can be 0,so change to (u64)-1 */ u64 logical = (u64)-1; @@ -1099,6 +1128,7 @@ int main(int argc, char **argv) int corrupt_item = 0; int corrupt_di = 0; int delete = 0; + int should_corrupt_key = 0; u64 metadata_block = 0; u64 inode = 0; u64 file_extent = (u64)-1; @@ -1135,7 +1165,7 @@ int main(int argc, char **argv) { NULL, 0, NULL, 0 } }; - c = getopt_long(argc, argv, "l:c:b:eEkuUi:f:x:m:K:IDdr:C:", + c = getopt_long(argc, argv, "l:c:b:eEkuUi:f:x:m:K:I:D:d:r:C:", long_options, NULL); if (c < 0) break; @@ -1177,24 +1207,20 @@ int main(int argc, char **argv) metadata_block = arg_strtou64(optarg); break; case 'K': - ret = sscanf(optarg, "%llu,%u,%llu", - &key.objectid, - (unsigned int *)&key.type, - &key.offset); - if (ret != 3) { - fprintf(stderr, "error reading key " - "%d\n", errno); - print_usage(1); - } + should_corrupt_key = 1; + parse_key(&key.objectid, &key.type, &key.offset); break; case 'D': corrupt_di = 1; + parse_key(&key.objectid, &key.type, &key.offset); break; case 'I': corrupt_item = 1; + parse_key(&key.objectid, &key.type, &key.offset); break; case 'd': delete = 1; + parse_key(&key.objectid, &key.type, &key.offset); break; case 'r': root_objectid = arg_strtou64(optarg); @@ -1220,6 +1246,10 @@ int main(int argc, char **argv) fprintf(stderr, "Open ctree failed\n"); exit(1); } + target_root = root; + if (root_objectid) + target_root = open_root(root->fs_info, root_objectid); + if (extent_rec) { struct btrfs_trans_handle *trans; @@ -1309,7 +1339,7 @@ int main(int argc, char **argv) if (corrupt_di) { if (!key.objectid || *field == 0) print_usage(1); - ret = corrupt_dir_item(root, &key, field); + ret = corrupt_dir_item(target_root, &key, field); goto out_close; } if (csum_bytenr) { @@ -1319,34 +1349,24 @@ int main(int argc, char **argv) if (corrupt_item) { if (!key.objectid) print_usage(1); - ret = corrupt_btrfs_item(root, &key, field); + if (!root_objectid) + print_usage(1); + + ret = corrupt_btrfs_item(target_root, &key, field); + goto out_close; } if (delete) { - struct btrfs_root *target = root; - if (!key.objectid) print_usage(1); - if (root_objectid) { - struct btrfs_key root_key; - - root_key.objectid = root_objectid; - root_key.type = BTRFS_ROOT_ITEM_KEY; - root_key.offset = (u64)-1; - - target = btrfs_read_fs_root(root->fs_info, &root_key); - if (IS_ERR(target)) { - fprintf(stderr, "Couldn't find root %llu\n", - (unsigned long long)root_objectid); - print_usage(1); - } - } - ret = delete_item(target, &key); + + ret = delete_item(target_root, &key); goto out_close; } - if (key.objectid || key.offset || key.type) { + if (should_corrupt_key) { if (*field == 0) print_usage(1); - ret = corrupt_key(root, &key, field); + + ret = corrupt_key(target_root, &key, field); goto out_close; } /* diff --git a/btrfs-map-logical.c b/btrfs-map-logical.c index 7a8bcff9..4508f365 100644 --- a/btrfs-map-logical.c +++ b/btrfs-map-logical.c @@ -39,7 +39,7 @@ static FILE *info_file; static int map_one_extent(struct btrfs_fs_info *fs_info, - u64 *logical_ret, u64 *len_ret, int search_foward) + u64 *logical_ret, u64 *len_ret, int search_forward) { struct btrfs_path *path; struct btrfs_key key; @@ -67,11 +67,11 @@ static int map_one_extent(struct btrfs_fs_info *fs_info, again: btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); - if ((search_foward && key.objectid < logical) || - (!search_foward && key.objectid > logical) || + if ((search_forward && key.objectid < logical) || + (!search_forward && key.objectid > logical) || (key.type != BTRFS_EXTENT_ITEM_KEY && key.type != BTRFS_METADATA_ITEM_KEY)) { - if (!search_foward) + if (!search_forward) ret = btrfs_previous_extent_item(fs_info->extent_root, path, 0); else diff --git a/check/main.c b/check/main.c index c4a1801f..3190b5d4 100644 --- a/check/main.c +++ b/check/main.c @@ -576,6 +576,8 @@ static void print_inode_error(struct btrfs_root *root, struct inode_record *rec) fprintf(stderr, ", link count wrong"); if (errors & I_ERR_FILE_EXTENT_ORPHAN) fprintf(stderr, ", orphan file extent"); + if (errors & I_ERR_ODD_INODE_FLAGS) + fprintf(stderr, ", odd inode flags"); fprintf(stderr, "\n"); /* Print the orphan extents if needed */ if (errors & I_ERR_FILE_EXTENT_ORPHAN) @@ -805,6 +807,7 @@ static int process_inode_item(struct extent_buffer *eb, { struct inode_record *rec; struct btrfs_inode_item *item; + u64 flags; rec = active_node->current; BUG_ON(rec->ino != key->objectid || rec->refs > 1); @@ -822,6 +825,10 @@ static int process_inode_item(struct extent_buffer *eb, rec->found_inode_item = 1; if (rec->nlink == 0) rec->errors |= I_ERR_NO_ORPHAN_ITEM; + flags = btrfs_inode_flags(eb, item); + if (S_ISLNK(rec->imode) && + flags & (BTRFS_INODE_IMMUTABLE | BTRFS_INODE_APPEND)) + rec->errors |= I_ERR_ODD_INODE_FLAGS; maybe_free_inode_rec(&active_node->inode_cache, rec); return 0; } @@ -1622,9 +1629,9 @@ static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path, refs = nrefs->refs[*level]; ret = 0; } else { - ret = btrfs_lookup_extent_info(NULL, root, - path->nodes[*level]->start, - *level, 1, &refs, NULL); + ret = btrfs_lookup_extent_info(NULL, fs_info, + path->nodes[*level]->start, + *level, 1, &refs, NULL); if (ret < 0) { err = ret; goto out; @@ -1664,7 +1671,7 @@ static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path, if (bytenr == nrefs->bytenr[*level - 1]) { refs = nrefs->refs[*level - 1]; } else { - ret = btrfs_lookup_extent_info(NULL, root, bytenr, + ret = btrfs_lookup_extent_info(NULL, fs_info, bytenr, *level - 1, 1, &refs, NULL); if (ret < 0) { refs = 0; @@ -5147,7 +5154,7 @@ static int check_cache_range(struct btrfs_root *root, for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { bytenr = btrfs_sb_offset(i); ret = btrfs_rmap_block(root->fs_info, - cache->key.objectid, bytenr, 0, + cache->key.objectid, bytenr, &logical, &nr, &stripe_len); if (ret) return ret; @@ -5381,6 +5388,13 @@ static int check_space_cache(struct btrfs_root *root) return error ? -EINVAL : 0; } +/* + * Check data checksum for [@bytenr, @bytenr + @num_bytes). + * + * Return <0 for fatal error (fails to read checksum/data or allocate memory). + * Return >0 for csum mismatch for any copy. + * Return 0 if everything is OK. + */ static int check_extent_csums(struct btrfs_root *root, u64 bytenr, u64 num_bytes, unsigned long leaf_offset, struct extent_buffer *eb) @@ -5398,6 +5412,7 @@ static int check_extent_csums(struct btrfs_root *root, u64 bytenr, int ret = 0; int mirror; int num_copies; + bool csum_mismatch = false; if (num_bytes % fs_info->sectorsize) return -EINVAL; @@ -5406,47 +5421,51 @@ static int check_extent_csums(struct btrfs_root *root, u64 bytenr, if (!data) return -ENOMEM; + num_copies = btrfs_num_copies(root->fs_info, bytenr, num_bytes); while (offset < num_bytes) { - mirror = 0; -again: - read_len = num_bytes - offset; - /* read as much space once a time */ - ret = read_extent_data(fs_info, data + offset, - bytenr + offset, &read_len, mirror); - if (ret) - goto out; - data_checked = 0; - /* verify every 4k data's checksum */ - while (data_checked < read_len) { - csum = ~(u32)0; - tmp = offset + data_checked; - - csum = btrfs_csum_data((char *)data + tmp, - csum, fs_info->sectorsize); - btrfs_csum_final(csum, (u8 *)&csum); - - csum_offset = leaf_offset + - tmp / fs_info->sectorsize * csum_size; - read_extent_buffer(eb, (char *)&csum_expected, - csum_offset, csum_size); - /* try another mirror */ - if (csum != csum_expected) { - fprintf(stderr, "mirror %d bytenr %llu csum %u expected csum %u\n", + /* + * Mirror 0 means 'read from any valid copy', so it's skipped. + * The indexes 1-N represent the n-th copy for levels with + * redundancy. + */ + for (mirror = 1; mirror <= num_copies; mirror++) { + read_len = num_bytes - offset; + /* read as much space once a time */ + ret = read_extent_data(fs_info, data + offset, + bytenr + offset, &read_len, mirror); + if (ret) + goto out; + + data_checked = 0; + /* verify every 4k data's checksum */ + while (data_checked < read_len) { + csum = ~(u32)0; + tmp = offset + data_checked; + + csum = btrfs_csum_data((char *)data + tmp, + csum, fs_info->sectorsize); + btrfs_csum_final(csum, (u8 *)&csum); + + csum_offset = leaf_offset + + tmp / fs_info->sectorsize * csum_size; + read_extent_buffer(eb, (char *)&csum_expected, + csum_offset, csum_size); + if (csum != csum_expected) { + csum_mismatch = true; + fprintf(stderr, + "mirror %d bytenr %llu csum %u expected csum %u\n", mirror, bytenr + tmp, csum, csum_expected); - num_copies = btrfs_num_copies(root->fs_info, - bytenr, num_bytes); - if (mirror < num_copies - 1) { - mirror += 1; - goto again; } + data_checked += fs_info->sectorsize; } - data_checked += fs_info->sectorsize; } offset += read_len; } out: free(data); + if (!ret && csum_mismatch) + ret = 1; return ret; } @@ -5660,8 +5679,14 @@ static int check_csums(struct btrfs_root *root) leaf_offset = btrfs_item_ptr_offset(leaf, path.slots[0]); ret = check_extent_csums(root, key.offset, data_len, leaf_offset, leaf); - if (ret) + /* + * Only break for fatal errors, if mismatch is found, continue + * checking until all extents are checked. + */ + if (ret < 0) break; + if (ret > 0) + errors++; skip_csum_check: if (!num_bytes) { offset = key.offset; @@ -5910,7 +5935,7 @@ static int run_next_block(struct btrfs_root *root, flags = 0; if (!init_extent_tree) { - ret = btrfs_lookup_extent_info(NULL, root, bytenr, + ret = btrfs_lookup_extent_info(NULL, fs_info, bytenr, btrfs_header_level(buf), 1, NULL, &flags); if (ret < 0) { @@ -5970,7 +5995,7 @@ static int run_next_block(struct btrfs_root *root, goto out; if (btrfs_is_leaf(buf)) { - btree_space_waste += btrfs_leaf_free_space(fs_info, buf); + btree_space_waste += btrfs_leaf_free_space(buf); for (i = 0; i < nritems; i++) { struct btrfs_file_extent_item *fi; @@ -6277,10 +6302,10 @@ out: } static int delete_extent_records(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct btrfs_path *path, u64 bytenr) { + struct btrfs_fs_info *fs_info = trans->fs_info; struct btrfs_key key; struct btrfs_key found_key; struct extent_buffer *leaf; @@ -6293,8 +6318,8 @@ static int delete_extent_records(struct btrfs_trans_handle *trans, key.offset = (u64)-1; while (1) { - ret = btrfs_search_slot(trans, root->fs_info->extent_root, - &key, path, 0, 1); + ret = btrfs_search_slot(trans, fs_info->extent_root, &key, + path, 0, 1); if (ret < 0) break; @@ -6336,7 +6361,7 @@ static int delete_extent_records(struct btrfs_trans_handle *trans, "repair deleting extent record: key [%llu,%u,%llu]\n", found_key.objectid, found_key.type, found_key.offset); - ret = btrfs_del_item(trans, root->fs_info->extent_root, path); + ret = btrfs_del_item(trans, fs_info->extent_root, path); if (ret) break; btrfs_release_path(path); @@ -6344,10 +6369,10 @@ static int delete_extent_records(struct btrfs_trans_handle *trans, if (found_key.type == BTRFS_EXTENT_ITEM_KEY || found_key.type == BTRFS_METADATA_ITEM_KEY) { u64 bytes = (found_key.type == BTRFS_EXTENT_ITEM_KEY) ? - found_key.offset : root->fs_info->nodesize; + found_key.offset : fs_info->nodesize; - ret = btrfs_update_block_group(root, bytenr, - bytes, 0, 0); + ret = btrfs_update_block_group(fs_info->extent_root, + bytenr, bytes, 0, 0); if (ret) break; } @@ -7275,8 +7300,7 @@ static int fixup_extent_refs(struct btrfs_fs_info *info, } /* step two, delete all the existing records */ - ret = delete_extent_records(trans, info->extent_root, &path, - rec->start); + ret = delete_extent_records(trans, &path, rec->start); if (ret < 0) goto out; @@ -7654,7 +7678,7 @@ repair_abort: goto repair_abort; } - ret = btrfs_fix_block_accounting(trans, root); + ret = btrfs_fix_block_accounting(trans); if (ret) goto repair_abort; ret = btrfs_commit_transaction(trans, root); @@ -8349,94 +8373,6 @@ init: return 0; } -static int pin_down_tree_blocks(struct btrfs_fs_info *fs_info, - struct extent_buffer *eb, int tree_root) -{ - struct extent_buffer *tmp; - struct btrfs_root_item *ri; - struct btrfs_key key; - u64 bytenr; - int level = btrfs_header_level(eb); - int nritems; - int ret; - int i; - - /* - * If we have pinned this block before, don't pin it again. - * This can not only avoid forever loop with broken filesystem - * but also give us some speedups. - */ - if (test_range_bit(&fs_info->pinned_extents, eb->start, - eb->start + eb->len - 1, EXTENT_DIRTY, 0)) - return 0; - - btrfs_pin_extent(fs_info, eb->start, eb->len); - - nritems = btrfs_header_nritems(eb); - for (i = 0; i < nritems; i++) { - if (level == 0) { - btrfs_item_key_to_cpu(eb, &key, i); - if (key.type != BTRFS_ROOT_ITEM_KEY) - continue; - /* Skip the extent root and reloc roots */ - if (key.objectid == BTRFS_EXTENT_TREE_OBJECTID || - key.objectid == BTRFS_TREE_RELOC_OBJECTID || - key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID) - continue; - ri = btrfs_item_ptr(eb, i, struct btrfs_root_item); - bytenr = btrfs_disk_root_bytenr(eb, ri); - - /* - * If at any point we start needing the real root we - * will have to build a stump root for the root we are - * in, but for now this doesn't actually use the root so - * just pass in extent_root. - */ - tmp = read_tree_block(fs_info, bytenr, 0); - if (!extent_buffer_uptodate(tmp)) { - fprintf(stderr, "Error reading root block\n"); - return -EIO; - } - ret = pin_down_tree_blocks(fs_info, tmp, 0); - free_extent_buffer(tmp); - if (ret) - return ret; - } else { - bytenr = btrfs_node_blockptr(eb, i); - - /* If we aren't the tree root don't read the block */ - if (level == 1 && !tree_root) { - btrfs_pin_extent(fs_info, bytenr, - fs_info->nodesize); - continue; - } - - tmp = read_tree_block(fs_info, bytenr, 0); - if (!extent_buffer_uptodate(tmp)) { - fprintf(stderr, "Error reading tree block\n"); - return -EIO; - } - ret = pin_down_tree_blocks(fs_info, tmp, tree_root); - free_extent_buffer(tmp); - if (ret) - return ret; - } - } - - return 0; -} - -static int pin_metadata_blocks(struct btrfs_fs_info *fs_info) -{ - int ret; - - ret = pin_down_tree_blocks(fs_info, fs_info->chunk_root->node, 0); - if (ret) - return ret; - - return pin_down_tree_blocks(fs_info, fs_info->tree_root->node, 1); -} - static int reset_block_groups(struct btrfs_fs_info *fs_info) { struct btrfs_block_group_cache *cache; @@ -8611,7 +8547,7 @@ out: } static int reinit_extent_tree(struct btrfs_trans_handle *trans, - struct btrfs_fs_info *fs_info) + struct btrfs_fs_info *fs_info, bool pin) { u64 start = 0; int ret; @@ -8633,13 +8569,26 @@ static int reinit_extent_tree(struct btrfs_trans_handle *trans, /* * first we need to walk all of the trees except the extent tree and pin - * down the bytes that are in use so we don't overwrite any existing - * metadata. + * down/exclude the bytes that are in use so we don't overwrite any + * existing metadata. + * If pinnned, unpin will be done in the end of transaction. + * If excluded, cleanup will be done in check_chunks_and_extents_lowmem. */ - ret = pin_metadata_blocks(fs_info); - if (ret) { - fprintf(stderr, "error pinning down used bytes\n"); - return ret; +again: + if (pin) { + ret = pin_metadata_blocks(fs_info); + if (ret) { + fprintf(stderr, "error pinning down used bytes\n"); + return ret; + } + } else { + ret = exclude_metadata_blocks(fs_info); + if (ret) { + fprintf(stderr, "error excluding used bytes\n"); + printf("try to pin down used bytes\n"); + pin = true; + goto again; + } } /* @@ -8684,7 +8633,7 @@ static int reinit_extent_tree(struct btrfs_trans_handle *trans, fprintf(stderr, "Error adding block group\n"); return ret; } - btrfs_extent_post_op(trans, fs_info->extent_root); + btrfs_extent_post_op(trans); } ret = reset_balance(trans, fs_info); @@ -9467,6 +9416,7 @@ int cmd_check(int argc, char **argv) int clear_space_cache = 0; int qgroup_report = 0; int qgroups_repaired = 0; + int qgroup_report_ret; unsigned ctree_flags = OPEN_CTREE_EXCLUSIVE; int force = 0; @@ -9709,7 +9659,7 @@ int cmd_check(int argc, char **argv) ret = qgroup_verify_all(info); err |= !!ret; if (ret == 0) - report_qgroups(1); + err |= !!report_qgroups(1); goto close_out; } if (subvolid) { @@ -9733,7 +9683,8 @@ int cmd_check(int argc, char **argv) if (init_extent_tree) { printf("Creating a new extent tree\n"); - ret = reinit_extent_tree(trans, info); + ret = reinit_extent_tree(trans, info, + check_mode == CHECK_MODE_ORIGINAL); err |= !!ret; if (ret) goto close_out; @@ -9841,13 +9792,19 @@ int cmd_check(int argc, char **argv) goto out; } - fprintf(stderr, "checking csums\n"); + if (check_data_csum) + fprintf(stderr, "checking csums against data\n"); + else + fprintf(stderr, + "checking only csum items (without verifying data)\n"); ret = check_csums(root); - err |= !!ret; - if (ret) { + /* + * Data csum error is not fatal, and it may indicate more serious + * corruption, continue checking. + */ + if (ret) error("errors found in csum tree"); - goto out; - } + err |= !!ret; fprintf(stderr, "checking root refs\n"); /* For low memory mode, check_fs_roots_v2 handles root refs */ @@ -9894,13 +9851,14 @@ int cmd_check(int argc, char **argv) error("failed to check quota groups"); goto out; } - report_qgroups(0); + qgroup_report_ret = report_qgroups(0); ret = repair_qgroups(info, &qgroups_repaired); - err |= !!ret; - if (err) { + if (ret) { error("failed to repair quota groups"); goto out; } + if (qgroup_report_ret && (!qgroups_repaired || ret)) + err |= qgroup_report_ret; ret = 0; } diff --git a/check/mode-common.c b/check/mode-common.c index e857d44d..15e2bbd1 100644 --- a/check/mode-common.c +++ b/check/mode-common.c @@ -379,18 +379,14 @@ int insert_inode_item(struct btrfs_trans_handle *trans, time_t now = time(NULL); int ret; + memset(&ii, 0, sizeof(ii)); btrfs_set_stack_inode_size(&ii, size); btrfs_set_stack_inode_nbytes(&ii, nbytes); btrfs_set_stack_inode_nlink(&ii, nlink); btrfs_set_stack_inode_mode(&ii, mode); btrfs_set_stack_inode_generation(&ii, trans->transid); - btrfs_set_stack_timespec_nsec(&ii.atime, 0); btrfs_set_stack_timespec_sec(&ii.ctime, now); - btrfs_set_stack_timespec_nsec(&ii.ctime, 0); btrfs_set_stack_timespec_sec(&ii.mtime, now); - btrfs_set_stack_timespec_nsec(&ii.mtime, 0); - btrfs_set_stack_timespec_sec(&ii.otime, 0); - btrfs_set_stack_timespec_nsec(&ii.otime, 0); ret = btrfs_insert_inode(trans, root, ino, &ii); ASSERT(!ret); @@ -605,3 +601,144 @@ void reset_cached_block_groups(struct btrfs_fs_info *fs_info) start = cache->key.objectid + cache->key.offset; } } + +static int traverse_tree_blocks(struct btrfs_fs_info *fs_info, + struct extent_buffer *eb, int tree_root, + int pin) +{ + struct extent_buffer *tmp; + struct btrfs_root_item *ri; + struct btrfs_key key; + struct extent_io_tree *tree; + u64 bytenr; + int level = btrfs_header_level(eb); + int nritems; + int ret; + int i; + u64 end = eb->start + eb->len; + + if (pin) + tree = &fs_info->pinned_extents; + else + tree = fs_info->excluded_extents; + /* + * If we have pinned/excluded this block before, don't do it again. + * This can not only avoid forever loop with broken filesystem + * but also give us some speedups. + */ + if (test_range_bit(tree, eb->start, end - 1, EXTENT_DIRTY, 0)) + return 0; + + if (pin) + btrfs_pin_extent(fs_info, eb->start, eb->len); + else + set_extent_dirty(tree, eb->start, end - 1); + + nritems = btrfs_header_nritems(eb); + for (i = 0; i < nritems; i++) { + if (level == 0) { + bool is_extent_root; + btrfs_item_key_to_cpu(eb, &key, i); + if (key.type != BTRFS_ROOT_ITEM_KEY) + continue; + /* Skip the extent root and reloc roots */ + if (key.objectid == BTRFS_TREE_RELOC_OBJECTID || + key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID) + continue; + is_extent_root = + key.objectid == BTRFS_EXTENT_TREE_OBJECTID; + /* If pin, skip the extent root */ + if (pin && is_extent_root) + continue; + ri = btrfs_item_ptr(eb, i, struct btrfs_root_item); + bytenr = btrfs_disk_root_bytenr(eb, ri); + + /* + * If at any point we start needing the real root we + * will have to build a stump root for the root we are + * in, but for now this doesn't actually use the root so + * just pass in extent_root. + */ + tmp = read_tree_block(fs_info, bytenr, 0); + if (!extent_buffer_uptodate(tmp)) { + fprintf(stderr, "Error reading root block\n"); + return -EIO; + } + ret = traverse_tree_blocks(fs_info, tmp, 0, pin); + free_extent_buffer(tmp); + if (ret) + return ret; + } else { + bytenr = btrfs_node_blockptr(eb, i); + + /* If we aren't the tree root don't read the block */ + if (level == 1 && !tree_root) { + btrfs_pin_extent(fs_info, bytenr, + fs_info->nodesize); + continue; + } + + tmp = read_tree_block(fs_info, bytenr, 0); + if (!extent_buffer_uptodate(tmp)) { + fprintf(stderr, "Error reading tree block\n"); + return -EIO; + } + ret = traverse_tree_blocks(fs_info, tmp, tree_root, + pin); + free_extent_buffer(tmp); + if (ret) + return ret; + } + } + + return 0; +} + +static int pin_down_tree_blocks(struct btrfs_fs_info *fs_info, + struct extent_buffer *eb, int tree_root) +{ + return traverse_tree_blocks(fs_info, eb, tree_root, 1); +} + +int pin_metadata_blocks(struct btrfs_fs_info *fs_info) +{ + int ret; + + ret = pin_down_tree_blocks(fs_info, fs_info->chunk_root->node, 0); + if (ret) + return ret; + + return pin_down_tree_blocks(fs_info, fs_info->tree_root->node, 1); +} + +static int exclude_tree_blocks(struct btrfs_fs_info *fs_info, + struct extent_buffer *eb, int tree_root) +{ + return traverse_tree_blocks(fs_info, eb, tree_root, 0); +} + +int exclude_metadata_blocks(struct btrfs_fs_info *fs_info) +{ + int ret; + struct extent_io_tree *excluded_extents; + + excluded_extents = malloc(sizeof(*excluded_extents)); + if (!excluded_extents) + return -ENOMEM; + extent_io_tree_init(excluded_extents); + fs_info->excluded_extents = excluded_extents; + + ret = exclude_tree_blocks(fs_info, fs_info->chunk_root->node, 0); + if (ret) + return ret; + return exclude_tree_blocks(fs_info, fs_info->tree_root->node, 1); +} + +void cleanup_excluded_extents(struct btrfs_fs_info *fs_info) +{ + if (fs_info->excluded_extents) { + extent_io_tree_cleanup(fs_info->excluded_extents); + free(fs_info->excluded_extents); + } + fs_info->excluded_extents = NULL; +} diff --git a/check/mode-common.h b/check/mode-common.h index 877c1aa9..a4748578 100644 --- a/check/mode-common.h +++ b/check/mode-common.h @@ -98,5 +98,8 @@ void reada_walk_down(struct btrfs_root *root, struct extent_buffer *node, int check_child_node(struct extent_buffer *parent, int slot, struct extent_buffer *child); void reset_cached_block_groups(struct btrfs_fs_info *fs_info); +int pin_metadata_blocks(struct btrfs_fs_info *fs_info); +int exclude_metadata_blocks(struct btrfs_fs_info *fs_info); +void cleanup_excluded_extents(struct btrfs_fs_info *fs_info); #endif diff --git a/check/mode-lowmem.c b/check/mode-lowmem.c index bfe45aba..66da4531 100644 --- a/check/mode-lowmem.c +++ b/check/mode-lowmem.c @@ -28,6 +28,8 @@ #include "check/mode-common.h" #include "check/mode-lowmem.h" +static u64 last_allocated_chunk; + static int calc_extent_flag(struct btrfs_root *root, struct extent_buffer *eb, u64 *flags_ret) { @@ -184,8 +186,8 @@ static int update_nodes_refs(struct btrfs_root *root, u64 bytenr, if (bytenr != (u64)-1) { /* the return value of this function seems a mistake */ - ret = btrfs_lookup_extent_info(NULL, root, bytenr, - level, 1, &refs, &flags); + ret = btrfs_lookup_extent_info(NULL, root->fs_info, bytenr, + level, 1, &refs, &flags); /* temporary fix */ if (ret < 0 && !check_all) return ret; @@ -234,17 +236,343 @@ static int update_nodes_refs(struct btrfs_root *root, u64 bytenr, } /* + * Mark all extents unfree in the block group. And set @block_group->cached + * according to @cache. + */ +static int modify_block_group_cache(struct btrfs_fs_info *fs_info, + struct btrfs_block_group_cache *block_group, int cache) +{ + struct extent_io_tree *free_space_cache = &fs_info->free_space_cache; + u64 start = block_group->key.objectid; + u64 end = start + block_group->key.offset; + + if (cache && !block_group->cached) { + block_group->cached = 1; + clear_extent_dirty(free_space_cache, start, end - 1); + } + + if (!cache && block_group->cached) { + block_group->cached = 0; + clear_extent_dirty(free_space_cache, start, end - 1); + } + return 0; +} + +/* + * Modify block groups which have @flags unfree in free space cache. + * + * @cache: if 0, clear block groups cache state; + * not 0, mark blocks groups cached. + */ +static int modify_block_groups_cache(struct btrfs_fs_info *fs_info, u64 flags, + int cache) +{ + struct btrfs_root *root = fs_info->extent_root; + struct btrfs_key key; + struct btrfs_path path; + struct btrfs_block_group_cache *bg_cache; + struct btrfs_block_group_item *bi; + struct btrfs_block_group_item bg_item; + struct extent_buffer *eb; + int slot; + int ret; + + key.objectid = 0; + key.type = BTRFS_BLOCK_GROUP_ITEM_KEY; + key.offset = 0; + + btrfs_init_path(&path); + ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); + if (ret < 0) { + error("fail to search block groups due to %s", strerror(-ret)); + goto out; + } + + while (1) { + eb = path.nodes[0]; + slot = path.slots[0]; + btrfs_item_key_to_cpu(eb, &key, slot); + bg_cache = btrfs_lookup_block_group(fs_info, key.objectid); + if (!bg_cache) { + ret = -ENOENT; + goto out; + } + + bi = btrfs_item_ptr(eb, slot, struct btrfs_block_group_item); + read_extent_buffer(eb, &bg_item, (unsigned long)bi, + sizeof(bg_item)); + if (btrfs_block_group_flags(&bg_item) & flags) + modify_block_group_cache(fs_info, bg_cache, cache); + + ret = btrfs_next_item(root, &path); + if (ret > 0) { + ret = 0; + goto out; + } + if (ret < 0) + goto out; + } + +out: + btrfs_release_path(&path); + return ret; +} + +static int mark_block_groups_full(struct btrfs_fs_info *fs_info, u64 flags) +{ + return modify_block_groups_cache(fs_info, flags, 1); +} + +static int clear_block_groups_full(struct btrfs_fs_info *fs_info, u64 flags) +{ + return modify_block_groups_cache(fs_info, flags, 0); +} + +static int create_chunk_and_block_group(struct btrfs_fs_info *fs_info, + u64 flags, u64 *start, u64 *nbytes) +{ + struct btrfs_trans_handle *trans; + struct btrfs_root *root = fs_info->extent_root; + int ret; + + if ((flags & BTRFS_BLOCK_GROUP_TYPE_MASK) == 0) + return -EINVAL; + + trans = btrfs_start_transaction(root, 1); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + error("error starting transaction %s", strerror(-ret)); + return ret; + } + ret = btrfs_alloc_chunk(trans, fs_info, start, nbytes, flags); + if (ret) { + error("fail to allocate new chunk %s", strerror(-ret)); + goto out; + } + ret = btrfs_make_block_group(trans, fs_info, 0, flags, *start, + *nbytes); + if (ret) { + error("fail to make block group for chunk %llu %llu %s", + *start, *nbytes, strerror(-ret)); + goto out; + } +out: + btrfs_commit_transaction(trans, root); + return ret; +} + +static int force_cow_in_new_chunk(struct btrfs_fs_info *fs_info, + u64 *start_ret) +{ + struct btrfs_block_group_cache *bg; + u64 start; + u64 nbytes; + u64 alloc_profile; + u64 flags; + int ret; + + alloc_profile = (fs_info->avail_metadata_alloc_bits & + fs_info->metadata_alloc_profile); + flags = BTRFS_BLOCK_GROUP_METADATA | alloc_profile; + if (btrfs_fs_incompat(fs_info, MIXED_GROUPS)) + flags |= BTRFS_BLOCK_GROUP_DATA; + + ret = create_chunk_and_block_group(fs_info, flags, &start, &nbytes); + if (ret) + goto err; + printf("Created new chunk [%llu %llu]\n", start, nbytes); + + flags = BTRFS_BLOCK_GROUP_METADATA; + /* Mark all metadata block groups cached and full in free space*/ + ret = mark_block_groups_full(fs_info, flags); + if (ret) + goto clear_bgs_full; + + bg = btrfs_lookup_block_group(fs_info, start); + if (!bg) { + ret = -ENOENT; + error("fail to look up block group %llu %llu", start, nbytes); + goto clear_bgs_full; + } + + /* Clear block group cache just allocated */ + ret = modify_block_group_cache(fs_info, bg, 0); + if (ret) + goto clear_bgs_full; + if (start_ret) + *start_ret = start; + return 0; + +clear_bgs_full: + clear_block_groups_full(fs_info, flags); +err: + return ret; +} + +/* + * Returns 0 means not almost full. + * Returns >0 means almost full. + * Returns <0 means fatal error. + */ +static int is_chunk_almost_full(struct btrfs_fs_info *fs_info, u64 start) +{ + struct btrfs_path path; + struct btrfs_key key; + struct btrfs_root *root = fs_info->extent_root; + struct btrfs_block_group_item *bi; + struct btrfs_block_group_item bg_item; + struct extent_buffer *eb; + u64 used; + u64 total; + u64 min_free; + int ret; + int slot; + + key.objectid = start; + key.type = BTRFS_BLOCK_GROUP_ITEM_KEY; + key.offset = (u64)-1; + + btrfs_init_path(&path); + ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0); + if (!ret) + ret = -EIO; + if (ret < 0) + goto out; + ret = btrfs_previous_item(root, &path, start, + BTRFS_BLOCK_GROUP_ITEM_KEY); + if (ret) { + error("failed to find block group %llu", start); + ret = -ENOENT; + goto out; + } + + eb = path.nodes[0]; + slot = path.slots[0]; + btrfs_item_key_to_cpu(eb, &key, slot); + if (key.objectid != start) { + ret = -ENOENT; + goto out; + } + + total = key.offset; + bi = btrfs_item_ptr(eb, slot, struct btrfs_block_group_item); + read_extent_buffer(eb, &bg_item, (unsigned long)bi, sizeof(bg_item)); + used = btrfs_block_group_used(&bg_item); + + /* + * if the free space in the chunk is less than %10 of total, + * or not not enough for CoW once, we think the chunk is almost full. + */ + min_free = max_t(u64, (BTRFS_MAX_LEVEL + 1) * fs_info->nodesize, + div_factor(total, 1)); + + if ((total - used) > min_free) + ret = 0; + else + ret = 1; +out: + btrfs_release_path(&path); + return ret; +} + +/* + * Returns <0 for error. + * Returns 0 for success. + */ +static int try_to_force_cow_in_new_chunk(struct btrfs_fs_info *fs_info, + u64 old_start, u64 *new_start) +{ + int ret; + + if (old_start) { + ret = is_chunk_almost_full(fs_info, old_start); + if (ret <= 0) + return ret; + } + ret = force_cow_in_new_chunk(fs_info, new_start); + return ret; +} + +static int avoid_extents_overwrite(struct btrfs_fs_info *fs_info) +{ + int ret; + int mixed = btrfs_fs_incompat(fs_info, MIXED_GROUPS); + + if (fs_info->excluded_extents) + return 0; + + if (last_allocated_chunk != (u64)-1) { + ret = try_to_force_cow_in_new_chunk(fs_info, + last_allocated_chunk, &last_allocated_chunk); + if (!ret) + goto out; + /* + * If failed, do not try to allocate chunk again in + * next call. + * If there is no space left to allocate, try to exclude all + * metadata blocks. Mixed filesystem is unsupported. + */ + last_allocated_chunk = (u64)-1; + if (ret != -ENOSPC || mixed) + goto out; + } + + printf( + "Try to exclude all metadata blcoks and extents, it may be slow\n"); + ret = exclude_metadata_blocks(fs_info); +out: + if (ret) + error("failed to avoid extents overwrite %s", strerror(-ret)); + return ret; +} + +static int end_avoid_extents_overwrite(struct btrfs_fs_info *fs_info) +{ + int ret = 0; + + cleanup_excluded_extents(fs_info); + if (last_allocated_chunk) + ret = clear_block_groups_full(fs_info, + BTRFS_BLOCK_GROUP_METADATA); + return ret; +} + +/* + * Wrapper function for btrfs_fix_block_accounting(). + * + * Returns 0 on success. + * Returns != 0 on error. + */ +static int repair_block_accounting(struct btrfs_fs_info *fs_info) +{ + struct btrfs_trans_handle *trans = NULL; + struct btrfs_root *root = fs_info->extent_root; + int ret; + + trans = btrfs_start_transaction(root, 1); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + error("fail to start transaction %s", strerror(-ret)); + return ret; + } + + ret = btrfs_fix_block_accounting(trans); + btrfs_commit_transaction(trans, root); + return ret; +} + +/* * This function only handles BACKREF_MISSING, * If corresponding extent item exists, increase the ref, else insert an extent * item and backref. * * Returns error bits after repair. */ -static int repair_tree_block_ref(struct btrfs_trans_handle *trans, - struct btrfs_root *root, +static int repair_tree_block_ref(struct btrfs_root *root, struct extent_buffer *node, struct node_refs *nrefs, int level, int err) { + struct btrfs_trans_handle *trans = NULL; struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_root *extent_root = fs_info->extent_root; struct btrfs_path path; @@ -294,6 +622,16 @@ static int repair_tree_block_ref(struct btrfs_trans_handle *trans, if (nrefs->full_backref[level] != 0) flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF; + ret = avoid_extents_overwrite(root->fs_info); + if (ret) + goto out; + trans = btrfs_start_transaction(extent_root, 1); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + trans = NULL; + error("fail to start transaction %s", strerror(-ret)); + goto out; + } /* insert an extent item */ if (insert_extent) { struct btrfs_disk_key copy_key; @@ -359,6 +697,8 @@ static int repair_tree_block_ref(struct btrfs_trans_handle *trans, nrefs->refs[level]++; out: + if (trans) + btrfs_commit_transaction(trans, extent_root); btrfs_release_path(&path); if (ret) { error( @@ -390,7 +730,7 @@ static void account_bytes(struct btrfs_root *root, struct btrfs_path *path, total_extent_tree_bytes += eb->len; if (level == 0) { - btree_space_waste += btrfs_leaf_free_space(root->fs_info, eb); + btree_space_waste += btrfs_leaf_free_space(eb); } else { free_nrs = (BTRFS_NODEPTRS_PER_BLOCK(root->fs_info) - btrfs_header_nritems(eb)); @@ -635,6 +975,10 @@ int repair_ternary_lowmem(struct btrfs_root *root, u64 dir_ino, u64 ino, goto out; } if (stage == 1) { + ret = btrfs_unlink(trans, root, ino, dir_ino, index, name, + name_len, 0); + if (ret) + goto out; ret = btrfs_add_link(trans, root, ino, dir_ino, name, name_len, filetype, &index, 1, 1); goto out; @@ -921,14 +1265,13 @@ next: * @namelen: the length of name in the INODE_REF/INODE_EXTREF * @index_ret: the index in the INODE_REF/INODE_EXTREF, * value (64)-1 means do not check index - * @ext_ref: the EXTENDED_IREF feature * * Return 0 if no error occurred. * Return >0 for error bitmap */ static int find_inode_ref(struct btrfs_root *root, struct btrfs_key *key, - char *name, int namelen, u64 *index_ret, - unsigned int ext_ref) + char *name, int namelen, u64 *index_ret) + { struct btrfs_path path; struct btrfs_inode_ref *ref; @@ -1001,8 +1344,9 @@ next_ref: } extref: + /* Skip if not support EXTENDED_IREF feature */ - if (!ext_ref) + if (!btrfs_fs_incompat(root->fs_info, EXTENDED_IREF)) goto out; btrfs_release_path(&path); @@ -1188,14 +1532,12 @@ static void print_dir_item_err(struct btrfs_root *root, struct btrfs_key *key, * @key: the key of the INODE_REF/INODE_EXTREF * @path: the path * @size: the st_size of the INODE_ITEM - * @ext_ref: the EXTENDED_IREF feature * * Return 0 if no error occurred. * Return DIR_COUNT_AGAIN if the isize of the inode should be recalculated. */ static int check_dir_item(struct btrfs_root *root, struct btrfs_key *di_key, - struct btrfs_path *path, u64 *size, - unsigned int ext_ref) + struct btrfs_path *path, u64 *size) { struct btrfs_dir_item *di; struct btrfs_inode_item *ii; @@ -1217,14 +1559,6 @@ static int check_dir_item(struct btrfs_root *root, struct btrfs_key *di_key, int tmp_err; int need_research = 0; - /* - * For DIR_ITEM set index to (u64)-1, so that find_inode_ref - * ignore index check. - */ - if (di_key->type == BTRFS_DIR_INDEX_KEY) - index = di_key->offset; - else - index = (u64)-1; begin: err = 0; cur = 0; @@ -1254,6 +1588,15 @@ begin: memset(namebuf, 0, sizeof(namebuf) / sizeof(*namebuf)); while (cur < total) { + /* + * For DIR_ITEM set index to (u64)-1, so that find_inode_ref + * ignore index check. + */ + if (di_key->type == BTRFS_DIR_INDEX_KEY) + index = di_key->offset; + else + index = (u64)-1; + data_len = btrfs_dir_data_len(node, di); tmp_err = 0; if (data_len) @@ -1311,8 +1654,7 @@ begin: key.objectid = location.objectid; key.type = BTRFS_INODE_REF_KEY; key.offset = di_key->objectid; - tmp_err |= find_inode_ref(root, &key, namebuf, len, - &index, ext_ref); + tmp_err |= find_inode_ref(root, &key, namebuf, len, &index); /* check relative INDEX/ITEM */ key.objectid = di_key->objectid; @@ -1921,13 +2263,10 @@ static bool has_orphan_item(struct btrfs_root *root, u64 ino) * 2. check inode ref/extref * 3. check dir item/index * - * @ext_ref: the EXTENDED_IREF feature - * * Return 0 if no error occurred. * Return >0 for error or hit the traversal is done(by error bitmap) */ -static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path, - unsigned int ext_ref) +static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path) { struct extent_buffer *node; struct btrfs_inode_item *ii; @@ -1935,6 +2274,7 @@ static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path, struct btrfs_key last_key; u64 inode_id; u32 mode; + u64 flags; u64 nlink; u64 nbytes; u64 isize; @@ -1968,10 +2308,19 @@ static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path, isize = btrfs_inode_size(node, ii); nbytes = btrfs_inode_nbytes(node, ii); mode = btrfs_inode_mode(node, ii); + flags = btrfs_inode_flags(node, ii); dir = imode_to_type(mode) == BTRFS_FT_DIR; nlink = btrfs_inode_nlink(node, ii); nodatasum = btrfs_inode_flags(node, ii) & BTRFS_INODE_NODATASUM; + if (S_ISLNK(mode) && + flags & (BTRFS_INODE_IMMUTABLE | BTRFS_INODE_APPEND)) { + err |= INODE_FLAGS_ERROR; + error( +"symlinks must never have immutable/append flags set, root %llu inode item %llu flags %llu may be corrupted", + root->objectid, inode_id, flags); + } + while (1) { btrfs_item_key_to_cpu(path->nodes[0], &last_key, path->slots[0]); ret = btrfs_next_item(root, path); @@ -1996,6 +2345,9 @@ static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path, err |= ret; break; case BTRFS_INODE_EXTREF_KEY: + { + bool ext_ref = btrfs_fs_incompat(root->fs_info, + EXTENDED_IREF); if (key.type == BTRFS_INODE_EXTREF_KEY && !ext_ref) warning("root %llu EXTREF[%llu %llu] isn't supported", root->objectid, key.objectid, @@ -2004,6 +2356,7 @@ static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path, mode); err |= ret; break; + } case BTRFS_DIR_ITEM_KEY: case BTRFS_DIR_INDEX_KEY: if (!dir) { @@ -2012,7 +2365,7 @@ static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path, imode_to_type(mode), key.objectid, key.offset); } - ret = check_dir_item(root, &key, path, &size, ext_ref); + ret = check_dir_item(root, &key, path, &size); err |= ret; break; case BTRFS_EXTENT_DATA_KEY: @@ -2143,7 +2496,7 @@ out: * Returns 0 No errors found */ static int process_one_leaf(struct btrfs_root *root, struct btrfs_path *path, - struct node_refs *nrefs, int *level, int ext_ref) + struct node_refs *nrefs, int *level) { struct extent_buffer *cur = path->nodes[0]; struct btrfs_key key; @@ -2174,7 +2527,7 @@ static int process_one_leaf(struct btrfs_root *root, struct btrfs_path *path, path->slots[0] = i; again: - err |= check_inode_item(root, path, ext_ref); + err |= check_inode_item(root, path); /* modify cur since check_inode_item may change path */ cur = path->nodes[0]; @@ -2491,12 +2844,12 @@ out: * * Returns error bits after reapir. */ -static int repair_extent_data_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, +static int repair_extent_data_item(struct btrfs_root *root, struct btrfs_path *pathp, struct node_refs *nrefs, int err) { + struct btrfs_trans_handle *trans = NULL; struct btrfs_file_extent_item *fi; struct btrfs_key fi_key; struct btrfs_key key; @@ -2513,6 +2866,7 @@ static int repair_extent_data_item(struct btrfs_trans_handle *trans, u64 file_offset; int generation; int slot; + int need_insert = 0; int ret = 0; eb = pathp->nodes[0]; @@ -2531,6 +2885,11 @@ static int repair_extent_data_item(struct btrfs_trans_handle *trans, extent_offset = btrfs_file_extent_offset(eb, fi); offset = file_offset - extent_offset; + if (nrefs->full_backref[0]) + parent = btrfs_header_bytenr(eb); + else + parent = 0; + /* now repair only adds backref */ if ((err & BACKREF_MISSING) == 0) return err; @@ -2546,9 +2905,20 @@ static int repair_extent_data_item(struct btrfs_trans_handle *trans, ret = -EIO; goto out; } + need_insert = ret; + ret = avoid_extents_overwrite(root->fs_info); + if (ret) + goto out; + trans = btrfs_start_transaction(root, 1); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + trans = NULL; + error("fail to start transaction %s", strerror(-ret)); + goto out; + } /* insert an extent item */ - if (ret > 0) { + if (need_insert) { key.objectid = disk_bytenr; key.type = BTRFS_EXTENT_ITEM_KEY; key.offset = num_bytes; @@ -2572,11 +2942,6 @@ static int repair_extent_data_item(struct btrfs_trans_handle *trans, btrfs_release_path(&path); } - if (nrefs->full_backref[0]) - parent = btrfs_header_bytenr(eb); - else - parent = 0; - ret = btrfs_inc_extent_ref(trans, root, disk_bytenr, num_bytes, parent, root->objectid, parent ? BTRFS_FIRST_FREE_OBJECTID : fi_key.objectid, @@ -2593,6 +2958,9 @@ static int repair_extent_data_item(struct btrfs_trans_handle *trans, err &= ~BACKREF_MISSING; out: + if (trans) + btrfs_commit_transaction(trans, root); + btrfs_release_path(&path); if (ret) error("can't repair root %llu extent data item[%llu %llu]", root->objectid, disk_bytenr, num_bytes); @@ -3326,40 +3694,55 @@ out: * means error after repair * Returns 0 nothing happened */ -static int repair_extent_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct btrfs_path *path, +static int repair_extent_item(struct btrfs_root *root, struct btrfs_path *path, u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid, u64 owner, u64 offset, int err) { + struct btrfs_trans_handle *trans; + struct btrfs_root *extent_root = root->fs_info->extent_root; struct btrfs_key old_key; int freed = 0; int ret; btrfs_item_key_to_cpu(path->nodes[0], &old_key, path->slots[0]); - if (err & (REFERENCER_MISSING | REFERENCER_MISMATCH)) { - /* delete the backref */ - ret = btrfs_free_extent(trans, root->fs_info->fs_root, bytenr, - num_bytes, parent, root_objectid, owner, offset); - if (!ret) { - freed = 1; - err &= ~REFERENCER_MISSING; - printf("Delete backref in extent [%llu %llu]\n", - bytenr, num_bytes); - } else { - error("fail to delete backref in extent [%llu %llu]", - bytenr, num_bytes); - } + if ((err & (REFERENCER_MISSING | REFERENCER_MISMATCH)) == 0) + return err; + + ret = avoid_extents_overwrite(root->fs_info); + if (ret) + return err; + + trans = btrfs_start_transaction(extent_root, 1); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + error("fail to start transaction %s", strerror(-ret)); + /* nothing happened */ + ret = 0; + goto out; + } + /* delete the backref */ + ret = btrfs_free_extent(trans, root->fs_info->fs_root, bytenr, + num_bytes, parent, root_objectid, owner, offset); + if (!ret) { + freed = 1; + err &= ~REFERENCER_MISSING; + printf("Delete backref in extent [%llu %llu]\n", + bytenr, num_bytes); + } else { + error("fail to delete backref in extent [%llu %llu]", + bytenr, num_bytes); } + btrfs_commit_transaction(trans, extent_root); /* btrfs_free_extent may delete the extent */ btrfs_release_path(path); ret = btrfs_search_slot(NULL, root, &old_key, path, 0, 0); - if (ret) ret = -ENOENT; else if (freed) ret = err; +out: return ret; } @@ -3369,8 +3752,7 @@ static int repair_extent_item(struct btrfs_trans_handle *trans, * * Since we don't use extent_record anymore, introduce new error bit */ -static int check_extent_item(struct btrfs_trans_handle *trans, - struct btrfs_fs_info *fs_info, +static int check_extent_item(struct btrfs_fs_info *fs_info, struct btrfs_path *path) { struct btrfs_extent_item *ei; @@ -3501,7 +3883,7 @@ next: } if (err && repair) { - ret = repair_extent_item(trans, fs_info->extent_root, path, + ret = repair_extent_item(fs_info->extent_root, path, key.objectid, num_bytes, parent, root_objectid, owner, owner_offset, ret); if (ret < 0) @@ -3764,13 +4146,14 @@ out: * * Returns error after repair. */ -static int repair_chunk_item(struct btrfs_trans_handle *trans, - struct btrfs_root *chunk_root, +static int repair_chunk_item(struct btrfs_root *chunk_root, struct btrfs_path *path, int err) { struct btrfs_chunk *chunk; struct btrfs_key chunk_key; struct extent_buffer *eb = path->nodes[0]; + struct btrfs_root *extent_root = chunk_root->fs_info->extent_root; + struct btrfs_trans_handle *trans; u64 length; int slot = path->slots[0]; u64 type; @@ -3783,31 +4166,55 @@ static int repair_chunk_item(struct btrfs_trans_handle *trans, type = btrfs_chunk_type(path->nodes[0], chunk); length = btrfs_chunk_length(eb, chunk); - if (err & REFERENCER_MISSING) { - ret = btrfs_make_block_group(trans, chunk_root->fs_info, 0, - type, chunk_key.offset, length); - if (ret) { - error("fail to add block group item[%llu %llu]", - chunk_key.offset, length); - goto out; - } else { - err &= ~REFERENCER_MISSING; - printf("Added block group item[%llu %llu]\n", - chunk_key.offset, length); - } + /* now repair only adds block group */ + if ((err & REFERENCER_MISSING) == 0) + return err; + + ret = avoid_extents_overwrite(chunk_root->fs_info); + if (ret) + return ret; + + trans = btrfs_start_transaction(extent_root, 1); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + error("fail to start transaction %s", strerror(-ret)); + return ret; } -out: + ret = btrfs_make_block_group(trans, chunk_root->fs_info, 0, type, + chunk_key.offset, length); + if (ret) { + error("fail to add block group item [%llu %llu]", + chunk_key.offset, length); + } else { + err &= ~REFERENCER_MISSING; + printf("Added block group item[%llu %llu]\n", chunk_key.offset, + length); + } + + btrfs_commit_transaction(trans, extent_root); + if (ret) + error("fail to repair item(s) related to chunk item [%llu %llu]", + chunk_key.objectid, chunk_key.offset); return err; } -static int delete_extent_tree_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, +static int delete_extent_tree_item(struct btrfs_root *root, struct btrfs_path *path) { struct btrfs_key key; + struct btrfs_trans_handle *trans; int ret = 0; + ret = avoid_extents_overwrite(root->fs_info); + if (ret) + return ret; + trans = btrfs_start_transaction(root, 1); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + error("fail to start transaction %s", strerror(-ret)); + goto out; + } btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); btrfs_release_path(path); ret = btrfs_search_slot(trans, root, &key, path, -1, 1); @@ -3825,6 +4232,7 @@ static int delete_extent_tree_item(struct btrfs_trans_handle *trans, else path->slots[0]--; out: + btrfs_commit_transaction(trans, root); if (ret) error("failed to delete root %llu item[%llu, %u, %llu]", root->objectid, key.objectid, key.type, key.offset); @@ -3837,8 +4245,7 @@ out: /* * Main entry function to check known items and update related accounting info */ -static int check_leaf_items(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct btrfs_path *path, +static int check_leaf_items(struct btrfs_root *root, struct btrfs_path *path, struct node_refs *nrefs, int account_bytes) { struct btrfs_fs_info *fs_info = root->fs_info; @@ -3869,15 +4276,14 @@ again: case BTRFS_EXTENT_DATA_KEY: ret = check_extent_data_item(root, path, nrefs, account_bytes); if (repair && ret) - ret = repair_extent_data_item(trans, root, path, nrefs, - ret); + ret = repair_extent_data_item(root, path, nrefs, ret); err |= ret; break; case BTRFS_BLOCK_GROUP_ITEM_KEY: ret = check_block_group_item(fs_info, eb, slot); if (repair && ret & REFERENCER_MISSING) - ret = delete_extent_tree_item(trans, root, path); + ret = delete_extent_tree_item(root, path); err |= ret; break; case BTRFS_DEV_ITEM_KEY: @@ -3887,7 +4293,7 @@ again: case BTRFS_CHUNK_ITEM_KEY: ret = check_chunk_item(fs_info, eb, slot); if (repair && ret) - ret = repair_chunk_item(trans, root, path, ret); + ret = repair_chunk_item(root, path, ret); err |= ret; break; case BTRFS_DEV_EXTENT_KEY: @@ -3896,7 +4302,7 @@ again: break; case BTRFS_EXTENT_ITEM_KEY: case BTRFS_METADATA_ITEM_KEY: - ret = check_extent_item(trans, fs_info, path); + ret = check_extent_item(fs_info, path); err |= ret; break; case BTRFS_EXTENT_CSUM_KEY: @@ -3908,7 +4314,7 @@ again: key.objectid, -1); if (repair && ret & (REFERENCER_MISMATCH | REFERENCER_MISSING)) - ret = delete_extent_tree_item(trans, root, path); + ret = delete_extent_tree_item(root, path); err |= ret; break; case BTRFS_EXTENT_DATA_REF_KEY: @@ -3921,7 +4327,7 @@ again: btrfs_extent_data_ref_count(eb, dref)); if (repair && ret & (REFERENCER_MISMATCH | REFERENCER_MISSING)) - ret = delete_extent_tree_item(trans, root, path); + ret = delete_extent_tree_item(root, path); err |= ret; break; case BTRFS_SHARED_BLOCK_REF_KEY: @@ -3929,7 +4335,7 @@ again: key.objectid, -1); if (repair && ret & (REFERENCER_MISMATCH | REFERENCER_MISSING)) - ret = delete_extent_tree_item(trans, root, path); + ret = delete_extent_tree_item(root, path); err |= ret; break; case BTRFS_SHARED_DATA_REF_KEY: @@ -3937,7 +4343,7 @@ again: key.objectid); if (repair && ret & (REFERENCER_MISMATCH | REFERENCER_MISSING)) - ret = delete_extent_tree_item(trans, root, path); + ret = delete_extent_tree_item(root, path); err |= ret; break; default: @@ -3959,10 +4365,8 @@ out: * Returns <0 Fatal error, must exit the whole check * Returns 0 No errors found */ -static int walk_down_tree(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct btrfs_path *path, - int *level, struct node_refs *nrefs, int ext_ref, - int check_all) +static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path, + int *level, struct node_refs *nrefs, int check_all) { enum btrfs_tree_block_status status; u64 bytenr; @@ -4004,7 +4408,7 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, btrfs_header_owner(cur), nrefs); if (repair && ret) - ret = repair_tree_block_ref(trans, root, + ret = repair_tree_block_ref(root, path->nodes[*level], nrefs, *level, ret); err |= ret; @@ -4032,10 +4436,9 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, ret = 0; if (!check_all) - ret = process_one_leaf(root, path, nrefs, - level, ext_ref); + ret = process_one_leaf(root, path, nrefs, level); else - ret = check_leaf_items(trans, root, path, + ret = check_leaf_items(root, path, nrefs, account_file_data); err |= ret; break; @@ -4200,7 +4603,7 @@ out: * returns >0 means error * returns <0 means fatal error */ -static int check_fs_first_inode(struct btrfs_root *root, unsigned int ext_ref) +static int check_fs_first_inode(struct btrfs_root *root) { struct btrfs_path path; struct btrfs_key key; @@ -4241,7 +4644,7 @@ static int check_fs_first_inode(struct btrfs_root *root, unsigned int ext_ref) /* special index value */ index = 0; - ret = find_inode_ref(root, &key, "..", strlen(".."), &index, ext_ref); + ret = find_inode_ref(root, &key, "..", strlen(".."), &index); if (ret < 0) goto out; err |= ret; @@ -4266,16 +4669,13 @@ out: * blocks and integrity of fs tree items. * * @root: the root of the tree to be checked. - * @ext_ref feature EXTENDED_IREF is enable or not. * @account if NOT 0 means check the tree (including tree)'s treeblocks. * otherwise means check fs tree(s) items relationship and * @root MUST be a fs tree root. * Returns 0 represents OK. - * Returns not 0 represents error. + * Returns >0 represents error bits. */ -static int check_btrfs_root(struct btrfs_trans_handle *trans, - struct btrfs_root *root, unsigned int ext_ref, - int check_all) +static int check_btrfs_root(struct btrfs_root *root, int check_all) { struct btrfs_path path; struct node_refs nrefs; @@ -4292,9 +4692,9 @@ static int check_btrfs_root(struct btrfs_trans_handle *trans, * the first inode item in the leaf, if inode item (256) is * missing we will skip it forever. */ - ret = check_fs_first_inode(root, ext_ref); + ret = check_fs_first_inode(root); if (ret < 0) - return ret; + return FATAL_ERROR; } @@ -4319,14 +4719,13 @@ static int check_btrfs_root(struct btrfs_trans_handle *trans, } while (1) { - ret = walk_down_tree(trans, root, &path, &level, &nrefs, - ext_ref, check_all); - - err |= !!ret; + ret = walk_down_tree(root, &path, &level, &nrefs, check_all); + if (ret > 0) + err |= ret; /* if ret is negative, walk shall stop */ if (ret < 0) { - ret = err; + ret = err | FATAL_ERROR; break; } @@ -4347,15 +4746,14 @@ out: * Iterate all items in the tree and call check_inode_item() to check. * * @root: the root of the tree to be checked. - * @ext_ref: the EXTENDED_IREF feature * * Return 0 if no error found. * Return <0 for error. */ -static int check_fs_root(struct btrfs_root *root, unsigned int ext_ref) +static int check_fs_root(struct btrfs_root *root) { reset_cached_block_groups(root->fs_info); - return check_btrfs_root(NULL, root, ext_ref, 0); + return check_btrfs_root(root, 0); } /* @@ -4464,13 +4862,10 @@ int check_fs_roots_lowmem(struct btrfs_fs_info *fs_info) struct btrfs_path path; struct btrfs_key key; struct extent_buffer *node; - unsigned int ext_ref; int slot; int ret; int err = 0; - ext_ref = btrfs_fs_incompat(fs_info, EXTENDED_IREF); - btrfs_init_path(&path); key.objectid = BTRFS_FS_TREE_OBJECTID; key.offset = 0; @@ -4508,7 +4903,7 @@ int check_fs_roots_lowmem(struct btrfs_fs_info *fs_info) goto next; } - ret = check_fs_root(cur_root, ext_ref); + ret = check_fs_root(cur_root); err |= ret; if (key.objectid == BTRFS_TREE_RELOC_OBJECTID) @@ -4538,7 +4933,6 @@ out: */ int check_chunks_and_extents_lowmem(struct btrfs_fs_info *fs_info) { - struct btrfs_trans_handle *trans = NULL; struct btrfs_path path; struct btrfs_key old_key; struct btrfs_key key; @@ -4550,20 +4944,12 @@ int check_chunks_and_extents_lowmem(struct btrfs_fs_info *fs_info) root = fs_info->fs_root; - if (repair) { - trans = btrfs_start_transaction(fs_info->extent_root, 1); - if (IS_ERR(trans)) { - error("failed to start transaction before check"); - return PTR_ERR(trans); - } - } - root1 = root->fs_info->chunk_root; - ret = check_btrfs_root(trans, root1, 0, 1); + ret = check_btrfs_root(root1, 1); err |= ret; root1 = root->fs_info->tree_root; - ret = check_btrfs_root(trans, root1, 0, 1); + ret = check_btrfs_root(root1, 1); err |= ret; btrfs_init_path(&path); @@ -4594,7 +4980,7 @@ int check_chunks_and_extents_lowmem(struct btrfs_fs_info *fs_info) goto next; } - ret = check_btrfs_root(trans, cur_root, 0, 1); + ret = check_btrfs_root(cur_root, 1); err |= ret; if (key.objectid == BTRFS_TREE_RELOC_OBJECTID) @@ -4612,19 +4998,21 @@ next: } out: - /* if repair, update block accounting */ if (repair) { - ret = btrfs_fix_block_accounting(trans, root); + ret = end_avoid_extents_overwrite(fs_info); + if (ret < 0) + ret = FATAL_ERROR; + err |= ret; + + reset_cached_block_groups(fs_info); + /* update block accounting */ + ret = repair_block_accounting(fs_info); if (ret) err |= ret; else err &= ~BG_ACCOUNTING_ERROR; } - if (trans) - btrfs_commit_transaction(trans, root->fs_info->extent_root); - btrfs_release_path(&path); - return err; } diff --git a/check/mode-lowmem.h b/check/mode-lowmem.h index 73d57999..91f7b6b1 100644 --- a/check/mode-lowmem.h +++ b/check/mode-lowmem.h @@ -43,6 +43,8 @@ #define DIR_INDEX_MISMATCH (1<<19) /* INODE_INDEX found but not match */ #define DIR_COUNT_AGAIN (1<<20) /* DIR isize should be recalculated */ #define BG_ACCOUNTING_ERROR (1<<21) /* Block group accounting error */ +#define FATAL_ERROR (1<<22) /* Fatal bit for errno */ +#define INODE_FLAGS_ERROR (1<<23) /* Invalid inode flags */ /* * Error bit for low memory mode check. diff --git a/check/mode-original.h b/check/mode-original.h index 368de692..13cfa5b9 100644 --- a/check/mode-original.h +++ b/check/mode-original.h @@ -186,6 +186,7 @@ struct file_extent_hole { #define I_ERR_LINK_COUNT_WRONG (1 << 13) #define I_ERR_FILE_EXTENT_ORPHAN (1 << 14) #define I_ERR_FILE_EXTENT_TOO_LARGE (1 << 15) +#define I_ERR_ODD_INODE_FLAGS (1 << 16) struct inode_record { struct list_head backrefs; diff --git a/cmds-fi-usage.c b/cmds-fi-usage.c index de7ad668..3bd2ccdf 100644 --- a/cmds-fi-usage.c +++ b/cmds-fi-usage.c @@ -629,7 +629,7 @@ int load_chunk_and_device_info(int fd, struct chunk_info **chunkinfo, ret = load_chunk_info(fd, chunkinfo, chunkcount); if (ret == -EPERM) { warning( -"cannot read detailed chunk info, RAID5/6 numbers will be incorrect, run as root"); +"cannot read detailed chunk info, per-device usage will not be shown, run as root"); } else if (ret) { return ret; } @@ -660,7 +660,7 @@ static u64 calc_chunk_size(struct chunk_info *ci) else if (ci->type & BTRFS_BLOCK_GROUP_RAID6) return ci->size / (ci->num_stripes -2); else if (ci->type & BTRFS_BLOCK_GROUP_RAID10) - return ci->size / ci->num_stripes; + return ci->size / (ci->num_stripes / 2); return ci->size; } @@ -923,9 +923,11 @@ static void _cmd_filesystem_usage_linear(unsigned unit_mode, printf("\n"); } - printf("Unallocated:\n"); - print_unused(info_ptr, info_count, device_info_ptr, device_info_count, - unit_mode | UNITS_NEGATIVE); + if (info_count) { + printf("Unallocated:\n"); + print_unused(info_ptr, info_count, device_info_ptr, + device_info_count, unit_mode | UNITS_NEGATIVE); + } } static int print_filesystem_usage_by_chunk(int fd, @@ -936,9 +938,6 @@ static int print_filesystem_usage_by_chunk(int fd, struct btrfs_ioctl_space_args *sargs; int ret = 0; - if (!chunkinfo) - return 0; - sargs = load_space_info(fd, path); if (!sargs) { ret = 1; diff --git a/cmds-restore.c b/cmds-restore.c index f228acab..342f5cc7 100644 --- a/cmds-restore.c +++ b/cmds-restore.c @@ -825,7 +825,7 @@ static int overwrite_ok(const char * path) int ret; /* don't be fooled by symlinks */ - ret = fstatat(-1, path_name, &st, AT_SYMLINK_NOFOLLOW); + ret = fstatat(AT_FDCWD, path_name, &st, AT_SYMLINK_NOFOLLOW); if (!ret) { if (overwrite) diff --git a/config.h.in b/config.h.in index 0e40ae4b..df264eea 100644 --- a/config.h.in +++ b/config.h.in @@ -21,9 +21,6 @@ /* Define to 1 if you have the <memory.h> header file. */ #undef HAVE_MEMORY_H -/* E2fsprogs does not support BIGALLOC */ -#undef HAVE_OLD_E2FSPROGS - /* Define to 1 if you have the `openat' function. */ #undef HAVE_OPENAT diff --git a/config/config.guess b/config/config.guess index 1bf683d0..33c33bf5 100755 --- a/config/config.guess +++ b/config/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2017 Free Software Foundation, Inc. +# Copyright 1992-2018 Free Software Foundation, Inc. -timestamp='2017-05-27' +timestamp='2018-03-08' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -15,7 +15,7 @@ timestamp='2017-05-27' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see <http://www.gnu.org/licenses/>. +# along with this program; if not, see <https://www.gnu.org/licenses/>. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -27,7 +27,7 @@ timestamp='2017-05-27' # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to <config-patches@gnu.org>. @@ -39,7 +39,7 @@ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2017 Free Software Foundation, Inc. +Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -107,9 +107,9 @@ trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; + ,,) echo "int x;" > "$dummy.c" ; for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; @@ -132,14 +132,14 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown -case "${UNAME_SYSTEM}" in +case "$UNAME_SYSTEM" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu - eval $set_cc_for_build - cat <<-EOF > $dummy.c + eval "$set_cc_for_build" + cat <<-EOF > "$dummy.c" #include <features.h> #if defined(__UCLIBC__) LIBC=uclibc @@ -149,7 +149,14 @@ Linux|GNU|GNU/*) LIBC=gnu #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + + # If ldd exists, use it to detect musl libc. + if command -v ldd >/dev/null && \ + ldd --version 2>&1 | grep -q ^musl + then + LIBC=musl + fi ;; esac @@ -165,7 +172,7 @@ test -f /etc/SuSE-release -o -f /.buildenv && VENDOR=suse # Note: order is significant - the case branches are not exclusive. -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in +case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, @@ -179,30 +186,30 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ - /sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || \ + "/sbin/$sysctl" 2>/dev/null || \ + "/usr/sbin/$sysctl" 2>/dev/null || \ echo unknown)` - case "${UNAME_MACHINE_ARCH}" in + case "$UNAME_MACHINE_ARCH" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) - arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` - endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` - machine=${arch}${endian}-${VENDOR}-unknown + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine="${arch}${endian}"-${VENDOR}-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-${VENDOR}-unknown ;; + *) machine="$UNAME_MACHINE_ARCH"-${VENDOR}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. - case "${UNAME_MACHINE_ARCH}" in + case "$UNAME_MACHINE_ARCH" in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build + eval "$set_cc_for_build" if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -218,10 +225,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ;; esac # Determine ABI tags. - case "${UNAME_MACHINE_ARCH}" in + case "$UNAME_MACHINE_ARCH" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' - abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release @@ -229,46 +236,55 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in + case "$UNAME_VERSION" in Debian*) release='-gnu' ;; *) - release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}${abi}" + echo "$machine-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-${VENDOR}-bitrig${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-${VENDOR}-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-${VENDOR}-openbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-${VENDOR}-openbsd"$UNAME_RELEASE" exit ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` - echo ${UNAME_MACHINE_ARCH}-${VENDOR}-libertybsd${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-${VENDOR}-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-${VENDOR}-midnightbsd"$UNAME_RELEASE" exit ;; *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-ekkobsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-${VENDOR}-ekkobsd"$UNAME_RELEASE" exit ;; *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-solidbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-${VENDOR}-solidbsd"$UNAME_RELEASE" exit ;; macppc:MirBSD:*:*) - echo powerpc-${VENDOR}-mirbsd${UNAME_RELEASE} + echo powerpc-${VENDOR}-mirbsd"$UNAME_RELEASE" exit ;; *:MirBSD:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-mirbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-${VENDOR}-mirbsd"$UNAME_RELEASE" exit ;; *:Sortix:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-sortix + echo "$UNAME_MACHINE"-${VENDOR}-sortix + exit ;; + *:Redox:*:*) + echo "$UNAME_MACHINE"-${VENDOR}-redox exit ;; + mips:OSF1:*.*) + echo mips-dec-osf1 + exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) @@ -320,28 +336,19 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-${VENDOR}-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-amigaos + echo "$UNAME_MACHINE"-${VENDOR}-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-morphos + echo "$UNAME_MACHINE"-${VENDOR}-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition @@ -353,7 +360,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} + echo arm-acorn-riscix"$UNAME_RELEASE" exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-${VENDOR}-riscos @@ -380,19 +387,19 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} + echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build + eval "$set_cc_for_build" SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. @@ -405,13 +412,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in SUN_ARCH=x86_64 fi fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in @@ -420,25 +427,25 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" exit ;; sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" ;; sun4) - echo sparc-sun-sunos${UNAME_RELEASE} + echo sparc-sun-sunos"$UNAME_RELEASE" ;; esac exit ;; aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} + echo sparc-auspex-sunos"$UNAME_RELEASE" exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not @@ -449,44 +456,44 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} + echo m68k-milan-mint"$UNAME_RELEASE" exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} + echo m68k-hades-mint"$UNAME_RELEASE" exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-${VENDOR}-mint${UNAME_RELEASE} + echo m68k-${VENDOR}-mint"$UNAME_RELEASE" exit ;; m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} + echo m68k-apple-machten"$UNAME_RELEASE" exit ;; powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} + echo powerpc-apple-machten"$UNAME_RELEASE" exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} + echo mips-dec-ultrix"$UNAME_RELEASE" exit ;; VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} + echo vax-dec-ultrix"$UNAME_RELEASE" exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} + echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include <stdio.h> /* for printf() prototype */ int main (int argc, char *argv[]) { @@ -495,23 +502,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} + echo mips-mips-riscos"$UNAME_RELEASE" exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax @@ -537,17 +544,17 @@ EOF AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] + if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ + [ "$TARGET_BINARY_INTERFACE"x = x ] then - echo m88k-dg-dgux${UNAME_RELEASE} + echo m88k-dg-dgux"$UNAME_RELEASE" else - echo m88k-dg-dguxbcs${UNAME_RELEASE} + echo m88k-dg-dguxbcs"$UNAME_RELEASE" fi else - echo i586-dg-dgux${UNAME_RELEASE} + echo i586-dg-dgux"$UNAME_RELEASE" fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) @@ -564,7 +571,7 @@ EOF echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id @@ -576,14 +583,14 @@ EOF if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #include <sys/systemcfg.h> main() @@ -594,7 +601,7 @@ EOF exit(0); } EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then echo "$SYSTEM_NAME" else @@ -608,7 +615,7 @@ EOF exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc @@ -617,18 +624,18 @@ EOF IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx @@ -643,28 +650,28 @@ EOF echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + case "$UNAME_MACHINE" in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in + case "$sc_cpu_version" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in + case "$sc_kernel_bits" in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + if [ "$HP_ARCH" = "" ]; then + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include <stdlib.h> @@ -697,13 +704,13 @@ EOF exit (0); } EOF - (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ ${HP_ARCH} = hppa2.0w ] + if [ "$HP_ARCH" = hppa2.0w ] then - eval $set_cc_for_build + eval "$set_cc_for_build" # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -722,15 +729,15 @@ EOF HP_ARCH=hppa64 fi fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #include <unistd.h> int main () @@ -755,11 +762,11 @@ EOF exit (0); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) @@ -768,7 +775,7 @@ EOF *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) @@ -776,9 +783,9 @@ EOF exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-${VENDOR}-osf1mk + echo "$UNAME_MACHINE"-${VENDOR}-osf1mk else - echo ${UNAME_MACHINE}-${VENDOR}-osf1 + echo "$UNAME_MACHINE"-${VENDOR}-osf1 fi exit ;; parisc*:Lites*:*:*) @@ -803,128 +810,109 @@ EOF echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" exit ;; sparc*:BSD/OS:*:*) - echo sparc-${VENDOR}-bsdi${UNAME_RELEASE} + echo sparc-${VENDOR}-bsdi"$UNAME_RELEASE" exit ;; *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-${VENDOR}-bsdi"$UNAME_RELEASE" exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in + case "$UNAME_PROCESSOR" in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac - echo ${UNAME_PROCESSOR}-${VENDOR}-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + echo "$UNAME_PROCESSOR"-${VENDOR}-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin + echo "$UNAME_MACHINE"-pc-cygwin exit ;; *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 + echo "$UNAME_MACHINE"-pc-mingw64 exit ;; *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 + echo "$UNAME_MACHINE"-pc-mingw32 exit ;; *:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 + echo "$UNAME_MACHINE"-pc-msys exit ;; i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 + echo "$UNAME_MACHINE"-pc-pw32 exit ;; *:Interix*:*) - case ${UNAME_MACHINE} in + case "$UNAME_MACHINE" in x86) - echo i586-pc-interix${UNAME_RELEASE} + echo i586-pc-interix"$UNAME_RELEASE" exit ;; authenticamd | genuineintel | EM64T) - echo x86_64-${VENDOR}-interix${UNAME_RELEASE} + echo x86_64-${VENDOR}-interix"$UNAME_RELEASE" exit ;; IA64) - echo ia64-${VENDOR}-interix${UNAME_RELEASE} + echo ia64-${VENDOR}-interix"$UNAME_RELEASE" exit ;; esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin + echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-${VENDOR}-cygwin exit ;; - p*:CYGWIN*:*) - echo powerpcle-${VENDOR}-cygwin - exit ;; prep*:SunOS:5.*:*) - echo powerpcle-${VENDOR}-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo powerpcle-${VENDOR}-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-${VENDOR}-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-${VENDOR}-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-${VENDOR}-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + echo "$UNAME_MACHINE-${VENDOR}-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" exit ;; i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix + echo "$UNAME_MACHINE"-pc-minix exit ;; aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in @@ -938,63 +926,63 @@ EOF esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; arc:Linux:*:* | arceb:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; arm*:Linux:*:*) - eval $set_cc_for_build + eval "$set_cc_for_build" if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC}eabi + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC"eabi else - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC}eabihf + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC"eabihf fi fi exit ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; e2k:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; frv:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; i*86:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; k1om:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el @@ -1008,70 +996,70 @@ EOF #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-${VENDOR}-linux-${LIBC}"; exit; } + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" + test "x$CPU" != x && { echo "$CPU-${VENDOR}-linux-$LIBC"; exit; } ;; mips64el:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; openrisc*:Linux:*:*) - echo or1k-${VENDOR}-linux-${LIBC} + echo or1k-${VENDOR}-linux-"$LIBC" exit ;; or32:Linux:*:* | or1k*:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; padre:Linux:*:*) - echo sparc-${VENDOR}-linux-${LIBC} + echo sparc-${VENDOR}-linux-"$LIBC" exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-${VENDOR}-linux-${LIBC} + echo hppa64-${VENDOR}-linux-"$LIBC" exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-${VENDOR}-linux-${LIBC} ;; - PA8*) echo hppa2.0-${VENDOR}-linux-${LIBC} ;; - *) echo hppa-${VENDOR}-linux-${LIBC} ;; + PA7*) echo hppa1.1-${VENDOR}-linux-"$LIBC" ;; + PA8*) echo hppa2.0-${VENDOR}-linux-"$LIBC" ;; + *) echo hppa-${VENDOR}-linux-"$LIBC" ;; esac exit ;; ppc64:Linux:*:*) - echo powerpc64-${VENDOR}-linux-${LIBC} + echo powerpc64-${VENDOR}-linux-"$LIBC" exit ;; ppc:Linux:*:*) - echo powerpc-${VENDOR}-linux-${LIBC} + echo powerpc-${VENDOR}-linux-"$LIBC" exit ;; ppc64le:Linux:*:*) - echo powerpc64le-${VENDOR}-linux-${LIBC} + echo powerpc64le-${VENDOR}-linux-"$LIBC" exit ;; ppcle:Linux:*:*) - echo powerpcle-${VENDOR}-linux-${LIBC} + echo powerpcle-${VENDOR}-linux-"$LIBC" exit ;; riscv32:Linux:*:* | riscv64:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-${LIBC} + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} + echo "$UNAME_MACHINE"-${VENDOR}-linux-"$LIBC" exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -1085,34 +1073,34 @@ EOF # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx + echo "$UNAME_MACHINE"-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-${VENDOR}-stop + echo "$UNAME_MACHINE"-${VENDOR}-stop exit ;; i*86:atheos:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-atheos + echo "$UNAME_MACHINE"-${VENDOR}-atheos exit ;; i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable + echo "$UNAME_MACHINE"-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-${VENODR}-lynxos${UNAME_RELEASE} + echo i386-${VENDOR}-lynxos"$UNAME_RELEASE" exit ;; i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp + echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" fi exit ;; i*86:*:5:[678]*) @@ -1122,12 +1110,12 @@ EOF *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo ${UNAME_MACHINE}-${VENDOR}-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + echo "$UNAME_MACHINE-${VENDOR}-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` - echo ${UNAME_MACHINE}-pc-isc$UNAME_REL + echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL" elif /bin/uname -X 2>/dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 @@ -1137,9 +1125,9 @@ EOF && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv32 + echo "$UNAME_MACHINE"-pc-sysv32 fi exit ;; pc:*:*:*) @@ -1159,9 +1147,9 @@ EOF exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-${VENODR}-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + echo i860-${VENDOR}-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) @@ -1181,9 +1169,9 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; @@ -1192,28 +1180,28 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-${VENDOR}-lynxos${UNAME_RELEASE} + echo m68k-${VENDOR}-lynxos"$UNAME_RELEASE" exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) - echo sparc-${VENDOR}-lynxos${UNAME_RELEASE} + echo sparc-${VENDOR}-lynxos"$UNAME_RELEASE" exit ;; rs6000:LynxOS:2.*:*) - echo rs6000-${VENDOR}-lynxos${UNAME_RELEASE} + echo rs6000-${VENDOR}-lynxos"$UNAME_RELEASE" exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-${VENDOR}-lynxos${UNAME_RELEASE} + echo powerpc-${VENDOR}-lynxos"$UNAME_RELEASE" exit ;; SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} + echo mips-dde-sysv"$UNAME_RELEASE" exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 @@ -1224,7 +1212,7 @@ EOF *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 + echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv fi @@ -1244,23 +1232,23 @@ EOF exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos + echo "$UNAME_MACHINE"-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} + echo m68k-apple-aux"$UNAME_RELEASE" exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + echo mips-nec-sysv"$UNAME_RELEASE" else - echo mips-${VENDOR}-sysv${UNAME_RELEASE} + echo mips-${VENDOR}-sysv"$UNAME_RELEASE" fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. @@ -1279,39 +1267,39 @@ EOF echo x86_64-${VENDOR}-haiku exit ;; SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} + echo sx4-nec-superux"$UNAME_RELEASE" exit ;; SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} + echo sx5-nec-superux"$UNAME_RELEASE" exit ;; SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} + echo sx6-nec-superux"$UNAME_RELEASE" exit ;; SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} + echo sx7-nec-superux"$UNAME_RELEASE" exit ;; SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} + echo sx8-nec-superux"$UNAME_RELEASE" exit ;; SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} + echo sx8r-nec-superux"$UNAME_RELEASE" exit ;; SX-ACE:SUPER-UX:*:*) - echo sxace-nec-superux${UNAME_RELEASE} + echo sxace-nec-superux"$UNAME_RELEASE" exit ;; Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} + echo powerpc-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval $set_cc_for_build + eval "$set_cc_for_build" if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi - if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ @@ -1339,7 +1327,7 @@ EOF # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` @@ -1347,22 +1335,25 @@ EOF UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-*:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} + echo neo-tandem-nsk"$UNAME_RELEASE" exit ;; NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} + echo nse-tandem-nsk"$UNAME_RELEASE" exit ;; NSR-*:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} + echo nsr-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" exit ;; NSX-*:NONSTOP_KERNEL:*:*) - echo nsx-tandem-nsk${UNAME_RELEASE} + echo nsx-tandem-nsk"$UNAME_RELEASE" exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux @@ -1371,7 +1362,7 @@ EOF echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 @@ -1382,7 +1373,7 @@ EOF else UNAME_MACHINE="$cputype" fi - echo ${UNAME_MACHINE}-${VENDOR}-plan9 + echo "$UNAME_MACHINE"-${VENDOR}-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-${VENDOR}-tops10 @@ -1403,14 +1394,14 @@ EOF echo pdp10-${VENDOR}-its exit ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} + echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + echo "$UNAME_MACHINE"-${VENDOR}-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in + case "$UNAME_MACHINE" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; @@ -1419,32 +1410,44 @@ EOF echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` + echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" exit ;; i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos + echo "$UNAME_MACHINE"-pc-rdos exit ;; i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros + echo "$UNAME_MACHINE"-pc-aros exit ;; x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-esx + echo "$UNAME_MACHINE"-${VENDOR}-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-${VENDOR}-onefs exit ;; esac +echo "$0: unable to guess system type" >&2 + +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <<EOF + +NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize +the system type. Please install a C compiler and try again. +EOF + ;; +esac + cat >&2 <<EOF -$0: unable to guess system type This script (version $timestamp), has failed to recognize the -operating system you are using. If your script is old, overwrite -config.guess and config.sub with the latest versions from: +operating system you are using. If your script is old, overwrite *all* +copies of config.guess and config.sub with the latest versions from: - http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess + https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess and - http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub + https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub If $0 has already been updated, send the following data and any information you think might be pertinent to config-patches@gnu.org to @@ -1467,16 +1470,16 @@ hostinfo = `(hostinfo) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" EOF exit 1 # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/config/config.sub b/config/config.sub index 0399c1a5..d210453d 100755 --- a/config/config.sub +++ b/config/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2017 Free Software Foundation, Inc. +# Copyright 1992-2018 Free Software Foundation, Inc. -timestamp='2017-04-02' +timestamp='2018-03-08' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -15,7 +15,7 @@ timestamp='2017-04-02' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see <http://www.gnu.org/licenses/>. +# along with this program; if not, see <https://www.gnu.org/licenses/>. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -33,7 +33,7 @@ timestamp='2017-04-02' # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -57,7 +57,7 @@ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -67,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>." version="\ GNU config.sub ($timestamp) -Copyright 1992-2017 Free Software Foundation, Inc. +Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -94,7 +94,7 @@ while test $# -gt 0 ; do *local*) # First pass through any local machine types. - echo $1 + echo "$1" exit ;; * ) @@ -112,7 +112,7 @@ esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ @@ -120,16 +120,16 @@ case $maybe_os in kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` + basic_machine=`echo "$1" | sed 's/-[^-]*$//'` + if [ "$basic_machine" != "$1" ] + then os=`echo "$1" | sed 's/.*-/-/'` else os=; fi ;; esac @@ -178,44 +178,44 @@ case $os in ;; -sco6) os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 @@ -227,10 +227,7 @@ case $os in os=-lynxos ;; -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` ;; -psos*) os=-psos @@ -299,7 +296,7 @@ case $basic_machine in | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ - | pdp10 | pdp11 | pj | pjl \ + | pdp10 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pru \ | pyramid \ @@ -316,7 +313,6 @@ case $basic_machine in | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ | wasm32 \ - | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown @@ -337,7 +333,7 @@ case $basic_machine in basic_machine=$basic_machine-unknown os=-none ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) ;; ms1) basic_machine=mt-unknown @@ -366,7 +362,7 @@ case $basic_machine in ;; # Object if more than one company name word. *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. @@ -461,7 +457,7 @@ case $basic_machine in # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) - basic_machine=i386-unknown + basic_machine=i386-pc os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) @@ -495,7 +491,7 @@ case $basic_machine in basic_machine=x86_64-pc ;; amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl @@ -540,7 +536,7 @@ case $basic_machine in os=-linux ;; blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) @@ -548,13 +544,13 @@ case $basic_machine in os=-cnk ;; c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray @@ -643,7 +639,7 @@ case $basic_machine in basic_machine=rs6000-bull os=-bosx ;; - dpx2* | dpx2*-bull) + dpx2*) basic_machine=m68k-bull os=-sysv3 ;; @@ -652,7 +648,7 @@ case $basic_machine in os=$os"spe" ;; e500v[12]-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=$os"spe" ;; ebmon29k) @@ -744,9 +740,6 @@ case $basic_machine in hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; - hppa-next) - os=-nextstep3 - ;; hppaosf) basic_machine=hppa1.1-hp os=-osf @@ -759,26 +752,26 @@ case $basic_machine in basic_machine=i370-ibm ;; i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; - i386-vsta | vsta) + vsta) basic_machine=i386-unknown os=-vsta ;; @@ -797,19 +790,16 @@ case $basic_machine in os=-sysv ;; leon-*|leon[3-9]-*) - basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; - m88k-omron*) - basic_machine=m88k-omron - ;; magnum | m3230) basic_machine=mips-mips os=-sysv @@ -841,10 +831,10 @@ case $basic_machine in os=-mint ;; mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` ;; mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k @@ -863,7 +853,7 @@ case $basic_machine in os=-msdos ;; ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc @@ -905,7 +895,7 @@ case $basic_machine in basic_machine=v70-nec os=-sysv ;; - next | m*-next ) + next | m*-next) basic_machine=m68k-next case $os in -nextstep* ) @@ -950,6 +940,9 @@ case $basic_machine in nsr-tandem) basic_machine=nsr-tandem ;; + nsv-tandem) + basic_machine=nsv-tandem + ;; nsx-tandem) basic_machine=nsx-tandem ;; @@ -985,7 +978,7 @@ case $basic_machine in os=-linux ;; parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; pbd) @@ -1001,7 +994,7 @@ case $basic_machine in basic_machine=i386-pc ;; pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc @@ -1016,16 +1009,16 @@ case $basic_machine in basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould @@ -1035,23 +1028,23 @@ case $basic_machine in ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm @@ -1111,17 +1104,10 @@ case $basic_machine in sequent) basic_machine=i386-sequent ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; sh5el) basic_machine=sh5le-unknown ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) + simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; @@ -1140,7 +1126,7 @@ case $basic_machine in os=-sysv4 ;; strongarm-* | thumb-*) - basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun @@ -1254,9 +1240,6 @@ case $basic_machine in basic_machine=a29k-wrs os=-vxworks ;; - wasm32) - basic_machine=wasm32-unknown - ;; w65*) basic_machine=w65-wdc os=-none @@ -1265,6 +1248,9 @@ case $basic_machine in basic_machine=hppa1.1-winbond os=-proelf ;; + x64) + basic_machine=x86_64-pc + ;; xbox) basic_machine=i686-pc os=-mingw32 @@ -1273,20 +1259,12 @@ case $basic_machine in basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) - basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; none) basic_machine=none-none os=-none @@ -1315,10 +1293,6 @@ case $basic_machine in vax) basic_machine=vax-dec ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; pdp11) basic_machine=pdp11-dec ;; @@ -1328,9 +1302,6 @@ case $basic_machine in sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; cydra) basic_machine=cydra-cydrome ;; @@ -1350,7 +1321,7 @@ case $basic_machine in # Make sure to match an already-canonicalized machine name. ;; *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; esac @@ -1358,10 +1329,10 @@ esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` ;; *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` ;; *) ;; @@ -1372,8 +1343,8 @@ esac if [ x"$os" != x"" ] then case $os in - # First match some system type aliases - # that might get confused with valid system types. + # First match some system type aliases that might get confused + # with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux @@ -1384,18 +1355,19 @@ case $os in -solaris) os=-solaris2 ;; - -svr4*) - os=-sysv4 - ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; - # First accept the basic system types. + # es1800 is here to avoid being matched by es* (a different OS) + -es1800*) + os=-ose + ;; + # Now accept the basic system types. # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. + # Each alternative MUST end in a * to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ @@ -1405,25 +1377,26 @@ case $os in | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* | -hcos* \ | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -morphos* | -superux* | -rtmk* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ - | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*) + | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \ + | -midnightbsd*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1440,12 +1413,12 @@ case $os in -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + -sim | -xray | -os68k* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) - os=`echo $os | sed -e 's|mac|macos|'` + os=`echo "$os" | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc @@ -1454,10 +1427,10 @@ case $os in os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` + os=`echo "$os" | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` + os=`echo "$os" | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition @@ -1468,12 +1441,6 @@ case $os in -wince*) os=-wince ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; -utek*) os=-bsd ;; @@ -1498,7 +1465,7 @@ case $os in -nova*) os=-rtmk-nova ;; - -ns2 ) + -ns2) os=-nextstep2 ;; -nsk*) @@ -1520,7 +1487,7 @@ case $os in -oss*) os=-sysv3 ;; - -svr4) + -svr4*) os=-sysv4 ;; -svr3) @@ -1535,24 +1502,28 @@ case $os in -ose*) os=-ose ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; - -aros*) - os=-aros - ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; + -pikeos*) + # Until real need of OS specific support for + # particular features comes up, bare metal + # configurations are quite functional. + case $basic_machine in + arm*) + os=-eabi + ;; + *) + os=-elf + ;; + esac + ;; -nacl*) ;; -ios) @@ -1562,7 +1533,7 @@ case $os in *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 exit 1 ;; esac @@ -1658,9 +1629,6 @@ case $basic_machine in *-be) os=-beos ;; - *-haiku) - os=-haiku - ;; *-ibm) os=-aix ;; @@ -1700,7 +1668,7 @@ case $basic_machine in m88k-omron*) os=-luna ;; - *-next ) + *-next) os=-nextstep ;; *-sequent) @@ -1715,9 +1683,6 @@ case $basic_machine in i370-*) os=-mvs ;; - *-next) - os=-nextstep3 - ;; *-gould) os=-sysv ;; @@ -1827,15 +1792,15 @@ case $basic_machine in vendor=stratus ;; esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` ;; esac -echo $basic_machine$os +echo "$basic_machine$os" exit # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/config/install-sh b/config/install-sh index 0360b79e..8175c640 100755 --- a/config/install-sh +++ b/config/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2016-01-11.22; # UTC +scriptversion=2018-03-11.20; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -271,15 +271,18 @@ do fi dst=$dst_arg - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. + # If destination is a directory, append the input filename. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst - dst=$dstdir/`basename "$src"` + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac dstdir_status=0 else dstdir=`dirname "$dst"` @@ -288,6 +291,11 @@ do fi fi + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + obsolete_mkdir_used=false if test $dstdir_status != 0; then @@ -324,34 +332,43 @@ do # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) + # Note that $RANDOM variable is not portable (e.g. dash); Use it + # here however when possible just to lower collision chance. tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p' feature. if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi - rmdir "$tmpdir/d" "$tmpdir" + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac;; @@ -427,8 +444,8 @@ do else # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 @@ -493,7 +510,7 @@ do done # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" @@ -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.16.1. +# Generated by GNU Autoconf 2.69 for btrfs-progs v4.17 . # # Report bugs to <linux-btrfs@vger.kernel.org>. # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='btrfs-progs' PACKAGE_TARNAME='btrfs-progs' -PACKAGE_VERSION='v4.16.1' -PACKAGE_STRING='btrfs-progs v4.16.1' +PACKAGE_VERSION='v4.17 ' +PACKAGE_STRING='btrfs-progs v4.17 ' PACKAGE_BUGREPORT='linux-btrfs@vger.kernel.org' PACKAGE_URL='http://btrfs.wiki.kernel.org' @@ -692,6 +692,7 @@ build_os build_vendor build_cpu build +BTRFS_CSTD_FLAGS EGREP GREP CPP @@ -1320,7 +1321,7 @@ if test "$ac_init_help" = "long"; then # 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.16.1 to adapt to many kinds of systems. +\`configure' configures btrfs-progs v4.17 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1385,7 +1386,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of btrfs-progs v4.16.1:";; + short | recursive ) echo "Configuration of btrfs-progs v4.17 :";; esac cat <<\_ACEOF @@ -1513,7 +1514,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -btrfs-progs configure v4.16.1 +btrfs-progs configure v4.17 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1882,7 +1883,7 @@ cat >config.log <<_ACEOF 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.16.1, which was +It was created by btrfs-progs $as_me v4.17 , which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4066,6 +4067,46 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -std=gnu90" >&5 +$as_echo_n "checking whether C compiler accepts -std=gnu90... " >&6; } +if ${ax_cv_check_cflags___std_gnu90+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -std=gnu90" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ax_cv_check_cflags___std_gnu90=yes +else + ax_cv_check_cflags___std_gnu90=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___std_gnu90" >&5 +$as_echo "$ax_cv_check_cflags___std_gnu90" >&6; } +if test "x$ax_cv_check_cflags___std_gnu90" = xyes; then : + BTRFS_CSTD_FLAGS=-std=gnu90 +else + BTRFS_CSTD_FLAGS=-std=gnu89 +fi + + + + # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 @@ -5503,65 +5544,6 @@ if test "x$enable_convert" = xyes; then if test "x$with_convert" = "xauto" || echo "$with_convert" | grep -q "ext2"; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ext2fs >= 1.42" >&5 -$as_echo_n "checking for ext2fs >= 1.42... " >&6; } - -if test -n "$EXT2FS_CFLAGS"; then - pkg_cv_EXT2FS_CFLAGS="$EXT2FS_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ext2fs >= 1.42\""; } >&5 - ($PKG_CONFIG --exists --print-errors "ext2fs >= 1.42") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_EXT2FS_CFLAGS=`$PKG_CONFIG --cflags "ext2fs >= 1.42" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$EXT2FS_LIBS"; then - pkg_cv_EXT2FS_LIBS="$EXT2FS_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ext2fs >= 1.42\""; } >&5 - ($PKG_CONFIG --exists --print-errors "ext2fs >= 1.42") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_EXT2FS_LIBS=`$PKG_CONFIG --libs "ext2fs >= 1.42" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - EXT2FS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ext2fs >= 1.42" 2>&1` - else - EXT2FS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ext2fs >= 1.42" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$EXT2FS_PKG_ERRORS" >&5 - - -pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ext2fs" >&5 $as_echo_n "checking for ext2fs... " >&6; } @@ -5650,113 +5632,6 @@ else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } -$as_echo "#define HAVE_OLD_E2FSPROGS 1" >>confdefs.h - - -fi -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ext2fs" >&5 -$as_echo_n "checking for ext2fs... " >&6; } - -if test -n "$EXT2FS_CFLAGS"; then - pkg_cv_EXT2FS_CFLAGS="$EXT2FS_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ext2fs\""; } >&5 - ($PKG_CONFIG --exists --print-errors "ext2fs") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_EXT2FS_CFLAGS=`$PKG_CONFIG --cflags "ext2fs" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$EXT2FS_LIBS"; then - pkg_cv_EXT2FS_LIBS="$EXT2FS_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ext2fs\""; } >&5 - ($PKG_CONFIG --exists --print-errors "ext2fs") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_EXT2FS_LIBS=`$PKG_CONFIG --libs "ext2fs" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - EXT2FS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ext2fs" 2>&1` - else - EXT2FS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ext2fs" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$EXT2FS_PKG_ERRORS" >&5 - - as_fn_error $? "Package requirements (ext2fs) were not met: - -$EXT2FS_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables EXT2FS_CFLAGS -and EXT2FS_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables EXT2FS_CFLAGS -and EXT2FS_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/>. -See \`config.log' for more details" "$LINENO" 5; } -else - EXT2FS_CFLAGS=$pkg_cv_EXT2FS_CFLAGS - EXT2FS_LIBS=$pkg_cv_EXT2FS_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -$as_echo "#define HAVE_OLD_E2FSPROGS 1" >>confdefs.h - - -fi -else - EXT2FS_CFLAGS=$pkg_cv_EXT2FS_CFLAGS - EXT2FS_LIBS=$pkg_cv_EXT2FS_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - fi pkg_failed=no @@ -6571,7 +6446,7 @@ if ${am_cv_pathless_PYTHON+:} false; then : $as_echo_n "(cached) " >&6 else - for am_cv_pathless_PYTHON in python python2 python3 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do + for am_cv_pathless_PYTHON in python python2 python3 python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do test "$am_cv_pathless_PYTHON" = none && break prog="import sys # split strings by '.' and convert to numeric. Append some zeros @@ -7470,7 +7345,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # 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.16.1, which was +This file was extended by btrfs-progs $as_me v4.17 , which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -7533,7 +7408,7 @@ _ACEOF 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.16.1 +btrfs-progs config.status v4.17 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index a4c98b31..2567de12 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_INIT([btrfs-progs], - m4_chomp(m4_include([VERSION])), + m4_flatten(m4_include([VERSION])), [linux-btrfs@vger.kernel.org],, [http://btrfs.wiki.kernel.org]) @@ -26,6 +26,7 @@ AC_CONFIG_SRCDIR([btrfs.c]) AC_PREFIX_DEFAULT([/usr/local]) AC_PROG_CC +BTRFS_DETECT_CSTD AC_CANONICAL_HOST AC_C_CONST AC_C_VOLATILE @@ -144,11 +145,7 @@ BTRFSCONVERT_EXT2=0 BTRFSCONVERT_REISERFS=0 if test "x$enable_convert" = xyes; then if test "x$with_convert" = "xauto" || echo "$with_convert" | grep -q "ext2"; then - PKG_CHECK_MODULES(EXT2FS, [ext2fs >= 1.42],, - [PKG_CHECK_MODULES(EXT2FS, [ext2fs], - [AC_DEFINE([HAVE_OLD_E2FSPROGS], [1], - [E2fsprogs does not support BIGALLOC])] - )]) + PKG_CHECK_MODULES(EXT2FS, [ext2fs]) PKG_CHECK_MODULES(COM_ERR, [com_err]) convertfs="${convertfs:+$convertfs,}ext2" BTRFSCONVERT_EXT2=1 diff --git a/convert/main.c b/convert/main.c index 80f3bed8..7077fcba 100644 --- a/convert/main.c +++ b/convert/main.c @@ -957,7 +957,7 @@ static int init_btrfs(struct btrfs_mkfs_config *cfg, struct btrfs_root *root, ret = PTR_ERR(trans); goto err; } - ret = btrfs_fix_block_accounting(trans, root); + ret = btrfs_fix_block_accounting(trans); if (ret) goto err; ret = make_convert_data_block_groups(trans, fs_info, cfg, cctx); diff --git a/convert/source-ext2.h b/convert/source-ext2.h index 80833b21..c3214125 100644 --- a/convert/source-ext2.h +++ b/convert/source-ext2.h @@ -33,8 +33,18 @@ * BIGALLOC. * Unlike normal RO compat flag, BIGALLOC affects how e2fsprogs check used * space, and btrfs-convert heavily relies on it. + * + * e2fsprogs 1.42 also introduced the 64-bit API. Any file system + * that requires it will have EXT4_FEATURE_INCOMPAT_64BIT set and + * will fail to open with earlier releases. We can map it to the + * older API without risk of corruption. */ -#ifdef HAVE_OLD_E2FSPROGS +#ifndef EXT2_FLAG_64BITS +#define EXT2_FLAG_64BITS (0) +#define ext2fs_get_block_bitmap_range2 ext2fs_get_block_bitmap_range +#define ext2fs_inode_data_blocks2 ext2fs_inode_data_blocks +#define ext2fs_read_ext_attr2 ext2fs_read_ext_attr +#define ext2fs_blocks_count(s) ((s)->s_blocks_count) #define EXT2FS_CLUSTER_RATIO(fs) (1) #define EXT2_CLUSTERS_PER_GROUP(s) (EXT2_BLOCKS_PER_GROUP(s)) #define EXT2FS_B2C(fs, blk) (blk) @@ -192,7 +192,8 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, */ if (btrfs_block_can_be_shared(root, buf)) { - ret = btrfs_lookup_extent_info(trans, root, buf->start, + ret = btrfs_lookup_extent_info(trans, trans->fs_info, + buf->start, btrfs_header_level(buf), 1, &refs, &flags); BUG_ON(ret); @@ -235,7 +236,7 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, BUG_ON(ret); } if (new_flags != 0) { - ret = btrfs_set_block_flags(trans, root, buf->start, + ret = btrfs_set_block_flags(trans, buf->start, btrfs_header_level(buf), new_flags); BUG_ON(ret); @@ -251,7 +252,7 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, ret = btrfs_dec_ref(trans, root, buf, 1); BUG_ON(ret); } - clean_tree_block(trans, root, buf); + clean_tree_block(buf); } return 0; } @@ -480,11 +481,11 @@ btrfs_check_leaf(struct btrfs_root *root, struct btrfs_disk_key *parent_key, (unsigned long long)btrfs_header_bytenr(buf)); goto fail; } - if (btrfs_leaf_free_space(root->fs_info, buf) < 0) { + if (btrfs_leaf_free_space(buf) < 0) { ret = BTRFS_TREE_BLOCK_INVALID_FREE_SPACE; fprintf(stderr, "leaf free space incorrect %llu %d\n", (unsigned long long)btrfs_header_bytenr(buf), - btrfs_leaf_free_space(root->fs_info, buf)); + btrfs_leaf_free_space(buf)); goto fail; } @@ -717,7 +718,7 @@ static int balance_level(struct btrfs_trans_handle *trans, root->node = child; add_root_to_dirty_list(root); path->nodes[level] = NULL; - clean_tree_block(trans, root, mid); + clean_tree_block(mid); /* once for the path */ free_extent_buffer(mid); @@ -770,7 +771,7 @@ static int balance_level(struct btrfs_trans_handle *trans, u64 bytenr = right->start; u32 blocksize = right->len; - clean_tree_block(trans, root, right); + clean_tree_block(right); free_extent_buffer(right); right = NULL; wret = btrfs_del_ptr(root, path, level + 1, pslot + 1); @@ -816,7 +817,7 @@ static int balance_level(struct btrfs_trans_handle *trans, /* we've managed to empty the middle node, drop it */ u64 bytenr = mid->start; u32 blocksize = mid->len; - clean_tree_block(trans, root, mid); + clean_tree_block(mid); free_extent_buffer(mid); mid = NULL; wret = btrfs_del_ptr(root, path, level + 1, pslot); @@ -1193,7 +1194,7 @@ again: } else { p->slots[level] = slot; if (ins_len > 0 && - ins_len > btrfs_leaf_free_space(root->fs_info, b)) { + ins_len > btrfs_leaf_free_space(b)) { int sret = split_leaf(trans, root, key, p, ins_len, ret == 0); BUG_ON(sret > 0); @@ -1634,17 +1635,19 @@ static int leaf_space_used(struct extent_buffer *l, int start, int nr) * the start of the leaf data. IOW, how much room * the leaf has left for both items and data */ -int btrfs_leaf_free_space(struct btrfs_fs_info *fs_info, - struct extent_buffer *leaf) +int btrfs_leaf_free_space(struct extent_buffer *leaf) { int nritems = btrfs_header_nritems(leaf); + u32 leaf_data_size; int ret; - ret = BTRFS_LEAF_DATA_SIZE(fs_info) - leaf_space_used(leaf, 0, nritems); + BUG_ON(leaf->fs_info && leaf->fs_info->nodesize != leaf->len); + leaf_data_size = __BTRFS_LEAF_DATA_SIZE(leaf->len); + ret = leaf_data_size - leaf_space_used(leaf, 0 ,nritems); if (ret < 0) { - printk("leaf free space ret %d, leaf data size %lu, used %d nritems %d\n", - ret, BTRFS_LEAF_DATA_SIZE(fs_info), - leaf_space_used(leaf, 0, nritems), nritems); + printk("leaf free space ret %d, leaf data size %u, used %d nritems %d\n", + ret, leaf_data_size, leaf_space_used(leaf, 0, nritems), + nritems); } return ret; } @@ -1692,7 +1695,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root return PTR_ERR(right); return -EIO; } - free_space = btrfs_leaf_free_space(fs_info, right); + free_space = btrfs_leaf_free_space(right); if (free_space < data_size) { free_extent_buffer(right); return 1; @@ -1705,7 +1708,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root free_extent_buffer(right); return 1; } - free_space = btrfs_leaf_free_space(fs_info, right); + free_space = btrfs_leaf_free_space(right); if (free_space < data_size) { free_extent_buffer(right); return 1; @@ -1844,7 +1847,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root } left = read_node_slot(fs_info, path->nodes[1], slot - 1); - free_space = btrfs_leaf_free_space(fs_info, left); + free_space = btrfs_leaf_free_space(left); if (free_space < data_size) { free_extent_buffer(left); return 1; @@ -1859,7 +1862,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root return 1; } - free_space = btrfs_leaf_free_space(fs_info, left); + free_space = btrfs_leaf_free_space(left); if (free_space < data_size) { free_extent_buffer(left); return 1; @@ -2083,7 +2086,7 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, l = path->nodes[0]; /* did the pushes work? */ - if (btrfs_leaf_free_space(root->fs_info, l) >= data_size) + if (btrfs_leaf_free_space(l) >= data_size) return 0; } @@ -2240,7 +2243,7 @@ int btrfs_split_item(struct btrfs_trans_handle *trans, leaf = path->nodes[0]; btrfs_item_key_to_cpu(leaf, &orig_key, path->slots[0]); - if (btrfs_leaf_free_space(root->fs_info, leaf) >= + if (btrfs_leaf_free_space(leaf) >= sizeof(struct btrfs_item)) goto split; @@ -2261,8 +2264,7 @@ int btrfs_split_item(struct btrfs_trans_handle *trans, ret = split_leaf(trans, root, &orig_key, path, 0, 0); BUG_ON(ret); - BUG_ON(btrfs_leaf_free_space(root->fs_info, leaf) < - sizeof(struct btrfs_item)); + BUG_ON(btrfs_leaf_free_space(leaf) < sizeof(struct btrfs_item)); leaf = path->nodes[0]; split: @@ -2314,7 +2316,7 @@ split: btrfs_mark_buffer_dirty(leaf); ret = 0; - if (btrfs_leaf_free_space(root->fs_info, leaf) < 0) { + if (btrfs_leaf_free_space(leaf) < 0) { btrfs_print_leaf(leaf); BUG(); } @@ -2410,7 +2412,7 @@ int btrfs_truncate_item(struct btrfs_root *root, struct btrfs_path *path, btrfs_mark_buffer_dirty(leaf); ret = 0; - if (btrfs_leaf_free_space(root->fs_info, leaf) < 0) { + if (btrfs_leaf_free_space(leaf) < 0) { btrfs_print_leaf(leaf); BUG(); } @@ -2435,7 +2437,7 @@ int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path, nritems = btrfs_header_nritems(leaf); data_end = leaf_data_end(root->fs_info, leaf); - if (btrfs_leaf_free_space(root->fs_info, leaf) < data_size) { + if (btrfs_leaf_free_space(leaf) < data_size) { btrfs_print_leaf(leaf); BUG(); } @@ -2472,7 +2474,7 @@ int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path, btrfs_mark_buffer_dirty(leaf); ret = 0; - if (btrfs_leaf_free_space(root->fs_info, leaf) < 0) { + if (btrfs_leaf_free_space(leaf) < 0) { btrfs_print_leaf(leaf); BUG(); } @@ -2521,10 +2523,10 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, nritems = btrfs_header_nritems(leaf); data_end = leaf_data_end(root->fs_info, leaf); - if (btrfs_leaf_free_space(root->fs_info, leaf) < total_size) { + if (btrfs_leaf_free_space(leaf) < total_size) { btrfs_print_leaf(leaf); printk("not enough freespace need %u have %d\n", - total_size, btrfs_leaf_free_space(root->fs_info, leaf)); + total_size, btrfs_leaf_free_space(leaf)); BUG(); } @@ -2582,7 +2584,7 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, btrfs_fixup_low_keys(root, path, &disk_key, 1); } - if (btrfs_leaf_free_space(root->fs_info, leaf) < 0) { + if (btrfs_leaf_free_space(leaf) < 0) { btrfs_print_leaf(leaf); BUG(); } @@ -2738,7 +2740,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, if (leaf == root->node) { btrfs_set_header_level(leaf, 0); } else { - clean_tree_block(trans, root, leaf); + clean_tree_block(leaf); wret = btrfs_del_leaf(trans, root, path, leaf); BUG_ON(ret); if (wret) @@ -2774,7 +2776,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, } if (btrfs_header_nritems(leaf) == 0) { - clean_tree_block(trans, root, leaf); + clean_tree_block(leaf); path->slots[1] = slot; ret = btrfs_del_leaf(trans, root, path, leaf); BUG_ON(ret); @@ -556,7 +556,7 @@ struct btrfs_node { * The slots array records the index of the item or block pointer * used while walking the tree. */ - +enum { READA_NONE = 0, READA_BACK, READA_FORWARD }; struct btrfs_path { struct extent_buffer *nodes[BTRFS_MAX_LEVEL]; int slots[BTRFS_MAX_LEVEL]; @@ -1202,6 +1202,12 @@ static inline u32 BTRFS_NODEPTRS_PER_BLOCK(const struct btrfs_fs_info *info) return BTRFS_LEAF_DATA_SIZE(info) / sizeof(struct btrfs_key_ptr); } +static inline u32 BTRFS_NODEPTRS_PER_EXTENT_BUFFER(const struct extent_buffer *eb) +{ + BUG_ON(eb->fs_info && eb->fs_info->nodesize != eb->len); + return __BTRFS_LEAF_DATA_SIZE(eb->len) / sizeof(struct btrfs_key_ptr); +} + #define BTRFS_FILE_EXTENT_INLINE_DATA_START \ (offsetof(struct btrfs_file_extent_item, disk_bytenr)) static inline u32 BTRFS_MAX_INLINE_DATA_SIZE(const struct btrfs_fs_info *info) @@ -2462,7 +2468,7 @@ static inline u32 btrfs_file_extent_inline_len(struct extent_buffer *eb, #define btrfs_fs_incompat(fs_info, opt) \ __btrfs_fs_incompat((fs_info), BTRFS_FEATURE_INCOMPAT_##opt) -static inline int __btrfs_fs_incompat(struct btrfs_fs_info *fs_info, u64 flag) +static inline bool __btrfs_fs_incompat(struct btrfs_fs_info *fs_info, u64 flag) { struct btrfs_super_block *disk_super; disk_super = fs_info->super_copy; @@ -2494,13 +2500,11 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, u64 num_bytes, u64 empty_size, u64 hint_byte, u64 search_end, struct btrfs_key *ins, bool is_data); -int btrfs_fix_block_accounting(struct btrfs_trans_handle *trans, - struct btrfs_root *root); +int btrfs_fix_block_accounting(struct btrfs_trans_handle *trans); void btrfs_pin_extent(struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes); void btrfs_unpin_extent(struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes); -int btrfs_extent_post_op(struct btrfs_trans_handle *trans, - struct btrfs_root *root); +int btrfs_extent_post_op(struct btrfs_trans_handle *trans); struct btrfs_block_group_cache *btrfs_lookup_block_group(struct btrfs_fs_info *info, u64 bytenr); @@ -2513,11 +2517,10 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, struct btrfs_disk_key *key, int level, u64 hint, u64 empty_size); int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u64 bytenr, + struct btrfs_fs_info *fs_info, u64 bytenr, u64 offset, int metadata, u64 *refs, u64 *flags); -int btrfs_set_block_flags(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - u64 bytenr, int level, u64 flags); +int btrfs_set_block_flags(struct btrfs_trans_handle *trans, u64 bytenr, + int level, u64 flags); int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf, int record_parent); int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, @@ -2664,8 +2667,7 @@ static inline int btrfs_next_item(struct btrfs_root *root, } int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); -int btrfs_leaf_free_space(struct btrfs_fs_info *fs_info, - struct extent_buffer *leaf); +int btrfs_leaf_free_space(struct extent_buffer *leaf); void btrfs_fixup_low_keys(struct btrfs_root *root, struct btrfs_path *path, struct btrfs_disk_key *key, int level); int btrfs_set_item_key_safe(struct btrfs_root *root, struct btrfs_path *path, diff --git a/debian/changelog b/debian/changelog index 5063d6c8..454d3182 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +btrfs-progs (4.17-1) unstable; urgency=medium + + * New upstream release. + + -- Dimitri John Ledkov <xnox@ubuntu.com> Mon, 23 Jul 2018 14:31:22 +0100 + btrfs-progs (4.16.1-2) unstable; urgency=medium * Do not copy_exec btrfs-zero-log into initramfs, superseeded by `btrfs @@ -263,7 +263,6 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans, struct btrfs_path *path, struct btrfs_dir_item *di) { - struct extent_buffer *leaf; u32 sub_item_len; u32 item_len; @@ -273,7 +272,15 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans, sub_item_len = sizeof(*di) + btrfs_dir_name_len(leaf, di) + btrfs_dir_data_len(leaf, di); item_len = btrfs_item_size_nr(leaf, path->slots[0]); - if (sub_item_len == item_len) { + + /* + * If @sub_item_len is longer than @item_len, then it means the + * name_len is just corrupted. + * No good idea to know if there is anything we can recover from + * the corrupted item. + * Just delete the item. + */ + if (sub_item_len >= item_len) { ret = btrfs_del_item(trans, root, path); } else { unsigned long ptr = (unsigned long)di; @@ -294,12 +301,6 @@ static int verify_dir_item(struct btrfs_root *root, u16 namelen = BTRFS_NAME_LEN; u8 type = btrfs_dir_type(leaf, dir_item); - if (type >= BTRFS_FT_MAX) { - fprintf(stderr, "invalid dir item type: %d\n", - (int)type); - return 1; - } - if (type == BTRFS_FT_XATTR) namelen = XATTR_NAME_MAX; @@ -1606,10 +1606,10 @@ int write_all_supers(struct btrfs_fs_info *fs_info) return 0; } -int write_ctree_super(struct btrfs_trans_handle *trans, - struct btrfs_fs_info *fs_info) +int write_ctree_super(struct btrfs_trans_handle *trans) { int ret; + struct btrfs_fs_info *fs_info = trans->fs_info; struct btrfs_root *tree_root = fs_info->tree_root; struct btrfs_root *chunk_root = fs_info->chunk_root; @@ -1657,7 +1657,7 @@ int close_ctree_fs_info(struct btrfs_fs_info *fs_info) BUG_ON(ret); ret = __commit_transaction(trans, root); BUG_ON(ret); - write_ctree_super(trans, fs_info); + write_ctree_super(trans); kfree(trans); } @@ -1684,8 +1684,7 @@ skip_commit: return err; } -int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, - struct extent_buffer *eb) +int clean_tree_block(struct extent_buffer *eb) { return clear_extent_buffer_dirty(eb); } @@ -131,8 +131,7 @@ struct extent_buffer* btrfs_find_create_tree_block( void btrfs_setup_root(struct btrfs_root *root, struct btrfs_fs_info *fs_info, u64 objectid); -int clean_tree_block(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct extent_buffer *buf); +int clean_tree_block(struct extent_buffer *buf); void btrfs_free_fs_info(struct btrfs_fs_info *fs_info); struct btrfs_fs_info *btrfs_new_fs_info(int writable, u64 sb_bytenr); @@ -165,8 +164,7 @@ static inline int close_ctree(struct btrfs_root *root) } int write_all_supers(struct btrfs_fs_info *fs_info); -int write_ctree_super(struct btrfs_trans_handle *trans, - struct btrfs_fs_info *fs_info); +int write_ctree_super(struct btrfs_trans_handle *trans); int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr, unsigned sbflags); int btrfs_map_bh_to_logical(struct btrfs_root *root, struct extent_buffer *bh, diff --git a/extent-cache.c b/extent-cache.c index 38bed8b5..f458de26 100644 --- a/extent-cache.c +++ b/extent-cache.c @@ -93,24 +93,22 @@ void cache_tree_init(struct cache_tree *tree) tree->root = RB_ROOT; } -static struct cache_extent * -alloc_cache_extent(u64 objectid, u64 start, u64 size) +static struct cache_extent *alloc_cache_extent(u64 start, u64 size) { struct cache_extent *pe = malloc(sizeof(*pe)); if (!pe) return pe; - pe->objectid = objectid; + pe->objectid = 0; pe->start = start; pe->size = size; return pe; } -static int __add_cache_extent(struct cache_tree *tree, - u64 objectid, u64 start, u64 size) +int add_cache_extent(struct cache_tree *tree, u64 start, u64 size) { - struct cache_extent *pe = alloc_cache_extent(objectid, start, size); + struct cache_extent *pe = alloc_cache_extent(start, size); int ret; if (!pe) { @@ -125,17 +123,6 @@ static int __add_cache_extent(struct cache_tree *tree, return ret; } -int add_cache_extent(struct cache_tree *tree, u64 start, u64 size) -{ - return __add_cache_extent(tree, 0, start, size); -} - -int add_cache_extent2(struct cache_tree *tree, - u64 objectid, u64 start, u64 size) -{ - return __add_cache_extent(tree, objectid, start, size); -} - int insert_cache_extent(struct cache_tree *tree, struct cache_extent *pe) { return rb_insert(&tree->root, &pe->rb_node, cache_tree_comp_nodes); diff --git a/extent-cache.h b/extent-cache.h index 82db7fa3..33d018dd 100644 --- a/extent-cache.h +++ b/extent-cache.h @@ -106,8 +106,6 @@ struct cache_extent *search_cache_extent2(struct cache_tree *tree, */ struct cache_extent *lookup_cache_extent2(struct cache_tree *tree, u64 objectid, u64 start, u64 size); -int add_cache_extent2(struct cache_tree *tree, - u64 objectid, u64 start, u64 size); int insert_cache_extent2(struct cache_tree *tree, struct cache_extent *pe); /* diff --git a/extent-tree.c b/extent-tree.c index ea205ccf..0643815b 100644 --- a/extent-tree.c +++ b/extent-tree.c @@ -54,10 +54,8 @@ static int __free_extent(struct btrfs_trans_handle *trans, u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid, u64 owner_objectid, u64 owner_offset, int refs_to_drop); -static int finish_current_insert(struct btrfs_trans_handle *trans, struct - btrfs_root *extent_root); -static int del_pending_extents(struct btrfs_trans_handle *trans, struct - btrfs_root *extent_root); +static int finish_current_insert(struct btrfs_trans_handle *trans); +static int del_pending_extents(struct btrfs_trans_handle *trans); static struct btrfs_block_group_cache * btrfs_find_block_group(struct btrfs_root *root, struct btrfs_block_group_cache *hint, u64 search_start, int data, int owner); @@ -75,7 +73,7 @@ static int remove_sb_from_cache(struct btrfs_root *root, free_space_cache = &fs_info->free_space_cache; for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { bytenr = btrfs_sb_offset(i); - ret = btrfs_rmap_block(fs_info, cache->key.objectid, bytenr, 0, + ret = btrfs_rmap_block(fs_info, cache->key.objectid, bytenr, &logical, &nr, &stripe_len); BUG_ON(ret); while (nr--) { @@ -112,7 +110,7 @@ static int cache_block_group(struct btrfs_root *root, if (!path) return -ENOMEM; - path->reada = 2; + path->reada = READA_FORWARD; last = max_t(u64, block_group->key.objectid, BTRFS_SUPER_INFO_OFFSET); key.objectid = last; key.offset = 0; @@ -699,7 +697,7 @@ again: if (key.objectid != bytenr || key.type != BTRFS_EXTENT_DATA_REF_KEY) goto fail; - + ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_data_ref); @@ -1391,7 +1389,7 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, if (!path) return -ENOMEM; - path->reada = 1; + path->reada = READA_BACK; ret = insert_inline_extent_backref(trans, root->fs_info->extent_root, path, bytenr, num_bytes, parent, @@ -1403,7 +1401,7 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, err = ret; goto out; } - + leaf = path->nodes[0]; item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); refs = btrfs_extent_refs(leaf, item); @@ -1412,7 +1410,7 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, btrfs_mark_buffer_dirty(leaf); btrfs_release_path(path); - path->reada = 1; + path->reada = READA_BACK; /* now insert the actual backref */ ret = insert_extent_backref(trans, root->fs_info->extent_root, @@ -1422,22 +1420,21 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, err = ret; out: btrfs_free_path(path); - finish_current_insert(trans, root->fs_info->extent_root); - del_pending_extents(trans, root->fs_info->extent_root); + finish_current_insert(trans); + del_pending_extents(trans); BUG_ON(err); return err; } -int btrfs_extent_post_op(struct btrfs_trans_handle *trans, - struct btrfs_root *root) +int btrfs_extent_post_op(struct btrfs_trans_handle *trans) { - finish_current_insert(trans, root->fs_info->extent_root); - del_pending_extents(trans, root->fs_info->extent_root); + finish_current_insert(trans); + del_pending_extents(trans); return 0; } int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u64 bytenr, + struct btrfs_fs_info *fs_info, u64 bytenr, u64 offset, int metadata, u64 *refs, u64 *flags) { struct btrfs_path *path; @@ -1449,16 +1446,15 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, u64 num_refs; u64 extent_flags; - if (metadata && - !btrfs_fs_incompat(root->fs_info, SKINNY_METADATA)) { - offset = root->fs_info->nodesize; + if (metadata && !btrfs_fs_incompat(fs_info, SKINNY_METADATA)) { + offset = fs_info->nodesize; metadata = 0; } path = btrfs_alloc_path(); if (!path) return -ENOMEM; - path->reada = 1; + path->reada = READA_BACK; key.objectid = bytenr; key.offset = offset; @@ -1468,8 +1464,7 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, key.type = BTRFS_EXTENT_ITEM_KEY; again: - ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, - 0, 0); + ret = btrfs_search_slot(trans, fs_info->extent_root, &key, path, 0, 0); if (ret < 0) goto out; @@ -1486,14 +1481,14 @@ again: path->slots[0]); if (key.objectid == bytenr && key.type == BTRFS_EXTENT_ITEM_KEY && - key.offset == root->fs_info->nodesize) + key.offset == fs_info->nodesize) ret = 0; } if (ret) { btrfs_release_path(path); key.type = BTRFS_EXTENT_ITEM_KEY; - key.offset = root->fs_info->nodesize; + key.offset = fs_info->nodesize; metadata = 0; goto again; } @@ -1534,36 +1529,34 @@ out: return ret; } -int btrfs_set_block_flags(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - u64 bytenr, int level, u64 flags) +int btrfs_set_block_flags(struct btrfs_trans_handle *trans, u64 bytenr, + int level, u64 flags) { + struct btrfs_fs_info *fs_info = trans->fs_info; struct btrfs_path *path; int ret; struct btrfs_key key; struct extent_buffer *l; struct btrfs_extent_item *item; u32 item_size; - int skinny_metadata = - btrfs_fs_incompat(root->fs_info, SKINNY_METADATA); + int skinny_metadata = btrfs_fs_incompat(fs_info, SKINNY_METADATA); path = btrfs_alloc_path(); if (!path) return -ENOMEM; - path->reada = 1; + path->reada = READA_BACK; key.objectid = bytenr; if (skinny_metadata) { key.offset = level; key.type = BTRFS_METADATA_ITEM_KEY; } else { - key.offset = root->fs_info->nodesize; + key.offset = fs_info->nodesize; key.type = BTRFS_EXTENT_ITEM_KEY; } again: - ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, - 0, 0); + ret = btrfs_search_slot(trans, fs_info->extent_root, &key, path, 0, 0); if (ret < 0) goto out; @@ -1574,13 +1567,13 @@ again: btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); if (key.objectid == bytenr && - key.offset == root->fs_info->nodesize && + key.offset == fs_info->nodesize && key.type == BTRFS_EXTENT_ITEM_KEY) ret = 0; } if (ret) { btrfs_release_path(path); - key.offset = root->fs_info->nodesize; + key.offset = fs_info->nodesize; key.type = BTRFS_EXTENT_ITEM_KEY; goto again; } @@ -1596,8 +1589,8 @@ again: item_size = btrfs_item_size_nr(l, path->slots[0]); #ifdef BTRFS_COMPAT_EXTENT_TREE_V0 if (item_size < sizeof(*item)) { - ret = convert_extent_item_v0(trans, root->fs_info->extent_root, - path, (u64)-1, 0); + ret = convert_extent_item_v0(trans, fs_info->extent_root, path, + (u64)-1, 0); if (ret < 0) goto out; @@ -1611,8 +1604,8 @@ again: btrfs_set_extent_flags(l, item, flags); out: btrfs_free_path(path); - finish_current_insert(trans, root->fs_info->extent_root); - del_pending_extents(trans, root->fs_info->extent_root); + finish_current_insert(trans); + del_pending_extents(trans); return ret; } @@ -1666,7 +1659,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, bytenr = btrfs_file_extent_disk_bytenr(buf, fi); if (bytenr == 0) continue; - + num_bytes = btrfs_file_extent_disk_num_bytes(buf, fi); key.offset -= btrfs_file_extent_offset(buf, fi); ret = process_func(trans, root, bytenr, num_bytes, @@ -1706,13 +1699,12 @@ int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, } static int write_one_cache_group(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct btrfs_path *path, struct btrfs_block_group_cache *cache) { int ret; int pending_ret; - struct btrfs_root *extent_root = root->fs_info->extent_root; + struct btrfs_root *extent_root = trans->fs_info->extent_root; unsigned long bi; struct extent_buffer *leaf; @@ -1727,8 +1719,8 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans, btrfs_mark_buffer_dirty(leaf); btrfs_release_path(path); fail: - finish_current_insert(trans, extent_root); - pending_ret = del_pending_extents(trans, extent_root); + finish_current_insert(trans); + pending_ret = del_pending_extents(trans); if (ret) return ret; if (pending_ret) @@ -1772,7 +1764,7 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, BLOCK_GROUP_DIRTY); cache = (struct btrfs_block_group_cache *)(unsigned long)ptr; - ret = write_one_cache_group(trans, root, path, cache); + ret = write_one_cache_group(trans, path, cache); } btrfs_free_path(path); return 0; @@ -1981,12 +1973,11 @@ static int update_block_group(struct btrfs_root *root, return 0; } -static int update_pinned_extents(struct btrfs_root *root, +static int update_pinned_extents(struct btrfs_fs_info *fs_info, u64 bytenr, u64 num, int pin) { u64 len; struct btrfs_block_group_cache *cache; - struct btrfs_fs_info *fs_info = root->fs_info; if (pin) { set_extent_dirty(&fs_info->pinned_extents, @@ -2035,7 +2026,8 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, EXTENT_DIRTY); if (ret) break; - update_pinned_extents(root, start, end + 1 - start, 0); + update_pinned_extents(trans->fs_info, start, end + 1 - start, + 0); clear_extent_dirty(unpin, start, end); set_extent_dirty(free_space_cache, start, end); } @@ -2057,13 +2049,13 @@ static int extent_root_pending_ops(struct btrfs_fs_info *info) return ret == 0; } -static int finish_current_insert(struct btrfs_trans_handle *trans, - struct btrfs_root *extent_root) +static int finish_current_insert(struct btrfs_trans_handle *trans) { u64 start; u64 end; u64 priv; - struct btrfs_fs_info *info = extent_root->fs_info; + struct btrfs_fs_info *info = trans->fs_info; + struct btrfs_root *extent_root = info->extent_root; struct pending_extent_op *extent_op; struct btrfs_key key; int ret; @@ -2131,14 +2123,14 @@ static int pin_down_bytes(struct btrfs_trans_handle *trans, if (header_owner != BTRFS_TREE_LOG_OBJECTID && header_transid == trans->transid && !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) { - clean_tree_block(NULL, root, buf); + clean_tree_block(buf); free_extent_buffer(buf); return 1; } } free_extent_buffer(buf); pinit: - update_pinned_extents(root, bytenr, num_bytes, 1); + update_pinned_extents(trans->fs_info, bytenr, num_bytes, 1); BUG_ON(err < 0); return 0; @@ -2147,13 +2139,13 @@ pinit: void btrfs_pin_extent(struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes) { - update_pinned_extents(fs_info->extent_root, bytenr, num_bytes, 1); + update_pinned_extents(fs_info, bytenr, num_bytes, 1); } void btrfs_unpin_extent(struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes) { - update_pinned_extents(fs_info->extent_root, bytenr, num_bytes, 0); + update_pinned_extents(fs_info, bytenr, num_bytes, 0); } /* @@ -2192,7 +2184,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, if (!path) return -ENOMEM; - path->reada = 1; + path->reada = READA_BACK; is_data = owner_objectid >= BTRFS_FIRST_FREE_OBJECTID; if (is_data) @@ -2389,7 +2381,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, } fail: btrfs_free_path(path); - finish_current_insert(trans, extent_root); + finish_current_insert(trans); return ret; } @@ -2397,8 +2389,7 @@ fail: * find all the blocks marked as pending in the radix tree and remove * them from the extent map */ -static int del_pending_extents(struct btrfs_trans_handle *trans, struct - btrfs_root *extent_root) +static int del_pending_extents(struct btrfs_trans_handle *trans) { int ret; int err = 0; @@ -2408,6 +2399,8 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct struct extent_io_tree *pending_del; struct extent_io_tree *extent_ins; struct pending_extent_op *extent_op; + struct btrfs_fs_info *fs_info = trans->fs_info; + struct btrfs_root *extent_root = fs_info->extent_root; extent_ins = &extent_root->fs_info->extent_ins; pending_del = &extent_root->fs_info->pending_del; @@ -2497,7 +2490,7 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, } ret = __free_extent(trans, root, bytenr, num_bytes, parent, root_objectid, owner, offset, 1); - pending_ret = del_pending_extents(trans, root->fs_info->extent_root); + pending_ret = del_pending_extents(trans); return ret ? ret : pending_ret; } @@ -2789,8 +2782,8 @@ static int alloc_tree_block(struct btrfs_trans_handle *trans, ret = alloc_reserved_tree_block(trans, root, root_objectid, generation, flags, key, level, ins); - finish_current_insert(trans, root->fs_info->extent_root); - del_pending_extents(trans, root->fs_info->extent_root); + finish_current_insert(trans); + del_pending_extents(trans); } return ret; } @@ -3164,54 +3157,6 @@ error: return ret; } -static void account_super_bytes(struct btrfs_fs_info *fs_info, - struct btrfs_block_group_cache *cache) -{ - u64 bytenr; - u64 *logical; - int stripe_len; - int i, nr, ret; - - if (cache->key.objectid < BTRFS_SUPER_INFO_OFFSET) { - stripe_len = BTRFS_SUPER_INFO_OFFSET - cache->key.objectid; - cache->bytes_super += stripe_len; - } - - for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { - bytenr = btrfs_sb_offset(i); - ret = btrfs_rmap_block(fs_info, - cache->key.objectid, bytenr, - 0, &logical, &nr, &stripe_len); - if (ret) - return; - - while (nr--) { - u64 start, len; - - if (logical[nr] > cache->key.objectid + - cache->key.offset) - continue; - - if (logical[nr] + stripe_len <= cache->key.objectid) - continue; - - start = logical[nr]; - if (start < cache->key.objectid) { - start = cache->key.objectid; - len = (logical[nr] + stripe_len) - start; - } else { - len = min_t(u64, stripe_len, - cache->key.objectid + - cache->key.offset - start); - } - - cache->bytes_super += len; - } - - kfree(logical); - } -} - int btrfs_read_block_groups(struct btrfs_root *root) { struct btrfs_path *path; @@ -3287,7 +3232,7 @@ int btrfs_read_block_groups(struct btrfs_root *root) if (btrfs_chunk_readonly(info, cache->key.objectid)) cache->ro = 1; - account_super_bytes(info, cache); + exclude_super_stripes(root, cache); ret = update_space_info(info, cache->flags, found_key.offset, btrfs_block_group_used(&cache->item), @@ -3331,7 +3276,7 @@ btrfs_add_block_group(struct btrfs_fs_info *fs_info, u64 bytes_used, u64 type, cache->flags = type; btrfs_set_block_group_flags(&cache->item, type); - account_super_bytes(fs_info, cache); + exclude_super_stripes(fs_info->extent_root, cache); ret = update_space_info(fs_info, cache->flags, size, bytes_used, &cache->space_info); BUG_ON(ret); @@ -3364,9 +3309,9 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, sizeof(cache->item)); BUG_ON(ret); - ret = finish_current_insert(trans, extent_root); + ret = finish_current_insert(trans); BUG_ON(ret); - ret = del_pending_extents(trans, extent_root); + ret = del_pending_extents(trans); BUG_ON(ret); return 0; @@ -3464,8 +3409,8 @@ int btrfs_make_block_groups(struct btrfs_trans_handle *trans, sizeof(cache->item)); BUG_ON(ret); - finish_current_insert(trans, extent_root); - ret = del_pending_extents(trans, extent_root); + finish_current_insert(trans); + ret = del_pending_extents(trans); BUG_ON(ret); cur_start = cache->key.objectid + cache->key.offset; @@ -3836,8 +3781,7 @@ out: * Fixup block accounting. The initial block accounting created by * make_block_groups isn't accuracy in this case. */ -int btrfs_fix_block_accounting(struct btrfs_trans_handle *trans, - struct btrfs_root *root) +int btrfs_fix_block_accounting(struct btrfs_trans_handle *trans) { int ret = 0; int slot; @@ -3847,15 +3791,14 @@ int btrfs_fix_block_accounting(struct btrfs_trans_handle *trans, struct btrfs_key key; struct extent_buffer *leaf; struct btrfs_block_group_cache *cache; - struct btrfs_fs_info *fs_info = root->fs_info; - - root = root->fs_info->extent_root; + struct btrfs_fs_info *fs_info = trans->fs_info; + struct btrfs_root *root = fs_info->extent_root; while(extent_root_pending_ops(fs_info)) { - ret = finish_current_insert(trans, root); + ret = finish_current_insert(trans); if (ret) return ret; - ret = del_pending_extents(trans, root); + ret = del_pending_extents(trans); if (ret) return ret; } @@ -4063,7 +4006,7 @@ static int __btrfs_record_file_extent(struct btrfs_trans_handle *trans, } else if (ret != -EEXIST) { goto fail; } - btrfs_extent_post_op(trans, extent_root); + btrfs_extent_post_op(trans); extent_bytenr = disk_bytenr; extent_num_bytes = num_bytes; extent_offset = 0; @@ -4180,7 +4123,7 @@ int exclude_super_stripes(struct btrfs_root *root, bytenr = btrfs_sb_offset(i); ret = btrfs_rmap_block(root->fs_info, cache->key.objectid, bytenr, - 0, &logical, &nr, &stripe_len); + &logical, &nr, &stripe_len); if (ret) return ret; diff --git a/free-space-tree.c b/free-space-tree.c index 69a4eca8..139a031e 100644 --- a/free-space-tree.c +++ b/free-space-tree.c @@ -135,7 +135,7 @@ int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info) list_del(&free_space_root->dirty_list); - ret = clean_tree_block(trans, tree_root, free_space_root->node); + ret = clean_tree_block(free_space_root->node); if (ret) goto abort; ret = btrfs_free_tree_block(trans, free_space_root, diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4 new file mode 100644 index 00000000..dcabb92a --- /dev/null +++ b/m4/ax_check_compile_flag.m4 @@ -0,0 +1,74 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's compiler +# or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de> +# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com> +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <https://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 5 + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS diff --git a/m4/ax_gcc_version.m4 b/m4/ax_gcc_version.m4 new file mode 100644 index 00000000..63914d55 --- /dev/null +++ b/m4/ax_gcc_version.m4 @@ -0,0 +1,37 @@ +dnl @synopsis AX_GCC_VERSION(MAJOR, MINOR, PATCHLEVEL, [ACTION-SUCCESS], [ACTION-FAILURE]) +dnl @summary check wither gcc is at least version MAJOR.MINOR.PATCHLEVEL +dnl @category InstalledPackages +dnl +dnl Check whether we are using gcc and, if so, whether its version +dnl is at least MAJOR.MINOR.PATCHLEVEL +dnl +dnl ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +dnl success/failure. +dnl +dnl @version 2005-05-30 +dnl @license GPLWithACException +dnl @author Steven G. Johnson <stevenj@alum.mit.edu> and Matteo Frigo. +AC_DEFUN([AX_GCC_VERSION], +[ +AC_REQUIRE([AC_PROG_CC]) +AC_CACHE_CHECK(whether we are using gcc $1.$2.$3 or later, ax_cv_gcc_$1_$2_$3, +[ +ax_cv_gcc_$1_$2_$3=no +if test "$GCC" = "yes"; then +dnl The semicolon after "yes" below is to pacify NeXT's syntax-checking cpp. +AC_EGREP_CPP(yes, [ +#ifdef __GNUC__ +# if (__GNUC__ > $1) || (__GNUC__ == $1 && __GNUC_MINOR__ > $2) \ + || (__GNUC__ == $1 && __GNUC_MINOR__ == $2 && __GNUC_PATCHLEVEL__ >= $3) + yes; +# endif +#endif +], [ax_cv_gcc_$1_$2_$3=yes]) +fi +]) +if test "$ax_cv_gcc_$1_$2_$3" = yes; then + m4_default([$4], :) +else + m4_default([$5], :) +fi +]) diff --git a/m4/btrfs_detect_cstd.m4 b/m4/btrfs_detect_cstd.m4 new file mode 100644 index 00000000..f0c45d97 --- /dev/null +++ b/m4/btrfs_detect_cstd.m4 @@ -0,0 +1,20 @@ +dnl We prefer -std=gnu90 but gcc versions prior to 4.5.0 don't support +dnl it. AX_CHECK_COMPILE_FLAG is the right way to determine whether a +dnl particular version of gcc supports a flag, but it requires autoconf +dnl 2.64. Since (for now) we still want to support older releases +dnl that ship with autoconf 2.63, we the also-deprecated AX_GCC_VERSION +dnl macro there. +AC_DEFUN([BTRFS_DETECT_CSTD], +[ + m4_version_prereq([2.64], [ + AX_CHECK_COMPILE_FLAG([-std=gnu90], + [BTRFS_CSTD_FLAGS=-std=gnu90], + [BTRFS_CSTD_FLAGS=-std=gnu89]) + ], [ + AX_GCC_VERSION([4], [5], [0], + [BTRFS_CSTD_FLAGS=-std=gnu90], + [BTRFS_CSTD_FLAGS=-std=gnu89]) + ]) + AC_SUBST([BTRFS_CSTD_FLAGS]) +]) dnl BTRFS_DETECT_CSTD + diff --git a/mkfs/common.c b/mkfs/common.c index 3a80050c..0ace262b 100644 --- a/mkfs/common.c +++ b/mkfs/common.c @@ -514,7 +514,7 @@ u64 btrfs_min_dev_size(u32 nodesize, int mixed, u64 meta_profile, * * Temporary chunks sizes are always fixed: * One initial sys chunk, one SINGLE meta, and one SINGLE data. - * The latter two are all 8M, accroding to @calc_size of + * The latter two are all 8M, according to @calc_size of * btrfs_alloc_chunk(). */ reserved += BTRFS_BLOCK_RESERVED_1M_FOR_SUPER + diff --git a/mkfs/common.h b/mkfs/common.h index f6b60c28..28912906 100644 --- a/mkfs/common.h +++ b/mkfs/common.h @@ -16,7 +16,7 @@ /* * Defines and function declarations for users of the mkfs API, no internal - * defintions. + * definitions. */ #ifndef __BTRFS_MKFS_COMMON_H__ @@ -45,7 +45,7 @@ enum btrfs_mkfs_block { struct btrfs_mkfs_config { /* Label of the new filesystem */ const char *label; - /* Blck sizes */ + /* Block sizes */ u32 nodesize; u32 sectorsize; u32 stripesize; diff --git a/mkfs/main.c b/mkfs/main.c index 9bfddf30..b76462a7 100644 --- a/mkfs/main.c +++ b/mkfs/main.c @@ -1229,7 +1229,7 @@ raid_groups: if (source_dir_set) { ret = btrfs_mkfs_fill_dir(source_dir, root, verbose); if (ret) { - error("error wihle filling filesystem: %d", ret); + error("error while filling filesystem: %d", ret); goto out; } if (shrink_rootdir) { diff --git a/mkfs/rootdir.c b/mkfs/rootdir.c index ff00bb0f..c430bac6 100644 --- a/mkfs/rootdir.c +++ b/mkfs/rootdir.c @@ -253,7 +253,7 @@ static int add_xattr_item(struct btrfs_trans_handle *trans, if (ret < 0) { if (errno == ENOTSUP) return 0; - error("gettig a xattr value failed for %s attr %s: %s", + error("getting a xattr value failed for %s attr %s: %s", file_name, cur_name, strerror(errno)); return ret; } @@ -467,7 +467,7 @@ static int traverse_directory(struct btrfs_trans_handle *trans, dir_entry->dir_name = dir_name; dir_entry->path = realpath(dir_name, NULL); if (!dir_entry->path) { - error("realpath failed for %s: %s", dir_name, strerror(errno)); + error("realpath failed for %s: %s", dir_name, strerror(errno)); ret = -1; goto fail_no_dir; } @@ -553,6 +553,7 @@ static int traverse_directory(struct btrfs_trans_handle *trans, (unsigned long)st.st_nlink); goto fail; } + ret = 0; continue; } if (ret) { @@ -745,7 +746,7 @@ u64 btrfs_mkfs_size_dir(const char *dir_name, u32 sectorsize, u64 min_dev_size, /* - * Maximum metadata useage for every inode, which will be PATH_MAX + * Maximum metadata usage for every inode, which will be PATH_MAX * for the following items: * 1) DIR_ITEM * 2) DIR_INDEX @@ -790,7 +791,7 @@ u64 btrfs_mkfs_size_dir(const char *dir_name, u32 sectorsize, u64 min_dev_size, /* * Get the end position of the last device extent for given @devid; - * @size_ret is exclsuive (means it should be aligned to sectorsize) + * @size_ret is exclusive (means it should be aligned to sectorsize) */ static int get_device_extent_end(struct btrfs_fs_info *fs_info, u64 devid, u64 *size_ret) @@ -851,7 +852,7 @@ static int set_device_size(struct btrfs_fs_info *fs_info, int ret; /* - * Update in-meory device->total_bytes, so that at trans commit time, + * Update in-memory device->total_bytes, so that at trans commit time, * super->dev_item will also get updated */ device->total_bytes = new_size; diff --git a/print-tree.c b/print-tree.c index a1a7954a..dfa7bb6b 100644 --- a/print-tree.c +++ b/print-tree.c @@ -470,8 +470,9 @@ void print_extent_item(struct extent_buffer *eb, int slot, int metadata) offset = btrfs_extent_inline_ref_offset(eb, iref); switch (type) { case BTRFS_TREE_BLOCK_REF_KEY: - printf("\t\ttree block backref root %llu\n", - (unsigned long long)offset); + printf("\t\ttree block backref root "); + print_objectid(stdout, offset, 0); + printf("\n"); break; case BTRFS_SHARED_BLOCK_REF_KEY: printf("\t\tshared block backref parent %llu\n", @@ -479,11 +480,12 @@ void print_extent_item(struct extent_buffer *eb, int slot, int metadata) break; case BTRFS_EXTENT_DATA_REF_KEY: dref = (struct btrfs_extent_data_ref *)(&iref->offset); - printf("\t\textent data backref root %llu " - "objectid %llu offset %llu count %u\n", - (unsigned long long)btrfs_extent_data_ref_root(eb, dref), + printf("\t\textent data backref root "); + print_objectid(stdout, + (unsigned long long)btrfs_extent_data_ref_root(eb, dref), 0); + printf(" objectid %llu offset %lld count %u\n", (unsigned long long)btrfs_extent_data_ref_objectid(eb, dref), - (unsigned long long)btrfs_extent_data_ref_offset(eb, dref), + btrfs_extent_data_ref_offset(eb, dref), btrfs_extent_data_ref_count(eb, dref)); break; case BTRFS_SHARED_DATA_REF_KEY: @@ -1018,9 +1020,10 @@ static void print_extent_data_ref(struct extent_buffer *eb, int slot) struct btrfs_extent_data_ref *dref; dref = btrfs_item_ptr(eb, slot, struct btrfs_extent_data_ref); - printf("\t\textent data backref root %llu " - "objectid %llu offset %llu count %u\n", - (unsigned long long)btrfs_extent_data_ref_root(eb, dref), + printf("\t\textent data backref root "); + print_objectid(stdout, + (unsigned long long)btrfs_extent_data_ref_root(eb, dref), 0); + printf(" objectid %llu offset %llu count %u\n", (unsigned long long)btrfs_extent_data_ref_objectid(eb, dref), (unsigned long long)btrfs_extent_data_ref_offset(eb, dref), btrfs_extent_data_ref_count(eb, dref)); @@ -1150,6 +1153,14 @@ static void print_extent_csum(struct extent_buffer *eb, { u32 size; + /* + * If we don't have fs_info, only output its start position as we + * don't have sectorsize for the calculation + */ + if (!fs_info) { + printf("\t\trange start %llu\n", (unsigned long long)start); + return; + } size = (item_size / btrfs_super_csum_size(fs_info->super_copy)) * fs_info->sectorsize; printf("\t\trange start %llu end %llu length %u\n", @@ -1179,6 +1190,7 @@ void btrfs_print_leaf(struct extent_buffer *eb) struct btrfs_item *item; struct btrfs_disk_key disk_key; char flags_str[128]; + u32 leaf_data_size = BTRFS_LEAF_DATA_SIZE(fs_info); u32 i; u32 nr; u64 flags; @@ -1191,7 +1203,7 @@ void btrfs_print_leaf(struct extent_buffer *eb) printf("leaf %llu items %d free space %d generation %llu owner ", (unsigned long long)btrfs_header_bytenr(eb), nr, - btrfs_leaf_free_space(fs_info, eb), + btrfs_leaf_free_space(eb), (unsigned long long)btrfs_header_generation(eb)); print_objectid(stdout, btrfs_header_owner(eb), 0); printf("\n"); @@ -1207,6 +1219,23 @@ void btrfs_print_leaf(struct extent_buffer *eb) u32 type; u64 offset; + /* + * Extra check on item pointers + * Here we don't need to be as strict as kernel leaf check. + * Only need to ensure all pointers are pointing range inside + * the leaf, thus no segfault. + */ + if (btrfs_item_offset_nr(eb, i) > leaf_data_size || + btrfs_item_size_nr(eb, i) + btrfs_item_offset_nr(eb, i) > + leaf_data_size) { + error( +"leaf %llu slot %u pointer invalid, offset %u size %u leaf data limit %u", + btrfs_header_bytenr(eb), i, + btrfs_item_offset_nr(eb, i), + btrfs_item_size_nr(eb, i), leaf_data_size); + error("skip remaining slots"); + break; + } item = btrfs_item_nr(i); item_size = btrfs_item_size(eb, item); /* Untyped extraction of slot from btrfs_item_ptr */ @@ -1356,6 +1385,7 @@ void btrfs_print_tree(struct extent_buffer *eb, int follow) { u32 i; u32 nr; + u32 ptr_num; struct btrfs_fs_info *fs_info = eb->fs_info; struct btrfs_disk_key disk_key; struct btrfs_key key; @@ -1368,30 +1398,40 @@ void btrfs_print_tree(struct extent_buffer *eb, int follow) btrfs_print_leaf(eb); return; } + /* We are crossing eb boundary, this node must be corrupted */ + if (nr > BTRFS_NODEPTRS_PER_EXTENT_BUFFER(eb)) + warning( + "node nr_items corrupted, has %u limit %u, continue anyway", + nr, BTRFS_NODEPTRS_PER_EXTENT_BUFFER(eb)); printf("node %llu level %d items %d free %u generation %llu owner ", (unsigned long long)eb->start, btrfs_header_level(eb), nr, - (u32)BTRFS_NODEPTRS_PER_BLOCK(fs_info) - nr, + (u32)BTRFS_NODEPTRS_PER_EXTENT_BUFFER(eb) - nr, (unsigned long long)btrfs_header_generation(eb)); print_objectid(stdout, btrfs_header_owner(eb), 0); printf("\n"); print_uuids(eb); fflush(stdout); - for (i = 0; i < nr; i++) { + ptr_num = BTRFS_NODEPTRS_PER_EXTENT_BUFFER(eb); + for (i = 0; i < nr && i < ptr_num; i++) { u64 blocknr = btrfs_node_blockptr(eb, i); + btrfs_node_key(eb, &disk_key, i); btrfs_disk_key_to_cpu(&key, &disk_key); printf("\t"); btrfs_print_key(&disk_key); printf(" block %llu (%llu) gen %llu\n", (unsigned long long)blocknr, - (unsigned long long)blocknr / fs_info->nodesize, + (unsigned long long)blocknr / eb->len, (unsigned long long)btrfs_node_ptr_generation(eb, i)); fflush(stdout); } if (!follow) return; + if (follow && !fs_info) + return; + for (i = 0; i < nr; i++) { next = read_tree_block(fs_info, btrfs_node_blockptr(eb, i), @@ -1418,6 +1458,4 @@ void btrfs_print_tree(struct extent_buffer *eb, int follow) } return; - - free_extent_buffer(next); } diff --git a/qgroup-verify.c b/qgroup-verify.c index 571b4d4f..e2332be2 100644 --- a/qgroup-verify.c +++ b/qgroup-verify.c @@ -622,7 +622,7 @@ static void free_tree_blocks(void) ULIST_ITER_INIT(&uiter); while ((unode = ulist_next(tree_blocks, &uiter))) free(unode_tree_block(unode)); - ulist_free(tree_blocks); + ulist_free(tree_blocks); tree_blocks = NULL; } @@ -1160,7 +1160,7 @@ static int scan_extents(struct btrfs_fs_info *info, fprintf(stderr, "ERROR: Couldn't search slot: %d\n", ret); goto out; } - path.reada = 1; + path.reada = READA_BACK; while (1) { leaf = path.nodes[0]; @@ -1298,10 +1298,19 @@ static int report_qgroup_difference(struct qgroup_count *count, int verbose) return is_different; } -void report_qgroups(int all) +/* + * Report qgroups errors + * Return 0 if nothing wrong. + * Return <0 if any qgroup is inconsistent. + * + * @all: if set, all qgroup will be checked and reported even already + * inconsistent or under rescan. + */ +int report_qgroups(int all) { struct rb_node *node; struct qgroup_count *c; + bool found_err = false; if (!repair && counts.rescan_running) { if (all) { @@ -1310,7 +1319,7 @@ void report_qgroups(int all) } else { printf( "Qgroup rescan is running, qgroups will not be printed.\n"); - return; + return 0; } } if (counts.qgroup_inconsist && !counts.rescan_running) @@ -1319,11 +1328,16 @@ void report_qgroups(int all) while (node) { c = rb_entry(node, struct qgroup_count, rb_node); - if (report_qgroup_difference(c, all)) + if (report_qgroup_difference(c, all)) { list_add_tail(&c->bad_list, &bad_qgroups); + found_err = true; + } node = rb_next(node); } + if (found_err) + return -EUCLEAN; + return 0; } void free_qgroup_counts(void) diff --git a/qgroup-verify.h b/qgroup-verify.h index d7d83a46..14d36bbf 100644 --- a/qgroup-verify.h +++ b/qgroup-verify.h @@ -23,7 +23,7 @@ #include "ctree.h" int qgroup_verify_all(struct btrfs_fs_info *info); -void report_qgroups(int all); +int report_qgroups(int all); int repair_qgroups(struct btrfs_fs_info *info, int *repaired); int print_extent_state(struct btrfs_fs_info *info, u64 subvol); @@ -1051,7 +1051,7 @@ static int __qgroups_search(int fd, struct qgroup_lookup *qgroup_lookup) struct btrfs_qgroup_limit_item *limit; u64 flags; u64 qgroupid; - u64 qgroupid1; + u64 child, parent; memset(&args, 0, sizeof(args)); @@ -1119,14 +1119,14 @@ static int __qgroups_search(int fd, struct qgroup_lookup *qgroup_lookup) qgroupid, limit); break; case BTRFS_QGROUP_RELATION_KEY: - qgroupid = btrfs_search_header_offset(sh); - qgroupid1 = btrfs_search_header_objectid(sh); + child = btrfs_search_header_offset(sh); + parent = btrfs_search_header_objectid(sh); - if (qgroupid < qgroupid1) + if (parent <= child) break; ret = update_qgroup_relation(qgroup_lookup, - qgroupid, qgroupid1); + child, parent); break; default: return ret; diff --git a/tests/cli-tests.sh b/tests/cli-tests.sh index 9e0fbae4..d302a93e 100755 --- a/tests/cli-tests.sh +++ b/tests/cli-tests.sh @@ -52,7 +52,7 @@ do name=$(basename "$i") cd "$i" if [ -x test.sh ]; then - echo "=== Entering $i" >> "$RESULTS" + echo "=== START TEST $i" >> "$RESULTS" echo " [TEST/cli] $name" ./test.sh if [ $? -ne 0 ]; then diff --git a/tests/common b/tests/common index 4b266c5b..7e4e09df 100644 --- a/tests/common +++ b/tests/common @@ -136,7 +136,7 @@ run_check() cmd=$(eval echo "\${$spec}") spec=$(_cmd_spec "${@:$spec}") set -- "${@:1:$(($ins-1))}" $spec "${@: $ins}" - echo "############### $@" >> "$RESULTS" 2>&1 + echo "====== RUN CHECK $@" >> "$RESULTS" 2>&1 if [[ $TEST_LOG =~ tty ]]; then echo "CMD: $@" > /dev/tty; fi if [ "$1" = 'root_helper' ]; then "$@" >> "$RESULTS" 2>&1 || _fail "failed: $@" @@ -158,7 +158,7 @@ run_check_stdout() cmd=$(eval echo "\${$spec}") spec=$(_cmd_spec "${@:$spec}") set -- "${@:1:$(($ins-1))}" $spec "${@: $ins}" - echo "############### $@" >> "$RESULTS" 2>&1 + echo "====== RUN CHECK $@" >> "$RESULTS" 2>&1 if [[ $TEST_LOG =~ tty ]]; then echo "CMD(stdout): $@" > /dev/tty; fi if [ "$1" = 'root_helper' ]; then "$@" 2>&1 | tee -a "$RESULTS" @@ -185,7 +185,7 @@ run_mayfail() cmd=$(eval echo "\${$spec}") spec=$(_cmd_spec "${@:$spec}") set -- "${@:1:$(($ins-1))}" $spec "${@: $ins}" - echo "############### $@" >> "$RESULTS" 2>&1 + echo "====== RUN MAYFAIL $@" >> "$RESULTS" 2>&1 if [[ $TEST_LOG =~ tty ]]; then echo "CMD(mayfail): $@" > /dev/tty; fi if [ "$1" = 'root_helper' ]; then "$@" >> "$RESULTS" 2>&1 @@ -226,7 +226,7 @@ run_mustfail() cmd=$(eval echo "\${$spec}") spec=$(_cmd_spec "${@:$spec}") set -- "${@:1:$(($ins-1))}" $spec "${@: $ins}" - echo "############### $@" >> "$RESULTS" 2>&1 + echo "====== RUN MUSTFAIL $@" >> "$RESULTS" 2>&1 if [[ $TEST_LOG =~ tty ]]; then echo "CMD(mustfail): $@" > /dev/tty; fi if [ "$1" = 'root_helper' ]; then "$@" >> "$RESULTS" 2>&1 @@ -272,7 +272,7 @@ run_mustfail_stdout() cmd=$(eval echo "\${$spec}") spec=$(_cmd_spec "${@:$spec}") set -- "${@:1:$(($ins-1))}" $spec "${@: $ins}" - echo "############### $@" >> "$RESULTS" 2>&1 + echo "====== RUN MUSTFAIL $@" >> "$RESULTS" 2>&1 if [[ $TEST_LOG =~ tty ]]; then echo "CMD(mustfail): $@" > /dev/tty; fi if [ "$1" = 'root_helper' ]; then "$@" 2>&1 > "$tmp_output" diff --git a/tests/convert-tests.sh b/tests/convert-tests.sh index 4bc915db..f6c94043 100755 --- a/tests/convert-tests.sh +++ b/tests/convert-tests.sh @@ -58,7 +58,7 @@ run_one_test() { testname=$(basename "$testdir") echo " [TEST/conv] $testname" cd "$testdir" - echo "=== Entering $testname" >> "$RESULTS" + echo "=== START TEST $testname" >> "$RESULTS" if [ -x test.sh ]; then # Only support custom test scripts ./test.sh diff --git a/tests/fsck-tests.sh b/tests/fsck-tests.sh index 14287bbe..8fbc2b4b 100755 --- a/tests/fsck-tests.sh +++ b/tests/fsck-tests.sh @@ -54,7 +54,7 @@ run_one_test() { testname="$1" echo " [TEST/fsck] $(basename $testname)" cd "$testname" - echo "=== Entering $testname" >> "$RESULTS" + echo "=== START TEST $testname" >> "$RESULTS" if [ -x test.sh ]; then # Type 2 ./test.sh diff --git a/tests/fsck-tests/014-no-extent-info/.lowmem_repairable b/tests/fsck-tests/014-no-extent-info/.lowmem_repairable new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/tests/fsck-tests/014-no-extent-info/.lowmem_repairable diff --git a/tests/fsck-tests/014-no-extent-info/no_extent.raw.xz b/tests/fsck-tests/014-no-extent-info/no_extent.raw.xz Binary files differnew file mode 100644 index 00000000..6e568a9c --- /dev/null +++ b/tests/fsck-tests/014-no-extent-info/no_extent.raw.xz diff --git a/tests/fsck-tests/014-no-extent-info/default_case.img b/tests/fsck-tests/014-no-extent-info/no_extent_bad_dev.img Binary files differindex 1ff27434..1ff27434 100644 --- a/tests/fsck-tests/014-no-extent-info/default_case.img +++ b/tests/fsck-tests/014-no-extent-info/no_extent_bad_dev.img diff --git a/tests/fsck-tests/031-metadatadump-check-data-csum/test.sh b/tests/fsck-tests/031-metadatadump-check-data-csum/test.sh index 30b0b7a3..e9b2d5c6 100755 --- a/tests/fsck-tests/031-metadatadump-check-data-csum/test.sh +++ b/tests/fsck-tests/031-metadatadump-check-data-csum/test.sh @@ -16,6 +16,8 @@ run_check_mount_test_dev run_check $SUDO_HELPER dd if=/dev/urandom of="$TEST_MNT/file" bs=4k count=16 run_check_umount_test_dev +touch restored_image +chmod a+w restored_image run_check $SUDO_HELPER "$TOP/btrfs-image" "$TEST_DEV" "restored_image" # use prepare_test_dev() to wipe all existing data on $TEST_DEV @@ -27,4 +29,4 @@ run_check $SUDO_HELPER "$TOP/btrfs-image" -r "restored_image" "$TEST_DEV" # Should not report any error run_check "$TOP/btrfs" check --check-data-csum "$TEST_DEV" -rm -rf -- "restored_image*" +rm -rf -- "restored_image" diff --git a/tests/fsck-tests/032-corrupted-qgroup/qgroup_corrupted.img b/tests/fsck-tests/032-corrupted-qgroup/qgroup_corrupted.img Binary files differnew file mode 100644 index 00000000..a19a3035 --- /dev/null +++ b/tests/fsck-tests/032-corrupted-qgroup/qgroup_corrupted.img diff --git a/tests/fsck-tests/032-corrupted-qgroup/test.sh b/tests/fsck-tests/032-corrupted-qgroup/test.sh new file mode 100755 index 00000000..4bfa3601 --- /dev/null +++ b/tests/fsck-tests/032-corrupted-qgroup/test.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# Check if btrfs check can handle valid orphan items. +# Orphan item is a marker for deleted inodes that were open at the time of +# deletion. Orphan inode/root is not referenced and will have an orphan +# item, which should not be reported as error. + +source "$TEST_TOP/common" + +check_prereq btrfs + +check_image() { + run_mustfail "btrfs check failed to detect qgroup corruption" \ + "$TOP/btrfs" check "$1" + # Above command can fail due to other bugs, so add extra check to + # ensure we can fix qgroup without problems. + run_check "$TOP/btrfs" check --repair "$1" +} + +check_all_images diff --git a/tests/fsck-tests/033-lowmem-collission-dir-items/test.sh b/tests/fsck-tests/033-lowmem-collission-dir-items/test.sh new file mode 100755 index 00000000..60f34b25 --- /dev/null +++ b/tests/fsck-tests/033-lowmem-collission-dir-items/test.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# Ensure that running btrfs check on a fs which has name collisions of files +# doesn't result in false positives. This test is specifically targeted at +# lowmem mode. + +source "$TEST_TOP/common" + +check_prereq btrfs +check_prereq mkfs.btrfs + +setup_root_helper +prepare_test_dev + +run_check $SUDO_HELPER "$TOP/mkfs.btrfs" -f "$TEST_DEV" +run_check_mount_test_dev + +# Create 2 files whose names collide +run_check $SUDO_HELPER touch "$TEST_MNT/5ab4e206~~~~~~~~XVT1U3ZF647YS2PD4AKAG826" +run_check $SUDO_HELPER touch "$TEST_MNT/5ab4e26a~~~~~~~~AP1C3VQBE79IJOTVOEZIR9YU" + +run_check_umount_test_dev + +# The fs is clean so lowmem shouldn't produce any warnings +run_check "$TOP/btrfs" check --readonly "$TEST_DEV" diff --git a/tests/fsck-tests/034-bad-inode-flags/default_case.img b/tests/fsck-tests/034-bad-inode-flags/default_case.img Binary files differnew file mode 100644 index 00000000..43a2a6f6 --- /dev/null +++ b/tests/fsck-tests/034-bad-inode-flags/default_case.img diff --git a/tests/fsck-tests/034-bad-inode-flags/test.sh b/tests/fsck-tests/034-bad-inode-flags/test.sh new file mode 100755 index 00000000..4bdc2bf0 --- /dev/null +++ b/tests/fsck-tests/034-bad-inode-flags/test.sh @@ -0,0 +1,15 @@ +#!/bin/bash +# In order to confirm that 'btrfs check' supports checking symlinks +# with immutable/append attributes that are not possible to set by standard +# syscall or ioctl so they're handled as corruption + +source "$TEST_TOP/common" + +check_prereq btrfs + +check_image() { + run_mustfail "check should report errors about inode flags" \ + $SUDO_HELPER "$TOP/btrfs" check "$1" +} + +check_all_images diff --git a/tests/fuzz-tests.sh b/tests/fuzz-tests.sh index 7bc620f0..ae738710 100755 --- a/tests/fuzz-tests.sh +++ b/tests/fuzz-tests.sh @@ -51,7 +51,7 @@ do name=$(basename "$i") cd $i if [ -x test.sh ]; then - echo "=== Entering $i" >> "$RESULTS" + echo "=== START TEST $i" >> "$RESULTS" echo " [TEST/fuzz] $name" ./test.sh if [ $? -ne 0 ]; then diff --git a/tests/misc-tests.sh b/tests/misc-tests.sh index dad397ec..3e7b9e9b 100755 --- a/tests/misc-tests.sh +++ b/tests/misc-tests.sh @@ -57,7 +57,7 @@ for i in $(find "$TEST_TOP/misc-tests" -maxdepth 1 -mindepth 1 -type d \ do echo " [TEST/misc] $(basename $i)" cd "$i" - echo "=== Entering $i" >> "$RESULTS" + echo "=== START TEST $i" >> "$RESULTS" if [ -x test.sh ]; then ./test.sh if [ $? -ne 0 ]; then diff --git a/tests/misc-tests/031-qgroup-parent-child-relation/test.sh b/tests/misc-tests/031-qgroup-parent-child-relation/test.sh new file mode 100755 index 00000000..2d66fd60 --- /dev/null +++ b/tests/misc-tests/031-qgroup-parent-child-relation/test.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# Test that btrfs 'qgroup show' outputs the correct parent-child qgroup relation + +source "$TEST_TOP/common" + +check_prereq mkfs.btrfs +check_prereq btrfs + +setup_root_helper +prepare_test_dev + +run_check $SUDO_HELPER "$TOP/mkfs.btrfs" -f "$TEST_DEV" +run_check_mount_test_dev + +run_check $SUDO_HELPER "$TOP/btrfs" quota enable "$TEST_MNT" +run_check $SUDO_HELPER "$TOP/btrfs" qgroup create 1/0 "$TEST_MNT" +run_check $SUDO_HELPER "$TOP/btrfs" qgroup assign 0/5 1/0 "$TEST_MNT" +run_check $SUDO_HELPER "$TOP/btrfs" quota rescan -w "$TEST_MNT" + +run_check_stdout $SUDO_HELPER "$TOP/btrfs" qgroup show --sort=-qgroupid \ + -p "$TEST_MNT" | tail -n 1 | grep -q "1/0" \ + || _fail "parent qgroup check failed, please check the log" +run_check_stdout $SUDO_HELPER "$TOP/btrfs" qgroup show --sort=qgroupid \ + -c "$TEST_MNT" | tail -n 1 | grep -q "0/5" \ + || _fail "child qgroup check failed, please check the log" + +run_check_umount_test_dev "$TEST_MNT" diff --git a/tests/misc-tests/032-bad-item-ptr/bad_item_ptr.raw.xz b/tests/misc-tests/032-bad-item-ptr/bad_item_ptr.raw.xz Binary files differnew file mode 100644 index 00000000..7cf2e89f --- /dev/null +++ b/tests/misc-tests/032-bad-item-ptr/bad_item_ptr.raw.xz diff --git a/tests/misc-tests/032-bad-item-ptr/test.sh b/tests/misc-tests/032-bad-item-ptr/test.sh new file mode 100755 index 00000000..cfbfe1a5 --- /dev/null +++ b/tests/misc-tests/032-bad-item-ptr/test.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# +# Verify that btrfs inspect dump-tree won't segfault on heavily corrupted +# tree leaf +# Issue: #128 + +source "$TEST_TOP/common" + +check_prereq btrfs + +check_image() { + run_check "$TOP/btrfs" inspect-internal dump-tree "$1" + run_mustfail "btrfs check failed to detect such corruption" \ + "$TOP/btrfs" check "$1" +} + +check_all_images diff --git a/tests/mkfs-tests.sh b/tests/mkfs-tests.sh index 2ced4ac9..e76a805b 100755 --- a/tests/mkfs-tests.sh +++ b/tests/mkfs-tests.sh @@ -52,7 +52,7 @@ for i in $(find "$TEST_TOP/mkfs-tests" -maxdepth 1 -mindepth 1 -type d \ do echo " [TEST/mkfs] $(basename $i)" cd "$i" - echo "=== Entering $i" >> "$RESULTS" + echo "=== START TEST $i" >> "$RESULTS" if [ -x test.sh ]; then ./test.sh if [ $? -ne 0 ]; then diff --git a/tests/mkfs-tests/017-small-backing-size-thin-provision-device/test.sh b/tests/mkfs-tests/017-small-backing-size-thin-provision-device/test.sh new file mode 100755 index 00000000..32640ce5 --- /dev/null +++ b/tests/mkfs-tests/017-small-backing-size-thin-provision-device/test.sh @@ -0,0 +1,98 @@ +#!/bin/bash +# mkfs.btrfs must fail on a thin provision device with very small backing size +# and big virtual size. + +source "$TEST_TOP/common" + +check_prereq mkfs.btrfs +check_global_prereq udevadm +check_global_prereq dmsetup + +setup_root_helper +prepare_test_dev + +# Backing data dev +DMTHIN_DATA_NAME="btrfs-progs-thin-data" +DMTHIN_DATA_DEV="/dev/mapper/$DMTHIN_DATA_NAME" +# Backing metadata dev +DMTHIN_META_NAME="btrfs-progs-thin-meta" +DMTHIN_META_DEV="/dev/mapper/$DMTHIN_META_NAME" +# Backing pool dev (combination of above) +DMTHIN_POOL_NAME="btrfs-progs-thin-pool" +DMTHIN_POOL_DEV="/dev/mapper/$DMTHIN_POOL_NAME" +# Thin volume +DMTHIN_VOL_NAME="btrfs-progs-thin-vol" +DMTHIN_VOL_DEV="/dev/mapper/$DMTHIN_VOL_NAME" + +dmthin_cleanup() +{ + # wait for device to be fully settled + run_check $SUDO_HELPER udevadm settle + run_check $SUDO_HELPER dmsetup remove "$DMTHIN_VOL_NAME" + run_check $SUDO_HELPER dmsetup remove "$DMTHIN_POOL_NAME" + run_check $SUDO_HELPER dmsetup remove "$DMTHIN_META_NAME" + run_check $SUDO_HELPER dmsetup remove "$DMTHIN_DATA_NAME" +} + +sector_size=512 # in bytes +data_dev_size=$((1 * 1024 * 1024 / $sector_size)) # 1M +virtual_size=$((1 * 1024 * 1024 * 1024 * 1024 / $sector_size)) # 1T +cluster_size=1024 # 512k in sectors +low_water=$((104857600 / $cluster_size/ $sector_size)) # 100M / $cluster_size, in sectors + +# Need to make linear metadata and data devs. From kernel docs: +# As a guide, we suggest you calculate the number of bytes to use in the +# metadata device as 48 * $data_dev_size / $data_block_size but round it up +# to 2MB (4096 sectors) if the answer is smaller. +# So do that: +meta_dev_size=$((48 * $data_dev_size / $cluster_size)) +if [ "$meta_dev_size" -lt "4096" ]; then + meta_dev_size=4096 # 2MB +fi + +meta_dev_offset=0 +total_data_dev_size=$(($meta_dev_offset + $meta_dev_size + $data_dev_size)) + +run_check truncate -s0 img +chmod a+w img +run_check truncate -s"$(($total_data_dev_size * $sector_size))" img + +dm_backing_dev=`run_check_stdout $SUDO_HELPER losetup --find --show img` + +if ! [ -b "$dm_backing_dev" ]; then + _fail "cannot create backing device" +fi + +# Metadata device +DMTHIN_META_TABLE="0 $meta_dev_size linear $dm_backing_dev $meta_dev_offset" +run_check $SUDO_HELPER dmsetup create "$DMTHIN_META_NAME" --table "$DMTHIN_META_TABLE" + +# Data device +data_dev_offset=$((meta_dev_offset + $meta_dev_size)) +DMTHIN_DATA_TABLE="0 $data_dev_size linear $dm_backing_dev $data_dev_offset" +run_check $SUDO_HELPER dmsetup create "$DMTHIN_DATA_NAME" --table "$DMTHIN_DATA_TABLE" + +# Zap the pool metadata dev +run_check $SUDO_HELPER dd if=/dev/zero of="$DMTHIN_META_DEV" bs=4096 count=1 + +# Thin pool +# "start length thin-pool metadata_dev data_dev data_block_size low_water_mark" +DMTHIN_POOL_TABLE="0 $data_dev_size thin-pool $DMTHIN_META_DEV $DMTHIN_DATA_DEV $cluster_size $low_water" +run_check $SUDO_HELPER dmsetup create "$DMTHIN_POOL_NAME" --table "$DMTHIN_POOL_TABLE" + +# Thin volume +pool_id=$RANDOM +run_check $SUDO_HELPER dmsetup message "$DMTHIN_POOL_DEV" 0 "create_thin $pool_id" + +# start length thin pool_dev dev_id [external_origin_dev] +DMTHIN_VOL_TABLE="0 $virtual_size thin $DMTHIN_POOL_DEV $pool_id" +run_check $SUDO_HELPER dmsetup create "$DMTHIN_VOL_NAME" --table "$DMTHIN_VOL_TABLE" + +# mkfs.btrfs should fail due to the small backing device, the initial discard +# is disabled +run_mustfail "should fail for small backing size thin provision device" \ + $SUDO_HELPER "$TOP/mkfs.btrfs" -K -f "$DMTHIN_VOL_DEV" + +dmthin_cleanup +run_mayfail $SUDO_HELPER losetup -d "$dm_backing_dev" +rm -- img diff --git a/transaction.c b/transaction.c index ad705728..9619265e 100644 --- a/transaction.c +++ b/transaction.c @@ -168,7 +168,7 @@ commit_tree: BUG_ON(ret); ret = __commit_transaction(trans, root); BUG_ON(ret); - write_ctree_super(trans, fs_info); + write_ctree_super(trans); btrfs_finish_extent_commit(trans, fs_info->extent_root, &fs_info->pinned_extents); kfree(trans); @@ -2460,7 +2460,7 @@ const char *subvol_strip_mountpoint(const char *mnt, const char *full_path) if (!len) return full_path; - if ((strncmp(mnt, full_path, len) != 0) || (full_path[len] != '/')) { + if ((strncmp(mnt, full_path, len) != 0) || ((len > 1) && (full_path[len] != '/'))) { error("not on mount point: %s", mnt); exit(1); } @@ -420,7 +420,7 @@ static int find_free_dev_extent_start(struct btrfs_device *device, goto out; } - path->reada = 2; + path->reada = READA_FORWARD; key.objectid = device->devid; key.offset = search_start; @@ -846,7 +846,7 @@ static int btrfs_device_avail_bytes(struct btrfs_trans_handle *trans, key.offset = root->fs_info->alloc_start; key.type = BTRFS_DEV_EXTENT_KEY; - path->reada = 2; + path->reada = READA_FORWARD; ret = btrfs_search_slot(trans, root, &key, path, 0, 0); if (ret < 0) goto error; @@ -1364,9 +1364,8 @@ int btrfs_next_bg(struct btrfs_fs_info *fs_info, u64 *logical, return -ENOENT; } -int btrfs_rmap_block(struct btrfs_fs_info *fs_info, - u64 chunk_start, u64 physical, u64 devid, - u64 **logical, int *naddrs, int *stripe_len) +int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start, + u64 physical, u64 **logical, int *naddrs, int *stripe_len) { struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree; struct cache_extent *ce; @@ -1397,8 +1396,6 @@ int btrfs_rmap_block(struct btrfs_fs_info *fs_info, buf = kzalloc(sizeof(u64) * map->num_stripes, GFP_NOFS); for (i = 0; i < map->num_stripes; i++) { - if (devid && map->stripes[i].dev->devid != devid) - continue; if (map->stripes[i].physical > physical || map->stripes[i].physical + length <= physical) continue; @@ -254,8 +254,8 @@ static inline int btrfs_next_bg_system(struct btrfs_fs_info *fs_info, BTRFS_BLOCK_GROUP_SYSTEM); } int btrfs_rmap_block(struct btrfs_fs_info *fs_info, - u64 chunk_start, u64 physical, u64 devid, - u64 **logical, int *naddrs, int *stripe_len); + u64 chunk_start, u64 physical, u64 **logical, + int *naddrs, int *stripe_len); int btrfs_read_sys_array(struct btrfs_fs_info *fs_info); int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info); int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, |