Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs

Pull btrfs fixes from Chris Mason:
"These are assorted fixes, mostly from Josef nailing down xfstests
runs. Zach also has a long standing fix for problems with readdir
wrapping f_pos (or ctx->pos)

These patches were spread out over different bases, so I rebased
things on top of rc4 and retested overnight"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
btrfs: don't loop on large offsets in readdir
Btrfs: check to see if root_list is empty before adding it to dead roots
Btrfs: release both paths before logging dir/changed extents
Btrfs: allow splitting of hole em's when dropping extent cache
Btrfs: make sure the backref walker catches all refs to our extent
Btrfs: fix backref walking when we hit a compressed extent
Btrfs: do not offset physical if we're compressed
Btrfs: fix extent buffer leak after backref walking
Btrfs: fix a bug of snapshot-aware defrag to make it work on partial extents
btrfs: fix file truncation if FALLOC_FL_KEEP_SIZE is specified

+120 -69
+29 -19
fs/btrfs/backref.c
··· 36 36 u64 extent_item_pos, 37 37 struct extent_inode_elem **eie) 38 38 { 39 - u64 data_offset; 40 - u64 data_len; 39 + u64 offset = 0; 41 40 struct extent_inode_elem *e; 42 41 43 - data_offset = btrfs_file_extent_offset(eb, fi); 44 - data_len = btrfs_file_extent_num_bytes(eb, fi); 42 + if (!btrfs_file_extent_compression(eb, fi) && 43 + !btrfs_file_extent_encryption(eb, fi) && 44 + !btrfs_file_extent_other_encoding(eb, fi)) { 45 + u64 data_offset; 46 + u64 data_len; 45 47 46 - if (extent_item_pos < data_offset || 47 - extent_item_pos >= data_offset + data_len) 48 - return 1; 48 + data_offset = btrfs_file_extent_offset(eb, fi); 49 + data_len = btrfs_file_extent_num_bytes(eb, fi); 50 + 51 + if (extent_item_pos < data_offset || 52 + extent_item_pos >= data_offset + data_len) 53 + return 1; 54 + offset = extent_item_pos - data_offset; 55 + } 49 56 50 57 e = kmalloc(sizeof(*e), GFP_NOFS); 51 58 if (!e) ··· 60 53 61 54 e->next = *eie; 62 55 e->inum = key->objectid; 63 - e->offset = key->offset + (extent_item_pos - data_offset); 56 + e->offset = key->offset + offset; 64 57 *eie = e; 65 58 66 59 return 0; ··· 196 189 struct extent_buffer *eb; 197 190 struct btrfs_key key; 198 191 struct btrfs_file_extent_item *fi; 199 - struct extent_inode_elem *eie = NULL; 192 + struct extent_inode_elem *eie = NULL, *old = NULL; 200 193 u64 disk_byte; 201 194 202 195 if (level != 0) { ··· 230 223 231 224 if (disk_byte == wanted_disk_byte) { 232 225 eie = NULL; 226 + old = NULL; 233 227 if (extent_item_pos) { 234 228 ret = check_extent_in_eb(&key, eb, fi, 235 229 *extent_item_pos, ··· 238 230 if (ret < 0) 239 231 break; 240 232 } 241 - if (!ret) { 242 - ret = ulist_add(parents, eb->start, 243 - (uintptr_t)eie, GFP_NOFS); 244 - if (ret < 0) 245 - break; 246 - if (!extent_item_pos) { 247 - ret = btrfs_next_old_leaf(root, path, 248 - time_seq); 249 - continue; 250 - } 233 + if (ret > 0) 234 + goto next; 235 + ret = ulist_add_merge(parents, eb->start, 236 + (uintptr_t)eie, 237 + (u64 *)&old, GFP_NOFS); 238 + if (ret < 0) 239 + break; 240 + if (!ret && extent_item_pos) { 241 + while (old->next) 242 + old = old->next; 243 + old->next = eie; 251 244 } 252 245 } 246 + next: 253 247 ret = btrfs_next_old_item(root, path, time_seq); 254 248 } 255 249
-1
fs/btrfs/ctree.c
··· 1271 1271 BUG_ON(!eb_rewin); 1272 1272 } 1273 1273 1274 - extent_buffer_get(eb_rewin); 1275 1274 btrfs_tree_read_unlock(eb); 1276 1275 free_extent_buffer(eb); 1277 1276
+6 -3
fs/btrfs/extent_io.c
··· 4048 4048 } 4049 4049 4050 4050 while (!end) { 4051 - u64 offset_in_extent; 4051 + u64 offset_in_extent = 0; 4052 4052 4053 4053 /* break if the extent we found is outside the range */ 4054 4054 if (em->start >= max || extent_map_end(em) < off) ··· 4064 4064 4065 4065 /* 4066 4066 * record the offset from the start of the extent 4067 - * for adjusting the disk offset below 4067 + * for adjusting the disk offset below. Only do this if the 4068 + * extent isn't compressed since our in ram offset may be past 4069 + * what we have actually allocated on disk. 4068 4070 */ 4069 - offset_in_extent = em_start - em->start; 4071 + if (!test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) 4072 + offset_in_extent = em_start - em->start; 4070 4073 em_end = extent_map_end(em); 4071 4074 em_len = em_end - em_start; 4072 4075 emflags = em->flags;
+41 -23
fs/btrfs/file.c
··· 596 596 if (no_splits) 597 597 goto next; 598 598 599 - if (em->block_start < EXTENT_MAP_LAST_BYTE && 600 - em->start < start) { 599 + if (em->start < start) { 601 600 split->start = em->start; 602 601 split->len = start - em->start; 603 - split->orig_start = em->orig_start; 604 - split->block_start = em->block_start; 605 602 606 - if (compressed) 607 - split->block_len = em->block_len; 608 - else 609 - split->block_len = split->len; 610 - split->ram_bytes = em->ram_bytes; 611 - split->orig_block_len = max(split->block_len, 612 - em->orig_block_len); 603 + if (em->block_start < EXTENT_MAP_LAST_BYTE) { 604 + split->orig_start = em->orig_start; 605 + split->block_start = em->block_start; 606 + 607 + if (compressed) 608 + split->block_len = em->block_len; 609 + else 610 + split->block_len = split->len; 611 + split->orig_block_len = max(split->block_len, 612 + em->orig_block_len); 613 + split->ram_bytes = em->ram_bytes; 614 + } else { 615 + split->orig_start = split->start; 616 + split->block_len = 0; 617 + split->block_start = em->block_start; 618 + split->orig_block_len = 0; 619 + split->ram_bytes = split->len; 620 + } 621 + 613 622 split->generation = gen; 614 623 split->bdev = em->bdev; 615 624 split->flags = flags; ··· 629 620 split = split2; 630 621 split2 = NULL; 631 622 } 632 - if (em->block_start < EXTENT_MAP_LAST_BYTE && 633 - testend && em->start + em->len > start + len) { 623 + if (testend && em->start + em->len > start + len) { 634 624 u64 diff = start + len - em->start; 635 625 636 626 split->start = start + len; ··· 638 630 split->flags = flags; 639 631 split->compress_type = em->compress_type; 640 632 split->generation = gen; 641 - split->orig_block_len = max(em->block_len, 642 - em->orig_block_len); 643 - split->ram_bytes = em->ram_bytes; 644 633 645 - if (compressed) { 646 - split->block_len = em->block_len; 647 - split->block_start = em->block_start; 648 - split->orig_start = em->orig_start; 634 + if (em->block_start < EXTENT_MAP_LAST_BYTE) { 635 + split->orig_block_len = max(em->block_len, 636 + em->orig_block_len); 637 + 638 + split->ram_bytes = em->ram_bytes; 639 + if (compressed) { 640 + split->block_len = em->block_len; 641 + split->block_start = em->block_start; 642 + split->orig_start = em->orig_start; 643 + } else { 644 + split->block_len = split->len; 645 + split->block_start = em->block_start 646 + + diff; 647 + split->orig_start = em->orig_start; 648 + } 649 649 } else { 650 - split->block_len = split->len; 651 - split->block_start = em->block_start + diff; 652 - split->orig_start = em->orig_start; 650 + split->ram_bytes = split->len; 651 + split->orig_start = split->start; 652 + split->block_len = 0; 653 + split->block_start = em->block_start; 654 + split->orig_block_len = 0; 653 655 } 654 656 655 657 ret = add_extent_mapping(em_tree, split, modified);
+37 -15
fs/btrfs/inode.c
··· 2166 2166 if (btrfs_file_extent_disk_bytenr(leaf, extent) != old->bytenr) 2167 2167 continue; 2168 2168 2169 - extent_offset = btrfs_file_extent_offset(leaf, extent); 2170 - if (key.offset - extent_offset != offset) 2169 + /* 2170 + * 'offset' refers to the exact key.offset, 2171 + * NOT the 'offset' field in btrfs_extent_data_ref, ie. 2172 + * (key.offset - extent_offset). 2173 + */ 2174 + if (key.offset != offset) 2171 2175 continue; 2172 2176 2177 + extent_offset = btrfs_file_extent_offset(leaf, extent); 2173 2178 num_bytes = btrfs_file_extent_num_bytes(leaf, extent); 2179 + 2174 2180 if (extent_offset >= old->extent_offset + old->offset + 2175 2181 old->len || extent_offset + num_bytes <= 2176 2182 old->extent_offset + old->offset) 2177 2183 continue; 2178 2184 2185 + ret = 0; 2179 2186 break; 2180 2187 } 2181 2188 ··· 2194 2187 2195 2188 backref->root_id = root_id; 2196 2189 backref->inum = inum; 2197 - backref->file_pos = offset + extent_offset; 2190 + backref->file_pos = offset; 2198 2191 backref->num_bytes = num_bytes; 2199 2192 backref->extent_offset = extent_offset; 2200 2193 backref->generation = btrfs_file_extent_generation(leaf, extent); ··· 2217 2210 new->path = path; 2218 2211 2219 2212 list_for_each_entry_safe(old, tmp, &new->head, list) { 2220 - ret = iterate_inodes_from_logical(old->bytenr, fs_info, 2213 + ret = iterate_inodes_from_logical(old->bytenr + 2214 + old->extent_offset, fs_info, 2221 2215 path, record_one_backref, 2222 2216 old); 2223 2217 BUG_ON(ret < 0 && ret != -ENOENT); ··· 4399 4391 int mask = attr->ia_valid; 4400 4392 int ret; 4401 4393 4402 - if (newsize == oldsize) 4403 - return 0; 4404 - 4405 4394 /* 4406 4395 * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a 4407 4396 * special case where we need to update the times despite not having ··· 5170 5165 } 5171 5166 5172 5167 /* Reached end of directory/root. Bump pos past the last item. */ 5173 - if (key_type == BTRFS_DIR_INDEX_KEY) 5174 - /* 5175 - * 32-bit glibc will use getdents64, but then strtol - 5176 - * so the last number we can serve is this. 5177 - */ 5178 - ctx->pos = 0x7fffffff; 5179 - else 5180 - ctx->pos++; 5168 + ctx->pos++; 5169 + 5170 + /* 5171 + * Stop new entries from being returned after we return the last 5172 + * entry. 5173 + * 5174 + * New directory entries are assigned a strictly increasing 5175 + * offset. This means that new entries created during readdir 5176 + * are *guaranteed* to be seen in the future by that readdir. 5177 + * This has broken buggy programs which operate on names as 5178 + * they're returned by readdir. Until we re-use freed offsets 5179 + * we have this hack to stop new entries from being returned 5180 + * under the assumption that they'll never reach this huge 5181 + * offset. 5182 + * 5183 + * This is being careful not to overflow 32bit loff_t unless the 5184 + * last entry requires it because doing so has broken 32bit apps 5185 + * in the past. 5186 + */ 5187 + if (key_type == BTRFS_DIR_INDEX_KEY) { 5188 + if (ctx->pos >= INT_MAX) 5189 + ctx->pos = LLONG_MAX; 5190 + else 5191 + ctx->pos = INT_MAX; 5192 + } 5181 5193 nopos: 5182 5194 ret = 0; 5183 5195 err:
+4 -4
fs/btrfs/transaction.c
··· 983 983 * a dirty root struct and adds it into the list of dead roots that need to 984 984 * be deleted 985 985 */ 986 - int btrfs_add_dead_root(struct btrfs_root *root) 986 + void btrfs_add_dead_root(struct btrfs_root *root) 987 987 { 988 988 spin_lock(&root->fs_info->trans_lock); 989 - list_add_tail(&root->root_list, &root->fs_info->dead_roots); 989 + if (list_empty(&root->root_list)) 990 + list_add_tail(&root->root_list, &root->fs_info->dead_roots); 990 991 spin_unlock(&root->fs_info->trans_lock); 991 - return 0; 992 992 } 993 993 994 994 /* ··· 1925 1925 } 1926 1926 root = list_first_entry(&fs_info->dead_roots, 1927 1927 struct btrfs_root, root_list); 1928 - list_del(&root->root_list); 1928 + list_del_init(&root->root_list); 1929 1929 spin_unlock(&fs_info->trans_lock); 1930 1930 1931 1931 pr_debug("btrfs: cleaner removing %llu\n",
+1 -1
fs/btrfs/transaction.h
··· 143 143 int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, 144 144 struct btrfs_root *root); 145 145 146 - int btrfs_add_dead_root(struct btrfs_root *root); 146 + void btrfs_add_dead_root(struct btrfs_root *root); 147 147 int btrfs_defrag_root(struct btrfs_root *root); 148 148 int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root); 149 149 int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
+2 -3
fs/btrfs/tree-log.c
··· 3746 3746 } 3747 3747 3748 3748 log_extents: 3749 + btrfs_release_path(path); 3750 + btrfs_release_path(dst_path); 3749 3751 if (fast_search) { 3750 - btrfs_release_path(dst_path); 3751 3752 ret = btrfs_log_changed_extents(trans, root, inode, dst_path); 3752 3753 if (ret) { 3753 3754 err = ret; ··· 3765 3764 } 3766 3765 3767 3766 if (inode_only == LOG_INODE_ALL && S_ISDIR(inode->i_mode)) { 3768 - btrfs_release_path(path); 3769 - btrfs_release_path(dst_path); 3770 3767 ret = log_directory_changes(trans, root, inode, path, dst_path); 3771 3768 if (ret) { 3772 3769 err = ret;