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:
"This is a small pull with btrfs fixes. The biggest of the bunch is
another fix for the new backref walking code.

We're still hammering out one btrfs dio vs buffered reads problem, but
that one will have to wait for the next rc."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
Btrfs: delay iput with async extents
Btrfs: add a missing spin_lock
Btrfs: don't assume to be on the correct extent in add_all_parents
Btrfs: introduce btrfs_next_old_item

+62 -46
+52 -42
fs/btrfs/backref.c
··· 179 179 180 180 static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, 181 181 struct ulist *parents, int level, 182 - struct btrfs_key *key, u64 time_seq, 182 + struct btrfs_key *key_for_search, u64 time_seq, 183 183 u64 wanted_disk_byte, 184 184 const u64 *extent_item_pos) 185 185 { 186 - int ret; 187 - int slot = path->slots[level]; 188 - struct extent_buffer *eb = path->nodes[level]; 186 + int ret = 0; 187 + int slot; 188 + struct extent_buffer *eb; 189 + struct btrfs_key key; 189 190 struct btrfs_file_extent_item *fi; 190 191 struct extent_inode_elem *eie = NULL; 191 192 u64 disk_byte; 192 - u64 wanted_objectid = key->objectid; 193 193 194 - add_parent: 195 - if (level == 0 && extent_item_pos) { 196 - fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item); 197 - ret = check_extent_in_eb(key, eb, fi, *extent_item_pos, &eie); 194 + if (level != 0) { 195 + eb = path->nodes[level]; 196 + ret = ulist_add(parents, eb->start, 0, GFP_NOFS); 198 197 if (ret < 0) 199 198 return ret; 200 - } 201 - ret = ulist_add(parents, eb->start, (unsigned long)eie, GFP_NOFS); 202 - if (ret < 0) 203 - return ret; 204 - 205 - if (level != 0) 206 199 return 0; 200 + } 207 201 208 202 /* 209 - * if the current leaf is full with EXTENT_DATA items, we must 210 - * check the next one if that holds a reference as well. 211 - * ref->count cannot be used to skip this check. 212 - * repeat this until we don't find any additional EXTENT_DATA items. 203 + * We normally enter this function with the path already pointing to 204 + * the first item to check. But sometimes, we may enter it with 205 + * slot==nritems. In that case, go to the next leaf before we continue. 213 206 */ 214 - while (1) { 215 - eie = NULL; 207 + if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) 216 208 ret = btrfs_next_old_leaf(root, path, time_seq); 217 - if (ret < 0) 218 - return ret; 219 - if (ret) 220 - return 0; 221 209 210 + while (!ret) { 222 211 eb = path->nodes[0]; 223 - for (slot = 0; slot < btrfs_header_nritems(eb); ++slot) { 224 - btrfs_item_key_to_cpu(eb, key, slot); 225 - if (key->objectid != wanted_objectid || 226 - key->type != BTRFS_EXTENT_DATA_KEY) 227 - return 0; 228 - fi = btrfs_item_ptr(eb, slot, 229 - struct btrfs_file_extent_item); 230 - disk_byte = btrfs_file_extent_disk_bytenr(eb, fi); 231 - if (disk_byte == wanted_disk_byte) 232 - goto add_parent; 212 + slot = path->slots[0]; 213 + 214 + btrfs_item_key_to_cpu(eb, &key, slot); 215 + 216 + if (key.objectid != key_for_search->objectid || 217 + key.type != BTRFS_EXTENT_DATA_KEY) 218 + break; 219 + 220 + fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item); 221 + disk_byte = btrfs_file_extent_disk_bytenr(eb, fi); 222 + 223 + if (disk_byte == wanted_disk_byte) { 224 + eie = NULL; 225 + if (extent_item_pos) { 226 + ret = check_extent_in_eb(&key, eb, fi, 227 + *extent_item_pos, 228 + &eie); 229 + if (ret < 0) 230 + break; 231 + } 232 + if (!ret) { 233 + ret = ulist_add(parents, eb->start, 234 + (unsigned long)eie, GFP_NOFS); 235 + if (ret < 0) 236 + break; 237 + if (!extent_item_pos) { 238 + ret = btrfs_next_old_leaf(root, path, 239 + time_seq); 240 + continue; 241 + } 242 + } 233 243 } 244 + ret = btrfs_next_old_item(root, path, time_seq); 234 245 } 235 246 236 - return 0; 247 + if (ret > 0) 248 + ret = 0; 249 + return ret; 237 250 } 238 251 239 252 /* ··· 263 250 struct btrfs_path *path; 264 251 struct btrfs_root *root; 265 252 struct btrfs_key root_key; 266 - struct btrfs_key key = {0}; 267 253 struct extent_buffer *eb; 268 254 int ret = 0; 269 255 int root_level; ··· 307 295 goto out; 308 296 } 309 297 310 - if (level == 0) 311 - btrfs_item_key_to_cpu(eb, &key, path->slots[0]); 312 - 313 - ret = add_all_parents(root, path, parents, level, &key, time_seq, 314 - ref->wanted_disk_byte, extent_item_pos); 298 + ret = add_all_parents(root, path, parents, level, &ref->key_for_search, 299 + time_seq, ref->wanted_disk_byte, 300 + extent_item_pos); 315 301 out: 316 302 btrfs_free_path(path); 317 303 return ret;
+7 -2
fs/btrfs/ctree.h
··· 2755 2755 int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path); 2756 2756 int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path, 2757 2757 u64 time_seq); 2758 - static inline int btrfs_next_item(struct btrfs_root *root, struct btrfs_path *p) 2758 + static inline int btrfs_next_old_item(struct btrfs_root *root, 2759 + struct btrfs_path *p, u64 time_seq) 2759 2760 { 2760 2761 ++p->slots[0]; 2761 2762 if (p->slots[0] >= btrfs_header_nritems(p->nodes[0])) 2762 - return btrfs_next_leaf(root, p); 2763 + return btrfs_next_old_leaf(root, p, time_seq); 2763 2764 return 0; 2765 + } 2766 + static inline int btrfs_next_item(struct btrfs_root *root, struct btrfs_path *p) 2767 + { 2768 + return btrfs_next_old_item(root, p, 0); 2764 2769 } 2765 2770 int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); 2766 2771 int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf);
+1
fs/btrfs/disk-io.c
··· 3426 3426 mutex_unlock(&head->mutex); 3427 3427 btrfs_put_delayed_ref(ref); 3428 3428 3429 + spin_lock(&delayed_refs->lock); 3429 3430 continue; 3430 3431 } 3431 3432
+2 -2
fs/btrfs/inode.c
··· 987 987 async_cow->start, async_cow->end, async_cow, 988 988 &num_added); 989 989 if (num_added == 0) { 990 - iput(async_cow->inode); 990 + btrfs_add_delayed_iput(async_cow->inode); 991 991 async_cow->inode = NULL; 992 992 } 993 993 } ··· 1023 1023 struct async_cow *async_cow; 1024 1024 async_cow = container_of(work, struct async_cow, work); 1025 1025 if (async_cow->inode) 1026 - iput(async_cow->inode); 1026 + btrfs_add_delayed_iput(async_cow->inode); 1027 1027 kfree(async_cow); 1028 1028 } 1029 1029