aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cachefiles/rdwr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cachefiles/rdwr.c')
-rw-r--r--fs/cachefiles/rdwr.c114
1 files changed, 67 insertions, 47 deletions
diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c
index c994691d9445..480992259707 100644
--- a/fs/cachefiles/rdwr.c
+++ b/fs/cachefiles/rdwr.c
@@ -77,25 +77,25 @@ static int cachefiles_read_reissue(struct cachefiles_object *object,
77 struct page *backpage = monitor->back_page, *backpage2; 77 struct page *backpage = monitor->back_page, *backpage2;
78 int ret; 78 int ret;
79 79
80 kenter("{ino=%lx},{%lx,%lx}", 80 _enter("{ino=%lx},{%lx,%lx}",
81 object->backer->d_inode->i_ino, 81 object->backer->d_inode->i_ino,
82 backpage->index, backpage->flags); 82 backpage->index, backpage->flags);
83 83
84 /* skip if the page was truncated away completely */ 84 /* skip if the page was truncated away completely */
85 if (backpage->mapping != bmapping) { 85 if (backpage->mapping != bmapping) {
86 kleave(" = -ENODATA [mapping]"); 86 _leave(" = -ENODATA [mapping]");
87 return -ENODATA; 87 return -ENODATA;
88 } 88 }
89 89
90 backpage2 = find_get_page(bmapping, backpage->index); 90 backpage2 = find_get_page(bmapping, backpage->index);
91 if (!backpage2) { 91 if (!backpage2) {
92 kleave(" = -ENODATA [gone]"); 92 _leave(" = -ENODATA [gone]");
93 return -ENODATA; 93 return -ENODATA;
94 } 94 }
95 95
96 if (backpage != backpage2) { 96 if (backpage != backpage2) {
97 put_page(backpage2); 97 put_page(backpage2);
98 kleave(" = -ENODATA [different]"); 98 _leave(" = -ENODATA [different]");
99 return -ENODATA; 99 return -ENODATA;
100 } 100 }
101 101
@@ -114,7 +114,7 @@ static int cachefiles_read_reissue(struct cachefiles_object *object,
114 if (PageUptodate(backpage)) 114 if (PageUptodate(backpage))
115 goto unlock_discard; 115 goto unlock_discard;
116 116
117 kdebug("reissue read"); 117 _debug("reissue read");
118 ret = bmapping->a_ops->readpage(NULL, backpage); 118 ret = bmapping->a_ops->readpage(NULL, backpage);
119 if (ret < 0) 119 if (ret < 0)
120 goto unlock_discard; 120 goto unlock_discard;
@@ -129,7 +129,7 @@ static int cachefiles_read_reissue(struct cachefiles_object *object,
129 } 129 }
130 130
131 /* it'll reappear on the todo list */ 131 /* it'll reappear on the todo list */
132 kleave(" = -EINPROGRESS"); 132 _leave(" = -EINPROGRESS");
133 return -EINPROGRESS; 133 return -EINPROGRESS;
134 134
135unlock_discard: 135unlock_discard:
@@ -137,7 +137,7 @@ unlock_discard:
137 spin_lock_irq(&object->work_lock); 137 spin_lock_irq(&object->work_lock);
138 list_del(&monitor->op_link); 138 list_del(&monitor->op_link);
139 spin_unlock_irq(&object->work_lock); 139 spin_unlock_irq(&object->work_lock);
140 kleave(" = %d", ret); 140 _leave(" = %d", ret);
141 return ret; 141 return ret;
142} 142}
143 143
@@ -174,11 +174,13 @@ static void cachefiles_read_copier(struct fscache_operation *_op)
174 _debug("- copy {%lu}", monitor->back_page->index); 174 _debug("- copy {%lu}", monitor->back_page->index);
175 175
176 recheck: 176 recheck:
177 if (PageUptodate(monitor->back_page)) { 177 if (test_bit(FSCACHE_COOKIE_INVALIDATING,
178 &object->fscache.cookie->flags)) {
179 error = -ESTALE;
180 } else if (PageUptodate(monitor->back_page)) {
178 copy_highpage(monitor->netfs_page, monitor->back_page); 181 copy_highpage(monitor->netfs_page, monitor->back_page);
179 182 fscache_mark_page_cached(monitor->op,
180 pagevec_add(&pagevec, monitor->netfs_page); 183 monitor->netfs_page);
181 fscache_mark_pages_cached(monitor->op, &pagevec);
182 error = 0; 184 error = 0;
183 } else if (!PageError(monitor->back_page)) { 185 } else if (!PageError(monitor->back_page)) {
184 /* the page has probably been truncated */ 186 /* the page has probably been truncated */
@@ -198,6 +200,7 @@ static void cachefiles_read_copier(struct fscache_operation *_op)
198 200
199 fscache_end_io(op, monitor->netfs_page, error); 201 fscache_end_io(op, monitor->netfs_page, error);
200 page_cache_release(monitor->netfs_page); 202 page_cache_release(monitor->netfs_page);
203 fscache_retrieval_complete(op, 1);
201 fscache_put_retrieval(op); 204 fscache_put_retrieval(op);
202 kfree(monitor); 205 kfree(monitor);
203 206
@@ -239,7 +242,7 @@ static int cachefiles_read_backing_file_one(struct cachefiles_object *object,
239 _debug("read back %p{%lu,%d}", 242 _debug("read back %p{%lu,%d}",
240 netpage, netpage->index, page_count(netpage)); 243 netpage, netpage->index, page_count(netpage));
241 244
242 monitor = kzalloc(sizeof(*monitor), GFP_KERNEL); 245 monitor = kzalloc(sizeof(*monitor), cachefiles_gfp);
243 if (!monitor) 246 if (!monitor)
244 goto nomem; 247 goto nomem;
245 248
@@ -258,13 +261,14 @@ static int cachefiles_read_backing_file_one(struct cachefiles_object *object,
258 goto backing_page_already_present; 261 goto backing_page_already_present;
259 262
260 if (!newpage) { 263 if (!newpage) {
261 newpage = page_cache_alloc_cold(bmapping); 264 newpage = __page_cache_alloc(cachefiles_gfp |
265 __GFP_COLD);
262 if (!newpage) 266 if (!newpage)
263 goto nomem_monitor; 267 goto nomem_monitor;
264 } 268 }
265 269
266 ret = add_to_page_cache(newpage, bmapping, 270 ret = add_to_page_cache(newpage, bmapping,
267 netpage->index, GFP_KERNEL); 271 netpage->index, cachefiles_gfp);
268 if (ret == 0) 272 if (ret == 0)
269 goto installed_new_backing_page; 273 goto installed_new_backing_page;
270 if (ret != -EEXIST) 274 if (ret != -EEXIST)
@@ -335,11 +339,11 @@ backing_page_already_present:
335backing_page_already_uptodate: 339backing_page_already_uptodate:
336 _debug("- uptodate"); 340 _debug("- uptodate");
337 341
338 pagevec_add(pagevec, netpage); 342 fscache_mark_page_cached(op, netpage);
339 fscache_mark_pages_cached(op, pagevec);
340 343
341 copy_highpage(netpage, backpage); 344 copy_highpage(netpage, backpage);
342 fscache_end_io(op, netpage, 0); 345 fscache_end_io(op, netpage, 0);
346 fscache_retrieval_complete(op, 1);
343 347
344success: 348success:
345 _debug("success"); 349 _debug("success");
@@ -357,10 +361,13 @@ out:
357 361
358read_error: 362read_error:
359 _debug("read error %d", ret); 363 _debug("read error %d", ret);
360 if (ret == -ENOMEM) 364 if (ret == -ENOMEM) {
365 fscache_retrieval_complete(op, 1);
361 goto out; 366 goto out;
367 }
362io_error: 368io_error:
363 cachefiles_io_error_obj(object, "Page read error on backing file"); 369 cachefiles_io_error_obj(object, "Page read error on backing file");
370 fscache_retrieval_complete(op, 1);
364 ret = -ENOBUFS; 371 ret = -ENOBUFS;
365 goto out; 372 goto out;
366 373
@@ -370,6 +377,7 @@ nomem_monitor:
370 fscache_put_retrieval(monitor->op); 377 fscache_put_retrieval(monitor->op);
371 kfree(monitor); 378 kfree(monitor);
372nomem: 379nomem:
380 fscache_retrieval_complete(op, 1);
373 _leave(" = -ENOMEM"); 381 _leave(" = -ENOMEM");
374 return -ENOMEM; 382 return -ENOMEM;
375} 383}
@@ -408,7 +416,7 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
408 _enter("{%p},{%lx},,,", object, page->index); 416 _enter("{%p},{%lx},,,", object, page->index);
409 417
410 if (!object->backer) 418 if (!object->backer)
411 return -ENOBUFS; 419 goto enobufs;
412 420
413 inode = object->backer->d_inode; 421 inode = object->backer->d_inode;
414 ASSERT(S_ISREG(inode->i_mode)); 422 ASSERT(S_ISREG(inode->i_mode));
@@ -417,7 +425,7 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
417 425
418 /* calculate the shift required to use bmap */ 426 /* calculate the shift required to use bmap */
419 if (inode->i_sb->s_blocksize > PAGE_SIZE) 427 if (inode->i_sb->s_blocksize > PAGE_SIZE)
420 return -ENOBUFS; 428 goto enobufs;
421 429
422 shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits; 430 shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits;
423 431
@@ -448,15 +456,20 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
448 &pagevec); 456 &pagevec);
449 } else if (cachefiles_has_space(cache, 0, 1) == 0) { 457 } else if (cachefiles_has_space(cache, 0, 1) == 0) {
450 /* there's space in the cache we can use */ 458 /* there's space in the cache we can use */
451 pagevec_add(&pagevec, page); 459 fscache_mark_page_cached(op, page);
452 fscache_mark_pages_cached(op, &pagevec); 460 fscache_retrieval_complete(op, 1);
453 ret = -ENODATA; 461 ret = -ENODATA;
454 } else { 462 } else {
455 ret = -ENOBUFS; 463 goto enobufs;
456 } 464 }
457 465
458 _leave(" = %d", ret); 466 _leave(" = %d", ret);
459 return ret; 467 return ret;
468
469enobufs:
470 fscache_retrieval_complete(op, 1);
471 _leave(" = -ENOBUFS");
472 return -ENOBUFS;
460} 473}
461 474
462/* 475/*
@@ -465,8 +478,7 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
465 */ 478 */
466static int cachefiles_read_backing_file(struct cachefiles_object *object, 479static int cachefiles_read_backing_file(struct cachefiles_object *object,
467 struct fscache_retrieval *op, 480 struct fscache_retrieval *op,
468 struct list_head *list, 481 struct list_head *list)
469 struct pagevec *mark_pvec)
470{ 482{
471 struct cachefiles_one_read *monitor = NULL; 483 struct cachefiles_one_read *monitor = NULL;
472 struct address_space *bmapping = object->backer->d_inode->i_mapping; 484 struct address_space *bmapping = object->backer->d_inode->i_mapping;
@@ -485,7 +497,7 @@ static int cachefiles_read_backing_file(struct cachefiles_object *object,
485 netpage, netpage->index, page_count(netpage)); 497 netpage, netpage->index, page_count(netpage));
486 498
487 if (!monitor) { 499 if (!monitor) {
488 monitor = kzalloc(sizeof(*monitor), GFP_KERNEL); 500 monitor = kzalloc(sizeof(*monitor), cachefiles_gfp);
489 if (!monitor) 501 if (!monitor)
490 goto nomem; 502 goto nomem;
491 503
@@ -500,13 +512,14 @@ static int cachefiles_read_backing_file(struct cachefiles_object *object,
500 goto backing_page_already_present; 512 goto backing_page_already_present;
501 513
502 if (!newpage) { 514 if (!newpage) {
503 newpage = page_cache_alloc_cold(bmapping); 515 newpage = __page_cache_alloc(cachefiles_gfp |
516 __GFP_COLD);
504 if (!newpage) 517 if (!newpage)
505 goto nomem; 518 goto nomem;
506 } 519 }
507 520
508 ret = add_to_page_cache(newpage, bmapping, 521 ret = add_to_page_cache(newpage, bmapping,
509 netpage->index, GFP_KERNEL); 522 netpage->index, cachefiles_gfp);
510 if (ret == 0) 523 if (ret == 0)
511 goto installed_new_backing_page; 524 goto installed_new_backing_page;
512 if (ret != -EEXIST) 525 if (ret != -EEXIST)
@@ -536,10 +549,11 @@ static int cachefiles_read_backing_file(struct cachefiles_object *object,
536 _debug("- monitor add"); 549 _debug("- monitor add");
537 550
538 ret = add_to_page_cache(netpage, op->mapping, netpage->index, 551 ret = add_to_page_cache(netpage, op->mapping, netpage->index,
539 GFP_KERNEL); 552 cachefiles_gfp);
540 if (ret < 0) { 553 if (ret < 0) {
541 if (ret == -EEXIST) { 554 if (ret == -EEXIST) {
542 page_cache_release(netpage); 555 page_cache_release(netpage);
556 fscache_retrieval_complete(op, 1);
543 continue; 557 continue;
544 } 558 }
545 goto nomem; 559 goto nomem;
@@ -612,10 +626,11 @@ static int cachefiles_read_backing_file(struct cachefiles_object *object,
612 _debug("- uptodate"); 626 _debug("- uptodate");
613 627
614 ret = add_to_page_cache(netpage, op->mapping, netpage->index, 628 ret = add_to_page_cache(netpage, op->mapping, netpage->index,
615 GFP_KERNEL); 629 cachefiles_gfp);
616 if (ret < 0) { 630 if (ret < 0) {
617 if (ret == -EEXIST) { 631 if (ret == -EEXIST) {
618 page_cache_release(netpage); 632 page_cache_release(netpage);
633 fscache_retrieval_complete(op, 1);
619 continue; 634 continue;
620 } 635 }
621 goto nomem; 636 goto nomem;
@@ -626,16 +641,17 @@ static int cachefiles_read_backing_file(struct cachefiles_object *object,
626 page_cache_release(backpage); 641 page_cache_release(backpage);
627 backpage = NULL; 642 backpage = NULL;
628 643
629 if (!pagevec_add(mark_pvec, netpage)) 644 fscache_mark_page_cached(op, netpage);
630 fscache_mark_pages_cached(op, mark_pvec);
631 645
632 page_cache_get(netpage); 646 page_cache_get(netpage);
633 if (!pagevec_add(&lru_pvec, netpage)) 647 if (!pagevec_add(&lru_pvec, netpage))
634 __pagevec_lru_add_file(&lru_pvec); 648 __pagevec_lru_add_file(&lru_pvec);
635 649
650 /* the netpage is unlocked and marked up to date here */
636 fscache_end_io(op, netpage, 0); 651 fscache_end_io(op, netpage, 0);
637 page_cache_release(netpage); 652 page_cache_release(netpage);
638 netpage = NULL; 653 netpage = NULL;
654 fscache_retrieval_complete(op, 1);
639 continue; 655 continue;
640 } 656 }
641 657
@@ -661,6 +677,7 @@ out:
661 list_for_each_entry_safe(netpage, _n, list, lru) { 677 list_for_each_entry_safe(netpage, _n, list, lru) {
662 list_del(&netpage->lru); 678 list_del(&netpage->lru);
663 page_cache_release(netpage); 679 page_cache_release(netpage);
680 fscache_retrieval_complete(op, 1);
664 } 681 }
665 682
666 _leave(" = %d", ret); 683 _leave(" = %d", ret);
@@ -669,15 +686,17 @@ out:
669nomem: 686nomem:
670 _debug("nomem"); 687 _debug("nomem");
671 ret = -ENOMEM; 688 ret = -ENOMEM;
672 goto out; 689 goto record_page_complete;
673 690
674read_error: 691read_error:
675 _debug("read error %d", ret); 692 _debug("read error %d", ret);
676 if (ret == -ENOMEM) 693 if (ret == -ENOMEM)
677 goto out; 694 goto record_page_complete;
678io_error: 695io_error:
679 cachefiles_io_error_obj(object, "Page read error on backing file"); 696 cachefiles_io_error_obj(object, "Page read error on backing file");
680 ret = -ENOBUFS; 697 ret = -ENOBUFS;
698record_page_complete:
699 fscache_retrieval_complete(op, 1);
681 goto out; 700 goto out;
682} 701}
683 702
@@ -709,7 +728,7 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,
709 *nr_pages); 728 *nr_pages);
710 729
711 if (!object->backer) 730 if (!object->backer)
712 return -ENOBUFS; 731 goto all_enobufs;
713 732
714 space = 1; 733 space = 1;
715 if (cachefiles_has_space(cache, 0, *nr_pages) < 0) 734 if (cachefiles_has_space(cache, 0, *nr_pages) < 0)
@@ -722,7 +741,7 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,
722 741
723 /* calculate the shift required to use bmap */ 742 /* calculate the shift required to use bmap */
724 if (inode->i_sb->s_blocksize > PAGE_SIZE) 743 if (inode->i_sb->s_blocksize > PAGE_SIZE)
725 return -ENOBUFS; 744 goto all_enobufs;
726 745
727 shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits; 746 shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits;
728 747
@@ -762,7 +781,10 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,
762 nrbackpages++; 781 nrbackpages++;
763 } else if (space && pagevec_add(&pagevec, page) == 0) { 782 } else if (space && pagevec_add(&pagevec, page) == 0) {
764 fscache_mark_pages_cached(op, &pagevec); 783 fscache_mark_pages_cached(op, &pagevec);
784 fscache_retrieval_complete(op, 1);
765 ret = -ENODATA; 785 ret = -ENODATA;
786 } else {
787 fscache_retrieval_complete(op, 1);
766 } 788 }
767 } 789 }
768 790
@@ -775,18 +797,18 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,
775 /* submit the apparently valid pages to the backing fs to be read from 797 /* submit the apparently valid pages to the backing fs to be read from
776 * disk */ 798 * disk */
777 if (nrbackpages > 0) { 799 if (nrbackpages > 0) {
778 ret2 = cachefiles_read_backing_file(object, op, &backpages, 800 ret2 = cachefiles_read_backing_file(object, op, &backpages);
779 &pagevec);
780 if (ret2 == -ENOMEM || ret2 == -EINTR) 801 if (ret2 == -ENOMEM || ret2 == -EINTR)
781 ret = ret2; 802 ret = ret2;
782 } 803 }
783 804
784 if (pagevec_count(&pagevec) > 0)
785 fscache_mark_pages_cached(op, &pagevec);
786
787 _leave(" = %d [nr=%u%s]", 805 _leave(" = %d [nr=%u%s]",
788 ret, *nr_pages, list_empty(pages) ? " empty" : ""); 806 ret, *nr_pages, list_empty(pages) ? " empty" : "");
789 return ret; 807 return ret;
808
809all_enobufs:
810 fscache_retrieval_complete(op, *nr_pages);
811 return -ENOBUFS;
790} 812}
791 813
792/* 814/*
@@ -806,7 +828,6 @@ int cachefiles_allocate_page(struct fscache_retrieval *op,
806{ 828{
807 struct cachefiles_object *object; 829 struct cachefiles_object *object;
808 struct cachefiles_cache *cache; 830 struct cachefiles_cache *cache;
809 struct pagevec pagevec;
810 int ret; 831 int ret;
811 832
812 object = container_of(op->op.object, 833 object = container_of(op->op.object,
@@ -817,14 +838,12 @@ int cachefiles_allocate_page(struct fscache_retrieval *op,
817 _enter("%p,{%lx},", object, page->index); 838 _enter("%p,{%lx},", object, page->index);
818 839
819 ret = cachefiles_has_space(cache, 0, 1); 840 ret = cachefiles_has_space(cache, 0, 1);
820 if (ret == 0) { 841 if (ret == 0)
821 pagevec_init(&pagevec, 0); 842 fscache_mark_page_cached(op, page);
822 pagevec_add(&pagevec, page); 843 else
823 fscache_mark_pages_cached(op, &pagevec);
824 } else {
825 ret = -ENOBUFS; 844 ret = -ENOBUFS;
826 }
827 845
846 fscache_retrieval_complete(op, 1);
828 _leave(" = %d", ret); 847 _leave(" = %d", ret);
829 return ret; 848 return ret;
830} 849}
@@ -874,6 +893,7 @@ int cachefiles_allocate_pages(struct fscache_retrieval *op,
874 ret = -ENOBUFS; 893 ret = -ENOBUFS;
875 } 894 }
876 895
896 fscache_retrieval_complete(op, *nr_pages);
877 _leave(" = %d", ret); 897 _leave(" = %d", ret);
878 return ret; 898 return ret;
879} 899}