aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/write.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r--fs/nfs/write.c79
1 files changed, 46 insertions, 33 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index b39b37f80913..1dda78db6a73 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -20,6 +20,7 @@
20#include <linux/nfs_mount.h> 20#include <linux/nfs_mount.h>
21#include <linux/nfs_page.h> 21#include <linux/nfs_page.h>
22#include <linux/backing-dev.h> 22#include <linux/backing-dev.h>
23#include <linux/export.h>
23 24
24#include <asm/uaccess.h> 25#include <asm/uaccess.h>
25 26
@@ -390,7 +391,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
390 error = radix_tree_insert(&nfsi->nfs_page_tree, req->wb_index, req); 391 error = radix_tree_insert(&nfsi->nfs_page_tree, req->wb_index, req);
391 BUG_ON(error); 392 BUG_ON(error);
392 if (!nfsi->npages && nfs_have_delegation(inode, FMODE_WRITE)) 393 if (!nfsi->npages && nfs_have_delegation(inode, FMODE_WRITE))
393 nfsi->change_attr++; 394 inode->i_version++;
394 set_bit(PG_MAPPED, &req->wb_flags); 395 set_bit(PG_MAPPED, &req->wb_flags);
395 SetPagePrivate(req->wb_page); 396 SetPagePrivate(req->wb_page);
396 set_page_private(req->wb_page, (unsigned long)req); 397 set_page_private(req->wb_page, (unsigned long)req);
@@ -428,7 +429,6 @@ static void
428nfs_mark_request_dirty(struct nfs_page *req) 429nfs_mark_request_dirty(struct nfs_page *req)
429{ 430{
430 __set_page_dirty_nobuffers(req->wb_page); 431 __set_page_dirty_nobuffers(req->wb_page);
431 __mark_inode_dirty(req->wb_page->mapping->host, I_DIRTY_DATASYNC);
432} 432}
433 433
434#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 434#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
@@ -762,6 +762,8 @@ int nfs_updatepage(struct file *file, struct page *page,
762 status = nfs_writepage_setup(ctx, page, offset, count); 762 status = nfs_writepage_setup(ctx, page, offset, count);
763 if (status < 0) 763 if (status < 0)
764 nfs_set_pageerror(page); 764 nfs_set_pageerror(page);
765 else
766 __set_page_dirty_nobuffers(page);
765 767
766 dprintk("NFS: nfs_updatepage returns %d (isize %lld)\n", 768 dprintk("NFS: nfs_updatepage returns %d (isize %lld)\n",
767 status, (long long)i_size_read(inode)); 769 status, (long long)i_size_read(inode));
@@ -958,7 +960,7 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc, struct list_head
958 if (!data) 960 if (!data)
959 goto out_bad; 961 goto out_bad;
960 data->pagevec[0] = page; 962 data->pagevec[0] = page;
961 nfs_write_rpcsetup(req, data, wsize, offset, desc->pg_ioflags); 963 nfs_write_rpcsetup(req, data, len, offset, desc->pg_ioflags);
962 list_add(&data->list, res); 964 list_add(&data->list, res);
963 requests++; 965 requests++;
964 nbytes -= len; 966 nbytes -= len;
@@ -1010,7 +1012,6 @@ static int nfs_flush_one(struct nfs_pageio_descriptor *desc, struct list_head *r
1010 req = nfs_list_entry(head->next); 1012 req = nfs_list_entry(head->next);
1011 nfs_list_remove_request(req); 1013 nfs_list_remove_request(req);
1012 nfs_list_add_request(req, &data->pages); 1014 nfs_list_add_request(req, &data->pages);
1013 ClearPageError(req->wb_page);
1014 *pages++ = req->wb_page; 1015 *pages++ = req->wb_page;
1015 } 1016 }
1016 req = nfs_list_entry(data->pages.next); 1017 req = nfs_list_entry(data->pages.next);
@@ -1165,7 +1166,13 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
1165static void nfs_writeback_release_full(void *calldata) 1166static void nfs_writeback_release_full(void *calldata)
1166{ 1167{
1167 struct nfs_write_data *data = calldata; 1168 struct nfs_write_data *data = calldata;
1168 int status = data->task.tk_status; 1169 int ret, status = data->task.tk_status;
1170 struct nfs_pageio_descriptor pgio;
1171
1172 if (data->pnfs_error) {
1173 nfs_pageio_init_write_mds(&pgio, data->inode, FLUSH_STABLE);
1174 pgio.pg_recoalesce = 1;
1175 }
1169 1176
1170 /* Update attributes as result of writeback. */ 1177 /* Update attributes as result of writeback. */
1171 while (!list_empty(&data->pages)) { 1178 while (!list_empty(&data->pages)) {
@@ -1181,6 +1188,11 @@ static void nfs_writeback_release_full(void *calldata)
1181 req->wb_bytes, 1188 req->wb_bytes,
1182 (long long)req_offset(req)); 1189 (long long)req_offset(req));
1183 1190
1191 if (data->pnfs_error) {
1192 dprintk(", pnfs error = %d\n", data->pnfs_error);
1193 goto next;
1194 }
1195
1184 if (status < 0) { 1196 if (status < 0) {
1185 nfs_set_pageerror(page); 1197 nfs_set_pageerror(page);
1186 nfs_context_set_write_error(req->wb_context, status); 1198 nfs_context_set_write_error(req->wb_context, status);
@@ -1200,7 +1212,19 @@ remove_request:
1200 next: 1212 next:
1201 nfs_clear_page_tag_locked(req); 1213 nfs_clear_page_tag_locked(req);
1202 nfs_end_page_writeback(page); 1214 nfs_end_page_writeback(page);
1215 if (data->pnfs_error) {
1216 lock_page(page);
1217 nfs_pageio_cond_complete(&pgio, page->index);
1218 ret = nfs_page_async_flush(&pgio, page, 0);
1219 if (ret) {
1220 nfs_set_pageerror(page);
1221 dprintk("rewrite to MDS error = %d\n", ret);
1222 }
1223 unlock_page(page);
1224 }
1203 } 1225 }
1226 if (data->pnfs_error)
1227 nfs_pageio_complete(&pgio);
1204 nfs_writedata_release(calldata); 1228 nfs_writedata_release(calldata);
1205} 1229}
1206 1230
@@ -1220,7 +1244,6 @@ void nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1220{ 1244{
1221 struct nfs_writeargs *argp = &data->args; 1245 struct nfs_writeargs *argp = &data->args;
1222 struct nfs_writeres *resp = &data->res; 1246 struct nfs_writeres *resp = &data->res;
1223 struct nfs_server *server = NFS_SERVER(data->inode);
1224 int status; 1247 int status;
1225 1248
1226 dprintk("NFS: %5u nfs_writeback_done (status %d)\n", 1249 dprintk("NFS: %5u nfs_writeback_done (status %d)\n",
@@ -1254,7 +1277,7 @@ void nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1254 if (time_before(complain, jiffies)) { 1277 if (time_before(complain, jiffies)) {
1255 dprintk("NFS: faulty NFS server %s:" 1278 dprintk("NFS: faulty NFS server %s:"
1256 " (committed = %d) != (stable = %d)\n", 1279 " (committed = %d) != (stable = %d)\n",
1257 server->nfs_client->cl_hostname, 1280 NFS_SERVER(data->inode)->nfs_client->cl_hostname,
1258 resp->verf->committed, argp->stable); 1281 resp->verf->committed, argp->stable);
1259 complain = jiffies + 300 * HZ; 1282 complain = jiffies + 300 * HZ;
1260 } 1283 }
@@ -1281,7 +1304,7 @@ void nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1281 */ 1304 */
1282 argp->stable = NFS_FILE_SYNC; 1305 argp->stable = NFS_FILE_SYNC;
1283 } 1306 }
1284 nfs_restart_rpc(task, server->nfs_client); 1307 rpc_restart_call_prepare(task);
1285 return; 1308 return;
1286 } 1309 }
1287 if (time_before(complain, jiffies)) { 1310 if (time_before(complain, jiffies)) {
@@ -1553,6 +1576,10 @@ static int nfs_commit_unstable_pages(struct inode *inode, struct writeback_contr
1553 int flags = FLUSH_SYNC; 1576 int flags = FLUSH_SYNC;
1554 int ret = 0; 1577 int ret = 0;
1555 1578
1579 /* no commits means nothing needs to be done */
1580 if (!nfsi->ncommit)
1581 return ret;
1582
1556 if (wbc->sync_mode == WB_SYNC_NONE) { 1583 if (wbc->sync_mode == WB_SYNC_NONE) {
1557 /* Don't commit yet if this is a non-blocking flush and there 1584 /* Don't commit yet if this is a non-blocking flush and there
1558 * are a lot of outstanding writes for this mapping. 1585 * are a lot of outstanding writes for this mapping.
@@ -1686,34 +1713,20 @@ out_error:
1686int nfs_migrate_page(struct address_space *mapping, struct page *newpage, 1713int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
1687 struct page *page) 1714 struct page *page)
1688{ 1715{
1689 struct nfs_page *req; 1716 /*
1690 int ret; 1717 * If PagePrivate is set, then the page is currently associated with
1718 * an in-progress read or write request. Don't try to migrate it.
1719 *
1720 * FIXME: we could do this in principle, but we'll need a way to ensure
1721 * that we can safely release the inode reference while holding
1722 * the page lock.
1723 */
1724 if (PagePrivate(page))
1725 return -EBUSY;
1691 1726
1692 nfs_fscache_release_page(page, GFP_KERNEL); 1727 nfs_fscache_release_page(page, GFP_KERNEL);
1693 1728
1694 req = nfs_find_and_lock_request(page, false); 1729 return migrate_page(mapping, newpage, page);
1695 ret = PTR_ERR(req);
1696 if (IS_ERR(req))
1697 goto out;
1698
1699 ret = migrate_page(mapping, newpage, page);
1700 if (!req)
1701 goto out;
1702 if (ret)
1703 goto out_unlock;
1704 page_cache_get(newpage);
1705 spin_lock(&mapping->host->i_lock);
1706 req->wb_page = newpage;
1707 SetPagePrivate(newpage);
1708 set_page_private(newpage, (unsigned long)req);
1709 ClearPagePrivate(page);
1710 set_page_private(page, 0);
1711 spin_unlock(&mapping->host->i_lock);
1712 page_cache_release(page);
1713out_unlock:
1714 nfs_clear_page_tag_locked(req);
1715out:
1716 return ret;
1717} 1730}
1718#endif 1731#endif
1719 1732