Loading fs/btrfs/ctree.h +1 −0 Original line number Diff line number Diff line Loading @@ -349,6 +349,7 @@ struct btrfs_fs_info { u64 total_pinned; spinlock_t delalloc_lock; spinlock_t new_trans_lock; u64 delalloc_bytes; }; /* Loading fs/btrfs/disk-io.c +1 −0 Original line number Diff line number Diff line Loading @@ -639,6 +639,7 @@ struct btrfs_root *open_ctree(struct super_block *sb) INIT_LIST_HEAD(&fs_info->hashers); spin_lock_init(&fs_info->hash_lock); spin_lock_init(&fs_info->delalloc_lock); spin_lock_init(&fs_info->new_trans_lock); memset(&fs_info->super_kobj, 0, sizeof(fs_info->super_kobj)); init_completion(&fs_info->kobj_unregister); Loading fs/btrfs/inode.c +3 −10 Original line number Diff line number Diff line Loading @@ -993,20 +993,13 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) void btrfs_drop_inode(struct inode *inode) { struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(inode)->root; if (!BTRFS_I(inode)->ordered_trans) { if (!BTRFS_I(inode)->ordered_trans || inode->i_nlink) { generic_drop_inode(inode); return; } /* nasty, but it prevents a deadlock with data=ordered by preventing * a commit until after this inode is done */ trans = btrfs_start_transaction(root, 1); /* FIXME, make sure this delete actually ends up in the transaction */ btrfs_del_ordered_inode(inode); generic_drop_inode(inode); /* note, the inode is now untouchable */ btrfs_end_transaction(trans, root); } void btrfs_delete_inode(struct inode *inode) Loading fs/btrfs/ordered-data.c +36 −0 Original line number Diff line number Diff line Loading @@ -219,3 +219,39 @@ int btrfs_find_del_first_ordered_inode(struct btrfs_ordered_inode_tree *tree, kfree(entry); return 1; } static int __btrfs_del_ordered_inode(struct btrfs_ordered_inode_tree *tree, u64 root_objectid, u64 objectid) { struct tree_entry *entry; struct rb_node *node; struct rb_node *prev; write_lock(&tree->lock); node = __tree_search(&tree->tree, root_objectid, objectid, &prev); if (!node) { write_unlock(&tree->lock); return 0; } rb_erase(node, &tree->tree); write_unlock(&tree->lock); entry = rb_entry(node, struct tree_entry, rb_node); kfree(entry); return 1; } int btrfs_del_ordered_inode(struct inode *inode) { struct btrfs_root *root = BTRFS_I(inode)->root; u64 root_objectid = root->root_key.objectid; spin_lock(&root->fs_info->new_trans_lock); if (root->fs_info->running_transaction) { struct btrfs_ordered_inode_tree *tree; tree = &root->fs_info->running_transaction->ordered_inode_tree; __btrfs_del_ordered_inode(tree, root_objectid, inode->i_ino); } spin_unlock(&root->fs_info->new_trans_lock); return 0; } fs/btrfs/ordered-data.h +1 −0 Original line number Diff line number Diff line Loading @@ -36,4 +36,5 @@ int btrfs_find_del_first_ordered_inode(struct btrfs_ordered_inode_tree *tree, u64 *root_objectid, u64 *objectid); int btrfs_find_first_ordered_inode(struct btrfs_ordered_inode_tree *tree, u64 *root_objectid, u64 *objectid); int btrfs_del_ordered_inode(struct inode *inode); #endif Loading
fs/btrfs/ctree.h +1 −0 Original line number Diff line number Diff line Loading @@ -349,6 +349,7 @@ struct btrfs_fs_info { u64 total_pinned; spinlock_t delalloc_lock; spinlock_t new_trans_lock; u64 delalloc_bytes; }; /* Loading
fs/btrfs/disk-io.c +1 −0 Original line number Diff line number Diff line Loading @@ -639,6 +639,7 @@ struct btrfs_root *open_ctree(struct super_block *sb) INIT_LIST_HEAD(&fs_info->hashers); spin_lock_init(&fs_info->hash_lock); spin_lock_init(&fs_info->delalloc_lock); spin_lock_init(&fs_info->new_trans_lock); memset(&fs_info->super_kobj, 0, sizeof(fs_info->super_kobj)); init_completion(&fs_info->kobj_unregister); Loading
fs/btrfs/inode.c +3 −10 Original line number Diff line number Diff line Loading @@ -993,20 +993,13 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) void btrfs_drop_inode(struct inode *inode) { struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(inode)->root; if (!BTRFS_I(inode)->ordered_trans) { if (!BTRFS_I(inode)->ordered_trans || inode->i_nlink) { generic_drop_inode(inode); return; } /* nasty, but it prevents a deadlock with data=ordered by preventing * a commit until after this inode is done */ trans = btrfs_start_transaction(root, 1); /* FIXME, make sure this delete actually ends up in the transaction */ btrfs_del_ordered_inode(inode); generic_drop_inode(inode); /* note, the inode is now untouchable */ btrfs_end_transaction(trans, root); } void btrfs_delete_inode(struct inode *inode) Loading
fs/btrfs/ordered-data.c +36 −0 Original line number Diff line number Diff line Loading @@ -219,3 +219,39 @@ int btrfs_find_del_first_ordered_inode(struct btrfs_ordered_inode_tree *tree, kfree(entry); return 1; } static int __btrfs_del_ordered_inode(struct btrfs_ordered_inode_tree *tree, u64 root_objectid, u64 objectid) { struct tree_entry *entry; struct rb_node *node; struct rb_node *prev; write_lock(&tree->lock); node = __tree_search(&tree->tree, root_objectid, objectid, &prev); if (!node) { write_unlock(&tree->lock); return 0; } rb_erase(node, &tree->tree); write_unlock(&tree->lock); entry = rb_entry(node, struct tree_entry, rb_node); kfree(entry); return 1; } int btrfs_del_ordered_inode(struct inode *inode) { struct btrfs_root *root = BTRFS_I(inode)->root; u64 root_objectid = root->root_key.objectid; spin_lock(&root->fs_info->new_trans_lock); if (root->fs_info->running_transaction) { struct btrfs_ordered_inode_tree *tree; tree = &root->fs_info->running_transaction->ordered_inode_tree; __btrfs_del_ordered_inode(tree, root_objectid, inode->i_ino); } spin_unlock(&root->fs_info->new_trans_lock); return 0; }
fs/btrfs/ordered-data.h +1 −0 Original line number Diff line number Diff line Loading @@ -36,4 +36,5 @@ int btrfs_find_del_first_ordered_inode(struct btrfs_ordered_inode_tree *tree, u64 *root_objectid, u64 *objectid); int btrfs_find_first_ordered_inode(struct btrfs_ordered_inode_tree *tree, u64 *root_objectid, u64 *objectid); int btrfs_del_ordered_inode(struct inode *inode); #endif