13
13
#include <linux/file.h>
14
14
#include <linux/writeback.h>
15
15
#include <linux/swap.h>
16
+ #include <linux/migrate.h>
16
17
17
18
#include <linux/sunrpc/clnt.h>
18
19
#include <linux/nfs_fs.h>
26
27
#include "internal.h"
27
28
#include "iostat.h"
28
29
#include "nfs4_fs.h"
30
+ #include "fscache.h"
29
31
30
32
#define NFSDBG_FACILITY NFSDBG_PAGECACHE
31
33
@@ -220,24 +222,17 @@ static void nfs_end_page_writeback(struct page *page)
220
222
clear_bdi_congested (& nfss -> backing_dev_info , BLK_RW_ASYNC );
221
223
}
222
224
223
- /*
224
- * Find an associated nfs write request, and prepare to flush it out
225
- * May return an error if the user signalled nfs_wait_on_request().
226
- */
227
- static int nfs_page_async_flush (struct nfs_pageio_descriptor * pgio ,
228
- struct page * page )
225
+ static struct nfs_page * nfs_find_and_lock_request (struct page * page )
229
226
{
230
227
struct inode * inode = page -> mapping -> host ;
231
228
struct nfs_page * req ;
232
229
int ret ;
233
230
234
231
spin_lock (& inode -> i_lock );
235
- for (;;) {
232
+ for (;;) {
236
233
req = nfs_page_find_request_locked (page );
237
- if (req == NULL ) {
238
- spin_unlock (& inode -> i_lock );
239
- return 0 ;
240
- }
234
+ if (req == NULL )
235
+ break ;
241
236
if (nfs_set_page_tag_locked (req ))
242
237
break ;
243
238
/* Note: If we hold the page lock, as is the case in nfs_writepage,
@@ -249,23 +244,40 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
249
244
ret = nfs_wait_on_request (req );
250
245
nfs_release_request (req );
251
246
if (ret != 0 )
252
- return ret ;
247
+ return ERR_PTR ( ret ) ;
253
248
spin_lock (& inode -> i_lock );
254
249
}
255
- if (test_bit (PG_CLEAN , & req -> wb_flags )) {
256
- spin_unlock (& inode -> i_lock );
257
- BUG ();
258
- }
259
- if (nfs_set_page_writeback (page ) != 0 ) {
260
- spin_unlock (& inode -> i_lock );
261
- BUG ();
262
- }
263
250
spin_unlock (& inode -> i_lock );
251
+ return req ;
252
+ }
253
+
254
+ /*
255
+ * Find an associated nfs write request, and prepare to flush it out
256
+ * May return an error if the user signalled nfs_wait_on_request().
257
+ */
258
+ static int nfs_page_async_flush (struct nfs_pageio_descriptor * pgio ,
259
+ struct page * page )
260
+ {
261
+ struct nfs_page * req ;
262
+ int ret = 0 ;
263
+
264
+ req = nfs_find_and_lock_request (page );
265
+ if (!req )
266
+ goto out ;
267
+ ret = PTR_ERR (req );
268
+ if (IS_ERR (req ))
269
+ goto out ;
270
+
271
+ ret = nfs_set_page_writeback (page );
272
+ BUG_ON (ret != 0 );
273
+ BUG_ON (test_bit (PG_CLEAN , & req -> wb_flags ));
274
+
264
275
if (!nfs_pageio_add_request (pgio , req )) {
265
276
nfs_redirty_request (req );
266
- return pgio -> pg_error ;
277
+ ret = pgio -> pg_error ;
267
278
}
268
- return 0 ;
279
+ out :
280
+ return ret ;
269
281
}
270
282
271
283
static int nfs_do_writepage (struct page * page , struct writeback_control * wbc , struct nfs_pageio_descriptor * pgio )
@@ -1582,6 +1594,41 @@ int nfs_wb_page(struct inode *inode, struct page* page)
1582
1594
return nfs_wb_page_priority (inode , page , FLUSH_STABLE );
1583
1595
}
1584
1596
1597
+ #ifdef CONFIG_MIGRATION
1598
+ int nfs_migrate_page (struct address_space * mapping , struct page * newpage ,
1599
+ struct page * page )
1600
+ {
1601
+ struct nfs_page * req ;
1602
+ int ret ;
1603
+
1604
+ if (PageFsCache (page ))
1605
+ nfs_fscache_release_page (page , GFP_KERNEL );
1606
+
1607
+ req = nfs_find_and_lock_request (page );
1608
+ ret = PTR_ERR (req );
1609
+ if (IS_ERR (req ))
1610
+ goto out ;
1611
+
1612
+ ret = migrate_page (mapping , newpage , page );
1613
+ if (!req )
1614
+ goto out ;
1615
+ if (ret )
1616
+ goto out_unlock ;
1617
+ page_cache_get (newpage );
1618
+ req -> wb_page = newpage ;
1619
+ SetPagePrivate (newpage );
1620
+ set_page_private (newpage , page_private (page ));
1621
+ ClearPagePrivate (page );
1622
+ set_page_private (page , 0 );
1623
+ page_cache_release (page );
1624
+ out_unlock :
1625
+ nfs_clear_page_tag_locked (req );
1626
+ nfs_release_request (req );
1627
+ out :
1628
+ return ret ;
1629
+ }
1630
+ #endif
1631
+
1585
1632
int __init nfs_init_writepagecache (void )
1586
1633
{
1587
1634
nfs_wdata_cachep = kmem_cache_create ("nfs_write_data" ,
0 commit comments