diff options
author | Josef Bacik <josef@redhat.com> | 2012-01-13 12:09:22 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2012-01-16 15:29:43 -0500 |
commit | f248679e86fead40cc78e724c7181d6bec1a2046 (patch) | |
tree | 88abeee0b2a87c0f0377509525c92d3c9ec15a15 /fs | |
parent | 8c2a3ca20f6233677ac3222c6506174010eb414f (diff) |
Btrfs: add a delalloc mutex to inodes for delalloc reservations
I was using i_mutex for this, but we're getting bogus lockdep warnings by doing
that and theres no real way to get rid of those, so just stop using i_mutex to
protect delalloc metadata reservations and use a delalloc mutex instead. This
shouldn't be contended often at all, only if you are writing and mmap writing to
the file at the same time. Thanks,
Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/btrfs_inode.h | 3 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 5 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 11 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 2 | ||||
-rw-r--r-- | fs/btrfs/relocation.c | 2 |
5 files changed, 7 insertions, 16 deletions
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index 634608d2a6d0..9b9b15fd5204 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h | |||
@@ -51,6 +51,9 @@ struct btrfs_inode { | |||
51 | /* held while logging the inode in tree-log.c */ | 51 | /* held while logging the inode in tree-log.c */ |
52 | struct mutex log_mutex; | 52 | struct mutex log_mutex; |
53 | 53 | ||
54 | /* held while doing delalloc reservations */ | ||
55 | struct mutex delalloc_mutex; | ||
56 | |||
54 | /* used to order data wrt metadata */ | 57 | /* used to order data wrt metadata */ |
55 | struct btrfs_ordered_inode_tree ordered_tree; | 58 | struct btrfs_ordered_inode_tree ordered_tree; |
56 | 59 | ||
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 556f9aa25bb7..e0ad5f0f895e 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -4345,12 +4345,11 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) | |||
4345 | /* Need to be holding the i_mutex here if we aren't free space cache */ | 4345 | /* Need to be holding the i_mutex here if we aren't free space cache */ |
4346 | if (btrfs_is_free_space_inode(root, inode)) | 4346 | if (btrfs_is_free_space_inode(root, inode)) |
4347 | flush = 0; | 4347 | flush = 0; |
4348 | else | ||
4349 | WARN_ON(!mutex_is_locked(&inode->i_mutex)); | ||
4350 | 4348 | ||
4351 | if (flush && btrfs_transaction_in_commit(root->fs_info)) | 4349 | if (flush && btrfs_transaction_in_commit(root->fs_info)) |
4352 | schedule_timeout(1); | 4350 | schedule_timeout(1); |
4353 | 4351 | ||
4352 | mutex_lock(&BTRFS_I(inode)->delalloc_mutex); | ||
4354 | num_bytes = ALIGN(num_bytes, root->sectorsize); | 4353 | num_bytes = ALIGN(num_bytes, root->sectorsize); |
4355 | 4354 | ||
4356 | spin_lock(&BTRFS_I(inode)->lock); | 4355 | spin_lock(&BTRFS_I(inode)->lock); |
@@ -4405,6 +4404,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) | |||
4405 | btrfs_ino(inode), | 4404 | btrfs_ino(inode), |
4406 | to_free, 0); | 4405 | to_free, 0); |
4407 | } | 4406 | } |
4407 | mutex_unlock(&BTRFS_I(inode)->delalloc_mutex); | ||
4408 | return ret; | 4408 | return ret; |
4409 | } | 4409 | } |
4410 | 4410 | ||
@@ -4415,6 +4415,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) | |||
4415 | } | 4415 | } |
4416 | BTRFS_I(inode)->reserved_extents += nr_extents; | 4416 | BTRFS_I(inode)->reserved_extents += nr_extents; |
4417 | spin_unlock(&BTRFS_I(inode)->lock); | 4417 | spin_unlock(&BTRFS_I(inode)->lock); |
4418 | mutex_unlock(&BTRFS_I(inode)->delalloc_mutex); | ||
4418 | 4419 | ||
4419 | if (to_reserve) | 4420 | if (to_reserve) |
4420 | trace_btrfs_space_reservation(root->fs_info,"delalloc", | 4421 | trace_btrfs_space_reservation(root->fs_info,"delalloc", |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 619742d37166..5977987abdb1 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -2239,14 +2239,7 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) | |||
2239 | continue; | 2239 | continue; |
2240 | } | 2240 | } |
2241 | nr_truncate++; | 2241 | nr_truncate++; |
2242 | /* | ||
2243 | * Need to hold the imutex for reservation purposes, not | ||
2244 | * a huge deal here but I have a WARN_ON in | ||
2245 | * btrfs_delalloc_reserve_space to catch offenders. | ||
2246 | */ | ||
2247 | mutex_lock(&inode->i_mutex); | ||
2248 | ret = btrfs_truncate(inode); | 2242 | ret = btrfs_truncate(inode); |
2249 | mutex_unlock(&inode->i_mutex); | ||
2250 | } else { | 2243 | } else { |
2251 | nr_unlink++; | 2244 | nr_unlink++; |
2252 | } | 2245 | } |
@@ -6411,10 +6404,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
6411 | u64 page_start; | 6404 | u64 page_start; |
6412 | u64 page_end; | 6405 | u64 page_end; |
6413 | 6406 | ||
6414 | /* Need this to keep space reservations serialized */ | ||
6415 | mutex_lock(&inode->i_mutex); | ||
6416 | ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); | 6407 | ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); |
6417 | mutex_unlock(&inode->i_mutex); | ||
6418 | if (!ret) | 6408 | if (!ret) |
6419 | ret = btrfs_update_time(vma->vm_file); | 6409 | ret = btrfs_update_time(vma->vm_file); |
6420 | if (ret) { | 6410 | if (ret) { |
@@ -6758,6 +6748,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) | |||
6758 | extent_io_tree_init(&ei->io_tree, &inode->i_data); | 6748 | extent_io_tree_init(&ei->io_tree, &inode->i_data); |
6759 | extent_io_tree_init(&ei->io_failure_tree, &inode->i_data); | 6749 | extent_io_tree_init(&ei->io_failure_tree, &inode->i_data); |
6760 | mutex_init(&ei->log_mutex); | 6750 | mutex_init(&ei->log_mutex); |
6751 | mutex_init(&ei->delalloc_mutex); | ||
6761 | btrfs_ordered_inode_tree_init(&ei->ordered_tree); | 6752 | btrfs_ordered_inode_tree_init(&ei->ordered_tree); |
6762 | INIT_LIST_HEAD(&ei->i_orphan); | 6753 | INIT_LIST_HEAD(&ei->i_orphan); |
6763 | INIT_LIST_HEAD(&ei->delalloc_inodes); | 6754 | INIT_LIST_HEAD(&ei->delalloc_inodes); |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 7fdf22c2dc0d..6834be4c8709 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -868,10 +868,8 @@ static int cluster_pages_for_defrag(struct inode *inode, | |||
868 | return 0; | 868 | return 0; |
869 | file_end = (isize - 1) >> PAGE_CACHE_SHIFT; | 869 | file_end = (isize - 1) >> PAGE_CACHE_SHIFT; |
870 | 870 | ||
871 | mutex_lock(&inode->i_mutex); | ||
872 | ret = btrfs_delalloc_reserve_space(inode, | 871 | ret = btrfs_delalloc_reserve_space(inode, |
873 | num_pages << PAGE_CACHE_SHIFT); | 872 | num_pages << PAGE_CACHE_SHIFT); |
874 | mutex_unlock(&inode->i_mutex); | ||
875 | if (ret) | 873 | if (ret) |
876 | return ret; | 874 | return ret; |
877 | again: | 875 | again: |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index efe9f792544d..8c1aae2c845d 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -2949,9 +2949,7 @@ static int relocate_file_extent_cluster(struct inode *inode, | |||
2949 | index = (cluster->start - offset) >> PAGE_CACHE_SHIFT; | 2949 | index = (cluster->start - offset) >> PAGE_CACHE_SHIFT; |
2950 | last_index = (cluster->end - offset) >> PAGE_CACHE_SHIFT; | 2950 | last_index = (cluster->end - offset) >> PAGE_CACHE_SHIFT; |
2951 | while (index <= last_index) { | 2951 | while (index <= last_index) { |
2952 | mutex_lock(&inode->i_mutex); | ||
2953 | ret = btrfs_delalloc_reserve_metadata(inode, PAGE_CACHE_SIZE); | 2952 | ret = btrfs_delalloc_reserve_metadata(inode, PAGE_CACHE_SIZE); |
2954 | mutex_unlock(&inode->i_mutex); | ||
2955 | if (ret) | 2953 | if (ret) |
2956 | goto out; | 2954 | goto out; |
2957 | 2955 | ||