linux-cifs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH][CIFS] Add flock support
@ 2019-07-17  0:02 Steve French
  2019-07-17  0:49 ` Steve French
  2019-07-19 20:56 ` J. Bruce Fields
  0 siblings, 2 replies; 6+ messages in thread
From: Steve French @ 2019-07-17  0:02 UTC (permalink / raw)
  To: linux-fsdevel, CIFS

[-- Attachment #1: Type: text/plain, Size: 321 bytes --]

The attached patch adds support for flock support similar to AFS, NFS etc.

Although the patch did seem to work in my experiments with flock, I did notice
that xfstest generic/504 fails because /proc/locks is not updated by cifs.ko
after a successful lock.  Any idea which helper function does that?


-- 
Thanks,

Steve

[-- Attachment #2: 0001-cifs-add-support-for-flock.patch --]
[-- Type: text/x-patch, Size: 3959 bytes --]

From 9de8e68a8ab0c7e59080874f05b1df37477cf691 Mon Sep 17 00:00:00 2001
From: Steve French <stfrench@microsoft.com>
Date: Tue, 16 Jul 2019 18:55:38 -0500
Subject: [PATCH] cifs: add support for flock

The flock system call locks the whole file rather than a byte
range and is currently emulated by various other file systems
by simply sending a byte range lock for the whole file.

This version of the patch needs a minor update to pass
xfstest generic/504 (we need to figure out how to update
/proc/locks after an flock call is granted)

Signed-off-by: Steve French <stfrench@microsoft.com>
---
 fs/cifs/cifsfs.c |  3 +++
 fs/cifs/cifsfs.h |  1 +
 fs/cifs/file.c   | 54 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+)

diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 320c7a6fd318..a674f52b0403 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -1168,6 +1168,7 @@ const struct file_operations cifs_file_ops = {
 	.open = cifs_open,
 	.release = cifs_close,
 	.lock = cifs_lock,
+	.flock = cifs_flock,
 	.fsync = cifs_fsync,
 	.flush = cifs_flush,
 	.mmap  = cifs_file_mmap,
@@ -1187,6 +1188,7 @@ const struct file_operations cifs_file_strict_ops = {
 	.open = cifs_open,
 	.release = cifs_close,
 	.lock = cifs_lock,
+	.flock = cifs_flock,
 	.fsync = cifs_strict_fsync,
 	.flush = cifs_flush,
 	.mmap = cifs_file_strict_mmap,
@@ -1206,6 +1208,7 @@ const struct file_operations cifs_file_direct_ops = {
 	.open = cifs_open,
 	.release = cifs_close,
 	.lock = cifs_lock,
+	.flock = cifs_flock,
 	.fsync = cifs_fsync,
 	.flush = cifs_flush,
 	.mmap = cifs_file_mmap,
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index aea005703785..262f709822ee 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -108,6 +108,7 @@ extern ssize_t cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to);
 extern ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from);
 extern ssize_t cifs_direct_writev(struct kiocb *iocb, struct iov_iter *from);
 extern ssize_t cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from);
+extern int cifs_flock(struct file *file, int cmd, struct file_lock *fl);
 extern int cifs_lock(struct file *, int, struct file_lock *);
 extern int cifs_fsync(struct file *, loff_t, loff_t, int);
 extern int cifs_strict_fsync(struct file *, loff_t, loff_t, int);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 97090693d182..641927755d0b 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1685,6 +1685,60 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
 	return rc;
 }
 
