diff options
Diffstat (limited to 'fs/nfs/file.c')
-rw-r--r-- | fs/nfs/file.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 6bdcfa95de94..57d3e77d97ee 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -205,8 +205,8 @@ nfs_file_flush(struct file *file) | |||
205 | if (!status) { | 205 | if (!status) { |
206 | status = ctx->error; | 206 | status = ctx->error; |
207 | ctx->error = 0; | 207 | ctx->error = 0; |
208 | if (!status && !nfs_have_delegation(inode, FMODE_READ)) | 208 | if (!status) |
209 | __nfs_revalidate_inode(NFS_SERVER(inode), inode); | 209 | nfs_revalidate_inode(NFS_SERVER(inode), inode); |
210 | } | 210 | } |
211 | unlock_kernel(); | 211 | unlock_kernel(); |
212 | return status; | 212 | return status; |
@@ -376,22 +376,31 @@ out_swapfile: | |||
376 | 376 | ||
377 | static int do_getlk(struct file *filp, int cmd, struct file_lock *fl) | 377 | static int do_getlk(struct file *filp, int cmd, struct file_lock *fl) |
378 | { | 378 | { |
379 | struct file_lock *cfl; | ||
379 | struct inode *inode = filp->f_mapping->host; | 380 | struct inode *inode = filp->f_mapping->host; |
380 | int status = 0; | 381 | int status = 0; |
381 | 382 | ||
382 | lock_kernel(); | 383 | lock_kernel(); |
383 | /* Use local locking if mounted with "-onolock" */ | 384 | /* Try local locking first */ |
384 | if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)) | 385 | cfl = posix_test_lock(filp, fl); |
385 | status = NFS_PROTO(inode)->lock(filp, cmd, fl); | 386 | if (cfl != NULL) { |
386 | else { | 387 | locks_copy_lock(fl, cfl); |
387 | struct file_lock *cfl = posix_test_lock(filp, fl); | 388 | goto out; |
388 | |||
389 | fl->fl_type = F_UNLCK; | ||
390 | if (cfl != NULL) | ||
391 | memcpy(fl, cfl, sizeof(*fl)); | ||
392 | } | 389 | } |
390 | |||
391 | if (nfs_have_delegation(inode, FMODE_READ)) | ||
392 | goto out_noconflict; | ||
393 | |||
394 | if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM) | ||
395 | goto out_noconflict; | ||
396 | |||
397 | status = NFS_PROTO(inode)->lock(filp, cmd, fl); | ||
398 | out: | ||
393 | unlock_kernel(); | 399 | unlock_kernel(); |
394 | return status; | 400 | return status; |
401 | out_noconflict: | ||
402 | fl->fl_type = F_UNLCK; | ||
403 | goto out; | ||
395 | } | 404 | } |
396 | 405 | ||
397 | static int do_vfs_lock(struct file *file, struct file_lock *fl) | 406 | static int do_vfs_lock(struct file *file, struct file_lock *fl) |