diff options
Diffstat (limited to 'fs/nfs/file.c')
-rw-r--r-- | fs/nfs/file.c | 48 |
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 | ||
75 | struct 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 | */ | ||
135 | static 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; | ||
141 | force_reval: | 169 | force_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) |