Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6

* 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6:
NFS: Ensure that writepage respects the nonblock flag
NFS: kswapd must not block in nfs_release_page
nfs: include space for the NUL in root path

Changed files
+32 -11
fs
include
linux
+11 -2
fs/nfs/file.c
··· 27 27 #include <linux/pagemap.h> 28 28 #include <linux/aio.h> 29 29 #include <linux/gfp.h> 30 + #include <linux/swap.h> 30 31 31 32 #include <asm/uaccess.h> 32 33 #include <asm/system.h> ··· 494 493 */ 495 494 static int nfs_release_page(struct page *page, gfp_t gfp) 496 495 { 496 + struct address_space *mapping = page->mapping; 497 + 497 498 dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page); 498 499 499 500 /* Only do I/O if gfp is a superset of GFP_KERNEL */ 500 - if ((gfp & GFP_KERNEL) == GFP_KERNEL) 501 - nfs_wb_page(page->mapping->host, page); 501 + if (mapping && (gfp & GFP_KERNEL) == GFP_KERNEL) { 502 + int how = FLUSH_SYNC; 503 + 504 + /* Don't let kswapd deadlock waiting for OOM RPC calls */ 505 + if (current_is_kswapd()) 506 + how = 0; 507 + nfs_commit_inode(mapping->host, how); 508 + } 502 509 /* If PagePrivate() is set, then the page is not freeable */ 503 510 if (PagePrivate(page)) 504 511 return 0;
+1 -1
fs/nfs/nfsroot.c
··· 105 105 static __be32 servaddr __initdata = 0; 106 106 107 107 /* Name of directory to mount */ 108 - static char nfs_export_path[NFS_MAXPATHLEN] __initdata = { 0, }; 108 + static char nfs_export_path[NFS_MAXPATHLEN + 1] __initdata = { 0, }; 109 109 110 110 /* NFS-related data */ 111 111 static struct nfs_mount_data nfs_data __initdata = { 0, };/* NFS mount info */
+19 -8
fs/nfs/write.c
··· 222 222 clear_bdi_congested(&nfss->backing_dev_info, BLK_RW_ASYNC); 223 223 } 224 224 225 - static struct nfs_page *nfs_find_and_lock_request(struct page *page) 225 + static struct nfs_page *nfs_find_and_lock_request(struct page *page, bool nonblock) 226 226 { 227 227 struct inode *inode = page->mapping->host; 228 228 struct nfs_page *req; ··· 241 241 * request as dirty (in which case we don't care). 242 242 */ 243 243 spin_unlock(&inode->i_lock); 244 - ret = nfs_wait_on_request(req); 244 + if (!nonblock) 245 + ret = nfs_wait_on_request(req); 246 + else 247 + ret = -EAGAIN; 245 248 nfs_release_request(req); 246 249 if (ret != 0) 247 250 return ERR_PTR(ret); ··· 259 256 * May return an error if the user signalled nfs_wait_on_request(). 260 257 */ 261 258 static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio, 262 - struct page *page) 259 + struct page *page, bool nonblock) 263 260 { 264 261 struct nfs_page *req; 265 262 int ret = 0; 266 263 267 - req = nfs_find_and_lock_request(page); 264 + req = nfs_find_and_lock_request(page, nonblock); 268 265 if (!req) 269 266 goto out; 270 267 ret = PTR_ERR(req); ··· 286 283 static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, struct nfs_pageio_descriptor *pgio) 287 284 { 288 285 struct inode *inode = page->mapping->host; 286 + int ret; 289 287 290 288 nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE); 291 289 nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1); 292 290 293 291 nfs_pageio_cond_complete(pgio, page->index); 294 - return nfs_page_async_flush(pgio, page); 292 + ret = nfs_page_async_flush(pgio, page, 293 + wbc->sync_mode == WB_SYNC_NONE || 294 + wbc->nonblocking != 0); 295 + if (ret == -EAGAIN) { 296 + redirty_page_for_writepage(wbc, page); 297 + ret = 0; 298 + } 299 + return ret; 295 300 } 296 301 297 302 /* ··· 1390 1379 .rpc_release = nfs_commit_release, 1391 1380 }; 1392 1381 1393 - static int nfs_commit_inode(struct inode *inode, int how) 1382 + int nfs_commit_inode(struct inode *inode, int how) 1394 1383 { 1395 1384 LIST_HEAD(head); 1396 1385 int may_wait = how & FLUSH_SYNC; ··· 1454 1443 return ret; 1455 1444 } 1456 1445 #else 1457 - static int nfs_commit_inode(struct inode *inode, int how) 1446 + int nfs_commit_inode(struct inode *inode, int how) 1458 1447 { 1459 1448 return 0; 1460 1449 } ··· 1557 1546 1558 1547 nfs_fscache_release_page(page, GFP_KERNEL); 1559 1548 1560 - req = nfs_find_and_lock_request(page); 1549 + req = nfs_find_and_lock_request(page, false); 1561 1550 ret = PTR_ERR(req); 1562 1551 if (IS_ERR(req)) 1563 1552 goto out;
+1
include/linux/nfs_fs.h
··· 493 493 extern int nfs_wb_page(struct inode *inode, struct page* page); 494 494 extern int nfs_wb_page_cancel(struct inode *inode, struct page* page); 495 495 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 496 + extern int nfs_commit_inode(struct inode *, int); 496 497 extern struct nfs_write_data *nfs_commitdata_alloc(void); 497 498 extern void nfs_commit_free(struct nfs_write_data *wdata); 498 499 #endif