diff options
author | Chris Mason <chris.mason@oracle.com> | 2012-01-25 13:47:40 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2012-01-27 10:44:44 -0500 |
commit | 9998eb703490589c3e8f1bf09b15203156776edb (patch) | |
tree | 5d01f0e7efae049b9be80292c93fe30f11eeefd1 /fs/btrfs/inode.c | |
parent | 9b23062840e7c685ef0a0b561285d6e3a3b6811b (diff) |
Btrfs: fix reservations in btrfs_page_mkwrite
Josef fixed btrfs_page_mkwrite to properly release reserved
extents if there was an error. But if we fail to get a reservation
and we fail to dirty the inode (for ENOSPC reasons), we'll end up
trying to release a reservation we never had.
This makes sure we only release if we were able to reserve.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 5977987abdb1..7405753ec5d7 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -6401,18 +6401,23 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
6401 | unsigned long zero_start; | 6401 | unsigned long zero_start; |
6402 | loff_t size; | 6402 | loff_t size; |
6403 | int ret; | 6403 | int ret; |
6404 | int reserved = 0; | ||
6404 | u64 page_start; | 6405 | u64 page_start; |
6405 | u64 page_end; | 6406 | u64 page_end; |
6406 | 6407 | ||
6407 | ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); | 6408 | ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); |
6408 | if (!ret) | 6409 | if (!ret) { |
6409 | ret = btrfs_update_time(vma->vm_file); | 6410 | ret = btrfs_update_time(vma->vm_file); |
6411 | reserved = 1; | ||
6412 | } | ||
6410 | if (ret) { | 6413 | if (ret) { |
6411 | if (ret == -ENOMEM) | 6414 | if (ret == -ENOMEM) |
6412 | ret = VM_FAULT_OOM; | 6415 | ret = VM_FAULT_OOM; |
6413 | else /* -ENOSPC, -EIO, etc */ | 6416 | else /* -ENOSPC, -EIO, etc */ |
6414 | ret = VM_FAULT_SIGBUS; | 6417 | ret = VM_FAULT_SIGBUS; |
6415 | goto out; | 6418 | if (reserved) |
6419 | goto out; | ||
6420 | goto out_noreserve; | ||
6416 | } | 6421 | } |
6417 | 6422 | ||
6418 | ret = VM_FAULT_NOPAGE; /* make the VM retry the fault */ | 6423 | ret = VM_FAULT_NOPAGE; /* make the VM retry the fault */ |
@@ -6495,6 +6500,7 @@ out_unlock: | |||
6495 | unlock_page(page); | 6500 | unlock_page(page); |
6496 | out: | 6501 | out: |
6497 | btrfs_delalloc_release_space(inode, PAGE_CACHE_SIZE); | 6502 | btrfs_delalloc_release_space(inode, PAGE_CACHE_SIZE); |
6503 | out_noreserve: | ||
6498 | return ret; | 6504 | return ret; |
6499 | } | 6505 | } |
6500 | 6506 | ||