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 | |
| 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>
| -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 | ||
