write.c (074cc1deec5dee63fcd5d966b36fa4f3765b50fc) write.c (1ae88b2e446261c038f2c0c3150ffae142b227a2)
1/*
2 * linux/fs/nfs/write.c
3 *
4 * Write file data over NFS.
5 *
6 * Copyright (C) 1996, 1997, Olaf Kirch <okir@monad.swb.de>
7 */
8
9#include <linux/types.h>
10#include <linux/slab.h>
11#include <linux/mm.h>
12#include <linux/pagemap.h>
13#include <linux/file.h>
14#include <linux/writeback.h>
15#include <linux/swap.h>
1/*
2 * linux/fs/nfs/write.c
3 *
4 * Write file data over NFS.
5 *
6 * Copyright (C) 1996, 1997, Olaf Kirch <okir@monad.swb.de>
7 */
8
9#include <linux/types.h>
10#include <linux/slab.h>
11#include <linux/mm.h>
12#include <linux/pagemap.h>
13#include <linux/file.h>
14#include <linux/writeback.h>
15#include <linux/swap.h>
16#include <linux/migrate.h>
17
18#include <linux/sunrpc/clnt.h>
19#include <linux/nfs_fs.h>
20#include <linux/nfs_mount.h>
21#include <linux/nfs_page.h>
22#include <linux/backing-dev.h>
23
24#include <asm/uaccess.h>
25
26#include "delegation.h"
27#include "internal.h"
28#include "iostat.h"
29#include "nfs4_fs.h"
16
17#include <linux/sunrpc/clnt.h>
18#include <linux/nfs_fs.h>
19#include <linux/nfs_mount.h>
20#include <linux/nfs_page.h>
21#include <linux/backing-dev.h>
22
23#include <asm/uaccess.h>
24
25#include "delegation.h"
26#include "internal.h"
27#include "iostat.h"
28#include "nfs4_fs.h"
30#include "fscache.h"
31
32#define NFSDBG_FACILITY NFSDBG_PAGECACHE
33
34#define MIN_POOL_WRITE (32)
35#define MIN_POOL_COMMIT (4)
36
37/*
38 * Local function declarations

--- 45 unchanged lines hidden (view full) ---

84 mempool_free(p, nfs_wdata_mempool);
85 p = NULL;
86 }
87 }
88 }
89 return p;
90}
91
29
30#define NFSDBG_FACILITY NFSDBG_PAGECACHE
31
32#define MIN_POOL_WRITE (32)
33#define MIN_POOL_COMMIT (4)
34
35/*
36 * Local function declarations

--- 45 unchanged lines hidden (view full) ---

82 mempool_free(p, nfs_wdata_mempool);
83 p = NULL;
84 }
85 }
86 }
87 return p;
88}
89
92static void nfs_writedata_free(struct nfs_write_data *p)
90void nfs_writedata_free(struct nfs_write_data *p)
93{
94 if (p && (p->pagevec != &p->page_array[0]))
95 kfree(p->pagevec);
96 mempool_free(p, nfs_wdata_mempool);
97}
98
91{
92 if (p && (p->pagevec != &p->page_array[0]))
93 kfree(p->pagevec);
94 mempool_free(p, nfs_wdata_mempool);
95}
96
99void nfs_writedata_release(void *data)
97static void nfs_writedata_release(struct nfs_write_data *wdata)
100{
98{
101 struct nfs_write_data *wdata = data;
102
103 put_nfs_open_context(wdata->args.context);
104 nfs_writedata_free(wdata);
105}
106
107static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
108{
109 ctx->error = error;
110 smp_wmb();

--- 106 unchanged lines hidden (view full) ---

217 struct inode *inode = page->mapping->host;
218 struct nfs_server *nfss = NFS_SERVER(inode);
219
220 end_page_writeback(page);
221 if (atomic_long_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH)
222 clear_bdi_congested(&nfss->backing_dev_info, BLK_RW_ASYNC);
223}
224
99 put_nfs_open_context(wdata->args.context);
100 nfs_writedata_free(wdata);
101}
102
103static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
104{
105 ctx->error = error;
106 smp_wmb();

--- 106 unchanged lines hidden (view full) ---

213 struct inode *inode = page->mapping->host;
214 struct nfs_server *nfss = NFS_SERVER(inode);
215
216 end_page_writeback(page);
217 if (atomic_long_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH)
218 clear_bdi_congested(&nfss->backing_dev_info, BLK_RW_ASYNC);
219}
220
225static struct nfs_page *nfs_find_and_lock_request(struct page *page)
221/*
222 * Find an associated nfs write request, and prepare to flush it out
223 * May return an error if the user signalled nfs_wait_on_request().
224 */
225static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
226 struct page *page)
226{
227 struct inode *inode = page->mapping->host;
228 struct nfs_page *req;
229 int ret;
230
231 spin_lock(&inode->i_lock);
227{
228 struct inode *inode = page->mapping->host;
229 struct nfs_page *req;
230 int ret;
231
232 spin_lock(&inode->i_lock);
232 for (;;) {
233 for(;;) {
233 req = nfs_page_find_request_locked(page);
234 req = nfs_page_find_request_locked(page);
234 if (req == NULL)
235 break;
235 if (req == NULL) {
236 spin_unlock(&inode->i_lock);
237 return 0;
238 }
236 if (nfs_set_page_tag_locked(req))
237 break;
238 /* Note: If we hold the page lock, as is the case in nfs_writepage,
239 * then the call to nfs_set_page_tag_locked() will always
240 * succeed provided that someone hasn't already marked the
241 * request as dirty (in which case we don't care).
242 */
243 spin_unlock(&inode->i_lock);
244 ret = nfs_wait_on_request(req);
245 nfs_release_request(req);
246 if (ret != 0)
239 if (nfs_set_page_tag_locked(req))
240 break;
241 /* Note: If we hold the page lock, as is the case in nfs_writepage,
242 * then the call to nfs_set_page_tag_locked() will always
243 * succeed provided that someone hasn't already marked the
244 * request as dirty (in which case we don't care).
245 */
246 spin_unlock(&inode->i_lock);
247 ret = nfs_wait_on_request(req);
248 nfs_release_request(req);
249 if (ret != 0)
247 return ERR_PTR(ret);
250 return ret;
248 spin_lock(&inode->i_lock);
249 }
251 spin_lock(&inode->i_lock);
252 }
253 if (test_bit(PG_CLEAN, &req->wb_flags)) {
254 spin_unlock(&inode->i_lock);
255 BUG();
256 }
257 if (nfs_set_page_writeback(page) != 0) {
258 spin_unlock(&inode->i_lock);
259 BUG();
260 }
250 spin_unlock(&inode->i_lock);
261 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 */
258static 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
275 if (!nfs_pageio_add_request(pgio, req)) {
276 nfs_redirty_request(req);
262 if (!nfs_pageio_add_request(pgio, req)) {
263 nfs_redirty_request(req);
277 ret = pgio->pg_error;
264 return pgio->pg_error;
278 }
265 }
279out:
280 return ret;
266 return 0;
281}
282
283static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, struct nfs_pageio_descriptor *pgio)
284{
285 struct inode *inode = page->mapping->host;
286
287 nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE);
288 nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1);

