diff options
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 307 |
1 files changed, 147 insertions, 160 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index f333848fd3be..feca8c648766 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -34,9 +34,6 @@ | |||
34 | /* | 34 | /* |
35 | * Local function declarations | 35 | * Local function declarations |
36 | */ | 36 | */ |
37 | static struct nfs_page * nfs_update_request(struct nfs_open_context*, | ||
38 | struct page *, | ||
39 | unsigned int, unsigned int); | ||
40 | static void nfs_pageio_init_write(struct nfs_pageio_descriptor *desc, | 37 | static void nfs_pageio_init_write(struct nfs_pageio_descriptor *desc, |
41 | struct inode *inode, int ioflags); | 38 | struct inode *inode, int ioflags); |
42 | static void nfs_redirty_request(struct nfs_page *req); | 39 | static void nfs_redirty_request(struct nfs_page *req); |
@@ -169,29 +166,6 @@ static void nfs_mark_uptodate(struct page *page, unsigned int base, unsigned int | |||
169 | SetPageUptodate(page); | 166 | SetPageUptodate(page); |
170 | } | 167 | } |
171 | 168 | ||
172 | static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page, | ||
173 | unsigned int offset, unsigned int count) | ||
174 | { | ||
175 | struct nfs_page *req; | ||
176 | int ret; | ||
177 | |||
178 | for (;;) { | ||
179 | req = nfs_update_request(ctx, page, offset, count); | ||
180 | if (!IS_ERR(req)) | ||
181 | break; | ||
182 | ret = PTR_ERR(req); | ||
183 | if (ret != -EBUSY) | ||
184 | return ret; | ||
185 | ret = nfs_wb_page(page->mapping->host, page); | ||
186 | if (ret != 0) | ||
187 | return ret; | ||
188 | } | ||
189 | /* Update file length */ | ||
190 | nfs_grow_file(page, offset, count); | ||
191 | nfs_clear_page_tag_locked(req); | ||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static int wb_priority(struct writeback_control *wbc) | 169 | static int wb_priority(struct writeback_control *wbc) |
196 | { | 170 | { |
197 | if (wbc->for_reclaim) | 171 | if (wbc->for_reclaim) |
@@ -268,12 +242,9 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio, | |||
268 | return ret; | 242 | return ret; |
269 | spin_lock(&inode->i_lock); | 243 | spin_lock(&inode->i_lock); |
270 | } | 244 | } |
271 | if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) { | 245 | if (test_bit(PG_CLEAN, &req->wb_flags)) { |
272 | /* This request is marked for commit */ | ||
273 | spin_unlock(&inode->i_lock); | 246 | spin_unlock(&inode->i_lock); |
274 | nfs_clear_page_tag_locked(req); | 247 | BUG(); |
275 | nfs_pageio_complete(pgio); | ||
276 | return 0; | ||
277 | } | 248 | } |
278 | if (nfs_set_page_writeback(page) != 0) { | 249 | if (nfs_set_page_writeback(page) != 0) { |
279 | spin_unlock(&inode->i_lock); | 250 | spin_unlock(&inode->i_lock); |
@@ -355,11 +326,19 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) | |||
355 | /* | 326 | /* |
356 | * Insert a write request into an inode | 327 | * Insert a write request into an inode |
357 | */ | 328 | */ |
358 | static void nfs_inode_add_request(struct inode *inode, struct nfs_page *req) | 329 | static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) |
359 | { | 330 | { |
360 | struct nfs_inode *nfsi = NFS_I(inode); | 331 | struct nfs_inode *nfsi = NFS_I(inode); |
361 | int error; | 332 | int error; |
362 | 333 | ||
334 | error = radix_tree_preload(GFP_NOFS); | ||
335 | if (error != 0) | ||
336 | goto out; | ||
337 | |||
338 | /* Lock the request! */ | ||
339 | nfs_lock_request_dontget(req); | ||
340 | |||
341 | spin_lock(&inode->i_lock); | ||
363 | error = radix_tree_insert(&nfsi->nfs_page_tree, req->wb_index, req); | 342 | error = radix_tree_insert(&nfsi->nfs_page_tree, req->wb_index, req); |
364 | BUG_ON(error); | 343 | BUG_ON(error); |
365 | if (!nfsi->npages) { | 344 | if (!nfsi->npages) { |
@@ -373,6 +352,10 @@ static void nfs_inode_add_request(struct inode *inode, struct nfs_page *req) | |||
373 | kref_get(&req->wb_kref); | 352 | kref_get(&req->wb_kref); |
374 | radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, | 353 | radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, |
375 | NFS_PAGE_TAG_LOCKED); | 354 | NFS_PAGE_TAG_LOCKED); |
355 | spin_unlock(&inode->i_lock); | ||
356 | radix_tree_preload_end(); | ||
357 | out: | ||
358 | return error; | ||
376 | } | 359 | } |
377 | 360 | ||
378 | /* | 361 | /* |
@@ -405,19 +388,6 @@ nfs_mark_request_dirty(struct nfs_page *req) | |||
405 | __set_page_dirty_nobuffers(req->wb_page); | 388 | __set_page_dirty_nobuffers(req->wb_page); |
406 | } | 389 | } |
407 | 390 | ||
408 | /* | ||
409 | * Check if a request is dirty | ||
410 | */ | ||
411 | static inline int | ||
412 | nfs_dirty_request(struct nfs_page *req) | ||
413 | { | ||
414 | struct page *page = req->wb_page; | ||
415 | |||
416 | if (page == NULL || test_bit(PG_NEED_COMMIT, &req->wb_flags)) | ||
417 | return 0; | ||
418 | return !PageWriteback(page); | ||
419 | } | ||
420 | |||
421 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 391 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
422 | /* | 392 | /* |
423 | * Add a request to the inode's commit list. | 393 | * Add a request to the inode's commit list. |
@@ -430,7 +400,7 @@ nfs_mark_request_commit(struct nfs_page *req) | |||
430 | 400 | ||
431 | spin_lock(&inode->i_lock); | 401 | spin_lock(&inode->i_lock); |
432 | nfsi->ncommit++; | 402 | nfsi->ncommit++; |
433 | set_bit(PG_NEED_COMMIT, &(req)->wb_flags); | 403 | set_bit(PG_CLEAN, &(req)->wb_flags); |
434 | radix_tree_tag_set(&nfsi->nfs_page_tree, | 404 | radix_tree_tag_set(&nfsi->nfs_page_tree, |
435 | req->wb_index, | 405 | req->wb_index, |
436 | NFS_PAGE_TAG_COMMIT); | 406 | NFS_PAGE_TAG_COMMIT); |
@@ -440,6 +410,19 @@ nfs_mark_request_commit(struct nfs_page *req) | |||
440 | __mark_inode_dirty(inode, I_DIRTY_DATASYNC); | 410 | __mark_inode_dirty(inode, I_DIRTY_DATASYNC); |
441 | } | 411 | } |
442 | 412 | ||
413 | static int | ||
414 | nfs_clear_request_commit(struct nfs_page *req) | ||
415 | { | ||
416 | struct page *page = req->wb_page; | ||
417 | |||
418 | if (test_and_clear_bit(PG_CLEAN, &(req)->wb_flags)) { | ||
419 | dec_zone_page_state(page, NR_UNSTABLE_NFS); | ||
420 | dec_bdi_stat(page->mapping->backing_dev_info, BDI_RECLAIMABLE); | ||
421 | return 1; | ||
422 | } | ||
423 | return 0; | ||
424 | } | ||
425 | |||
443 | static inline | 426 | static inline |
444 | int nfs_write_need_commit(struct nfs_write_data *data) | 427 | int nfs_write_need_commit(struct nfs_write_data *data) |
445 | { | 428 | { |
@@ -449,7 +432,7 @@ int nfs_write_need_commit(struct nfs_write_data *data) | |||
449 | static inline | 432 | static inline |
450 | int nfs_reschedule_unstable_write(struct nfs_page *req) | 433 | int nfs_reschedule_unstable_write(struct nfs_page *req) |
451 | { | 434 | { |
452 | if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) { | 435 | if (test_and_clear_bit(PG_NEED_COMMIT, &req->wb_flags)) { |
453 | nfs_mark_request_commit(req); | 436 | nfs_mark_request_commit(req); |
454 | return 1; | 437 | return 1; |
455 | } | 438 | } |
@@ -465,6 +448,12 @@ nfs_mark_request_commit(struct nfs_page *req) | |||
465 | { | 448 | { |
466 | } | 449 | } |
467 | 450 | ||
451 | static inline int | ||
452 | nfs_clear_request_commit(struct nfs_page *req) | ||
453 | { | ||
454 | return 0; | ||
455 | } | ||
456 | |||
468 | static inline | 457 | static inline |
469 | int nfs_write_need_commit(struct nfs_write_data *data) | 458 | int nfs_write_need_commit(struct nfs_write_data *data) |
470 | { | 459 | { |
@@ -522,11 +511,8 @@ static void nfs_cancel_commit_list(struct list_head *head) | |||
522 | 511 | ||
523 | while(!list_empty(head)) { | 512 | while(!list_empty(head)) { |
524 | req = nfs_list_entry(head->next); | 513 | req = nfs_list_entry(head->next); |
525 | dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); | ||
526 | dec_bdi_stat(req->wb_page->mapping->backing_dev_info, | ||
527 | BDI_RECLAIMABLE); | ||
528 | nfs_list_remove_request(req); | 514 | nfs_list_remove_request(req); |
529 | clear_bit(PG_NEED_COMMIT, &(req)->wb_flags); | 515 | nfs_clear_request_commit(req); |
530 | nfs_inode_remove_request(req); | 516 | nfs_inode_remove_request(req); |
531 | nfs_unlock_request(req); | 517 | nfs_unlock_request(req); |
532 | } | 518 | } |
@@ -564,110 +550,124 @@ static inline int nfs_scan_commit(struct inode *inode, struct list_head *dst, pg | |||
564 | #endif | 550 | #endif |
565 | 551 | ||
566 | /* | 552 | /* |
567 | * Try to update any existing write request, or create one if there is none. | 553 | * Search for an existing write request, and attempt to update |
568 | * In order to match, the request's credentials must match those of | 554 | * it to reflect a new dirty region on a given page. |
569 | * the calling process. | ||
570 | * | 555 | * |
571 | * Note: Should always be called with the Page Lock held! | 556 | * If the attempt fails, then the existing request is flushed out |
557 | * to disk. | ||
572 | */ | 558 | */ |
573 | static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, | 559 | static struct nfs_page *nfs_try_to_update_request(struct inode *inode, |
574 | struct page *page, unsigned int offset, unsigned int bytes) | 560 | struct page *page, |
561 | unsigned int offset, | ||
562 | unsigned int bytes) | ||
575 | { | 563 | { |
576 | struct address_space *mapping = page->mapping; | 564 | struct nfs_page *req; |
577 | struct inode *inode = mapping->host; | 565 | unsigned int rqend; |
578 | struct nfs_page *req, *new = NULL; | 566 | unsigned int end; |
579 | pgoff_t rqend, end; | 567 | int error; |
568 | |||
569 | if (!PagePrivate(page)) | ||
570 | return NULL; | ||
580 | 571 | ||
581 | end = offset + bytes; | 572 | end = offset + bytes; |
573 | spin_lock(&inode->i_lock); | ||
582 | 574 | ||
583 | for (;;) { | 575 | for (;;) { |
584 | /* Loop over all inode entries and see if we find | 576 | req = nfs_page_find_request_locked(page); |
585 | * A request for the page we wish to update | 577 | if (req == NULL) |
578 | goto out_unlock; | ||
579 | |||
580 | rqend = req->wb_offset + req->wb_bytes; | ||
581 | /* | ||
582 | * Tell the caller to flush out the request if | ||
583 | * the offsets are non-contiguous. | ||
584 | * Note: nfs_flush_incompatible() will already | ||
585 | * have flushed out requests having wrong owners. | ||
586 | */ | 586 | */ |
587 | if (new) { | 587 | if (offset > rqend |
588 | if (radix_tree_preload(GFP_NOFS)) { | 588 | || end < req->wb_offset) |
589 | nfs_release_request(new); | 589 | goto out_flushme; |
590 | return ERR_PTR(-ENOMEM); | ||
591 | } | ||
592 | } | ||
593 | 590 | ||
594 | spin_lock(&inode->i_lock); | 591 | if (nfs_set_page_tag_locked(req)) |
595 | req = nfs_page_find_request_locked(page); | ||
596 | if (req) { | ||
597 | if (!nfs_set_page_tag_locked(req)) { | ||
598 | int error; | ||
599 | |||
600 | spin_unlock(&inode->i_lock); | ||
601 | error = nfs_wait_on_request(req); | ||
602 | nfs_release_request(req); | ||
603 | if (error < 0) { | ||
604 | if (new) { | ||
605 | radix_tree_preload_end(); | ||
606 | nfs_release_request(new); | ||
607 | } | ||
608 | return ERR_PTR(error); | ||
609 | } | ||
610 | continue; | ||
611 | } | ||
612 | spin_unlock(&inode->i_lock); | ||
613 | if (new) { | ||
614 | radix_tree_preload_end(); | ||
615 | nfs_release_request(new); | ||
616 | } | ||
617 | break; | 592 | break; |
618 | } | ||
619 | 593 | ||
620 | if (new) { | 594 | /* The request is locked, so wait and then retry */ |
621 | nfs_lock_request_dontget(new); | ||
622 | nfs_inode_add_request(inode, new); | ||
623 | spin_unlock(&inode->i_lock); | ||
624 | radix_tree_preload_end(); | ||
625 | req = new; | ||
626 | goto zero_page; | ||
627 | } | ||
628 | spin_unlock(&inode->i_lock); | 595 | spin_unlock(&inode->i_lock); |
629 | 596 | error = nfs_wait_on_request(req); | |
630 | new = nfs_create_request(ctx, inode, page, offset, bytes); | 597 | nfs_release_request(req); |
631 | if (IS_ERR(new)) | 598 | if (error != 0) |
632 | return new; | 599 | goto out_err; |
600 | spin_lock(&inode->i_lock); | ||
633 | } | 601 | } |
634 | 602 | ||
635 | /* We have a request for our page. | 603 | if (nfs_clear_request_commit(req)) |
636 | * If the creds don't match, or the | 604 | radix_tree_tag_clear(&NFS_I(inode)->nfs_page_tree, |
637 | * page addresses don't match, | 605 | req->wb_index, NFS_PAGE_TAG_COMMIT); |
638 | * tell the caller to wait on the conflicting | ||
639 | * request. | ||
640 | */ | ||
641 | rqend = req->wb_offset + req->wb_bytes; | ||
642 | if (req->wb_context != ctx | ||
643 | || req->wb_page != page | ||
644 | || !nfs_dirty_request(req) | ||
645 | || offset > rqend || end < req->wb_offset) { | ||
646 | nfs_clear_page_tag_locked(req); | ||
647 | return ERR_PTR(-EBUSY); | ||
648 | } | ||
649 | 606 | ||
650 | /* Okay, the request matches. Update the region */ | 607 | /* Okay, the request matches. Update the region */ |
651 | if (offset < req->wb_offset) { | 608 | if (offset < req->wb_offset) { |
652 | req->wb_offset = offset; | 609 | req->wb_offset = offset; |
653 | req->wb_pgbase = offset; | 610 | req->wb_pgbase = offset; |
654 | req->wb_bytes = max(end, rqend) - req->wb_offset; | ||
655 | goto zero_page; | ||
656 | } | 611 | } |
657 | |||
658 | if (end > rqend) | 612 | if (end > rqend) |
659 | req->wb_bytes = end - req->wb_offset; | 613 | req->wb_bytes = end - req->wb_offset; |
660 | 614 | else | |
615 | req->wb_bytes = rqend - req->wb_offset; | ||
616 | out_unlock: | ||
617 | spin_unlock(&inode->i_lock); | ||
661 | return req; | 618 | return req; |
662 | zero_page: | 619 | out_flushme: |
663 | /* If this page might potentially be marked as up to date, | 620 | spin_unlock(&inode->i_lock); |
664 | * then we need to zero any uninitalised data. */ | 621 | nfs_release_request(req); |
665 | if (req->wb_pgbase == 0 && req->wb_bytes != PAGE_CACHE_SIZE | 622 | error = nfs_wb_page(inode, page); |
666 | && !PageUptodate(req->wb_page)) | 623 | out_err: |
667 | zero_user_segment(req->wb_page, req->wb_bytes, PAGE_CACHE_SIZE); | 624 | return ERR_PTR(error); |
625 | } | ||
626 | |||
627 | /* | ||
628 | * Try to update an existing write request, or create one if there is none. | ||
629 | * | ||
630 | * Note: Should always be called with the Page Lock held to prevent races | ||
631 | * if we have to add a new request. Also assumes that the caller has | ||
632 | * already called nfs_flush_incompatible() if necessary. | ||
633 | */ | ||
634 | static struct nfs_page * nfs_setup_write_request(struct nfs_open_context* ctx, | ||
635 | struct page *page, unsigned int offset, unsigned int bytes) | ||
636 | { | ||
637 | struct inode *inode = page->mapping->host; | ||
638 | struct nfs_page *req; | ||
639 | int error; | ||
640 | |||
641 | req = nfs_try_to_update_request(inode, page, offset, bytes); | ||
642 | if (req != NULL) | ||
643 | goto out; | ||
644 | req = nfs_create_request(ctx, inode, page, offset, bytes); | ||
645 | if (IS_ERR(req)) | ||
646 | goto out; | ||
647 | error = nfs_inode_add_request(inode, req); | ||
648 | if (error != 0) { | ||
649 | nfs_release_request(req); | ||
650 | req = ERR_PTR(error); | ||
651 | } | ||
652 | out: | ||
668 | return req; | 653 | return req; |
669 | } | 654 | } |
670 | 655 | ||
656 | static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page, | ||
657 | unsigned int offset, unsigned int count) | ||
658 | { | ||
659 | struct nfs_page *req; | ||
660 | |||
661 | req = nfs_setup_write_request(ctx, page, offset, count); | ||
662 | if (IS_ERR(req)) | ||
663 | return PTR_ERR(req); | ||
664 | /* Update file length */ | ||
665 | nfs_grow_file(page, offset, count); | ||
666 | nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes); | ||
667 | nfs_clear_page_tag_locked(req); | ||
668 | return 0; | ||
669 | } | ||
670 | |||
671 | int nfs_flush_incompatible(struct file *file, struct page *page) | 671 | int nfs_flush_incompatible(struct file *file, struct page *page) |
672 | { | 672 | { |
673 | struct nfs_open_context *ctx = nfs_file_open_context(file); | 673 | struct nfs_open_context *ctx = nfs_file_open_context(file); |
@@ -685,8 +685,7 @@ int nfs_flush_incompatible(struct file *file, struct page *page) | |||
685 | req = nfs_page_find_request(page); | 685 | req = nfs_page_find_request(page); |
686 | if (req == NULL) | 686 | if (req == NULL) |
687 | return 0; | 687 | return 0; |
688 | do_flush = req->wb_page != page || req->wb_context != ctx | 688 | do_flush = req->wb_page != page || req->wb_context != ctx; |
689 | || !nfs_dirty_request(req); | ||
690 | nfs_release_request(req); | 689 | nfs_release_request(req); |
691 | if (!do_flush) | 690 | if (!do_flush) |
692 | return 0; | 691 | return 0; |
@@ -721,10 +720,10 @@ int nfs_updatepage(struct file *file, struct page *page, | |||
721 | 720 | ||
722 | nfs_inc_stats(inode, NFSIOS_VFSUPDATEPAGE); | 721 | nfs_inc_stats(inode, NFSIOS_VFSUPDATEPAGE); |
723 | 722 | ||
724 | dprintk("NFS: nfs_updatepage(%s/%s %d@%Ld)\n", | 723 | dprintk("NFS: nfs_updatepage(%s/%s %d@%lld)\n", |
725 | file->f_path.dentry->d_parent->d_name.name, | 724 | file->f_path.dentry->d_parent->d_name.name, |
726 | file->f_path.dentry->d_name.name, count, | 725 | file->f_path.dentry->d_name.name, count, |
727 | (long long)(page_offset(page) +offset)); | 726 | (long long)(page_offset(page) + offset)); |
728 | 727 | ||
729 | /* If we're not using byte range locks, and we know the page | 728 | /* If we're not using byte range locks, and we know the page |
730 | * is up to date, it may be more efficient to extend the write | 729 | * is up to date, it may be more efficient to extend the write |
@@ -744,7 +743,7 @@ int nfs_updatepage(struct file *file, struct page *page, | |||
744 | else | 743 | else |
745 | __set_page_dirty_nobuffers(page); | 744 | __set_page_dirty_nobuffers(page); |
746 | 745 | ||
747 | dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n", | 746 | dprintk("NFS: nfs_updatepage returns %d (isize %lld)\n", |
748 | status, (long long)i_size_read(inode)); | 747 | status, (long long)i_size_read(inode)); |
749 | return status; | 748 | return status; |
750 | } | 749 | } |
@@ -752,12 +751,7 @@ int nfs_updatepage(struct file *file, struct page *page, | |||
752 | static void nfs_writepage_release(struct nfs_page *req) | 751 | static void nfs_writepage_release(struct nfs_page *req) |
753 | { | 752 | { |
754 | 753 | ||
755 | if (PageError(req->wb_page)) { | 754 | if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req)) { |
756 | nfs_end_page_writeback(req->wb_page); | ||
757 | nfs_inode_remove_request(req); | ||
758 | } else if (!nfs_reschedule_unstable_write(req)) { | ||
759 | /* Set the PG_uptodate flag */ | ||
760 | nfs_mark_uptodate(req->wb_page, req->wb_pgbase, req->wb_bytes); | ||
761 | nfs_end_page_writeback(req->wb_page); | 755 | nfs_end_page_writeback(req->wb_page); |
762 | nfs_inode_remove_request(req); | 756 | nfs_inode_remove_request(req); |
763 | } else | 757 | } else |
@@ -834,7 +828,7 @@ static int nfs_write_rpcsetup(struct nfs_page *req, | |||
834 | NFS_PROTO(inode)->write_setup(data, &msg); | 828 | NFS_PROTO(inode)->write_setup(data, &msg); |
835 | 829 | ||
836 | dprintk("NFS: %5u initiated write call " | 830 | dprintk("NFS: %5u initiated write call " |
837 | "(req %s/%Ld, %u bytes @ offset %Lu)\n", | 831 | "(req %s/%lld, %u bytes @ offset %llu)\n", |
838 | data->task.tk_pid, | 832 | data->task.tk_pid, |
839 | inode->i_sb->s_id, | 833 | inode->i_sb->s_id, |
840 | (long long)NFS_FILEID(inode), | 834 | (long long)NFS_FILEID(inode), |
@@ -978,13 +972,13 @@ static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, | |||
978 | static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata) | 972 | static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata) |
979 | { | 973 | { |
980 | struct nfs_write_data *data = calldata; | 974 | struct nfs_write_data *data = calldata; |
981 | struct nfs_page *req = data->req; | ||
982 | 975 | ||
983 | dprintk("NFS: write (%s/%Ld %d@%Ld)", | 976 | dprintk("NFS: %5u write(%s/%lld %d@%lld)", |
984 | req->wb_context->path.dentry->d_inode->i_sb->s_id, | 977 | task->tk_pid, |
985 | (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode), | 978 | data->req->wb_context->path.dentry->d_inode->i_sb->s_id, |
986 | req->wb_bytes, | 979 | (long long) |
987 | (long long)req_offset(req)); | 980 | NFS_FILEID(data->req->wb_context->path.dentry->d_inode), |
981 | data->req->wb_bytes, (long long)req_offset(data->req)); | ||
988 | 982 | ||
989 | nfs_writeback_done(task, data); | 983 | nfs_writeback_done(task, data); |
990 | } | 984 | } |
@@ -1058,7 +1052,8 @@ static void nfs_writeback_release_full(void *calldata) | |||
1058 | 1052 | ||
1059 | nfs_list_remove_request(req); | 1053 | nfs_list_remove_request(req); |
1060 | 1054 | ||
1061 | dprintk("NFS: write (%s/%Ld %d@%Ld)", | 1055 | dprintk("NFS: %5u write (%s/%lld %d@%lld)", |
1056 | data->task.tk_pid, | ||
1062 | req->wb_context->path.dentry->d_inode->i_sb->s_id, | 1057 | req->wb_context->path.dentry->d_inode->i_sb->s_id, |
1063 | (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode), | 1058 | (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode), |
1064 | req->wb_bytes, | 1059 | req->wb_bytes, |
@@ -1078,8 +1073,6 @@ static void nfs_writeback_release_full(void *calldata) | |||
1078 | dprintk(" marked for commit\n"); | 1073 | dprintk(" marked for commit\n"); |
1079 | goto next; | 1074 | goto next; |
1080 | } | 1075 | } |
1081 | /* Set the PG_uptodate flag? */ | ||
1082 | nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes); | ||
1083 | dprintk(" OK\n"); | 1076 | dprintk(" OK\n"); |
1084 | remove_request: | 1077 | remove_request: |
1085 | nfs_end_page_writeback(page); | 1078 | nfs_end_page_writeback(page); |
@@ -1133,7 +1126,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data) | |||
1133 | static unsigned long complain; | 1126 | static unsigned long complain; |
1134 | 1127 | ||
1135 | if (time_before(complain, jiffies)) { | 1128 | if (time_before(complain, jiffies)) { |
1136 | dprintk("NFS: faulty NFS server %s:" | 1129 | dprintk("NFS: faulty NFS server %s:" |
1137 | " (committed = %d) != (stable = %d)\n", | 1130 | " (committed = %d) != (stable = %d)\n", |
1138 | NFS_SERVER(data->inode)->nfs_client->cl_hostname, | 1131 | NFS_SERVER(data->inode)->nfs_client->cl_hostname, |
1139 | resp->verf->committed, argp->stable); | 1132 | resp->verf->committed, argp->stable); |
@@ -1297,12 +1290,9 @@ static void nfs_commit_release(void *calldata) | |||
1297 | while (!list_empty(&data->pages)) { | 1290 | while (!list_empty(&data->pages)) { |
1298 | req = nfs_list_entry(data->pages.next); | 1291 | req = nfs_list_entry(data->pages.next); |
1299 | nfs_list_remove_request(req); | 1292 | nfs_list_remove_request(req); |
1300 | clear_bit(PG_NEED_COMMIT, &(req)->wb_flags); | 1293 | nfs_clear_request_commit(req); |
1301 | dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); | ||
1302 | dec_bdi_stat(req->wb_page->mapping->backing_dev_info, | ||
1303 | BDI_RECLAIMABLE); | ||
1304 | 1294 | ||
1305 | dprintk("NFS: commit (%s/%Ld %d@%Ld)", | 1295 | dprintk("NFS: commit (%s/%lld %d@%lld)", |
1306 | req->wb_context->path.dentry->d_inode->i_sb->s_id, | 1296 | req->wb_context->path.dentry->d_inode->i_sb->s_id, |
1307 | (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode), | 1297 | (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode), |
1308 | req->wb_bytes, | 1298 | req->wb_bytes, |
@@ -1318,9 +1308,6 @@ static void nfs_commit_release(void *calldata) | |||
1318 | * returned by the server against all stored verfs. */ | 1308 | * returned by the server against all stored verfs. */ |
1319 | if (!memcmp(req->wb_verf.verifier, data->verf.verifier, sizeof(data->verf.verifier))) { | 1309 | if (!memcmp(req->wb_verf.verifier, data->verf.verifier, sizeof(data->verf.verifier))) { |
1320 | /* We have a match */ | 1310 | /* We have a match */ |
1321 | /* Set the PG_uptodate flag */ | ||
1322 | nfs_mark_uptodate(req->wb_page, req->wb_pgbase, | ||
1323 | req->wb_bytes); | ||
1324 | nfs_inode_remove_request(req); | 1311 | nfs_inode_remove_request(req); |
1325 | dprintk(" OK\n"); | 1312 | dprintk(" OK\n"); |
1326 | goto next; | 1313 | goto next; |
@@ -1479,7 +1466,7 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page) | |||
1479 | req = nfs_page_find_request(page); | 1466 | req = nfs_page_find_request(page); |
1480 | if (req == NULL) | 1467 | if (req == NULL) |
1481 | goto out; | 1468 | goto out; |
1482 | if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) { | 1469 | if (test_bit(PG_CLEAN, &req->wb_flags)) { |
1483 | nfs_release_request(req); | 1470 | nfs_release_request(req); |
1484 | break; | 1471 | break; |
1485 | } | 1472 | } |