diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-01-03 13:46:11 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:58 -0400 |
commit | 5b92ee7204a5fb6542b204831202adbc1a7a851a (patch) | |
tree | ae4b52c53d6f59d8844e24dd109f2f5b39827b78 /fs | |
parent | bd09835d9aad9c7b664cddc8435cc37b86077971 (diff) | |
download | op-kernel-dev-5b92ee7204a5fb6542b204831202adbc1a7a851a.zip op-kernel-dev-5b92ee7204a5fb6542b204831202adbc1a7a851a.tar.gz |
Btrfs: Fix lock ordering of the snapshot semaphore against the page lock
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/file.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index c9ebd4f..e862292 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -251,7 +251,6 @@ static int noinline dirty_and_release_pages(struct btrfs_trans_handle *trans, num_bytes = (write_bytes + pos - start_pos + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); - down_read(&BTRFS_I(inode)->root->snap_sem); end_of_last_block = start_pos + num_bytes - 1; lock_extent(em_tree, start_pos, end_of_last_block, GFP_NOFS); @@ -356,7 +355,6 @@ out_unlock: mutex_unlock(&root->fs_info->fs_mutex); unlock_extent(em_tree, start_pos, end_of_last_block, GFP_NOFS); free_extent_map(em); - up_read(&BTRFS_I(inode)->root->snap_sem); return err; } @@ -726,6 +724,8 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL); + down_read(&BTRFS_I(inode)->root->snap_sem); + mutex_lock(&inode->i_mutex); first_index = pos >> PAGE_CACHE_SHIFT; last_index = (pos + count) >> PAGE_CACHE_SHIFT; @@ -804,6 +804,8 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, } out: mutex_unlock(&inode->i_mutex); + up_read(&BTRFS_I(inode)->root->snap_sem); + out_nolock: kfree(pages); if (pinned[0]) |