All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Add support for flock over a cifs mount.
@ 2011-11-07 20:05 Sachin Prabhu
       [not found] ` <1320696342.1690.19.camel-yuq4rhG59MBosH8Q1Ye95IGKTjYczspe@public.gmane.org>
  0 siblings, 1 reply; 12+ messages in thread
From: Sachin Prabhu @ 2011-11-07 20:05 UTC (permalink / raw)
  To: linux-cifs-u79uwXL29TY76Z2rM5mHXA
  Cc: Pavel Shilovsky, Steve French, Jeffrey Layton

Allow flock over a cifs mount.

Signed-off-by: Sachin Prabhu <sprabhu-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 8f1fe32..56d3b36 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -830,6 +830,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,
@@ -849,6 +850,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,
@@ -869,6 +871,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 30ff560..e119e9d 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -87,6 +87,7 @@ extern ssize_t cifs_user_writev(struct kiocb *iocb, const struct iovec *iov,
 extern ssize_t cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
 				  unsigned long nr_segs, loff_t pos);
 extern int cifs_lock(struct file *, int, struct file_lock *);
+extern int cifs_flock(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);
 extern int cifs_flush(struct file *, fl_owner_t id);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index c1f063c..dd34f0b 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -43,6 +43,23 @@
 #include "cifs_fs_sb.h"
 #include "fscache.h"
 
+static int do_vfs_lock(struct file *file, struct file_lock *fl)
+{
+	int res = 0;
+
+	switch (fl->fl_flags & (FL_POSIX|FL_FLOCK)) {
+	case FL_POSIX:
+		res = posix_lock_file_wait(file, fl);
+		break;
+	case FL_FLOCK:
+		res = flock_lock_file_wait(file, fl);
+		break;
+	default:
+		BUG();
+	}
+	return res;
+}
+
 static inline int cifs_convert_flags(unsigned int flags)
 {
 	if ((flags & O_ACCMODE) == O_RDONLY)
@@ -814,7 +831,7 @@ cifs_posix_lock_set(struct file *file, struct file_lock *flock)
 	struct cifsInodeInfo *cinode = CIFS_I(file->f_path.dentry->d_inode);
 	int rc = 1;
 
-	if ((flock->fl_flags & FL_POSIX) == 0)
+	if ((flock->fl_flags & (FL_POSIX | FL_FLOCK)) == 0)
 		return rc;
 
 	mutex_lock(&cinode->lock_mutex);
@@ -822,7 +839,7 @@ cifs_posix_lock_set(struct file *file, struct file_lock *flock)
 		mutex_unlock(&cinode->lock_mutex);
 		return rc;
 	}
-	rc = posix_lock_file_wait(file, flock);
+	rc = do_vfs_lock(file, flock);
 	mutex_unlock(&cinode->lock_mutex);
 	return rc;
 }
@@ -1231,12 +1248,27 @@ cifs_setlk(struct file *file,  struct file_lock *flock, __u8 type,
 	struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
 	struct cifsInodeInfo *cinode = CIFS_I(file->f_path.dentry->d_inode);
 	__u16 netfid = cfile->netfid;
+	unsigned char fl_flags = flock->fl_flags;
+
+	if (unlock) {
+		/*Check for existance of lock*/
+		flock->fl_flags |= FL_EXISTS;
+		if (do_vfs_lock(flock->fl_file, flock) == -ENOENT)
+			goto out;
+	} else {
+		/*Check if we can obtain lock*/
+		flock->fl_flags |= FL_ACCESS;
+		rc = do_vfs_lock(flock->fl_file, flock);
+		if (rc < 0)
+			goto out;
+	}
+	flock->fl_flags = fl_flags;
 
 	if (posix_lck) {
 		int posix_lock_type;
 
 		rc = cifs_posix_lock_set(file, flock);
-		if (!rc || rc < 0)
+		if (rc <= 0)
 			return rc;
 
 		if (type & LOCKING_ANDX_SHARED_LOCK)
@@ -1250,7 +1282,7 @@ cifs_setlk(struct file *file,  struct file_lock *flock, __u8 type,
 		rc = CIFSSMBPosixLock(xid, tcon, netfid, current->tgid,
 				      0 /* set */, length, flock,
 				      posix_lock_type, wait_flag);
-		goto out;
+		goto out_lock;
 	}
 
 	if (lock) {
@@ -1259,7 +1291,7 @@ cifs_setlk(struct file *file,  struct file_lock *flock, __u8 type,
 		if (rc < 0)
 			return rc;
 		else if (!rc)
-			goto out;
+			goto out_lock;
 
 		rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, length,
 				 flock->fl_start, 0, 1, type, wait_flag, 0);
@@ -1271,9 +1303,14 @@ cifs_setlk(struct file *file,  struct file_lock *flock, __u8 type,
 	} else if (unlock)
 		rc = cifs_unlock_range(cfile, flock, xid);
 
+out_lock:
+	if (rc == 0 && lock) {
+		/*We have to sleep here*/
+		flock->fl_flags |= FL_SLEEP;
+		do_vfs_lock(file, flock);
+	}
 out:
-	if (flock->fl_flags & FL_POSIX)
-		posix_lock_file_wait(file, flock);
+	flock->fl_flags = fl_flags;
 	return rc;
 }
 
@@ -1334,6 +1371,22 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
 	return rc;
 }
 
+int cifs_flock(struct file *file, int cmd, struct file_lock *flock)
+{
+	int rc;
+
+	rc = cifs_lock(file, cmd, flock);
+
+	/*
+	 * flock requires -EWOULDBLOCK in case of conflicting locks
+	 * and LOCK_NB is used
+	 */
+	if ((rc == -EACCES) && !(flock->fl_flags & FL_SLEEP))
+		rc = -EWOULDBLOCK;
+
+	return rc;
+}
+
 /* update the file size (if needed) after a write */
 void
 cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,

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

end of thread, other threads:[~2011-12-01 12:36 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-07 20:05 [PATCH] Add support for flock over a cifs mount Sachin Prabhu
     [not found] ` <1320696342.1690.19.camel-yuq4rhG59MBosH8Q1Ye95IGKTjYczspe@public.gmane.org>
