aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/exofs/inode.c61
1 files changed, 59 insertions, 2 deletions
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c
index 86c0ac87b8e3..3e5f3a6be90a 100644
--- a/fs/exofs/inode.c
+++ b/fs/exofs/inode.c
@@ -63,6 +63,7 @@ struct page_collect {
63 bool read_4_write; /* This means two things: that the read is sync 63 bool read_4_write; /* This means two things: that the read is sync
64 * And the pages should not be unlocked. 64 * And the pages should not be unlocked.
65 */ 65 */
66 struct page *that_locked_page;
66}; 67};
67 68
68static void _pcol_init(struct page_collect *pcol, unsigned expected_pages, 69static void _pcol_init(struct page_collect *pcol, unsigned expected_pages,
@@ -81,6 +82,7 @@ static void _pcol_init(struct page_collect *pcol, unsigned expected_pages,
81 pcol->length = 0; 82 pcol->length = 0;
82 pcol->pg_first = -1; 83 pcol->pg_first = -1;
83 pcol->read_4_write = false; 84 pcol->read_4_write = false;
85 pcol->that_locked_page = NULL;
84} 86}
85 87
86static void _pcol_reset(struct page_collect *pcol) 88static void _pcol_reset(struct page_collect *pcol)
@@ -93,6 +95,7 @@ static void _pcol_reset(struct page_collect *pcol)
93 pcol->length = 0; 95 pcol->length = 0;
94 pcol->pg_first = -1; 96 pcol->pg_first = -1;
95 pcol->ios = NULL; 97 pcol->ios = NULL;
98 pcol->that_locked_page = NULL;
96 99
97 /* this is probably the end of the loop but in writes 100 /* this is probably the end of the loop but in writes
98 * it might not end here. don't be left with nothing 101 * it might not end here. don't be left with nothing
@@ -391,6 +394,8 @@ static int readpage_strip(void *data, struct page *page)
391 EXOFS_ERR("PageUptodate(0x%lx, 0x%lx)\n", pcol->inode->i_ino, 394 EXOFS_ERR("PageUptodate(0x%lx, 0x%lx)\n", pcol->inode->i_ino,
392 page->index); 395 page->index);
393 396
397 pcol->that_locked_page = page;
398
394 if (page->index < end_index) 399 if (page->index < end_index)
395 len = PAGE_CACHE_SIZE; 400 len = PAGE_CACHE_SIZE;
396 else if (page->index == end_index) 401 else if (page->index == end_index)
@@ -560,6 +565,56 @@ static void writepages_done(struct ore_io_state *ios, void *p)
560 EXOFS_DBGMSG2("writepages_done END\n"); 565 EXOFS_DBGMSG2("writepages_done END\n");
561} 566}
562 567
568static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate)
569{
570 struct page_collect *pcol = priv;
571 pgoff_t index = offset / PAGE_SIZE;
572
573 if (!pcol->that_locked_page ||
574 (pcol->that_locked_page->index != index)) {
575 struct page *page = find_get_page(pcol->inode->i_mapping, index);
576
577 if (!page) {
578 page = find_or_create_page(pcol->inode->i_mapping,
579 index, GFP_NOFS);
580 if (unlikely(!page)) {
581 EXOFS_DBGMSG("grab_cache_page Failed "
582 "index=0x%llx\n", _LLU(index));
583 return NULL;
584 }
585 unlock_page(page);
586 }
587 if (PageDirty(page) || PageWriteback(page))
588 *uptodate = true;
589 else
590 *uptodate = PageUptodate(page);
591 EXOFS_DBGMSG("index=0x%lx uptodate=%d\n", index, *uptodate);
592 return page;
593 } else {
594 EXOFS_DBGMSG("YES that_locked_page index=0x%lx\n",
595 pcol->that_locked_page->index);
596 *uptodate = true;
597 return pcol->that_locked_page;
598 }
599}
600
601static void __r4w_put_page(void *priv, struct page *page)
602{
603 struct page_collect *pcol = priv;
604
605 if (pcol->that_locked_page != page) {
606 EXOFS_DBGMSG("index=0x%lx\n", page->index);
607 page_cache_release(page);
608 return;
609 }
610 EXOFS_DBGMSG("that_locked_page index=0x%lx\n", page->index);
611}
612
613static const struct _ore_r4w_op _r4w_op = {
614 .get_page = &__r4w_get_page,
615 .put_page = &__r4w_put_page,
616};
617
563static int write_exec(struct page_collect *pcol) 618static int write_exec(struct page_collect *pcol)
564{ 619{
565 struct exofs_i_info *oi = exofs_i(pcol->inode); 620 struct exofs_i_info *oi = exofs_i(pcol->inode);
@@ -589,6 +644,7 @@ static int write_exec(struct page_collect *pcol)
589 ios = pcol->ios; 644 ios = pcol->ios;
590 ios->pages = pcol_copy->pages; 645 ios->pages = pcol_copy->pages;
591 ios->done = writepages_done; 646 ios->done = writepages_done;
647 ios->r4w = &_r4w_op;
592 ios->private = pcol_copy; 648 ios->private = pcol_copy;
593 649
594 /* pages ownership was passed to pcol_copy */ 650 /* pages ownership was passed to pcol_copy */
@@ -773,6 +829,7 @@ static int exofs_writepages(struct address_space *mapping,
773 return 0; 829 return 0;
774} 830}
775 831
832/*
776static int exofs_writepage(struct page *page, struct writeback_control *wbc) 833static int exofs_writepage(struct page *page, struct writeback_control *wbc)
777{ 834{
778 struct page_collect pcol; 835 struct page_collect pcol;
@@ -788,7 +845,7 @@ static int exofs_writepage(struct page *page, struct writeback_control *wbc)
788 845
789 return write_exec(&pcol); 846 return write_exec(&pcol);
790} 847}
791 848*/
792/* i_mutex held using inode->i_size directly */ 849/* i_mutex held using inode->i_size directly */
793static void _write_failed(struct inode *inode, loff_t to) 850static void _write_failed(struct inode *inode, loff_t to)
794{ 851{
@@ -894,7 +951,7 @@ static void exofs_invalidatepage(struct page *page, unsigned long offset)
894const struct address_space_operations exofs_aops = { 951const struct address_space_operations exofs_aops = {
895 .readpage = exofs_readpage, 952 .readpage = exofs_readpage,
896 .readpages = exofs_readpages, 953 .readpages = exofs_readpages,
897 .writepage = exofs_writepage, 954 .writepage = NULL,
898 .writepages = exofs_writepages, 955 .writepages = exofs_writepages,
899 .write_begin = exofs_write_begin_export, 956 .write_begin = exofs_write_begin_export,
900 .write_end = exofs_write_end, 957 .write_end = exofs_write_end,