[PATCH 1/7] dax: A couple of fixes from Dave Chinner

From: Matthew Wilcox
Date: Wed Sep 10 2014 - 13:19:22 EST


If dax_clear_blocks() returns an error, segfault.

Don't bother calling get_block() again if the BH is unwritten; the block
is already allocated, and this won't help matters.

Call b_end_io() if it's set, after zeroing the block, enabling the fs
to convert the block from unwritten to written.

Signed-off-by: Matthew Wilcox <willy@xxxxxxxxxxxxxxx>
---
fs/dax.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/fs/dax.c b/fs/dax.c
index bdf6622..90418ca 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -327,7 +327,7 @@ static int do_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
if (error)
goto unlock_page;

- if (!buffer_written(&bh) && !vmf->cow_page) {
+ if (!buffer_mapped(&bh) && !vmf->cow_page) {
if (vmf->flags & FAULT_FLAG_WRITE) {
error = get_block(inode, block, &bh, 1);
count_vm_event(PGMAJFAULT);
@@ -364,8 +364,13 @@ static int do_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
return VM_FAULT_LOCKED;
}

- if (buffer_unwritten(&bh) || buffer_new(&bh))
- dax_clear_blocks(inode, bh.b_blocknr, bh.b_size);
+ if (buffer_unwritten(&bh) || buffer_new(&bh)) {
+ error = dax_clear_blocks(inode, bh.b_blocknr, bh.b_size);
+ if (error)
+ goto out;
+ if (bh.b_end_io)
+ bh.b_end_io(&bh, 1);
+ }

/* Check we didn't race with a read fault installing a new page */
if (!page && major)
--
2.1.0


--cNdxnHkX5QqsyA0e
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0002-dax-Missing-unlock-in-error-path.patch"