]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/nfs/write.c
Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso...
[karo-tx-linux.git] / fs / nfs / write.c
index 9347ab7c9574fa3b2468a54449d85d366aaf6b61..c483cc50b82ee5aa77f80f0d057550526469f466 100644 (file)
@@ -126,12 +126,16 @@ void nfs_writedata_release(struct nfs_write_data *wdata)
        put_nfs_open_context(wdata->args.context);
        if (wdata->pages.pagevec != wdata->pages.page_array)
                kfree(wdata->pages.pagevec);
-       if (wdata != &write_header->rpc_data)
-               kfree(wdata);
-       else
+       if (wdata == &write_header->rpc_data) {
                wdata->header = NULL;
+               wdata = NULL;
+       }
        if (atomic_dec_and_test(&hdr->refcnt))
                hdr->completion_ops->completion(hdr);
+       /* Note: we only free the rpc_task after callbacks are done.
+        * See the comment in rpc_free_task() for why
+        */
+       kfree(wdata);
 }
 EXPORT_SYMBOL_GPL(nfs_writedata_release);
 
@@ -202,7 +206,6 @@ out:
 /* A writeback failed: mark the page as bad, and invalidate the page cache */
 static void nfs_set_pageerror(struct page *page)
 {
-       SetPageError(page);
        nfs_zap_mapping(page_file_mapping(page)->host, page_file_mapping(page));
 }
 
@@ -239,21 +242,18 @@ int nfs_congestion_kb;
 #define NFS_CONGESTION_OFF_THRESH      \
        (NFS_CONGESTION_ON_THRESH - (NFS_CONGESTION_ON_THRESH >> 2))
 
-static int nfs_set_page_writeback(struct page *page)
+static void nfs_set_page_writeback(struct page *page)
 {
+       struct nfs_server *nfss = NFS_SERVER(page_file_mapping(page)->host);
        int ret = test_set_page_writeback(page);
 
-       if (!ret) {
-               struct inode *inode = page_file_mapping(page)->host;
-               struct nfs_server *nfss = NFS_SERVER(inode);
+       WARN_ON_ONCE(ret != 0);
 
-               if (atomic_long_inc_return(&nfss->writeback) >
-                               NFS_CONGESTION_ON_THRESH) {
-                       set_bdi_congested(&nfss->backing_dev_info,
-                                               BLK_RW_ASYNC);
-               }
+       if (atomic_long_inc_return(&nfss->writeback) >
+                       NFS_CONGESTION_ON_THRESH) {
+               set_bdi_congested(&nfss->backing_dev_info,
+                                       BLK_RW_ASYNC);
        }
-       return ret;
 }
 
 static void nfs_end_page_writeback(struct page *page)
@@ -315,10 +315,10 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
        if (IS_ERR(req))
                goto out;
 
-       ret = nfs_set_page_writeback(page);
-       BUG_ON(ret != 0);
-       BUG_ON(test_bit(PG_CLEAN, &req->wb_flags));
+       nfs_set_page_writeback(page);
+       WARN_ON_ONCE(test_bit(PG_CLEAN, &req->wb_flags));
 
+       ret = 0;
        if (!nfs_pageio_add_request(pgio, req)) {
                nfs_redirty_request(req);
                ret = pgio->pg_error;
@@ -451,8 +451,6 @@ static void nfs_inode_remove_request(struct nfs_page *req)
        struct inode *inode = req->wb_context->dentry->d_inode;
        struct nfs_inode *nfsi = NFS_I(inode);
 
-       BUG_ON (!NFS_WBACK_BUSY(req));
-
        spin_lock(&inode->i_lock);
        if (likely(!PageSwapCache(req->wb_page))) {
                set_page_private(req->wb_page, 0);
@@ -884,7 +882,7 @@ static bool nfs_write_pageuptodate(struct page *page, struct inode *inode)
 {
        if (nfs_have_delegated_attributes(inode))
                goto out;
-       if (NFS_I(inode)->cache_validity & NFS_INO_REVAL_PAGECACHE)
+       if (NFS_I(inode)->cache_validity & (NFS_INO_INVALID_DATA|NFS_INO_REVAL_PAGECACHE))
                return false;
 out:
        return PageUptodate(page) != 0;
@@ -1727,7 +1725,6 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page)
        struct nfs_page *req;
        int ret = 0;
 
-       BUG_ON(!PageLocked(page));
        for (;;) {
                wait_on_page_writeback(page);
                req = nfs_page_find_request(page);
@@ -1801,7 +1798,8 @@ int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
        if (PagePrivate(page))
                return -EBUSY;
 
-       nfs_fscache_release_page(page, GFP_KERNEL);
+       if (!nfs_fscache_release_page(page, GFP_KERNEL))
+               return -EBUSY;
 
        return migrate_page(mapping, newpage, page, mode);
 }
@@ -1829,7 +1827,7 @@ int __init nfs_init_writepagecache(void)
                goto out_destroy_write_mempool;
 
        nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT,
-                                                     nfs_wdata_cachep);
+                                                     nfs_cdata_cachep);
        if (nfs_commit_mempool == NULL)
                goto out_destroy_commit_cache;