2011-11-07 20:31   ` Jeff Layton
2011-11-08  7:57   ` Pavel Shilovsky
     [not found]     ` <CAKywueTSqckM1iVsrEu47RwBA3GnpfZU17QrrNineJBVOcZdvQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-11-08 11:26       ` Sachin Prabhu
2011-11-08 12:21         ` Pavel Shilovsky
     [not found]           ` <CAKywueQ65EgLz9iDd2exq85jBMGrBFLiq=mq2dOY9poy3_1h0g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-11-08 17:26             ` Sachin Prabhu
     [not found]               ` <1320773203.1690.35.camel-yuq4rhG59MBosH8Q1Ye95IGKTjYczspe@public.gmane.org>
2011-11-08 19:08                 ` Pavel Shilovsky
     [not found]                   ` <CAKywueSRYxizd+mKw8p93Os0Aqij+R2Dh=2hu6JuJ+bv7S+uWw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-11-11 14:11                     ` Sachin Prabhu
     [not found]                       ` <1321020680.1690.57.camel-yuq4rhG59MBosH8Q1Ye95IGKTjYczspe@public.gmane.org>
2011-11-14 12:54                         ` Pavel Shilovsky
     [not found]                           ` <CAKywueQwM49dfne1L_d4WVa3zENdshbuuiZ9tVzv=BiF171_8w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-11-14 13:18                             ` Sachin Prabhu
     [not found]                               ` <1321276715.1690.78.camel-yuq4rhG59MBosH8Q1Ye95IGKTjYczspe@public.gmane.org>
2011-11-17 16:31                                 ` RFC: Attach locks to cifsFileInfo instead of cifsInodeInfo Sachin Prabhu
     [not found]                                   ` <1321547488.1690.122.camel-yuq4rhG59MBosH8Q1Ye95IGKTjYczspe@public.gmane.org>
2011-12-01 12:36                                     ` Pavel Shilovsky

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.