|
@@ -684,7 +684,8 @@ static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
|
|
|
+static int
|
|
|
+do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
|
|
|
{
|
|
|
struct inode *inode = filp->f_mapping->host;
|
|
|
int status = 0;
|
|
@@ -699,7 +700,7 @@ static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
|
|
|
if (nfs_have_delegation(inode, FMODE_READ))
|
|
|
goto out_noconflict;
|
|
|
|
|
|
- if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)
|
|
|
+ if (is_local)
|
|
|
goto out_noconflict;
|
|
|
|
|
|
status = NFS_PROTO(inode)->lock(filp, cmd, fl);
|
|
@@ -730,7 +731,8 @@ static int do_vfs_lock(struct file *file, struct file_lock *fl)
|
|
|
return res;
|
|
|
}
|
|
|
|
|
|
-static int do_unlk(struct file *filp, int cmd, struct file_lock *fl)
|
|
|
+static int
|
|
|
+do_unlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
|
|
|
{
|
|
|
struct inode *inode = filp->f_mapping->host;
|
|
|
int status;
|
|
@@ -745,15 +747,19 @@ static int do_unlk(struct file *filp, int cmd, struct file_lock *fl)
|
|
|
* If we're signalled while cleaning up locks on process exit, we
|
|
|
* still need to complete the unlock.
|
|
|
*/
|
|
|
- /* Use local locking if mounted with "-onolock" */
|
|
|
- if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM))
|
|
|
+ /*
|
|
|
+ * Use local locking if mounted with "-onolock" or with appropriate
|
|
|
+ * "-olocal_lock="
|
|
|
+ */
|
|
|
+ if (!is_local)
|
|
|
status = NFS_PROTO(inode)->lock(filp, cmd, fl);
|
|
|
else
|
|
|
status = do_vfs_lock(filp, fl);
|
|
|
return status;
|
|
|
}
|
|
|
|
|
|
-static int do_setlk(struct file *filp, int cmd, struct file_lock *fl)
|
|
|
+static int
|
|
|
+do_setlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
|
|
|
{
|
|
|
struct inode *inode = filp->f_mapping->host;
|
|
|
int status;
|
|
@@ -766,8 +772,11 @@ static int do_setlk(struct file *filp, int cmd, struct file_lock *fl)
|
|
|
if (status != 0)
|
|
|
goto out;
|
|
|
|
|
|
- /* Use local locking if mounted with "-onolock" */
|
|
|
- if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM))
|
|
|
+ /*
|
|
|
+ * Use local locking if mounted with "-onolock" or with appropriate
|
|
|
+ * "-olocal_lock="
|
|
|
+ */
|
|
|
+ if (!is_local)
|
|
|
status = NFS_PROTO(inode)->lock(filp, cmd, fl);
|
|
|
else
|
|
|
status = do_vfs_lock(filp, fl);
|
|
@@ -791,6 +800,7 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
|
|
|
{
|
|
|
struct inode *inode = filp->f_mapping->host;
|
|
|
int ret = -ENOLCK;
|
|
|
+ int is_local = 0;
|
|
|
|
|
|
dprintk("NFS: lock(%s/%s, t=%x, fl=%x, r=%lld:%lld)\n",
|
|
|
filp->f_path.dentry->d_parent->d_name.name,
|
|
@@ -804,6 +814,9 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
|
|
|
if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
|
|
|
goto out_err;
|
|
|
|
|
|
+ if (NFS_SERVER(inode)->flags & NFS_MOUNT_LOCAL_FCNTL)
|
|
|
+ is_local = 1;
|
|
|
+
|
|
|
if (NFS_PROTO(inode)->lock_check_bounds != NULL) {
|
|
|
ret = NFS_PROTO(inode)->lock_check_bounds(fl);
|
|
|
if (ret < 0)
|
|
@@ -811,11 +824,11 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
|
|
|
}
|
|
|
|
|
|
if (IS_GETLK(cmd))
|
|
|
- ret = do_getlk(filp, cmd, fl);
|
|
|
+ ret = do_getlk(filp, cmd, fl, is_local);
|
|
|
else if (fl->fl_type == F_UNLCK)
|
|
|
- ret = do_unlk(filp, cmd, fl);
|
|
|
+ ret = do_unlk(filp, cmd, fl, is_local);
|
|
|
else
|
|
|
- ret = do_setlk(filp, cmd, fl);
|
|
|
+ ret = do_setlk(filp, cmd, fl, is_local);
|
|
|
out_err:
|
|
|
return ret;
|
|
|
}
|
|
@@ -825,6 +838,9 @@ out_err:
|
|
|
*/
|
|
|
static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
|
|
|
{
|
|
|
+ struct inode *inode = filp->f_mapping->host;
|
|
|
+ int is_local = 0;
|
|
|
+
|
|
|
dprintk("NFS: flock(%s/%s, t=%x, fl=%x)\n",
|
|
|
filp->f_path.dentry->d_parent->d_name.name,
|
|
|
filp->f_path.dentry->d_name.name,
|
|
@@ -833,14 +849,17 @@ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
|
|
|
if (!(fl->fl_flags & FL_FLOCK))
|
|
|
return -ENOLCK;
|
|
|
|
|
|
+ if (NFS_SERVER(inode)->flags & NFS_MOUNT_LOCAL_FLOCK)
|
|
|
+ is_local = 1;
|
|
|
+
|
|
|
/* We're simulating flock() locks using posix locks on the server */
|
|
|
fl->fl_owner = (fl_owner_t)filp;
|
|
|
fl->fl_start = 0;
|
|
|
fl->fl_end = OFFSET_MAX;
|
|
|
|
|
|
if (fl->fl_type == F_UNLCK)
|
|
|
- return do_unlk(filp, cmd, fl);
|
|
|
- return do_setlk(filp, cmd, fl);
|
|
|
+ return do_unlk(filp, cmd, fl, is_local);
|
|
|
+ return do_setlk(filp, cmd, fl, is_local);
|
|
|
}
|
|
|
|
|
|
/*
|