projects
/
linux-2.6-block.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Btrfs: Add delayed iput
[linux-2.6-block.git]
/
fs
/
btrfs
/
transaction.c
diff --git
a/fs/btrfs/transaction.c
b/fs/btrfs/transaction.c
index bca82a4ca8e6d8f78bad1bd21b511a433aaed48e..75b31caade29aa58810d73d780a84825856cf55e 100644
(file)
--- a/
fs/btrfs/transaction.c
+++ b/
fs/btrfs/transaction.c
@@
-163,8
+163,14
@@
static void wait_current_trans(struct btrfs_root *root)
}
}
}
}
+enum btrfs_trans_type {
+ TRANS_START,
+ TRANS_JOIN,
+ TRANS_USERSPACE,
+};
+
static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
- int num_blocks, int
wait
)
+ int num_blocks, int
type
)
{
struct btrfs_trans_handle *h =
kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
{
struct btrfs_trans_handle *h =
kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
@@
-172,7
+178,8
@@
static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
mutex_lock(&root->fs_info->trans_mutex);
if (!root->fs_info->log_root_recovering &&
mutex_lock(&root->fs_info->trans_mutex);
if (!root->fs_info->log_root_recovering &&
- ((wait == 1 && !root->fs_info->open_ioctl_trans) || wait == 2))
+ ((type == TRANS_START && !root->fs_info->open_ioctl_trans) ||
+ type == TRANS_USERSPACE))
wait_current_trans(root);
ret = join_transaction(root);
BUG_ON(ret);
wait_current_trans(root);
ret = join_transaction(root);
BUG_ON(ret);
@@
-186,7
+193,7
@@
static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
h->alloc_exclude_start = 0;
h->delayed_ref_updates = 0;
h->alloc_exclude_start = 0;
h->delayed_ref_updates = 0;
- if (!current->journal_info)
+ if (!current->journal_info
&& type != TRANS_USERSPACE
)
current->journal_info = h;
root->fs_info->running_transaction->use_count++;
current->journal_info = h;
root->fs_info->running_transaction->use_count++;
@@
-198,18
+205,18
@@
static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
int num_blocks)
{
struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
int num_blocks)
{
- return start_transaction(root, num_blocks,
1
);
+ return start_transaction(root, num_blocks,
TRANS_START
);
}
struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root,
int num_blocks)
{
}
struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root,
int num_blocks)
{
- return start_transaction(root, num_blocks,
0
);
+ return start_transaction(root, num_blocks,
TRANS_JOIN
);
}
struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *r,
int num_blocks)
{
}
struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *r,
int num_blocks)
{
- return start_transaction(r, num_blocks,
2
);
+ return start_transaction(r, num_blocks,
TRANS_USERSPACE
);
}
/* wait for a transaction commit to be fully complete */
}
/* wait for a transaction commit to be fully complete */
@@
-326,6
+333,9
@@
static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
memset(trans, 0, sizeof(*trans));
kmem_cache_free(btrfs_trans_handle_cachep, trans);
memset(trans, 0, sizeof(*trans));
kmem_cache_free(btrfs_trans_handle_cachep, trans);
+ if (throttle)
+ btrfs_run_delayed_iputs(root);
+
return 0;
}
return 0;
}
@@
-347,7
+357,7
@@
int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans,
* those extents are sent to disk but does not wait on them
*/
int btrfs_write_marked_extents(struct btrfs_root *root,
* those extents are sent to disk but does not wait on them
*/
int btrfs_write_marked_extents(struct btrfs_root *root,
- struct extent_io_tree *dirty_pages)
+ struct extent_io_tree *dirty_pages
, int mark
)
{
int ret;
int err = 0;
{
int ret;
int err = 0;
@@
-360,7
+370,7
@@
int btrfs_write_marked_extents(struct btrfs_root *root,
while (1) {
ret = find_first_extent_bit(dirty_pages, start, &start, &end,
while (1) {
ret = find_first_extent_bit(dirty_pages, start, &start, &end,
-
EXTENT_DIRTY
);
+
mark
);
if (ret)
break;
while (start <= end) {
if (ret)
break;
while (start <= end) {
@@
-406,7
+416,7
@@
int btrfs_write_marked_extents(struct btrfs_root *root,
* on all the pages and clear them from the dirty pages state tree
*/
int btrfs_wait_marked_extents(struct btrfs_root *root,
* on all the pages and clear them from the dirty pages state tree
*/
int btrfs_wait_marked_extents(struct btrfs_root *root,
- struct extent_io_tree *dirty_pages)
+ struct extent_io_tree *dirty_pages
, int mark
)
{
int ret;
int err = 0;
{
int ret;
int err = 0;
@@
-418,12
+428,12
@@
int btrfs_wait_marked_extents(struct btrfs_root *root,
unsigned long index;
while (1) {
unsigned long index;
while (1) {
- ret = find_first_extent_bit(dirty_pages,
0
, &start, &end,
-
EXTENT_DIRTY
);
+ ret = find_first_extent_bit(dirty_pages,
start
, &start, &end,
+
mark
);
if (ret)
break;
if (ret)
break;
- clear_extent_
dirty(dirty_pages, start, end
, GFP_NOFS);
+ clear_extent_
bits(dirty_pages, start, end, mark
, GFP_NOFS);
while (start <= end) {
index = start >> PAGE_CACHE_SHIFT;
start = (u64)(index + 1) << PAGE_CACHE_SHIFT;
while (start <= end) {
index = start >> PAGE_CACHE_SHIFT;
start = (u64)(index + 1) << PAGE_CACHE_SHIFT;
@@
-453,13
+463,13
@@
int btrfs_wait_marked_extents(struct btrfs_root *root,
* those extents are on disk for transaction or log commit
*/
int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
* those extents are on disk for transaction or log commit
*/
int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
-
struct extent_io_tree *dirty_pages
)
+
struct extent_io_tree *dirty_pages, int mark
)
{
int ret;
int ret2;
{
int ret;
int ret2;
- ret = btrfs_write_marked_extents(root, dirty_pages);
- ret2 = btrfs_wait_marked_extents(root, dirty_pages);
+ ret = btrfs_write_marked_extents(root, dirty_pages
, mark
);
+ ret2 = btrfs_wait_marked_extents(root, dirty_pages
, mark
);
return ret || ret2;
}
return ret || ret2;
}
@@
-472,7
+482,8
@@
int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
return filemap_write_and_wait(btree_inode->i_mapping);
}
return btrfs_write_and_wait_marked_extents(root,
return filemap_write_and_wait(btree_inode->i_mapping);
}
return btrfs_write_and_wait_marked_extents(root,
- &trans->transaction->dirty_pages);
+ &trans->transaction->dirty_pages,
+ EXTENT_DIRTY);
}
/*
}
/*
@@
-788,7
+799,6
@@
static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
memcpy(&pending->root_key, &key, sizeof(key));
fail:
kfree(new_root_item);
memcpy(&pending->root_key, &key, sizeof(key));
fail:
kfree(new_root_item);
- btrfs_unreserve_metadata_space(root, 6);
return ret;
}
return ret;
}
@@
-800,7
+810,6
@@
static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info,
u64 index = 0;
struct btrfs_trans_handle *trans;
struct inode *parent_inode;
u64 index = 0;
struct btrfs_trans_handle *trans;
struct inode *parent_inode;
- struct inode *inode;
struct btrfs_root *parent_root;
parent_inode = pending->dentry->d_parent->d_inode;
struct btrfs_root *parent_root;
parent_inode = pending->dentry->d_parent->d_inode;
@@
-832,8
+841,6
@@
static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info,
BUG_ON(ret);
BUG_ON(ret);
- inode = btrfs_lookup_dentry(parent_inode, pending->dentry);
- d_instantiate(pending->dentry, inode);
fail:
btrfs_end_transaction(trans, fs_info->fs_root);
return ret;
fail:
btrfs_end_transaction(trans, fs_info->fs_root);
return ret;
@@
-987,11
+994,11
@@
int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
mutex_unlock(&root->fs_info->trans_mutex);
if (flush_on_commit) {
mutex_unlock(&root->fs_info->trans_mutex);
if (flush_on_commit) {
- btrfs_start_delalloc_inodes(root);
- ret = btrfs_wait_ordered_extents(root, 0);
+ btrfs_start_delalloc_inodes(root
, 1
);
+ ret = btrfs_wait_ordered_extents(root, 0
, 1
);
BUG_ON(ret);
} else if (snap_pending) {
BUG_ON(ret);
} else if (snap_pending) {
- ret = btrfs_wait_ordered_extents(root, 1);
+ ret = btrfs_wait_ordered_extents(root,
0,
1);
BUG_ON(ret);
}
BUG_ON(ret);
}
@@
-1109,6
+1116,10
@@
int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
current->journal_info = NULL;
kmem_cache_free(btrfs_trans_handle_cachep, trans);
current->journal_info = NULL;
kmem_cache_free(btrfs_trans_handle_cachep, trans);
+
+ if (current != root->fs_info->transaction_kthread)
+ btrfs_run_delayed_iputs(root);
+
return ret;
}
return ret;
}