+int cifs_flock(struct file *file, int cmd, struct file_lock *fl)
+{
+	int rc, xid;
+	int lock = 0, unlock = 0;
+	bool wait_flag = false;
+	bool posix_lck = false;
+	struct cifs_sb_info *cifs_sb;
+	struct cifs_tcon *tcon;
+	struct cifsInodeInfo *cinode;
+	struct cifsFileInfo *cfile;
+	__u16 netfid;
+	__u32 type;
+
+	rc = -EACCES;
+	xid = get_xid();
+
+	if (!(fl->fl_flags & FL_FLOCK)) {
+		cifs_dbg(VFS, "ret nolock\n");
+		return -ENOLCK;
+	}
+
+	cfile = (struct cifsFileInfo *)file->private_data;
+	tcon = tlink_tcon(cfile->tlink);
+
+	cifs_read_flock(fl, &type, &lock, &unlock, &wait_flag,
+			tcon->ses->server);
+	cifs_sb = CIFS_FILE_SB(file);
+	netfid = cfile->fid.netfid;
+	cinode = CIFS_I(file_inode(file));
+
+	if (cap_unix(tcon->ses) &&
+	    (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
+	    ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
+		posix_lck = true;
+
+	if (!lock && !unlock) {
+		/*
+		 * if no lock or unlock then nothing to do since we do not
+		 * know what it is
+		 */
+		cifs_dbg(VFS, "return FLOCK EOPNOTSUPP\n");
+		free_xid(xid);
+		return -EOPNOTSUPP;
+	}
+
+	rc = cifs_setlk(file, fl, type, wait_flag, posix_lck, lock, unlock,
+			xid);
+	free_xid(xid);
+	cifs_dbg(VFS, "FLOCK rc = %d\n", rc);
+	return rc;
+
+
+}
+
 int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
 {
 	int rc, xid;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH][CIFS] Add flock support
  2019-07-17  0:02 [PATCH][CIFS] Add flock support Steve French
@ 2019-07-17  0:49 ` Steve French
  2019-07-17  1:02   ` ronnie sahlberg
  2019-07-19 20:56 ` J. Bruce Fields
  1 sibling, 1 reply; 6+ messages in thread
From: Steve French @ 2019-07-17  0:49 UTC (permalink / raw)
  To: linux-fsdevel, CIFS

[-- Attachment #1: Type: text/plain, Size: 499 bytes --]

Pavel spotted the problem - fixed and reattached updated patch


On Tue, Jul 16, 2019 at 7:02 PM Steve French <smfrench@gmail.com> wrote:
>
> The attached patch adds support for flock support similar to AFS, NFS etc.
>
> Although the patch did seem to work in my experiments with flock, I did notice
> that xfstest generic/504 fails because /proc/locks is not updated by cifs.ko
> after a successful lock.  Any idea which helper function does that?
>
>
> --
> Thanks,
>
> Steve



--
Thanks,

Steve

[-- Attachment #2: 0001-cifs-add-support-for-flock.patch --]
[-- Type: text/x-patch, Size: 4155 bytes --]

From 8d39f6fe03db250fe526c0028016073afa020b03 Mon Sep 17 00:00:00 2001
From: Steve French <stfrench@microsoft.com>
Date: Tue, 16 Jul 2019 18:55:38 -0500
Subject: [PATCH] cifs: add support for flock

The flock system call locks the whole file rather than a byte
range and so is currently emulated by various other file systems
by simply sending a byte range lock for the whole file.
Add flock handling for cifs.ko in similar way.

xfstest generic/504 passes with this as well

Signed-off-by: Steve French <stfrench@microsoft.com>
---
 fs/cifs/cifsfs.c |  3 +++
 fs/cifs/cifsfs.h |  1 +
 fs/cifs/file.c   | 52 +++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 320c7a6fd318..a674f52b0403 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -1168,6 +1168,7 @@ const struct file_operations cifs_file_ops = {
 	.open = cifs_open,
 	.release = cifs_close,
 	.lock = cifs_lock,
+	.flock = cifs_flock,
 	.fsync = cifs_fsync,
 	.flush = cifs_flush,
 	.mmap  = cifs_file_mmap,
@@ -1187,6 +1188,7 @@ const struct file_operations cifs_file_strict_ops = {
 	.open = cifs_open,
 	.release = cifs_close,
 	.lock = cifs_lock,
+	.flock = cifs_flock,
 	.fsync = cifs_strict_fsync,
 	.flush = cifs_flush,
 	.mmap = cifs_file_strict_mmap,
@@ -1206,6 +1208,7 @@ const struct file_operations cifs_file_direct_ops = {
 	.open = cifs_open,
 	.release = cifs_close,
 	.lock = cifs_lock,
+	.flock = cifs_flock,
 	.fsync = cifs_fsync,
 	.flush = cifs_flush,
 	.mmap = cifs_file_mmap,
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index aea005703785..262f709822ee 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -108,6 +108,7 @@ extern ssize_t cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to);
 extern ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from);
 extern ssize_t cifs_direct_writev(struct kiocb *iocb, struct iov_iter *from);
 extern ssize_t cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from);
+extern int cifs_flock(struct file *, int, struct file_lock *);
 extern int cifs_lock(struct file *, int, struct file_lock *);
 extern int cifs_fsync(struct file *, loff_t, loff_t, int);
 extern int cifs_strict_fsync(struct file *, loff_t, loff_t, int);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 97090693d182..e2def891fb2c 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1668,7 +1668,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
 		rc = server->ops->mand_unlock_range(cfile, flock, xid);
 
 out:
-	if (flock->fl_flags & FL_POSIX) {
+	if ((flock->fl_flags & FL_POSIX) || (flock->fl_flags & FL_FLOCK)) {
 		/*
 		 * If this is a request to remove all locks because we
 		 * are closing the file, it doesn't matter if the
@@ -1685,6 +1685,56 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
 	return rc;
 }
 
+int cifs_flock(struct file *file, int cmd, struct file_lock *fl)
+{
+	int rc, xid;
+	int lock = 0, unlock = 0;
+	bool wait_flag = false;
+	bool posix_lck = false;
+	struct cifs_sb_info *cifs_sb;
+	struct cifs_tcon *tcon;
+	struct cifsInodeInfo *cinode;
+	struct cifsFileInfo *cfile;
+	__u16 netfid;
+	__u32 type;
+
+	rc = -EACCES;
+	xid = get_xid();
+
+	if (!(fl->fl_flags & FL_FLOCK))
+		return -ENOLCK;
+
+	cfile = (struct cifsFileInfo *)file->private_data;
+	tcon = tlink_tcon(cfile->tlink);
+
+	cifs_read_flock(fl, &type, &lock, &unlock, &wait_flag,
+			tcon->ses->server);
+	cifs_sb = CIFS_FILE_SB(file);
+	netfid = cfile->fid.netfid;
+	cinode = CIFS_I(file_inode(file));
+
+	if (cap_unix(tcon->ses) &&
+	    (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
+	    ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
+		posix_lck = true;
+
+	if (!lock && !unlock) {
+		/*
+		 * if no lock or unlock then nothing to do since we do not
+		 * know what it is
+		 */
+		free_xid(xid);
+		return -EOPNOTSUPP;
+	}
+
+	rc = cifs_setlk(file, fl, type, wait_flag, posix_lck, lock, unlock,
+			xid);
+	free_xid(xid);
+	return rc;
+
+
+}
+
 int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
 {
 	int rc, xid;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH][CIFS] Add flock support
  2019-07-17  0:49 ` Steve French
@ 2019-07-17  1:02   ` ronnie sahlberg
  2019-07-17  1:05     ` Pavel Shilovsky
  0 siblings, 1 reply; 6+ messages in thread
From: ronnie sahlberg @ 2019-07-17  1:02 UTC (permalink / raw)
  To: Steve French; +Cc: linux-fsdevel, CIFS

Nice.

Reviewed-by me

On Wed, Jul 17, 2019 at 10:51 AM Steve French <smfrench@gmail.com> wrote:
>
> Pavel spotted the problem - fixed and reattached updated patch
>
>
> On Tue, Jul 16, 2019 at 7:02 PM Steve French <smfrench@gmail.com> wrote:
> >
> > The attached patch adds support for flock support similar to AFS, NFS etc.
> >
> > Although the patch did seem to work in my experiments with flock, I did notice
> > that xfstest generic/504 fails because /proc/locks is not updated by cifs.ko
> > after a successful lock.  Any idea which helper function does that?
> >
> >
> > --
> > Thanks,
> >
> > Steve
>
>
>
> --
> Thanks,
>
> Steve

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH][CIFS] Add flock support
  2019-07-17  1:02   ` ronnie sahlberg
@ 2019-07-17  1:05     ` Pavel Shilovsky
  0 siblings, 0 replies; 6+ messages in thread
From: Pavel Shilovsky @ 2019-07-17  1:05 UTC (permalink / raw)
  To: ronnie sahlberg; +Cc: Steve French, linux-fsdevel, CIFS

Looks good.

Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>

--
Best regards,
Pavel Shilovsky

вт, 16 июл. 2019 г. в 18:02, ronnie sahlberg <ronniesahlberg@gmail.com>:
>
> Nice.
>
> Reviewed-by me
>
> On Wed, Jul 17, 2019 at 10:51 AM Steve French <smfrench@gmail.com> wrote:
> >
> > Pavel spotted the problem - fixed and reattached updated patch
> >
> >
> > On Tue, Jul 16, 2019 at 7:02 PM Steve French <smfrench@gmail.com> wrote:
> > >
> > > The attached patch adds support for flock support similar to AFS, NFS etc.
> > >
> > > Although the patch did seem to work in my experiments with flock, I did notice
> > > that xfstest generic/504 fails because /proc/locks is not updated by cifs.ko
> > > after a successful lock.  Any idea which helper function does that?
> > >
> > >
> > > --
> > > Thanks,
> > >
> > > Steve
> >
> >
> >
> > --
> > Thanks,
> >
> > Steve

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH][CIFS] Add flock support
  2019-07-17  0:02 [PATCH][CIFS] Add flock support Steve French
  2019-07-17  0:49 ` Steve French
@ 2019-07-19 20:56 ` J. Bruce Fields
  2019-07-19 21:30   ` Steve French
  1 sibling, 1 reply; 6+ messages in thread
From: J. Bruce Fields @ 2019-07-19 20:56 UTC (permalink / raw)
  To: Steve French; +Cc: linux-fsdevel, CIFS

On Tue, Jul 16, 2019 at 07:02:48PM -0500, Steve French wrote:
> The attached patch adds support for flock support similar to AFS, NFS etc.
> 
> Although the patch did seem to work in my experiments with flock, I did notice
> that xfstest generic/504 fails because /proc/locks is not updated by cifs.ko
> after a successful lock.  Any idea which helper function does that?

You have to call into locks.c code, I'm not sure of the details off the
top of my head but you could probably look at the nfs lock code for an
example.

Could you also send in an update to the flock(2) man page?  (See the
"NFS details" section under NOTES.  Sounds like it could use a mention
of AFS as well.)

--b.

> From 9de8e68a8ab0c7e59080874f05b1df37477cf691 Mon Sep 17 00:00:00 2001
> From: Steve French <stfrench@microsoft.com>
> Date: Tue, 16 Jul 2019 18:55:38 -0500
> Subject: [PATCH] cifs: add support for flock
> 
> The flock system call locks the whole file rather than a byte
> range and is currently emulated by various other file systems
> by simply sending a byte range lock for the whole file.
> 
> This version of the patch needs a minor update to pass
> xfstest generic/504 (we need to figure out how to update
> /proc/locks after an flock call is granted)
> 
> Signed-off-by: Steve French <stfrench@microsoft.com>
> ---
>  fs/cifs/cifsfs.c |  3 +++
>  fs/cifs/cifsfs.h |  1 +
>  fs/cifs/file.c   | 54 ++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 58 insertions(+)
> 
> diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> index 320c7a6fd318..a674f52b0403 100644
> --- a/fs/cifs/cifsfs.c
> +++ b/fs/cifs/cifsfs.c
> @@ -1168,6 +1168,7 @@ const struct file_operations cifs_file_ops = {
>  	.open = cifs_open,
>  	.release = cifs_close,
>  	.lock = cifs_lock,
> +	.flock = cifs_flock,
>  	.fsync = cifs_fsync,
>  	.flush = cifs_flush,
>  	.mmap  = cifs_file_mmap,
> @@ -1187,6 +1188,7 @@ const struct file_operations cifs_file_strict_ops = {
>  	.open = cifs_open,
>  	.release = cifs_close,
>  	.lock = cifs_lock,
> +	.flock = cifs_flock,
>  	.fsync = cifs_strict_fsync,
>  	.flush = cifs_flush,
>  	.mmap = cifs_file_strict_mmap,
> @@ -1206,6 +1208,7 @@ const struct file_operations cifs_file_direct_ops = {
>  	.open = cifs_open,
>  	.release = cifs_close,
>  	.lock = cifs_lock,
> +	.flock = cifs_flock,
>  	.fsync = cifs_fsync,
>  	.flush = cifs_flush,
>  	.mmap = cifs_file_mmap,
> diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
> index aea005703785..262f709822ee 100644
> --- a/fs/cifs/cifsfs.h
> +++ b/fs/cifs/cifsfs.h
> @@ -108,6 +108,7 @@ extern ssize_t cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to);
>  extern ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from);
>  extern ssize_t cifs_direct_writev(struct kiocb *iocb, struct iov_iter *from);
>  extern ssize_t cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from);
> +extern int cifs_flock(struct file *file, int cmd, struct file_lock *fl);
>  extern int cifs_lock(struct file *, int, struct file_lock *);
>  extern int cifs_fsync(struct file *, loff_t, loff_t, int);
>  extern int cifs_strict_fsync(struct file *, loff_t, loff_t, int);
> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
> index 97090693d182..641927755d0b 100644
> --- a/fs/cifs/file.c
> +++ b/fs/cifs/file.c
> @@ -1685,6 +1685,60 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
>  	return rc;
>  }
>  
> +int cifs_flock(struct file *file, int cmd, struct file_lock *fl)
> +{
> +	int rc, xid;
> +	int lock = 0, unlock = 0;
> +	bool wait_flag = false;
> +	bool posix_lck = false;
> +	struct cifs_sb_info *cifs_sb;
> +	struct cifs_tcon *tcon;
> +	struct cifsInodeInfo *cinode;
> +	struct cifsFileInfo *cfile;
> +	__u16 netfid;
> +	__u32 type;
> +
> +	rc = -EACCES;
> +	xid = get_xid();
> +
> +	if (!(fl->fl_flags & FL_FLOCK)) {
> +		cifs_dbg(VFS, "ret nolock\n");
> +		return -ENOLCK;
> +	}
> +
> +	cfile = (struct cifsFileInfo *)file->private_data;
> +	tcon = tlink_tcon(cfile->tlink);
> +
> +	cifs_read_flock(fl, &type, &lock, &unlock, &wait_flag,
> +			tcon->ses->server);
> +	cifs_sb = CIFS_FILE_SB(file);
> +	netfid = cfile->fid.netfid;
> +	cinode = CIFS_I(file_inode(file));
> +
> +	if (cap_unix(tcon->ses) &&
> +	    (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
> +	    ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
> +		posix_lck = true;
> +
> +	if (!lock && !unlock) {
> +		/*
> +		 * if no lock or unlock then nothing to do since we do not
> +		 * know what it is
> +		 */
> +		cifs_dbg(VFS, "return FLOCK EOPNOTSUPP\n");
> +		free_xid(xid);
> +		return -EOPNOTSUPP;
> +	}
> +
> +	rc = cifs_setlk(file, fl, type, wait_flag, posix_lck, lock, unlock,
> +			xid);
> +	free_xid(xid);
> +	cifs_dbg(VFS, "FLOCK rc = %d\n", rc);
> +	return rc;
> +
> +
> +}
> +
>  int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
>  {
>  	int rc, xid;
> -- 
> 2.20.1
> 


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH][CIFS] Add flock support
  2019-07-19 20:56 ` J. Bruce Fields
