History

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

Linus Torvalds committed 16 years ago

Commit fc71ff82 parents 1cf66e1 cfb506e4 files · +32 −11Browse files

Unified · Split

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