diff options
Diffstat (limited to 'mm/page_io.c')
-rw-r--r-- | mm/page_io.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/mm/page_io.c b/mm/page_io.c index 34f02923744c..307a3e795290 100644 --- a/mm/page_io.c +++ b/mm/page_io.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/swap.h> | 17 | #include <linux/swap.h> |
18 | #include <linux/bio.h> | 18 | #include <linux/bio.h> |
19 | #include <linux/swapops.h> | 19 | #include <linux/swapops.h> |
20 | #include <linux/buffer_head.h> | ||
20 | #include <linux/writeback.h> | 21 | #include <linux/writeback.h> |
21 | #include <linux/frontswap.h> | 22 | #include <linux/frontswap.h> |
22 | #include <asm/pgtable.h> | 23 | #include <asm/pgtable.h> |
@@ -94,6 +95,7 @@ int swap_writepage(struct page *page, struct writeback_control *wbc) | |||
94 | { | 95 | { |
95 | struct bio *bio; | 96 | struct bio *bio; |
96 | int ret = 0, rw = WRITE; | 97 | int ret = 0, rw = WRITE; |
98 | struct swap_info_struct *sis = page_swap_info(page); | ||
97 | 99 | ||
98 | if (try_to_free_swap(page)) { | 100 | if (try_to_free_swap(page)) { |
99 | unlock_page(page); | 101 | unlock_page(page); |
@@ -105,6 +107,32 @@ int swap_writepage(struct page *page, struct writeback_control *wbc) | |||
105 | end_page_writeback(page); | 107 | end_page_writeback(page); |
106 | goto out; | 108 | goto out; |
107 | } | 109 | } |
110 | |||
111 | if (sis->flags & SWP_FILE) { | ||
112 | struct kiocb kiocb; | ||
113 | struct file *swap_file = sis->swap_file; | ||
114 | struct address_space *mapping = swap_file->f_mapping; | ||
115 | struct iovec iov = { | ||
116 | .iov_base = page_address(page), | ||
117 | .iov_len = PAGE_SIZE, | ||
118 | }; | ||
119 | |||
120 | init_sync_kiocb(&kiocb, swap_file); | ||
121 | kiocb.ki_pos = page_file_offset(page); | ||
122 | kiocb.ki_left = PAGE_SIZE; | ||
123 | kiocb.ki_nbytes = PAGE_SIZE; | ||
124 | |||
125 | unlock_page(page); | ||
126 | ret = mapping->a_ops->direct_IO(KERNEL_WRITE, | ||
127 | &kiocb, &iov, | ||
128 | kiocb.ki_pos, 1); | ||
129 | if (ret == PAGE_SIZE) { | ||
130 | count_vm_event(PSWPOUT); | ||
131 | ret = 0; | ||
132 | } | ||
133 | return ret; | ||
134 | } | ||
135 | |||
108 | bio = get_swap_bio(GFP_NOIO, page, end_swap_bio_write); | 136 | bio = get_swap_bio(GFP_NOIO, page, end_swap_bio_write); |
109 | if (bio == NULL) { | 137 | if (bio == NULL) { |
110 | set_page_dirty(page); | 138 | set_page_dirty(page); |
@@ -126,6 +154,7 @@ int swap_readpage(struct page *page) | |||
126 | { | 154 | { |
127 | struct bio *bio; | 155 | struct bio *bio; |
128 | int ret = 0; | 156 | int ret = 0; |
157 | struct swap_info_struct *sis = page_swap_info(page); | ||
129 | 158 | ||
130 | VM_BUG_ON(!PageLocked(page)); | 159 | VM_BUG_ON(!PageLocked(page)); |
131 | VM_BUG_ON(PageUptodate(page)); | 160 | VM_BUG_ON(PageUptodate(page)); |
@@ -134,6 +163,17 @@ int swap_readpage(struct page *page) | |||
134 | unlock_page(page); | 163 | unlock_page(page); |
135 | goto out; | 164 | goto out; |
136 | } | 165 | } |
166 | |||
167 | if (sis->flags & SWP_FILE) { | ||
168 | struct file *swap_file = sis->swap_file; | ||
169 | struct address_space *mapping = swap_file->f_mapping; | ||
170 | |||
171 | ret = mapping->a_ops->readpage(swap_file, page); | ||
172 | if (!ret) | ||
173 | count_vm_event(PSWPIN); | ||
174 | return ret; | ||
175 | } | ||
176 | |||
137 | bio = get_swap_bio(GFP_KERNEL, page, end_swap_bio_read); | 177 | bio = get_swap_bio(GFP_KERNEL, page, end_swap_bio_read); |
138 | if (bio == NULL) { | 178 | if (bio == NULL) { |
139 | unlock_page(page); | 179 | unlock_page(page); |
@@ -145,3 +185,15 @@ int swap_readpage(struct page *page) | |||
145 | out: | 185 | out: |
146 | return ret; | 186 | return ret; |
147 | } | 187 | } |
188 | |||
189 | int swap_set_page_dirty(struct page *page) | ||
190 | { | ||
191 | struct swap_info_struct *sis = page_swap_info(page); | ||
192 | |||
193 | if (sis->flags & SWP_FILE) { | ||
194 | struct address_space *mapping = sis->swap_file->f_mapping; | ||
195 | return mapping->a_ops->set_page_dirty(page); | ||
196 | } else { | ||
197 | return __set_page_dirty_no_writeback(page); | ||
198 | } | ||
199 | } | ||