aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-12-05 00:35:40 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-12-06 10:46:38 -0500
commit200baa2112012dd8a13db9da3ee6885403f9c013 (patch)
tree261f9c2b85927c2dfaaecfb7ab808d353bd84da4 /fs/nfs
parente21195a740533348e77efa8a2e2cf03bb4092b2b (diff)
NFS: Remove nfs_writepage_sync()
Maintaining two parallel ways of doing synchronous writes is rather pointless. This patch gets rid of the legacy nfs_writepage_sync(), and replaces it with the faster asynchronous writes. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/file.c6
-rw-r--r--fs/nfs/nfs3proc.c47
-rw-r--r--fs/nfs/nfs4proc.c85
-rw-r--r--fs/nfs/proc.c28
-rw-r--r--fs/nfs/write.c100
5 files changed, 10 insertions, 256 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index d6ee60fc3ba6..143a19037ce8 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -378,6 +378,12 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
378 378
379 nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count); 379 nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count);
380 result = generic_file_aio_write(iocb, iov, nr_segs, pos); 380 result = generic_file_aio_write(iocb, iov, nr_segs, pos);
381 /* Return error values for O_SYNC and IS_SYNC() */
382 if (result >= 0 && (IS_SYNC(inode) || (iocb->ki_filp->f_flags & O_SYNC))) {
383 int err = nfs_fsync(iocb->ki_filp, dentry, 1);
384 if (err < 0)
385 result = err;
386 }
381out: 387out:
382 return result; 388 return result;
383 389
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 7fba06306b82..510ae524f3fd 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -276,51 +276,6 @@ static int nfs3_proc_read(struct nfs_read_data *rdata)
276 return status; 276 return status;
277} 277}
278 278
279static int nfs3_proc_write(struct nfs_write_data *wdata)
280{
281 int rpcflags = wdata->flags;
282 struct inode * inode = wdata->inode;
283 struct nfs_fattr * fattr = wdata->res.fattr;
284 struct rpc_message msg = {
285 .rpc_proc = &nfs3_procedures[NFS3PROC_WRITE],
286 .rpc_argp = &wdata->args,
287 .rpc_resp = &wdata->res,
288 .rpc_cred = wdata->cred,
289 };
290 int status;
291
292 dprintk("NFS call write %d @ %Ld\n", wdata->args.count,
293 (long long) wdata->args.offset);
294 nfs_fattr_init(fattr);
295 status = rpc_call_sync(NFS_CLIENT(inode), &msg, rpcflags);
296 if (status >= 0)
297 nfs_post_op_update_inode(inode, fattr);
298 dprintk("NFS reply write: %d\n", status);
299 return status < 0? status : wdata->res.count;
300}
301
302static int nfs3_proc_commit(struct nfs_write_data *cdata)
303{
304 struct inode * inode = cdata->inode;
305 struct nfs_fattr * fattr = cdata->res.fattr;
306 struct rpc_message msg = {
307 .rpc_proc = &nfs3_procedures[NFS3PROC_COMMIT],
308 .rpc_argp = &cdata->args,
309 .rpc_resp = &cdata->res,
310 .rpc_cred = cdata->cred,
311 };
312 int status;
313
314 dprintk("NFS call commit %d @ %Ld\n", cdata->args.count,
315 (long long) cdata->args.offset);
316 nfs_fattr_init(fattr);
317 status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
318 if (status >= 0)
319 nfs_post_op_update_inode(inode, fattr);
320 dprintk("NFS reply commit: %d\n", status);
321 return status;
322}
323
324/* 279/*
325 * Create a regular file. 280 * Create a regular file.
326 * For now, we don't implement O_EXCL. 281 * For now, we don't implement O_EXCL.
@@ -901,8 +856,6 @@ const struct nfs_rpc_ops nfs_v3_clientops = {
901 .access = nfs3_proc_access, 856 .access = nfs3_proc_access,
902 .readlink = nfs3_proc_readlink, 857 .readlink = nfs3_proc_readlink,
903 .read = nfs3_proc_read, 858 .read = nfs3_proc_read,
904 .write = nfs3_proc_write,
905 .commit = nfs3_proc_commit,
906 .create = nfs3_proc_create, 859 .create = nfs3_proc_create,
907 .remove = nfs3_proc_remove, 860 .remove = nfs3_proc_remove,
908 .unlink_setup = nfs3_proc_unlink_setup, 861 .unlink_setup = nfs3_proc_unlink_setup,
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 4b5fc714d786..ee458aeab24a 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1775,89 +1775,6 @@ static int nfs4_proc_read(struct nfs_read_data *rdata)
1775 return err; 1775 return err;
1776} 1776}
1777 1777
1778static int _nfs4_proc_write(struct nfs_write_data *wdata)
1779{
1780 int rpcflags = wdata->flags;
1781 struct inode *inode = wdata->inode;
1782 struct nfs_fattr *fattr = wdata->res.fattr;
1783 struct nfs_server *server = NFS_SERVER(inode);
1784 struct rpc_message msg = {
1785 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE],
1786 .rpc_argp = &wdata->args,
1787 .rpc_resp = &wdata->res,
1788 .rpc_cred = wdata->cred,
1789 };
1790 int status;
1791
1792 dprintk("NFS call write %d @ %Ld\n", wdata->args.count,
1793 (long long) wdata->args.offset);
1794
1795 wdata->args.bitmask = server->attr_bitmask;
1796 wdata->res.server = server;
1797 wdata->timestamp = jiffies;
1798 nfs_fattr_init(fattr);
1799 status = rpc_call_sync(server->client, &msg, rpcflags);
1800 dprintk("NFS reply write: %d\n", status);
1801 if (status < 0)
1802 return status;
1803 renew_lease(server, wdata->timestamp);
1804 nfs_post_op_update_inode(inode, fattr);
1805 return wdata->res.count;
1806}
1807
1808static int nfs4_proc_write(struct nfs_write_data *wdata)
1809{
1810 struct nfs4_exception exception = { };
1811 int err;
1812 do {
1813 err = nfs4_handle_exception(NFS_SERVER(wdata->inode),
1814 _nfs4_proc_write(wdata),
1815 &exception);
1816 } while (exception.retry);
1817 return err;
1818}
1819
1820static int _nfs4_proc_commit(struct nfs_write_data *cdata)
1821{
1822 struct inode *inode = cdata->inode;
1823 struct nfs_fattr *fattr = cdata->res.fattr;
1824 struct nfs_server *server = NFS_SERVER(inode);
1825 struct rpc_message msg = {
1826 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT],
1827 .rpc_argp = &cdata->args,
1828 .rpc_resp = &cdata->res,
1829 .rpc_cred = cdata->cred,
1830 };
1831 int status;
1832
1833 dprintk("NFS call commit %d @ %Ld\n", cdata->args.count,
1834 (long long) cdata->args.offset);
1835
1836 cdata->args.bitmask = server->attr_bitmask;
1837 cdata->res.server = server;
1838 cdata->timestamp = jiffies;
1839 nfs_fattr_init(fattr);
1840 status = rpc_call_sync(server->client, &msg, 0);
1841 if (status >= 0)
1842 renew_lease(server, cdata->timestamp);
1843 dprintk("NFS reply commit: %d\n", status);
1844 if (status >= 0)
1845 nfs_post_op_update_inode(inode, fattr);
1846 return status;
1847}
1848
1849static int nfs4_proc_commit(struct nfs_write_data *cdata)
1850{
1851 struct nfs4_exception exception = { };
1852 int err;
1853 do {
1854 err = nfs4_handle_exception(NFS_SERVER(cdata->inode),
1855 _nfs4_proc_commit(cdata),
1856 &exception);
1857 } while (exception.retry);
1858 return err;
1859}
1860
1861/* 1778/*
1862 * Got race? 1779 * Got race?
1863 * We will need to arrange for the VFS layer to provide an atomic open. 1780 * We will need to arrange for the VFS layer to provide an atomic open.
@@ -3730,8 +3647,6 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
3730 .access = nfs4_proc_access, 3647 .access = nfs4_proc_access,
3731 .readlink = nfs4_proc_readlink, 3648 .readlink = nfs4_proc_readlink,
3732 .read = nfs4_proc_read, 3649 .read = nfs4_proc_read,
3733 .write = nfs4_proc_write,
3734 .commit = nfs4_proc_commit,
3735 .create = nfs4_proc_create, 3650 .create = nfs4_proc_create,
3736 .remove = nfs4_proc_remove, 3651 .remove = nfs4_proc_remove,
3737 .unlink_setup = nfs4_proc_unlink_setup, 3652 .unlink_setup = nfs4_proc_unlink_setup,
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 7a9013dd5d0a..10f5e80ca157 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -215,32 +215,6 @@ static int nfs_proc_read(struct nfs_read_data *rdata)
215 return status; 215 return status;
216} 216}
217 217
218static int nfs_proc_write(struct nfs_write_data *wdata)
219{
220 int flags = wdata->flags;
221 struct inode * inode = wdata->inode;
222 struct nfs_fattr * fattr = wdata->res.fattr;
223 struct rpc_message msg = {
224 .rpc_proc = &nfs_procedures[NFSPROC_WRITE],
225 .rpc_argp = &wdata->args,
226 .rpc_resp = &wdata->res,
227 .rpc_cred = wdata->cred,
228 };
229 int status;
230
231 dprintk("NFS call write %d @ %Ld\n", wdata->args.count,
232 (long long) wdata->args.offset);
233 nfs_fattr_init(fattr);
234 status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
235 if (status >= 0) {
236 nfs_post_op_update_inode(inode, fattr);
237 wdata->res.count = wdata->args.count;
238 wdata->verf.committed = NFS_FILE_SYNC;
239 }
240 dprintk("NFS reply write: %d\n", status);
241 return status < 0? status : wdata->res.count;
242}
243
244static int 218static int
245nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, 219nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
246 int flags, struct nameidata *nd) 220 int flags, struct nameidata *nd)
@@ -693,8 +667,6 @@ const struct nfs_rpc_ops nfs_v2_clientops = {
693 .access = NULL, /* access */ 667 .access = NULL, /* access */
694 .readlink = nfs_proc_readlink, 668 .readlink = nfs_proc_readlink,
695 .read = nfs_proc_read, 669 .read = nfs_proc_read,
696 .write = nfs_proc_write,
697 .commit = NULL, /* commit */
698 .create = nfs_proc_create, 670 .create = nfs_proc_create,
699 .remove = nfs_proc_remove, 671 .remove = nfs_proc_remove,
700 .unlink_setup = nfs_proc_unlink_setup, 672 .unlink_setup = nfs_proc_unlink_setup,
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index de9a16a8f7e4..f0720b544b12 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -210,78 +210,6 @@ static void nfs_mark_uptodate(struct page *page, unsigned int base, unsigned int
210 SetPageUptodate(page); 210 SetPageUptodate(page);
211} 211}
212 212
213/*
214 * Write a page synchronously.
215 * Offset is the data offset within the page.
216 */
217static int nfs_writepage_sync(struct nfs_open_context *ctx, struct page *page,
218 unsigned int offset, unsigned int count, int how)
219{
220 struct inode *inode = page->mapping->host;
221 unsigned int wsize = NFS_SERVER(inode)->wsize;
222 int result, written = 0;
223 struct nfs_write_data *wdata;
224
225 wdata = nfs_writedata_alloc(wsize);
226 if (!wdata)
227 return -ENOMEM;
228
229 wdata->flags = how;
230 wdata->cred = ctx->cred;
231 wdata->inode = inode;
232 wdata->args.fh = NFS_FH(inode);
233 wdata->args.context = ctx;
234 wdata->args.pages = &page;
235 wdata->args.stable = NFS_FILE_SYNC;
236 wdata->args.pgbase = offset;
237 wdata->args.count = wsize;
238 wdata->res.fattr = &wdata->fattr;
239 wdata->res.verf = &wdata->verf;
240
241 dprintk("NFS: nfs_writepage_sync(%s/%Ld %d@%Ld)\n",
242 inode->i_sb->s_id,
243 (long long)NFS_FILEID(inode),
244 count, (long long)(page_offset(page) + offset));
245
246 set_page_writeback(page);
247 nfs_begin_data_update(inode);
248 do {
249 if (count < wsize)
250 wdata->args.count = count;
251 wdata->args.offset = page_offset(page) + wdata->args.pgbase;
252
253 result = NFS_PROTO(inode)->write(wdata);
254
255 if (result < 0) {
256 /* Must mark the page invalid after I/O error */
257 ClearPageUptodate(page);
258 goto io_error;
259 }
260 if (result < wdata->args.count)
261 printk(KERN_WARNING "NFS: short write, count=%u, result=%d\n",
262 wdata->args.count, result);
263
264 wdata->args.offset += result;
265 wdata->args.pgbase += result;
266 written += result;
267 count -= result;
268 nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, result);
269 } while (count);
270 /* Update file length */
271 nfs_grow_file(page, offset, written);
272 /* Set the PG_uptodate flag? */
273 nfs_mark_uptodate(page, offset, written);
274
275 if (PageError(page))
276 ClearPageError(page);
277
278io_error:
279 nfs_end_data_update(inode);
280 end_page_writeback(page);
281 nfs_writedata_release(wdata);
282 return written ? written : result;
283}
284
285static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page, 213static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page,
286 unsigned int offset, unsigned int count) 214 unsigned int offset, unsigned int count)
287{ 215{
@@ -342,22 +270,12 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc)
342 err = -EBADF; 270 err = -EBADF;
343 goto out; 271 goto out;
344 } 272 }
345 lock_kernel(); 273 err = nfs_writepage_setup(ctx, page, 0, offset);
346 if (!IS_SYNC(inode)) {
347 err = nfs_writepage_setup(ctx, page, 0, offset);
348 if (!wbc->for_writepages)
349 nfs_flush_mapping(page->mapping, wbc, wb_priority(wbc));
350 } else {
351 err = nfs_writepage_sync(ctx, page, 0, offset, wb_priority(wbc));
352 if (err >= 0) {
353 if (err != offset)
354 redirty_page_for_writepage(wbc, page);
355 err = 0;
356 }
357 }
358 unlock_kernel();
359 put_nfs_open_context(ctx); 274 put_nfs_open_context(ctx);
275
360out: 276out:
277 if (!wbc->for_writepages)
278 nfs_flush_mapping(page->mapping, wbc, wb_priority(wbc));
361 unlock_page(page); 279 unlock_page(page);
362 return err; 280 return err;
363} 281}
@@ -777,16 +695,6 @@ int nfs_updatepage(struct file *file, struct page *page,
777 file->f_dentry->d_name.name, count, 695 file->f_dentry->d_name.name, count,
778 (long long)(page_offset(page) +offset)); 696 (long long)(page_offset(page) +offset));
779 697
780 if (IS_SYNC(inode)) {
781 status = nfs_writepage_sync(ctx, page, offset, count, 0);
782 if (status > 0) {
783 if (offset == 0 && status == PAGE_CACHE_SIZE)
784 SetPageUptodate(page);
785 return 0;
786 }
787 return status;
788 }
789
790 /* If we're not using byte range locks, and we know the page 698 /* If we're not using byte range locks, and we know the page
791 * is entirely in cache, it may be more efficient to avoid 699 * is entirely in cache, it may be more efficient to avoid
792 * fragmenting write requests. 700 * fragmenting write requests.