diff options
Diffstat (limited to 'fs/nfs/file.c')
-rw-r--r-- | fs/nfs/file.c | 40 |
1 files changed, 17 insertions, 23 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index b3bb89f7d5d2..ef57a5ae5904 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -349,7 +349,9 @@ static int nfs_write_end(struct file *file, struct address_space *mapping, | |||
349 | unlock_page(page); | 349 | unlock_page(page); |
350 | page_cache_release(page); | 350 | page_cache_release(page); |
351 | 351 | ||
352 | return status < 0 ? status : copied; | 352 | if (status < 0) |
353 | return status; | ||
354 | return copied; | ||
353 | } | 355 | } |
354 | 356 | ||
355 | static void nfs_invalidate_page(struct page *page, unsigned long offset) | 357 | static void nfs_invalidate_page(struct page *page, unsigned long offset) |
@@ -392,35 +394,27 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page) | |||
392 | struct file *filp = vma->vm_file; | 394 | struct file *filp = vma->vm_file; |
393 | unsigned pagelen; | 395 | unsigned pagelen; |
394 | int ret = -EINVAL; | 396 | int ret = -EINVAL; |
395 | void *fsdata; | ||
396 | struct address_space *mapping; | 397 | struct address_space *mapping; |
397 | loff_t offset; | ||
398 | 398 | ||
399 | lock_page(page); | 399 | lock_page(page); |
400 | mapping = page->mapping; | 400 | mapping = page->mapping; |
401 | if (mapping != vma->vm_file->f_path.dentry->d_inode->i_mapping) { | 401 | if (mapping != vma->vm_file->f_path.dentry->d_inode->i_mapping) |
402 | unlock_page(page); | 402 | goto out_unlock; |
403 | return -EINVAL; | 403 | |
404 | } | 404 | ret = 0; |
405 | pagelen = nfs_page_length(page); | 405 | pagelen = nfs_page_length(page); |
406 | offset = (loff_t)page->index << PAGE_CACHE_SHIFT; | 406 | if (pagelen == 0) |
407 | unlock_page(page); | 407 | goto out_unlock; |
408 | 408 | ||
409 | /* | 409 | ret = nfs_flush_incompatible(filp, page); |
410 | * we can use mapping after releasing the page lock, because: | 410 | if (ret != 0) |
411 | * we hold mmap_sem on the fault path, which should pin the vma | 411 | goto out_unlock; |
412 | * which should pin the file, which pins the dentry which should | ||
413 | * hold a reference on inode. | ||
414 | */ | ||
415 | 412 | ||
416 | if (pagelen) { | 413 | ret = nfs_updatepage(filp, page, 0, pagelen); |
417 | struct page *page2 = NULL; | 414 | if (ret == 0) |
418 | ret = nfs_write_begin(filp, mapping, offset, pagelen, | 415 | ret = pagelen; |
419 | 0, &page2, &fsdata); | 416 | out_unlock: |
420 | if (!ret) | 417 | unlock_page(page); |
421 | ret = nfs_write_end(filp, mapping, offset, pagelen, | ||
422 | pagelen, page2, fsdata); | ||
423 | } | ||
424 | return ret; | 418 | return ret; |
425 | } | 419 | } |
426 | 420 | ||