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 --- |