Btrfs: avoid sleeping in verify_parent_transid while atomic

verify_parent_transid needs to lock the extent range to make
sure no IO is underway, and so it can safely clear the
uptodate bits if our checks fail.

But, a few callers are using it with spinlocks held. Most
of the time, the generation numbers are going to match, and
we don't want to switch to a blocking lock just for the error
case. This adds an atomic flag to verify_parent_transid,
and changes it to return EAGAIN if it needs to block to
properly verifiy things.

Signed-off-by: Chris Mason <chris.mason@oracle.com>

+34 -17
+17 -9
fs/btrfs/ctree.c
··· 725 725 726 726 cur = btrfs_find_tree_block(root, blocknr, blocksize); 727 727 if (cur) 728 - uptodate = btrfs_buffer_uptodate(cur, gen); 728 + uptodate = btrfs_buffer_uptodate(cur, gen, 0); 729 729 else 730 730 uptodate = 0; 731 731 if (!cur || !uptodate) { ··· 1360 1360 block1 = btrfs_node_blockptr(parent, slot - 1); 1361 1361 gen = btrfs_node_ptr_generation(parent, slot - 1); 1362 1362 eb = btrfs_find_tree_block(root, block1, blocksize); 1363 - if (eb && btrfs_buffer_uptodate(eb, gen)) 1363 + /* 1364 + * if we get -eagain from btrfs_buffer_uptodate, we 1365 + * don't want to return eagain here. That will loop 1366 + * forever 1367 + */ 1368 + if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0) 1364 1369 block1 = 0; 1365 1370 free_extent_buffer(eb); 1366 1371 } ··· 1373 1368 block2 = btrfs_node_blockptr(parent, slot + 1); 1374 1369 gen = btrfs_node_ptr_generation(parent, slot + 1); 1375 1370 eb = btrfs_find_tree_block(root, block2, blocksize); 1376 - if (eb && btrfs_buffer_uptodate(eb, gen)) 1371 + if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0) 1377 1372 block2 = 0; 1378 1373 free_extent_buffer(eb); 1379 1374 } ··· 1511 1506 1512 1507 tmp = btrfs_find_tree_block(root, blocknr, blocksize); 1513 1508 if (tmp) { 1514 - if (btrfs_buffer_uptodate(tmp, 0)) { 1515 - if (btrfs_buffer_uptodate(tmp, gen)) { 1509 + /* first we do an atomic uptodate check */ 1510 + if (btrfs_buffer_uptodate(tmp, 0, 1) > 0) { 1511 + if (btrfs_buffer_uptodate(tmp, gen, 1) > 0) { 1516 1512 /* 1517 1513 * we found an up to date block without 1518 1514 * sleeping, return ··· 1531 1525 free_extent_buffer(tmp); 1532 1526 btrfs_set_path_blocking(p); 1533 1527 1528 + /* now we're allowed to do a blocking uptodate check */ 1534 1529 tmp = read_tree_block(root, blocknr, blocksize, gen); 1535 - if (tmp && btrfs_buffer_uptodate(tmp, gen)) { 1530 + if (tmp && btrfs_buffer_uptodate(tmp, gen, 0) > 0) { 1536 1531 *eb_ret = tmp; 1537 1532 return 0; 1538 1533 } ··· 1568 1561 * and give up so that our caller doesn't loop forever 1569 1562 * on our EAGAINs. 1570 1563 */ 1571 - if (!btrfs_buffer_uptodate(tmp, 0)) 1564 + if (!btrfs_buffer_uptodate(tmp, 0, 0)) 1572 1565 ret = -EIO; 1573 1566 free_extent_buffer(tmp); 1574 1567 } ··· 4052 4045 tmp = btrfs_find_tree_block(root, blockptr, 4053 4046 btrfs_level_size(root, level - 1)); 4054 4047 4055 - if (tmp && btrfs_buffer_uptodate(tmp, gen)) { 4048 + if (tmp && btrfs_buffer_uptodate(tmp, gen, 1) > 0) { 4056 4049 free_extent_buffer(tmp); 4057 4050 break; 4058 4051 } ··· 4175 4168 struct extent_buffer *cur; 4176 4169 cur = btrfs_find_tree_block(root, blockptr, 4177 4170 btrfs_level_size(root, level - 1)); 4178 - if (!cur || !btrfs_buffer_uptodate(cur, gen)) { 4171 + if (!cur || 4172 + btrfs_buffer_uptodate(cur, gen, 1) <= 0) { 4179 4173 slot++; 4180 4174 if (cur) 4181 4175 free_extent_buffer(cur);
+13 -5
fs/btrfs/disk-io.c
··· 323 323 * in the wrong place. 324 324 */ 325 325 static int verify_parent_transid(struct extent_io_tree *io_tree, 326 - struct extent_buffer *eb, u64 parent_transid) 326 + struct extent_buffer *eb, u64 parent_transid, 327 + int atomic) 327 328 { 328 329 struct extent_state *cached_state = NULL; 329 330 int ret; 330 331 331 332 if (!parent_transid || btrfs_header_generation(eb) == parent_transid) 332 333 return 0; 334 + 335 + if (atomic) 336 + return -EAGAIN; 333 337 334 338 lock_extent_bits(io_tree, eb->start, eb->start + eb->len - 1, 335 339 0, &cached_state); ··· 376 372 ret = read_extent_buffer_pages(io_tree, eb, start, 377 373 WAIT_COMPLETE, 378 374 btree_get_extent, mirror_num); 379 - if (!ret && !verify_parent_transid(io_tree, eb, parent_transid)) 375 + if (!ret && !verify_parent_transid(io_tree, eb, 376 + parent_transid, 0)) 380 377 break; 381 378 382 379 /* ··· 1207 1202 root->commit_root = NULL; 1208 1203 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), 1209 1204 blocksize, generation); 1210 - if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) { 1205 + if (!root->node || !btrfs_buffer_uptodate(root->node, generation, 0)) { 1211 1206 free_extent_buffer(root->node); 1212 1207 root->node = NULL; 1213 1208 return -EIO; ··· 3148 3143 return 0; 3149 3144 } 3150 3145 3151 - int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid) 3146 + int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid, 3147 + int atomic) 3152 3148 { 3153 3149 int ret; 3154 3150 struct inode *btree_inode = buf->pages[0]->mapping->host; ··· 3159 3153 return ret; 3160 3154 3161 3155 ret = verify_parent_transid(&BTRFS_I(btree_inode)->io_tree, buf, 3162 - parent_transid); 3156 + parent_transid, atomic); 3157 + if (ret == -EAGAIN) 3158 + return ret; 3163 3159 return !ret; 3164 3160 } 3165 3161
+2 -1
fs/btrfs/disk-io.h
··· 66 66 void __btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr); 67 67 void btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root); 68 68 void btrfs_mark_buffer_dirty(struct extent_buffer *buf); 69 - int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid); 69 + int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid, 70 + int atomic); 70 71 int btrfs_set_buffer_uptodate(struct extent_buffer *buf); 71 72 int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid); 72 73 u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len);
+1 -1
fs/btrfs/extent-tree.c
··· 6568 6568 goto skip; 6569 6569 } 6570 6570 6571 - if (!btrfs_buffer_uptodate(next, generation)) { 6571 + if (!btrfs_buffer_uptodate(next, generation, 0)) { 6572 6572 btrfs_tree_unlock(next); 6573 6573 free_extent_buffer(next); 6574 6574 next = NULL;
+1 -1
fs/btrfs/tree-log.c
··· 279 279 log->fs_info->extent_root, 280 280 eb->start, eb->len); 281 281 282 - if (btrfs_buffer_uptodate(eb, gen)) { 282 + if (btrfs_buffer_uptodate(eb, gen, 0)) { 283 283 if (wc->write) 284 284 btrfs_write_tree_block(eb); 285 285 if (wc->wait)