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 tag 'for-7.1-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fixes from David Sterba:

- space reservation fixes:
- correctly undo 'may_use' accounting for remap tree
- avoid double decrement of 'may_use' when submitting async io

- actually enable the shutdown ioctl callback (not just the superblock
ops)

- raid stripe tree fixes when deleting extents
- add missing error handling
- fix various incorrect values set

- fix transaction state when removing a directory, possibly leading to
EIO during log replay

- additional b-tree node key checks during metadata readahead

- error handling and transaction abort updates

* tag 'for-7.1-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
btrfs: fix double-decrement of bytes_may_use in submit_one_async_extent()
btrfs: check return value of btrfs_partially_delete_raid_extent()
btrfs: handle -EAGAIN from btrfs_duplicate_item and refresh stale leaf pointer
btrfs: replace ASSERT with proper error handling in stripe lookup fallback
btrfs: fix wrong min_objectid in btrfs_previous_item() call
btrfs: fix raid stripe search missing entries at leaf boundaries
btrfs: copy devid in btrfs_partially_delete_raid_extent()
btrfs: handle unexpected free-space-tree key types
btrfs: fix missing last_unlink_trans update when removing a directory
btrfs: don't clobber errors in add_remap_tree_entries()
btrfs: enable shutdown ioctl for non-experimental builds
btrfs: apply first key check for readahead when possible
btrfs: abort transaction in do_remap_reloc_trans() on failure
btrfs: fix bytes_may_use leak in do_remap_reloc_trans()
btrfs: fix bytes_may_use leak in move_existing_remap()

