aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2009-03-13 11:00:37 -0400
committerChris Mason <chris.mason@oracle.com>2009-03-24 16:14:28 -0400
commitb9473439d3e84d9fc1a0a83faca69cc1b7566341 (patch)
treebef8321b80589026b617d61d0fabaf545d459269 /fs/btrfs/inode.c
parent89573b9c516b24af8a3b9958dd5afca8fa874e3d (diff)
Btrfs: leave btree locks spinning more often
btrfs_mark_buffer dirty would set dirty bits in the extent_io tree for the buffers it was dirtying. This may require a kmalloc and it was not atomic. So, anyone who called btrfs_mark_buffer_dirty had to set any btree locks they were holding to blocking first. This commit changes dirty tracking for extent buffers to just use a flag in the extent buffer. Now that we have one and only one extent buffer per page, this can be safely done without losing dirty bits along the way. This also introduces a path->leave_spinning flag that callers of btrfs_search_slot can use to indicate they will properly deal with a path returned where all the locks are spinning instead of blocking. Many of the btree search callers now expect spinning paths, resulting in better btree concurrency overall. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index c427011dc453..b83a45dc717e 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -134,6 +134,7 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans,
134 if (!path) 134 if (!path)
135 return -ENOMEM; 135 return -ENOMEM;
136 136
137 path->leave_spinning = 1;
137 btrfs_set_trans_block_group(trans, inode); 138 btrfs_set_trans_block_group(trans, inode);
138 139
139 key.objectid = inode->i_ino; 140 key.objectid = inode->i_ino;
@@ -167,9 +168,9 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans,
167 cur_size = min_t(unsigned long, compressed_size, 168 cur_size = min_t(unsigned long, compressed_size,
168 PAGE_CACHE_SIZE); 169 PAGE_CACHE_SIZE);
169 170
170 kaddr = kmap(cpage); 171 kaddr = kmap_atomic(cpage, KM_USER0);
171 write_extent_buffer(leaf, kaddr, ptr, cur_size); 172 write_extent_buffer(leaf, kaddr, ptr, cur_size);
172 kunmap(cpage); 173 kunmap_atomic(kaddr, KM_USER0);
173 174
174 i++; 175 i++;
175 ptr += cur_size; 176 ptr += cur_size;
@@ -1452,6 +1453,7 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans,
1452 path = btrfs_alloc_path(); 1453 path = btrfs_alloc_path();
1453 BUG_ON(!path); 1454 BUG_ON(!path);
1454 1455
1456 path->leave_spinning = 1;
1455 ret = btrfs_drop_extents(trans, root, inode, file_pos, 1457 ret = btrfs_drop_extents(trans, root, inode, file_pos,
1456 file_pos + num_bytes, file_pos, &hint); 1458 file_pos + num_bytes, file_pos, &hint);
1457 BUG_ON(ret); 1459 BUG_ON(ret);
@@ -1474,6 +1476,10 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans,
1474 btrfs_set_file_extent_compression(leaf, fi, compression); 1476 btrfs_set_file_extent_compression(leaf, fi, compression);
1475 btrfs_set_file_extent_encryption(leaf, fi, encryption); 1477 btrfs_set_file_extent_encryption(leaf, fi, encryption);
1476 btrfs_set_file_extent_other_encoding(leaf, fi, other_encoding); 1478 btrfs_set_file_extent_other_encoding(leaf, fi, other_encoding);
1479
1480 btrfs_unlock_up_safe(path, 1);
1481 btrfs_set_lock_blocking(leaf);
1482
1477 btrfs_mark_buffer_dirty(leaf); 1483 btrfs_mark_buffer_dirty(leaf);
1478 1484
1479 inode_add_bytes(inode, num_bytes); 1485 inode_add_bytes(inode, num_bytes);
@@ -1486,8 +1492,8 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans,
1486 root->root_key.objectid, 1492 root->root_key.objectid,
1487 trans->transid, inode->i_ino, &ins); 1493 trans->transid, inode->i_ino, &ins);
1488 BUG_ON(ret); 1494 BUG_ON(ret);
1489
1490 btrfs_free_path(path); 1495 btrfs_free_path(path);
1496
1491 return 0; 1497 return 0;
1492} 1498}
1493 1499
@@ -2118,6 +2124,7 @@ noinline int btrfs_update_inode(struct btrfs_trans_handle *trans,
2118 2124
2119 path = btrfs_alloc_path(); 2125 path = btrfs_alloc_path();
2120 BUG_ON(!path); 2126 BUG_ON(!path);
2127 path->leave_spinning = 1;
2121 ret = btrfs_lookup_inode(trans, root, path, 2128 ret = btrfs_lookup_inode(trans, root, path,
2122 &BTRFS_I(inode)->location, 1); 2129 &BTRFS_I(inode)->location, 1);
2123 if (ret) { 2130 if (ret) {
@@ -2164,6 +2171,7 @@ int btrfs_unlink_inode(struct btrfs_trans_handle *trans,
2164 goto err; 2171 goto err;
2165 } 2172 }
2166 2173
2174 path->leave_spinning = 1;
2167 di = btrfs_lookup_dir_item(trans, root, path, dir->i_ino, 2175 di = btrfs_lookup_dir_item(trans, root, path, dir->i_ino,
2168 name, name_len, -1); 2176 name, name_len, -1);
2169 if (IS_ERR(di)) { 2177 if (IS_ERR(di)) {
@@ -2515,6 +2523,7 @@ noinline int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
2515 key.type = (u8)-1; 2523 key.type = (u8)-1;
2516 2524
2517search_again: 2525search_again:
2526 path->leave_spinning = 1;
2518 ret = btrfs_search_slot(trans, root, &key, path, -1, 1); 2527 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
2519 if (ret < 0) 2528 if (ret < 0)
2520 goto error; 2529 goto error;
@@ -2661,6 +2670,7 @@ delete:
2661 break; 2670 break;
2662 } 2671 }
2663 if (found_extent) { 2672 if (found_extent) {
2673 btrfs_set_path_blocking(path);
2664 ret = btrfs_free_extent(trans, root, extent_start, 2674 ret = btrfs_free_extent(trans, root, extent_start,
2665 extent_num_bytes, 2675 extent_num_bytes,
2666 leaf->start, root_owner, 2676 leaf->start, root_owner,
@@ -3466,6 +3476,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
3466 sizes[0] = sizeof(struct btrfs_inode_item); 3476 sizes[0] = sizeof(struct btrfs_inode_item);
3467 sizes[1] = name_len + sizeof(*ref); 3477 sizes[1] = name_len + sizeof(*ref);
3468 3478
3479 path->leave_spinning = 1;
3469 ret = btrfs_insert_empty_items(trans, root, path, key, sizes, 2); 3480 ret = btrfs_insert_empty_items(trans, root, path, key, sizes, 2);
3470 if (ret != 0) 3481 if (ret != 0)
3471 goto fail; 3482 goto fail;