diff options
Diffstat (limited to 'fs/nilfs2/page.c')
-rw-r--r-- | fs/nilfs2/page.c | 55 |
1 files changed, 29 insertions, 26 deletions
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c index aab11db2cb08..a6c3c2e817f8 100644 --- a/fs/nilfs2/page.c +++ b/fs/nilfs2/page.c | |||
@@ -79,8 +79,8 @@ struct buffer_head *nilfs_grab_buffer(struct inode *inode, | |||
79 | { | 79 | { |
80 | int blkbits = inode->i_blkbits; | 80 | int blkbits = inode->i_blkbits; |
81 | pgoff_t index = blkoff >> (PAGE_CACHE_SHIFT - blkbits); | 81 | pgoff_t index = blkoff >> (PAGE_CACHE_SHIFT - blkbits); |
82 | struct page *page, *opage; | 82 | struct page *page; |
83 | struct buffer_head *bh, *obh; | 83 | struct buffer_head *bh; |
84 | 84 | ||
85 | page = grab_cache_page(mapping, index); | 85 | page = grab_cache_page(mapping, index); |
86 | if (unlikely(!page)) | 86 | if (unlikely(!page)) |
@@ -92,30 +92,6 @@ struct buffer_head *nilfs_grab_buffer(struct inode *inode, | |||
92 | page_cache_release(page); | 92 | page_cache_release(page); |
93 | return NULL; | 93 | return NULL; |
94 | } | 94 | } |
95 | if (!buffer_uptodate(bh) && mapping->assoc_mapping != NULL) { | ||
96 | /* | ||
97 | * Shadow page cache uses assoc_mapping to point its original | ||
98 | * page cache. The following code tries the original cache | ||
99 | * if the given cache is a shadow and it didn't hit. | ||
100 | */ | ||
101 | opage = find_lock_page(mapping->assoc_mapping, index); | ||
102 | if (!opage) | ||
103 | return bh; | ||
104 | |||
105 | obh = __nilfs_get_page_block(opage, blkoff, index, blkbits, | ||
106 | b_state); | ||
107 | if (buffer_uptodate(obh)) { | ||
108 | nilfs_copy_buffer(bh, obh); | ||
109 | if (buffer_dirty(obh)) { | ||
110 | nilfs_mark_buffer_dirty(bh); | ||
111 | if (!buffer_nilfs_node(bh) && NILFS_MDT(inode)) | ||
112 | nilfs_mdt_mark_dirty(inode); | ||
113 | } | ||
114 | } | ||
115 | brelse(obh); | ||
116 | unlock_page(opage); | ||
117 | page_cache_release(opage); | ||
118 | } | ||
119 | return bh; | 95 | return bh; |
120 | } | 96 | } |
121 | 97 | ||
@@ -131,6 +107,7 @@ void nilfs_forget_buffer(struct buffer_head *bh) | |||
131 | lock_buffer(bh); | 107 | lock_buffer(bh); |
132 | clear_buffer_nilfs_volatile(bh); | 108 | clear_buffer_nilfs_volatile(bh); |
133 | clear_buffer_nilfs_checked(bh); | 109 | clear_buffer_nilfs_checked(bh); |
110 | clear_buffer_nilfs_redirected(bh); | ||
134 | clear_buffer_dirty(bh); | 111 | clear_buffer_dirty(bh); |
135 | if (nilfs_page_buffers_clean(page)) | 112 | if (nilfs_page_buffers_clean(page)) |
136 | __nilfs_clear_page_dirty(page); | 113 | __nilfs_clear_page_dirty(page); |
@@ -483,6 +460,7 @@ void nilfs_clear_dirty_pages(struct address_space *mapping) | |||
483 | clear_buffer_dirty(bh); | 460 | clear_buffer_dirty(bh); |
484 | clear_buffer_nilfs_volatile(bh); | 461 | clear_buffer_nilfs_volatile(bh); |
485 | clear_buffer_nilfs_checked(bh); | 462 | clear_buffer_nilfs_checked(bh); |
463 | clear_buffer_nilfs_redirected(bh); | ||
486 | clear_buffer_uptodate(bh); | 464 | clear_buffer_uptodate(bh); |
487 | clear_buffer_mapped(bh); | 465 | clear_buffer_mapped(bh); |
488 | unlock_buffer(bh); | 466 | unlock_buffer(bh); |
@@ -513,6 +491,31 @@ unsigned nilfs_page_count_clean_buffers(struct page *page, | |||
513 | } | 491 | } |
514 | return nc; | 492 | return nc; |
515 | } | 493 | } |
494 | |||
495 | void nilfs_mapping_init_once(struct address_space *mapping) | ||
496 | { | ||
497 | memset(mapping, 0, sizeof(*mapping)); | ||
498 | INIT_RADIX_TREE(&mapping->page_tree, GFP_ATOMIC); | ||
499 | spin_lock_init(&mapping->tree_lock); | ||
500 | INIT_LIST_HEAD(&mapping->private_list); | ||
501 | spin_lock_init(&mapping->private_lock); | ||
502 | |||
503 | spin_lock_init(&mapping->i_mmap_lock); | ||
504 | INIT_RAW_PRIO_TREE_ROOT(&mapping->i_mmap); | ||
505 | INIT_LIST_HEAD(&mapping->i_mmap_nonlinear); | ||
506 | } | ||
507 | |||
508 | void nilfs_mapping_init(struct address_space *mapping, | ||
509 | struct backing_dev_info *bdi, | ||
510 | const struct address_space_operations *aops) | ||
511 | { | ||
512 | mapping->host = NULL; | ||
513 | mapping->flags = 0; | ||
514 | mapping_set_gfp_mask(mapping, GFP_NOFS); | ||
515 | mapping->assoc_mapping = NULL; | ||
516 | mapping->backing_dev_info = bdi; | ||
517 | mapping->a_ops = aops; | ||
518 | } | ||
516 | 519 | ||
517 | /* | 520 | /* |
518 | * NILFS2 needs clear_page_dirty() in the following two cases: | 521 | * NILFS2 needs clear_page_dirty() in the following two cases: |