aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.c18
-rw-r--r--fs/btrfs/file.c2
-rw-r--r--fs/btrfs/inode.c4
-rw-r--r--fs/btrfs/ordered-data.c6
-rw-r--r--fs/btrfs/ordered-data.h2
5 files changed, 19 insertions, 13 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 1b756fae2799..9601241e552b 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1245,7 +1245,10 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
1245 int level; 1245 int level;
1246 int should_reada = p->reada; 1246 int should_reada = p->reada;
1247 int lowest_unlock = 1; 1247 int lowest_unlock = 1;
1248 int blocksize;
1248 u8 lowest_level = 0; 1249 u8 lowest_level = 0;
1250 u64 blocknr;
1251 u64 gen;
1249 1252
1250 lowest_level = p->lowest_level; 1253 lowest_level = p->lowest_level;
1251 WARN_ON(lowest_level && ins_len); 1254 WARN_ON(lowest_level && ins_len);
@@ -1320,11 +1323,12 @@ again:
1320 reada_for_search(root, p, level, slot, 1323 reada_for_search(root, p, level, slot,
1321 key->objectid); 1324 key->objectid);
1322 1325
1323 tmp = btrfs_find_tree_block(root, 1326 blocknr = btrfs_node_blockptr(b, slot);
1324 btrfs_node_blockptr(b, slot), 1327 gen = btrfs_node_ptr_generation(b, slot);
1325 btrfs_level_size(root, level - 1)); 1328 blocksize = btrfs_level_size(root, level - 1);
1326 if (tmp && btrfs_buffer_uptodate(tmp, 1329
1327 btrfs_node_ptr_generation(b, slot))) { 1330 tmp = btrfs_find_tree_block(root, blocknr, blocksize);
1331 if (tmp && btrfs_buffer_uptodate(tmp, gen)) {
1328 b = tmp; 1332 b = tmp;
1329 } else { 1333 } else {
1330 /* 1334 /*
@@ -1336,6 +1340,10 @@ again:
1336 btrfs_release_path(NULL, p); 1340 btrfs_release_path(NULL, p);
1337 if (tmp) 1341 if (tmp)
1338 free_extent_buffer(tmp); 1342 free_extent_buffer(tmp);
1343 tmp = read_tree_block(root, blocknr,
1344 blocksize, gen);
1345 if (tmp)
1346 free_extent_buffer(tmp);
1339 goto again; 1347 goto again;
1340 } else { 1348 } else {
1341 b = read_node_slot(root, b, slot); 1349 b = read_node_slot(root, b, slot);
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 18bbe108a0e6..b7f8f92daf8a 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -976,7 +976,7 @@ out_nolock:
976 976
977int btrfs_release_file(struct inode * inode, struct file * filp) 977int btrfs_release_file(struct inode * inode, struct file * filp)
978{ 978{
979 btrfs_del_ordered_inode(inode); 979 btrfs_del_ordered_inode(inode, 0);
980 if (filp->private_data) 980 if (filp->private_data)
981 btrfs_ioctl_trans_end(filp); 981 btrfs_ioctl_trans_end(filp);
982 return 0; 982 return 0;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index b2251e27ac84..cf27b5984627 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -852,7 +852,7 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry)
852 * we don't need to worry about 852 * we don't need to worry about
853 * data=ordered 853 * data=ordered
854 */ 854 */
855 btrfs_del_ordered_inode(inode); 855 btrfs_del_ordered_inode(inode, 1);
856 } 856 }
857 857
858 btrfs_end_transaction(trans, root); 858 btrfs_end_transaction(trans, root);
@@ -1276,14 +1276,12 @@ void btrfs_delete_inode(struct inode *inode)
1276 1276
1277 btrfs_end_transaction(trans, root); 1277 btrfs_end_transaction(trans, root);
1278 btrfs_btree_balance_dirty(root, nr); 1278 btrfs_btree_balance_dirty(root, nr);
1279 btrfs_throttle(root);
1280 return; 1279 return;
1281 1280
1282no_delete_lock: 1281no_delete_lock:
1283 nr = trans->blocks_used; 1282 nr = trans->blocks_used;
1284 btrfs_end_transaction(trans, root); 1283 btrfs_end_transaction(trans, root);
1285 btrfs_btree_balance_dirty(root, nr); 1284 btrfs_btree_balance_dirty(root, nr);
1286 btrfs_throttle(root);
1287no_delete: 1285no_delete:
1288 clear_inode(inode); 1286 clear_inode(inode);
1289} 1287}
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 8dd8180183ff..5e4c0d95ce43 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -254,7 +254,7 @@ static void __btrfs_del_ordered_inode(struct btrfs_ordered_inode_tree *tree,
254 return; 254 return;
255} 255}
256 256
257void btrfs_del_ordered_inode(struct inode *inode) 257void btrfs_del_ordered_inode(struct inode *inode, int force)
258{ 258{
259 struct btrfs_root *root = BTRFS_I(inode)->root; 259 struct btrfs_root *root = BTRFS_I(inode)->root;
260 u64 root_objectid = root->root_key.objectid; 260 u64 root_objectid = root->root_key.objectid;
@@ -263,8 +263,8 @@ void btrfs_del_ordered_inode(struct inode *inode)
263 return; 263 return;
264 } 264 }
265 265
266 if (mapping_tagged(inode->i_mapping, PAGECACHE_TAG_DIRTY) || 266 if (!force && (mapping_tagged(inode->i_mapping, PAGECACHE_TAG_DIRTY) ||
267 mapping_tagged(inode->i_mapping, PAGECACHE_TAG_WRITEBACK)) 267 mapping_tagged(inode->i_mapping, PAGECACHE_TAG_WRITEBACK)))
268 return; 268 return;
269 269
270 spin_lock(&root->fs_info->new_trans_lock); 270 spin_lock(&root->fs_info->new_trans_lock);
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h
index c515c4b39996..4fa78736423e 100644
--- a/fs/btrfs/ordered-data.h
+++ b/fs/btrfs/ordered-data.h
@@ -38,6 +38,6 @@ int btrfs_find_del_first_ordered_inode(struct btrfs_ordered_inode_tree *tree,
38int btrfs_find_first_ordered_inode(struct btrfs_ordered_inode_tree *tree, 38int btrfs_find_first_ordered_inode(struct btrfs_ordered_inode_tree *tree,
39 u64 *root_objectid, u64 *objectid, 39 u64 *root_objectid, u64 *objectid,
40 struct inode **inode); 40 struct inode **inode);
41void btrfs_del_ordered_inode(struct inode *inode); 41void btrfs_del_ordered_inode(struct inode *inode, int force);
42int btrfs_ordered_throttle(struct btrfs_root *root, struct inode *inode); 42int btrfs_ordered_throttle(struct btrfs_root *root, struct inode *inode);
43#endif 43#endif