aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/file.c')
-rw-r--r--fs/nfs/file.c84
1 files changed, 44 insertions, 40 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 8d965bddb87e..2d141a74ae82 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -27,6 +27,7 @@
27#include <linux/pagemap.h> 27#include <linux/pagemap.h>
28#include <linux/aio.h> 28#include <linux/aio.h>
29#include <linux/gfp.h> 29#include <linux/gfp.h>
30#include <linux/swap.h>
30 31
31#include <asm/uaccess.h> 32#include <asm/uaccess.h>
32#include <asm/system.h> 33#include <asm/system.h>
@@ -53,7 +54,7 @@ static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
53static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, 54static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
54 unsigned long nr_segs, loff_t pos); 55 unsigned long nr_segs, loff_t pos);
55static int nfs_file_flush(struct file *, fl_owner_t id); 56static int nfs_file_flush(struct file *, fl_owner_t id);
56static int nfs_file_fsync(struct file *, struct dentry *dentry, int datasync); 57static int nfs_file_fsync(struct file *, int datasync);
57static int nfs_check_flags(int flags); 58static int nfs_check_flags(int flags);
58static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); 59static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
59static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); 60static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
@@ -161,14 +162,17 @@ static int nfs_revalidate_file_size(struct inode *inode, struct file *filp)
161 struct nfs_server *server = NFS_SERVER(inode); 162 struct nfs_server *server = NFS_SERVER(inode);
162 struct nfs_inode *nfsi = NFS_I(inode); 163 struct nfs_inode *nfsi = NFS_I(inode);
163 164
164 if (server->flags & NFS_MOUNT_NOAC) 165 if (nfs_have_delegated_attributes(inode))
165 goto force_reval; 166 goto out_noreval;
167
166 if (filp->f_flags & O_DIRECT) 168 if (filp->f_flags & O_DIRECT)
167 goto force_reval; 169 goto force_reval;
168 if (nfsi->npages != 0) 170 if (nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
169 return 0; 171 goto force_reval;
170 if (!(nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE) && !nfs_attribute_timeout(inode)) 172 if (nfs_attribute_timeout(inode))
171 return 0; 173 goto force_reval;
174out_noreval:
175 return 0;
172force_reval: 176force_reval:
173 return __nfs_revalidate_inode(server, inode); 177 return __nfs_revalidate_inode(server, inode);
174} 178}
@@ -199,37 +203,11 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
199} 203}
200 204
201/* 205/*
202 * Helper for nfs_file_flush() and nfs_file_fsync()
203 *
204 * Notice that it clears the NFS_CONTEXT_ERROR_WRITE before synching to
205 * disk, but it retrieves and clears ctx->error after synching, despite
206 * the two being set at the same time in nfs_context_set_write_error().
207 * This is because the former is used to notify the _next_ call to
208 * nfs_file_write() that a write error occured, and hence cause it to
209 * fall back to doing a synchronous write.
210 */
211static int nfs_do_fsync(struct nfs_open_context *ctx, struct inode *inode)
212{
213 int have_error, status;
214 int ret = 0;
215
216 have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
217 status = nfs_wb_all(inode);
218 have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
219 if (have_error)
220 ret = xchg(&ctx->error, 0);
221 if (!ret)
222 ret = status;
223 return ret;
224}
225
226/*
227 * Flush all dirty pages, and check for write errors. 206 * Flush all dirty pages, and check for write errors.
228 */ 207 */
229static int 208static int
230nfs_file_flush(struct file *file, fl_owner_t id) 209nfs_file_flush(struct file *file, fl_owner_t id)
231{ 210{
232 struct nfs_open_context *ctx = nfs_file_open_context(file);
233 struct dentry *dentry = file->f_path.dentry; 211 struct dentry *dentry = file->f_path.dentry;
234 struct inode *inode = dentry->d_inode; 212 struct inode *inode = dentry->d_inode;
235 213
@@ -242,7 +220,7 @@ nfs_file_flush(struct file *file, fl_owner_t id)
242 return 0; 220 return 0;
243 221
244 /* Flush writes to the server and return any errors */ 222 /* Flush writes to the server and return any errors */
245 return nfs_do_fsync(ctx, inode); 223 return vfs_fsync(file, 0);
246} 224}
247 225
248static ssize_t 226static ssize_t
@@ -317,19 +295,37 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
317 * Flush any dirty pages for this process, and check for write errors. 295 * Flush any dirty pages for this process, and check for write errors.
318 * The return status from this call provides a reliable indication of 296 * The return status from this call provides a reliable indication of
319 * whether any write errors occurred for this process. 297 * whether any write errors occurred for this process.
298 *
299 * Notice that it clears the NFS_CONTEXT_ERROR_WRITE before synching to
300 * disk, but it retrieves and clears ctx->error after synching, despite
301 * the two being set at the same time in nfs_context_set_write_error().
302 * This is because the former is used to notify the _next_ call to
303 * nfs_file_write() that a write error occured, and hence cause it to
304 * fall back to doing a synchronous write.
320 */ 305 */
321static int 306static int
322nfs_file_fsync(struct file *file, struct dentry *dentry, int datasync) 307nfs_file_fsync(struct file *file, int datasync)
323{ 308{
309 struct dentry *dentry = file->f_path.dentry;
324 struct nfs_open_context *ctx = nfs_file_open_context(file); 310 struct nfs_open_context *ctx = nfs_file_open_context(file);
325 struct inode *inode = dentry->d_inode; 311 struct inode *inode = dentry->d_inode;
312 int have_error, status;
313 int ret = 0;
314
326 315
327 dprintk("NFS: fsync file(%s/%s) datasync %d\n", 316 dprintk("NFS: fsync file(%s/%s) datasync %d\n",
328 dentry->d_parent->d_name.name, dentry->d_name.name, 317 dentry->d_parent->d_name.name, dentry->d_name.name,
329 datasync); 318 datasync);
330 319
331 nfs_inc_stats(inode, NFSIOS_VFSFSYNC); 320 nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
332 return nfs_do_fsync(ctx, inode); 321 have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
322 status = nfs_commit_inode(inode, FLUSH_SYNC);
323 have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
324 if (have_error)
325 ret = xchg(&ctx->error, 0);
326 if (!ret)
327 ret = status;
328 return ret;
333} 329}
334 330
335/* 331/*
@@ -489,11 +485,19 @@ static void nfs_invalidate_page(struct page *page, unsigned long offset)
489 */ 485 */
490static int nfs_release_page(struct page *page, gfp_t gfp) 486static int nfs_release_page(struct page *page, gfp_t gfp)
491{ 487{
488 struct address_space *mapping = page->mapping;
489
492 dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page); 490 dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page);
493 491
494 /* Only do I/O if gfp is a superset of GFP_KERNEL */ 492 /* Only do I/O if gfp is a superset of GFP_KERNEL */
495 if ((gfp & GFP_KERNEL) == GFP_KERNEL) 493 if (mapping && (gfp & GFP_KERNEL) == GFP_KERNEL) {
496 nfs_wb_page(page->mapping->host, page); 494 int how = FLUSH_SYNC;
495
496 /* Don't let kswapd deadlock waiting for OOM RPC calls */
497 if (current_is_kswapd())
498 how = 0;
499 nfs_commit_inode(mapping->host, how);
500 }
497 /* If PagePrivate() is set, then the page is not freeable */ 501 /* If PagePrivate() is set, then the page is not freeable */
498 if (PagePrivate(page)) 502 if (PagePrivate(page))
499 return 0; 503 return 0;
@@ -635,7 +639,7 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
635 639
636 /* Return error values for O_DSYNC and IS_SYNC() */ 640 /* Return error values for O_DSYNC and IS_SYNC() */
637 if (result >= 0 && nfs_need_sync_write(iocb->ki_filp, inode)) { 641 if (result >= 0 && nfs_need_sync_write(iocb->ki_filp, inode)) {
638 int err = nfs_do_fsync(nfs_file_open_context(iocb->ki_filp), inode); 642 int err = vfs_fsync(iocb->ki_filp, 0);
639 if (err < 0) 643 if (err < 0)
640 result = err; 644 result = err;
641 } 645 }
@@ -671,7 +675,7 @@ static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
671 written = ret; 675 written = ret;
672 676
673 if (ret >= 0 && nfs_need_sync_write(filp, inode)) { 677 if (ret >= 0 && nfs_need_sync_write(filp, inode)) {
674 int err = nfs_do_fsync(nfs_file_open_context(filp), inode); 678 int err = vfs_fsync(filp, 0);
675 if (err < 0) 679 if (err < 0)
676 ret = err; 680 ret = err;
677 } 681 }