+104 -29
+12 -2
fs/btrfs/extent_io.c
··· 4641 4641 * to read the block we will not block on anything. 4642 4642 */ 4643 4643 void btrfs_readahead_tree_block(struct btrfs_fs_info *fs_info, 4644 - u64 bytenr, u64 owner_root, u64 gen, int level) 4644 + u64 bytenr, u64 owner_root, u64 gen, int level, 4645 + const struct btrfs_key *first_key) 4645 4646 { 4646 4647 struct btrfs_tree_parent_check check = { 4647 4648 .level = level, ··· 4650 4649 }; 4651 4650 struct extent_buffer *eb; 4652 4651 int ret; 4652 + 4653 + if (first_key) { 4654 + memcpy(&check.first_key, first_key, sizeof(struct btrfs_key)); 4655 + check.has_first_key = true; 4656 + } 4653 4657 4654 4658 eb = btrfs_find_create_tree_block(fs_info, bytenr, owner_root, level); 4655 4659 if (IS_ERR(eb)) ··· 4683 4677 */ 4684 4678 void btrfs_readahead_node_child(struct extent_buffer *node, int slot) 4685 4679 { 4680 + struct btrfs_key node_key; 4681 + 4682 + btrfs_node_key_to_cpu(node, &node_key, slot); 4686 4683 btrfs_readahead_tree_block(node->fs_info, 4687 4684 btrfs_node_blockptr(node, slot), 4688 4685 btrfs_header_owner(node), 4689 4686 btrfs_node_ptr_generation(node, slot), 4690 - btrfs_header_level(node) - 1); 4687 + btrfs_header_level(node) - 1, 4688 + &node_key); 4691 4689 }
+2 -1
fs/btrfs/extent_io.h
··· 287 287 } 288 288 289 289 void btrfs_readahead_tree_block(struct btrfs_fs_info *fs_info, 290 - u64 bytenr, u64 owner_root, u64 gen, int level); 290 + u64 bytenr, u64 owner_root, u64 gen, int level, 291 + const struct btrfs_key *first_key); 291 292 void btrfs_readahead_node_child(struct extent_buffer *node, int slot); 292 293 293 294 /* Note: this can be used in for loops without caching the value in a variable. */
+15 -3
fs/btrfs/free-space-tree.c
··· 259 259 nr++; 260 260 path->slots[0]--; 261 261 } else { 262 - ASSERT(0); 262 + btrfs_err(fs_info, "unexpected free space tree key type %u", 263 + found_key.type); 264 + ret = -EUCLEAN; 265 + btrfs_abort_transaction(trans, ret); 266 + goto out; 263 267 } 264 268 } 265 269 ··· 409 405 410 406 nr++; 411 407 } else { 412 - ASSERT(0); 408 + btrfs_err(fs_info, "unexpected free space tree key type %u", 409 + found_key.type); 410 + ret = -EUCLEAN; 411 + btrfs_abort_transaction(trans, ret); 412 + goto out; 413 413 } 414 414 } 415 415 ··· 1526 1518 nr++; 1527 1519 path->slots[0]--; 1528 1520 } else { 1529 - ASSERT(0); 1521 + btrfs_err(trans->fs_info, "unexpected free space tree key type %u", 1522 + found_key.type); 1523 + ret = -EUCLEAN; 1524 + btrfs_abort_transaction(trans, ret); 1525 + return ret; 1530 1526 } 1531 1527 } 1532 1528
+3 -1
fs/btrfs/inode.c
··· 1153 1153 NULL, &cached, 1154 1154 EXTENT_LOCKED | EXTENT_DELALLOC | 1155 1155 EXTENT_DELALLOC_NEW | 1156 - EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING, 1156 + EXTENT_DEFRAG | EXTENT_CLEAR_META_RESV, 1157 1157 PAGE_UNLOCK | PAGE_START_WRITEBACK | 1158 1158 PAGE_END_WRITEBACK); 1159 1159 if (async_extent->cb) ··· 4958 4958 ret = btrfs_orphan_add(trans, inode); 4959 4959 if (ret) 4960 4960 goto out; 4961 + 4962 + btrfs_record_unlink_dir(trans, dir, inode, false); 4961 4963 4962 4964 /* now the directory is empty */ 4963 4965 ret = btrfs_unlink_inode(trans, dir, inode, &fname.disk_name);
+3 -4
fs/btrfs/ioctl.c
··· 5102 5102 return 0; 5103 5103 } 5104 5104 5105 - #ifdef CONFIG_BTRFS_EXPERIMENTAL 5106 5105 static int btrfs_ioctl_shutdown(struct btrfs_fs_info *fs_info, unsigned long arg) 5107 5106 { 5108 5107 int ret = 0; ··· 5133 5134 case BTRFS_SHUTDOWN_FLAGS_NOLOGFLUSH: 5134 5135 btrfs_force_shutdown(fs_info); 5135 5136 break; 5137 + default: 5138 + ret = -EINVAL; 5139 + break; 5136 5140 } 5137 5141 return ret; 5138 5142 } 5139 - #endif 5140 5143 5141 5144 long btrfs_ioctl(struct file *file, unsigned int 5142 5145 cmd, unsigned long arg) ··· 5295 5294 #endif 5296 5295 case BTRFS_IOC_SUBVOL_SYNC_WAIT: 5297 5296 return btrfs_ioctl_subvol_sync(fs_info, argp); 5298 - #ifdef CONFIG_BTRFS_EXPERIMENTAL 5299 5297 case BTRFS_IOC_SHUTDOWN: 5300 5298 return btrfs_ioctl_shutdown(fs_info, arg); 5301 - #endif 5302 5299 } 5303 5300 5304 5301 return -ENOTTY;
+45 -12
fs/btrfs/raid-stripe-tree.c
··· 45 45 46 46 for (int i = 0; i < btrfs_num_raid_stripes(item_size); i++) { 47 47 struct btrfs_raid_stride *stride = &extent->strides[i]; 48 + u64 devid; 48 49 u64 phys; 49 50 51 + devid = btrfs_raid_stride_devid(leaf, stride); 52 + btrfs_set_stack_raid_stride_devid(&newitem->strides[i], devid); 50 53 phys = btrfs_raid_stride_physical(leaf, stride) + frontpad; 51 54 btrfs_set_stack_raid_stride_physical(&newitem->strides[i], phys); 52 55 } ··· 98 95 while (1) { 99 96 key.objectid = start; 100 97 key.type = BTRFS_RAID_STRIPE_KEY; 101 - key.offset = 0; 98 + key.offset = (u64)-1; 102 99 103 100 ret = btrfs_search_slot(trans, stripe_root, &key, path, -1, 1); 104 101 if (ret < 0) 105 102 break; 106 103 107 - if (path->slots[0] == btrfs_header_nritems(path->nodes[0])) 108 - path->slots[0]--; 104 + /* 105 + * Search with offset=(u64)-1 ensures we land on the correct 106 + * leaf even when the target entry is the first item on a leaf. 107 + * Since no real entry has offset=(u64)-1, ret is always 1 and 108 + * slot points past the last entry with objectid==start (or 109 + * past the end of the leaf if that entry is the last item). 110 + * Back up one slot to find the actual entry. 111 + */ 112 + if (path->slots[0] == 0) { 113 + /* No entry with objectid <= start exists. */ 114 + ret = 0; 115 + break; 116 + } 117 + path->slots[0]--; 109 118 110 119 leaf = path->nodes[0]; 111 120 slot = path->slots[0]; ··· 138 123 */ 139 124 if (found_start > start) { 140 125 if (slot == 0) { 141 - ret = btrfs_previous_item(stripe_root, path, start, 126 + ret = btrfs_previous_item(stripe_root, path, 0, 142 127 BTRFS_RAID_STRIPE_KEY); 143 128 if (ret) { 144 129 if (ret > 0) ··· 154 139 btrfs_item_key_to_cpu(leaf, &key, slot); 155 140 found_start = key.objectid; 156 141 found_end = found_start + key.offset; 157 - ASSERT(found_start <= start); 142 + if (found_start > start || found_end <= start) { 143 + ret = -ENOENT; 144 + break; 145 + } 158 146 } 159 147 160 148 if (key.type != BTRFS_RAID_STRIPE_KEY) ··· 194 176 195 177 /* The "right" item. */ 196 178 ret = btrfs_duplicate_item(trans, stripe_root, path, &newkey); 179 + if (ret == -EAGAIN) { 180 + btrfs_release_path(path); 181 + continue; 182 + } 197 183 if (ret) 198 184 break; 199 185 186 + /* 187 + * btrfs_duplicate_item() may have triggered a leaf 188 + * split via setup_leaf_for_split(), so we must refresh 189 + * our leaf pointer from the path. 190 + */ 191 + leaf = path->nodes[0]; 200 192 item_size = btrfs_item_size(leaf, path->slots[0]); 201 193 extent = btrfs_item_ptr(leaf, path->slots[0], 202 194 struct btrfs_stripe_extent); ··· 223 195 /* The "left" item. */ 224 196 path->slots[0]--; 225 197 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); 226 - btrfs_partially_delete_raid_extent(trans, path, &key, 227 - diff_start, 0); 198 + ret = btrfs_partially_delete_raid_extent(trans, path, 199 + &key, 200 + diff_start, 0); 228 201 break; 229 202 } 230 203 ··· 241 212 if (found_start < start) { 242 213 u64 diff_start = start - found_start; 243 214 244 - btrfs_partially_delete_raid_extent(trans, path, &key, 245 - diff_start, 0); 215 + ret = btrfs_partially_delete_raid_extent(trans, path, 216 + &key, 217 + diff_start, 0); 218 + if (ret) 219 + break; 246 220 247 221 start += (key.offset - diff_start); 248 222 length -= (key.offset - diff_start); ··· 268 236 if (found_end > end) { 269 237 u64 diff_end = found_end - end; 270 238 271 - btrfs_partially_delete_raid_extent(trans, path, &key, 272 - key.offset - length, 273 - length); 239 + ret = btrfs_partially_delete_raid_extent(trans, path, 240 + &key, 241 + key.offset - length, 242 + length); 274 243 ASSERT(key.offset - diff_end == length); 275 244 break; 276 245 }
+24 -6
fs/btrfs/relocation.c
··· 2607 2607 if (!block->key_ready) 2608 2608 btrfs_readahead_tree_block(fs_info, block->bytenr, 2609 2609 block->owner, 0, 2610 - block->level); 2610 + block->level, NULL); 2611 2611 } 2612 2612 2613 2613 /* Get first keys */ ··· 3876 3876 ret = btrfs_insert_empty_items(trans, fs_info->remap_root, path, &batch); 3877 3877 btrfs_release_path(path); 3878 3878 3879 - if (num_entries <= max_items) 3879 + if (ret || num_entries <= max_items) 3880 3880 break; 3881 3881 3882 3882 num_entries -= max_items; ··· 4172 4172 btrfs_space_info_update_bytes_may_use(sinfo, -length); 4173 4173 spin_unlock(&sinfo->lock); 4174 4174 return ret; 4175 + } 4176 + 4177 + if (ins.offset < length) { 4178 + spin_lock(&sinfo->lock); 4179 + btrfs_space_info_update_bytes_may_use(sinfo, ins.offset - length); 4180 + spin_unlock(&sinfo->lock); 4175 4181 } 4176 4182 4177 4183 dest_addr = ins.objectid; ··· 5006 5000 return ret; 5007 5001 } 5008 5002 5003 + if (ins.offset < remap_length) { 5004 + spin_lock(&sinfo->lock); 5005 + btrfs_space_info_update_bytes_may_use(sinfo, ins.offset - remap_length); 5006 + spin_unlock(&sinfo->lock); 5007 + } 5008 + 5009 5009 made_reservation = true; 5010 5010 5011 5011 new_addr = ins.objectid; ··· 5035 5023 5036 5024 if (bg_needs_free_space) { 5037 5025 ret = btrfs_add_block_group_free_space(trans, dest_bg); 5038 - if (ret) 5026 + if (ret) { 5027 + btrfs_abort_transaction(trans, ret); 5039 5028 goto fail; 5029 + } 5040 5030 } 5041 5031 5042 5032 ret = copy_remapped_data(fs_info, start, new_addr, length); 5043 - if (ret) 5033 + if (ret) { 5034 + btrfs_abort_transaction(trans, ret); 5044 5035 goto fail; 5036 + } 5045 5037 5046 5038 ret = btrfs_remove_from_free_space_tree(trans, new_addr, length); 5047 - if (ret) 5039 + if (ret) { 5040 + btrfs_abort_transaction(trans, ret); 5048 5041 goto fail; 5042 + } 5049 5043 5050 5044 ret = add_remap_entry(trans, path, src_bg, start, new_addr, length); 5051 5045 if (ret) { 5052 - btrfs_add_to_free_space_tree(trans, new_addr, length); 5046 + btrfs_abort_transaction(trans, ret); 5053 5047 goto fail; 5054 5048 } 5055 5049