@ 2019-07-19 21:30   ` Steve French
  0 siblings, 0 replies; 6+ messages in thread
From: Steve French @ 2019-07-19 21:30 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: linux-fsdevel, CIFS

Pavel spotted the missing locks.c callout so the missing /proc/locks
entry isn't an issue, but will want to make sure no tests break (504
doesn't but there were some other test cases that call flock
indirectly).   Looks like the network/cluster fs which support flock
are

9p, afs, ceph, gfs2, nfs, ocfs2 (and now cifs)

so updating the man page is not a bad idea.

On Fri, Jul 19, 2019 at 3:57 PM J. Bruce Fields <bfields@fieldses.org> wrote:
>
> On Tue, Jul 16, 2019 at 07:02:48PM -0500, Steve French wrote:
> > The attached patch adds support for flock support similar to AFS, NFS etc.
> >
> > Although the patch did seem to work in my experiments with flock, I did notice
> > that xfstest generic/504 fails because /proc/locks is not updated by cifs.ko
> > after a successful lock.  Any idea which helper function does that?
>
> You have to call into locks.c code, I'm not sure of the details off the
> top of my head but you could probably look at the nfs lock code for an
> example.
>
> Could you also send in an update to the flock(2) man page?  (See the
> "NFS details" section under NOTES.  Sounds like it could use a mention
> of AFS as well.)
>
> --b.
>
> > From 9de8e68a8ab0c7e59080874f05b1df37477cf691 Mon Sep 17 00:00:00 2001
> > From: Steve French <stfrench@microsoft.com>
> > Date: Tue, 16 Jul 2019 18:55:38 -0500
> > Subject: [PATCH] cifs: add support for flock
> >
> > The flock system call locks the whole file rather than a byte
> > range and is currently emulated by various other file systems
> > by simply sending a byte range lock for the whole file.
> >
> > This version of the patch needs a minor update to pass
> > xfstest generic/504 (we need to figure out how to update
> > /proc/locks after an flock call is granted)
> >
> > Signed-off-by: Steve French <stfrench@microsoft.com>
> > ---
> >  fs/cifs/cifsfs.c |  3 +++
> >  fs/cifs/cifsfs.h |  1 +
> >  fs/cifs/file.c   | 54 ++++++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 58 insertions(+)
> >
> > diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> > index 320c7a6fd318..a674f52b0403 100644
> > --- a/fs/cifs/cifsfs.c
> > +++ b/fs/cifs/cifsfs.c
> > @@ -1168,6 +1168,7 @@ const struct file_operations cifs_file_ops = {
> >       .open = cifs_open,
> >       .release = cifs_close,
> >       .lock = cifs_lock,
> > +     .flock = cifs_flock,
> >       .fsync = cifs_fsync,
> >       .flush = cifs_flush,
> >       .mmap  = cifs_file_mmap,
> > @@ -1187,6 +1188,7 @@ const struct file_operations cifs_file_strict_ops = {
> >       .open = cifs_open,
> >       .release = cifs_close,
> >       .lock = cifs_lock,
> > +     .flock = cifs_flock,
> >       .fsync = cifs_strict_fsync,
> >       .flush = cifs_flush,
> >       .mmap = cifs_file_strict_mmap,
> > @@ -1206,6 +1208,7 @@ const struct file_operations cifs_file_direct_ops = {
> >       .open = cifs_open,
> >       .release = cifs_close,
> >       .lock = cifs_lock,
> > +     .flock = cifs_flock,
> >       .fsync = cifs_fsync,
> >       .flush = cifs_flush,
> >       .mmap = cifs_file_mmap,
> > diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
> > index aea005703785..262f709822ee 100644
> > --- a/fs/cifs/cifsfs.h
> > +++ b/fs/cifs/cifsfs.h
> > @@ -108,6 +108,7 @@ extern ssize_t cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to);
> >  extern ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from);
> >  extern ssize_t cifs_direct_writev(struct kiocb *iocb, struct iov_iter *from);
> >  extern ssize_t cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from);
> > +extern int cifs_flock(struct file *file, int cmd, struct file_lock *fl);
> >  extern int cifs_lock(struct file *, int, struct file_lock *);
> >  extern int cifs_fsync(struct file *, loff_t, loff_t, int);
> >  extern int cifs_strict_fsync(struct file *, loff_t, loff_t, int);
> > diff --git a/fs/cifs/file.c b/fs/cifs/file.c
> > index 97090693d182..641927755d0b 100644
> > --- a/fs/cifs/file.c
> > +++ b/fs/cifs/file.c
> > @@ -1685,6 +1685,60 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
> >       return rc;
> >  }
> >
> > +int cifs_flock(struct file *file, int cmd, struct file_lock *fl)
> > +{
> > +     int rc, xid;
> > +     int lock = 0, unlock = 0;
> > +     bool wait_flag = false;
> > +     bool posix_lck = false;
> > +     struct cifs_sb_info *cifs_sb;
> > +     struct cifs_tcon *tcon;
> > +     struct cifsInodeInfo *cinode;
> > +     struct cifsFileInfo *cfile;
> > +     __u16 netfid;
> > +     __u32 type;
> > +
> > +     rc = -EACCES;
> > +     xid = get_xid();
> > +
> > +     if (!(fl->fl_flags & FL_FLOCK)) {
> > +             cifs_dbg(VFS, "ret nolock\n");
> > +             return -ENOLCK;
> > +     }
> > +
> > +     cfile = (struct cifsFileInfo *)file->private_data;
> > +     tcon = tlink_tcon(cfile->tlink);
> > +
> > +     cifs_read_flock(fl, &type, &lock, &unlock, &wait_flag,
> > +                     tcon->ses->server);
> > +     cifs_sb = CIFS_FILE_SB(file);
> > +     netfid = cfile->fid.netfid;
> > +     cinode = CIFS_I(file_inode(file));
> > +
> > +     if (cap_unix(tcon->ses) &&
> > +         (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
> > +         ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
> > +             posix_lck = true;
> > +
> > +     if (!lock && !unlock) {
> > +             /*
> > +              * if no lock or unlock then nothing to do since we do not
> > +              * know what it is
> > +              */
> > +             cifs_dbg(VFS, "return FLOCK EOPNOTSUPP\n");
> > +             free_xid(xid);
> > +             return -EOPNOTSUPP;
> > +     }
> > +
> > +     rc = cifs_setlk(file, fl, type, wait_flag, posix_lck, lock, unlock,
> > +                     xid);
> > +     free_xid(xid);
> > +     cifs_dbg(VFS, "FLOCK rc = %d\n", rc);
> > +     return rc;
> > +
> > +
> > +}
> > +
> >  int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
> >  {
> >       int rc, xid;
> > --
> > 2.20.1
> >
>


-- 
Thanks,

Steve

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2019-07-19 21:30 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-17  0:02 [PATCH][CIFS] Add flock support Steve French
2019-07-17  0:49 ` Steve French
2019-07-17  1:02   ` ronnie sahlberg
2019-07-17  1:05     ` Pavel Shilovsky
2019-07-19 20:56 ` J. Bruce Fields
2019-07-19 21:30   ` Steve French

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).