|
@@ -376,22 +376,31 @@ out_swapfile:
|
|
|
|
|
|
static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
|
|
|
{
|
|
|
+ struct file_lock *cfl;
|
|
|
struct inode *inode = filp->f_mapping->host;
|
|
|
int status = 0;
|
|
|
|
|
|
lock_kernel();
|
|
|
- /* Use local locking if mounted with "-onolock" */
|
|
|
- if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM))
|
|
|
- status = NFS_PROTO(inode)->lock(filp, cmd, fl);
|
|
|
- else {
|
|
|
- struct file_lock *cfl = posix_test_lock(filp, fl);
|
|
|
-
|
|
|
- fl->fl_type = F_UNLCK;
|
|
|
- if (cfl != NULL)
|
|
|
- memcpy(fl, cfl, sizeof(*fl));
|
|
|
+ /* Try local locking first */
|
|
|
+ cfl = posix_test_lock(filp, fl);
|
|
|
+ if (cfl != NULL) {
|
|
|
+ locks_copy_lock(fl, cfl);
|
|
|
+ goto out;
|
|
|
}
|
|
|
+
|
|
|
+ if (nfs_have_delegation(inode, FMODE_READ))
|
|
|
+ goto out_noconflict;
|
|
|
+
|
|
|
+ if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)
|
|
|
+ goto out_noconflict;
|
|
|
+
|
|
|
+ status = NFS_PROTO(inode)->lock(filp, cmd, fl);
|
|
|
+out:
|
|
|
unlock_kernel();
|
|
|
return status;
|
|
|
+out_noconflict:
|
|
|
+ fl->fl_type = F_UNLCK;
|
|
|
+ goto out;
|
|
|
}
|
|
|
|
|
|
static int do_vfs_lock(struct file *file, struct file_lock *fl)
|