--- 1300 unchanged lines hidden (view full) ---

1589/*
1590 * Write back all requests on one page - we do this before reading it.
1591 */
1592int nfs_wb_page(struct inode *inode, struct page* page)
1593{
1594 return nfs_wb_page_priority(inode, page, FLUSH_STABLE);
1595}
1596
267}
268
269static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, struct nfs_pageio_descriptor *pgio)
270{
271 struct inode *inode = page->mapping->host;
272
273 nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE);
274 nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1);

--- 1300 unchanged lines hidden (view full) ---

1575/*
1576 * Write back all requests on one page - we do this before reading it.
1577 */
1578int nfs_wb_page(struct inode *inode, struct page* page)
1579{
1580 return nfs_wb_page_priority(inode, page, FLUSH_STABLE);
1581}
1582
1597#ifdef CONFIG_MIGRATION
1598int 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);
1624out_unlock:
1625 nfs_clear_page_tag_locked(req);
1626 nfs_release_request(req);
1627out:
1628 return ret;
1629}
1630#endif
1631
1632int __init nfs_init_writepagecache(void)
1633{
1634 nfs_wdata_cachep = kmem_cache_create("nfs_write_data",
1635 sizeof(struct nfs_write_data),
1636 0, SLAB_HWCACHE_ALIGN,
1637 NULL);
1638 if (nfs_wdata_cachep == NULL)
1639 return -ENOMEM;

--- 41 unchanged lines hidden ---
1583int __init nfs_init_writepagecache(void)
1584{
1585 nfs_wdata_cachep = kmem_cache_create("nfs_write_data",
1586 sizeof(struct nfs_write_data),
1587 0, SLAB_HWCACHE_ALIGN,
1588 NULL);
1589 if (nfs_wdata_cachep == NULL)
1590 return -ENOMEM;

--- 41 unchanged lines hidden ---