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.c48
1 files changed, 41 insertions, 7 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 55c907592490..5621ba9885f4 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -71,6 +71,18 @@ struct inode_operations nfs_file_inode_operations = {
71 .setattr = nfs_setattr, 71 .setattr = nfs_setattr,
72}; 72};
73 73
74#ifdef CONFIG_NFS_V3
75struct inode_operations nfs3_file_inode_operations = {
76 .permission = nfs_permission,
77 .getattr = nfs_getattr,
78 .setattr = nfs_setattr,
79 .listxattr = nfs3_listxattr,
80 .getxattr = nfs3_getxattr,
81 .setxattr = nfs3_setxattr,
82 .removexattr = nfs3_removexattr,
83};
84#endif /* CONFIG_NFS_v3 */
85
74/* Hack for future NFS swap support */ 86/* Hack for future NFS swap support */
75#ifndef IS_SWAPFILE 87#ifndef IS_SWAPFILE
76# define IS_SWAPFILE(inode) (0) 88# define IS_SWAPFILE(inode) (0)
@@ -116,6 +128,21 @@ nfs_file_release(struct inode *inode, struct file *filp)
116} 128}
117 129
118/** 130/**
131 * nfs_revalidate_file - Revalidate the page cache & related metadata
132 * @inode - pointer to inode struct
133 * @file - pointer to file
134 */
135static int nfs_revalidate_file(struct inode *inode, struct file *filp)
136{
137 int retval = 0;
138
139 if ((NFS_FLAGS(inode) & NFS_INO_REVAL_PAGECACHE) || nfs_attribute_timeout(inode))
140 retval = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
141 nfs_revalidate_mapping(inode, filp->f_mapping);
142 return 0;
143}
144
145/**
119 * nfs_revalidate_size - Revalidate the file size 146 * nfs_revalidate_size - Revalidate the file size
120 * @inode - pointer to inode struct 147 * @inode - pointer to inode struct
121 * @file - pointer to struct file 148 * @file - pointer to struct file
@@ -137,7 +164,8 @@ static int nfs_revalidate_file_size(struct inode *inode, struct file *filp)
137 goto force_reval; 164 goto force_reval;
138 if (nfsi->npages != 0) 165 if (nfsi->npages != 0)
139 return 0; 166 return 0;
140 return nfs_revalidate_inode(server, inode); 167 if (!(NFS_FLAGS(inode) & NFS_INO_REVAL_PAGECACHE) && !nfs_attribute_timeout(inode))
168 return 0;
141force_reval: 169force_reval:
142 return __nfs_revalidate_inode(server, inode); 170 return __nfs_revalidate_inode(server, inode);
143} 171}
@@ -198,7 +226,7 @@ nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos)
198 dentry->d_parent->d_name.name, dentry->d_name.name, 226 dentry->d_parent->d_name.name, dentry->d_name.name,
199 (unsigned long) count, (unsigned long) pos); 227 (unsigned long) count, (unsigned long) pos);
200 228
201 result = nfs_revalidate_inode(NFS_SERVER(inode), inode); 229 result = nfs_revalidate_file(inode, iocb->ki_filp);
202 if (!result) 230 if (!result)
203 result = generic_file_aio_read(iocb, buf, count, pos); 231 result = generic_file_aio_read(iocb, buf, count, pos);
204 return result; 232 return result;
@@ -216,7 +244,7 @@ nfs_file_sendfile(struct file *filp, loff_t *ppos, size_t count,
216 dentry->d_parent->d_name.name, dentry->d_name.name, 244 dentry->d_parent->d_name.name, dentry->d_name.name,
217 (unsigned long) count, (unsigned long long) *ppos); 245 (unsigned long) count, (unsigned long long) *ppos);
218 246
219 res = nfs_revalidate_inode(NFS_SERVER(inode), inode); 247 res = nfs_revalidate_file(inode, filp);
220 if (!res) 248 if (!res)
221 res = generic_file_sendfile(filp, ppos, count, actor, target); 249 res = generic_file_sendfile(filp, ppos, count, actor, target);
222 return res; 250 return res;
@@ -232,7 +260,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
232 dfprintk(VFS, "nfs: mmap(%s/%s)\n", 260 dfprintk(VFS, "nfs: mmap(%s/%s)\n",
233 dentry->d_parent->d_name.name, dentry->d_name.name); 261 dentry->d_parent->d_name.name, dentry->d_name.name);
234 262
235 status = nfs_revalidate_inode(NFS_SERVER(inode), inode); 263 status = nfs_revalidate_file(inode, file);
236 if (!status) 264 if (!status)
237 status = generic_file_mmap(file, vma); 265 status = generic_file_mmap(file, vma);
238 return status; 266 return status;
@@ -321,9 +349,15 @@ nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t
321 result = -EBUSY; 349 result = -EBUSY;
322 if (IS_SWAPFILE(inode)) 350 if (IS_SWAPFILE(inode))
323 goto out_swapfile; 351 goto out_swapfile;
324 result = nfs_revalidate_inode(NFS_SERVER(inode), inode); 352 /*
325 if (result) 353 * O_APPEND implies that we must revalidate the file length.
326 goto out; 354 */
355 if (iocb->ki_filp->f_flags & O_APPEND) {
356 result = nfs_revalidate_file_size(inode, iocb->ki_filp);
357 if (result)
358 goto out;
359 }
360 nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
327 361
328 result = count; 362 result = count;
329 if (!count) 363 if (!count)