All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] CIFS: Invalidate inode pages on the last close
@ 2010-11-02 19:44 Pavel Shilovsky
       [not found] ` <1288727061-18759-1-git-send-email-piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 5+ messages in thread
From: Pavel Shilovsky @ 2010-11-02 19:44 UTC (permalink / raw)
  To: linux-cifs-u79uwXL29TY76Z2rM5mHXA

On strict cache mode when we close the last file handle of the inode we
should invalidate itt o prevent data coherency problem when we open it
again but it has been modified by other clients.

Signed-off-by: Pavel Shilovsky <piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 fs/cifs/cifs_fs_sb.h |    1 +
 fs/cifs/file.c       |    6 ++++++
 2 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index e9a393c..be7b159 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -40,6 +40,7 @@
 #define CIFS_MOUNT_FSCACHE	0x8000 /* local caching enabled */
 #define CIFS_MOUNT_MF_SYMLINKS	0x10000 /* Minshall+French Symlinks enabled */
 #define CIFS_MOUNT_MULTIUSER	0x20000 /* multiuser mount */
+#define CIFS_MOUNT_STRICT_IO	0x40000 /* strict cache mode */
 
 struct cifs_sb_info {
 	struct rb_root tlink_tree;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 71185d1..81ec50e 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -264,7 +264,9 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
 	struct inode *inode = cifs_file->dentry->d_inode;
 	struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink);
 	struct cifsInodeInfo *cifsi = CIFS_I(inode);
+	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
 	struct cifsLockInfo *li, *tmp;
+	bool last_open_file = false;
 
 	spin_lock(&cifs_file_list_lock);
 	if (--cifs_file->count > 0) {
@@ -279,10 +281,14 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
 	if (list_empty(&cifsi->openFileList)) {
 		cFYI(1, "closing last open instance for inode %p",
 			cifs_file->dentry->d_inode);
+		last_open_file = true;
 		cifs_set_oplock_level(inode, 0);
 	}
 	spin_unlock(&cifs_file_list_lock);
 
+	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) && last_open_file)
+		invalidate_remote_inode(inode);
+
 	if (!tcon->need_reconnect && !cifs_file->invalidHandle) {
 		int xid, rc;
 
-- 
1.7.2.3

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

* [PATCH 2/4] CIFS: New read logic
       [not found] ` <1288727061-18759-1-git-send-email-piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2010-11-02 19:44   ` Pavel Shilovsky
  2010-11-02 19:44   ` [PATCH 3/4] CIFS: New write logic Pavel Shilovsky
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Pavel Shilovsky @ 2010-11-02 19:44 UTC (permalink / raw)
  To: linux-cifs-u79uwXL29TY76Z2rM5mHXA

Add cifs_file_aio_read to let the client works with strict cache mode.

Signed-off-by: Pavel Shilovsky <piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 fs/cifs/cifsfs.c |   28 ++++++++++++++++++++++++++--
 1 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 38526a6..bb7f36e 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -569,6 +569,30 @@ cifs_do_mount(struct file_system_type *fs_type,
 	return dget(sb->s_root);
 }
 
+static ssize_t cifs_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
+				   unsigned long nr_segs, loff_t pos)
+{
+	struct inode *inode;
+	struct cifs_sb_info *cifs_sb;
+	ssize_t read;
+
+	inode = iocb->ki_filp->f_path.dentry->d_inode;
+	cifs_sb = CIFS_SB(iocb->ki_filp->f_path.dentry->d_sb);
+
+	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) == 0)
+		/* BB call cifs_revalidate_file before generic_file_aio_read */
+		return generic_file_aio_read(iocb, iov, nr_segs, pos);
+
+	if (!CIFS_I(inode)->clientCanCacheRead) {
+		read = cifs_user_read(iocb->ki_filp, iov->iov_base,
+				      iov->iov_len, &pos);
+		iocb->ki_pos = pos;
+	} else
+		read = generic_file_aio_read(iocb, iov, nr_segs, pos);
+
+	return read;
+}
+
 static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 				   unsigned long nr_segs, loff_t pos)
 {
@@ -691,7 +715,7 @@ const struct inode_operations cifs_symlink_inode_ops = {
 const struct file_operations cifs_file_ops = {
 	.read = do_sync_read,
 	.write = do_sync_write,
-	.aio_read = generic_file_aio_read,
+	.aio_read = cifs_file_aio_read,
 	.aio_write = cifs_file_aio_write,
 	.open = cifs_open,
 	.release = cifs_close,
@@ -728,7 +752,7 @@ const struct file_operations cifs_file_direct_ops = {
 const struct file_operations cifs_file_nobrl_ops = {
 	.read = do_sync_read,
 	.write = do_sync_write,
-	.aio_read = generic_file_aio_read,
+	.aio_read = cifs_file_aio_read,
 	.aio_write = cifs_file_aio_write,
 	.open = cifs_open,
 	.release = cifs_close,
-- 
1.7.2.3

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

* [PATCH 3/4] CIFS: New write logic
       [not found] ` <1288727061-18759-1-git-send-email-piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2010-11-02 19:44   ` [PATCH 2/4] CIFS: New read logic Pavel Shilovsky
@ 2010-11-02 19:44   ` Pavel Shilovsky
  2010-11-02 19:44   ` [PATCH 4/4] CIFS: Add strictcache mount option Pavel Shilovsky
  2010-11-04 11:23   ` [PATCH 1/4] CIFS: Invalidate inode pages on the last close Pavel Shilovsky
  3 siblings, 0 replies; 5+ messages in thread
From: Pavel Shilovsky @ 2010-11-02 19:44 UTC (permalink / raw)
  To: linux-cifs-u79uwXL29TY76Z2rM5mHXA

Modify cifs_file_aio_write and cifs_write_end to let the client works with
strict cache mode.

Signed-off-by: Pavel Shilovsky <piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 fs/cifs/cifsfs.c |   41 ++++++++++++++++++++++++++++++++++++-----
 fs/cifs/file.c   |   14 ++++++++++++--
 2 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index bb7f36e..ccbbea0 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -596,12 +596,43 @@ static ssize_t cifs_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
 static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 				   unsigned long nr_segs, loff_t pos)
 {
-	struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
-	ssize_t written;
+	struct inode *inode;
+	struct cifs_sb_info *cifs_sb;
+	ssize_t written, cache_written;
+	loff_t saved_pos;
+
+	inode = iocb->ki_filp->f_path.dentry->d_inode;
+
+	if (CIFS_I(inode)->clientCanCacheAll)
+		return generic_file_aio_write(iocb, iov, nr_segs, pos);
+
+	cifs_sb = CIFS_SB(iocb->ki_filp->f_path.dentry->d_sb);
+
+	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) == 0) {
+		int rc;
+
+		written = generic_file_aio_write(iocb, iov, nr_segs, pos);
+
+		rc = filemap_fdatawrite(inode->i_mapping);
+		if (rc)
+			cFYI(1, "cifs_file_aio_write: %d rc on %p inode",
+			     rc, inode);
+		return written;
+	}
+
+	saved_pos = pos;
+	written = cifs_user_write(iocb->ki_filp, iov->iov_base,
+				  iov->iov_len, &pos);
+
+	if (written > 0) {
+		cache_written = generic_file_aio_write(iocb, iov,
+						       nr_segs, saved_pos);
+		if (cache_written != written)
+			cERROR(1, "Cache written and server written data "
+			       "lengths are different");
+	} else
+		iocb->ki_pos = pos;
 
-	written = generic_file_aio_write(iocb, iov, nr_segs, pos);
-	if (!CIFS_I(inode)->clientCanCacheAll)
-		filemap_fdatawrite(inode->i_mapping);
 	return written;
 }
 
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 81ec50e..9bde94a 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1541,7 +1541,11 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
 			struct page *page, void *fsdata)
 {
 	int rc;
-	struct inode *inode = mapping->host;
+	struct inode *inode;
+	struct cifs_sb_info *cifs_sb;
+
+	inode = mapping->host;
+	cifs_sb = CIFS_SB(inode->i_sb);
 
 	cFYI(1, "write_end for page %p from pos %lld with %d bytes",
 		 page, pos, copied);
@@ -1574,7 +1578,13 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
 	} else {
 		rc = copied;
 		pos += copied;
-		set_page_dirty(page);
+		/* if we have strict cache switched on and don't have Exclusive
+		   oplock for the inode, we don't have to set_page_dirty
+		   because we flushed the data to the server in
+		   cifs_file_aio_write before */
+		if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) == 0 ||
+		    CIFS_I(inode)->clientCanCacheAll)
+			set_page_dirty(page);
 	}
 
 	if (rc > 0) {
-- 
1.7.2.3

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

* [PATCH 4/4] CIFS: Add strictcache mount option
       [not found] ` <1288727061-18759-1-git-send-email-piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2010-11-02 19:44   ` [PATCH 2/4] CIFS: New read logic Pavel Shilovsky
  2010-11-02 19:44   ` [PATCH 3/4] CIFS: New write logic Pavel Shilovsky
@ 2010-11-02 19:44   ` Pavel Shilovsky
  2010-11-04 11:23   ` [PATCH 1/4] CIFS: Invalidate inode pages on the last close Pavel Shilovsky
  3 siblings, 0 replies; 5+ messages in thread
From: Pavel Shilovsky @ 2010-11-02 19:44 UTC (permalink / raw)
  To: linux-cifs-u79uwXL29TY76Z2rM5mHXA

Use for switching on strict cache mode. In this mode the
client read from the cache all the time it has Oplock Level II,
otherwise - read from the server. All written data are stored
in the cache, but if the client doesn't have Exclusive Oplock,
it writes the data to the server.

Signed-off-by: Pavel Shilovsky <piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 fs/cifs/README    |    5 +++++
 fs/cifs/connect.c |    5 +++++
 2 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/fs/cifs/README b/fs/cifs/README
index ee68d10..8fb6192 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -443,6 +443,11 @@ A partial list of the supported mount options follows:
 		if oplock (caching token) is granted and held. Note that
 		direct allows write operations larger than page size
 		to be sent to the server.
+  strictcache   Use for switching on strict cache mode. In this mode the
+		client read from the cache all the time it has Oplock Level II,
+		otherwise - read from the server. All written data are stored
+		in the cache, but if the client doesn't have Exclusive Oplock,
+		it writes the data to the server.
   acl   	Allow setfacl and getfacl to manage posix ACLs if server
 		supports them.  (default)
   noacl 	Do not allow setfacl and getfacl calls on this mount
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index c9699ce..1735a12 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -84,6 +84,7 @@ struct smb_vol {
 	bool no_xattr:1;   /* set if xattr (EA) support should be disabled*/
 	bool server_ino:1; /* use inode numbers from server ie UniqueId */
 	bool direct_io:1;
+	bool strict_io:1; /* strict cache behavior */
 	bool remap:1;      /* set to remap seven reserved chars in filenames */
 	bool posix_paths:1; /* unset to not ask for posix pathnames. */
 	bool no_linux_ext:1;
@@ -1347,6 +1348,8 @@ cifs_parse_mount_options(char *options, const char *devname,
 			vol->direct_io = 1;
 		} else if (strnicmp(data, "forcedirectio", 13) == 0) {
 			vol->direct_io = 1;
+		} else if (strnicmp(data, "strictcache", 11) == 0) {
+			vol->strict_io = 1;
 		} else if (strnicmp(data, "noac", 4) == 0) {
 			printk(KERN_WARNING "CIFS: Mount option noac not "
 				"supported. Instead set "
@@ -2597,6 +2600,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
 	if (pvolume_info->multiuser)
 		cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER |
 					    CIFS_MOUNT_NO_PERM);
+	if (pvolume_info->strict_io)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_STRICT_IO;
 	if (pvolume_info->direct_io) {
 		cFYI(1, "mounting share using direct i/o");
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
-- 
1.7.2.3

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

* Re: [PATCH 1/4] CIFS: Invalidate inode pages on the last close
       [not found] ` <1288727061-18759-1-git-send-email-piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (2 preceding siblings ...)
  2010-11-02 19:44   ` [PATCH 4/4] CIFS: Add strictcache mount option Pavel Shilovsky
@ 2010-11-04 11:23   ` Pavel Shilovsky
  3 siblings, 0 replies; 5+ messages in thread
From: Pavel Shilovsky @ 2010-11-04 11:23 UTC (permalink / raw)
  To: linux-cifs-u79uwXL29TY76Z2rM5mHXA

2010/11/2 Pavel Shilovsky <piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:
> On strict cache mode when we close the last file handle of the inode we
> should invalidate itt o prevent data coherency problem when we open it
> again but it has been modified by other clients.
>
> Signed-off-by: Pavel Shilovsky <piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
>  fs/cifs/cifs_fs_sb.h |    1 +
>  fs/cifs/file.c       |    6 ++++++
>  2 files changed, 7 insertions(+), 0 deletions(-)
>
> diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
> index e9a393c..be7b159 100644
> --- a/fs/cifs/cifs_fs_sb.h
> +++ b/fs/cifs/cifs_fs_sb.h
> @@ -40,6 +40,7 @@
>  #define CIFS_MOUNT_FSCACHE     0x8000 /* local caching enabled */
>  #define CIFS_MOUNT_MF_SYMLINKS 0x10000 /* Minshall+French Symlinks enabled */
>  #define CIFS_MOUNT_MULTIUSER   0x20000 /* multiuser mount */
> +#define CIFS_MOUNT_STRICT_IO   0x40000 /* strict cache mode */
>
>  struct cifs_sb_info {
>        struct rb_root tlink_tree;
> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
> index 71185d1..81ec50e 100644
> --- a/fs/cifs/file.c
> +++ b/fs/cifs/file.c
> @@ -264,7 +264,9 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
>        struct inode *inode = cifs_file->dentry->d_inode;
>        struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink);
>        struct cifsInodeInfo *cifsi = CIFS_I(inode);
> +       struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
>        struct cifsLockInfo *li, *tmp;
> +       bool last_open_file = false;
>
>        spin_lock(&cifs_file_list_lock);
>        if (--cifs_file->count > 0) {
> @@ -279,10 +281,14 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
>        if (list_empty(&cifsi->openFileList)) {
>                cFYI(1, "closing last open instance for inode %p",
>                        cifs_file->dentry->d_inode);
> +               last_open_file = true;
>                cifs_set_oplock_level(inode, 0);
>        }
>        spin_unlock(&cifs_file_list_lock);
>
> +       if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) && last_open_file)
> +               invalidate_remote_inode(inode);
> +
>        if (!tcon->need_reconnect && !cifs_file->invalidHandle) {
>                int xid, rc;
>
> --
> 1.7.2.3
>
>

What's about this and patch number 2 (New read logic)?

-- 
Best regards,
Pavel Shilovsky.

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

end of thread, other threads:[~2010-11-04 11:23 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-02 19:44 [PATCH 1/4] CIFS: Invalidate inode pages on the last close Pavel Shilovsky
     [not found] ` <1288727061-18759-1-git-send-email-piastryyy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2010-11-02 19:44   ` [PATCH 2/4] CIFS: New read logic Pavel Shilovsky
2010-11-02 19:44   ` [PATCH 3/4] CIFS: New write logic Pavel Shilovsky
2010-11-02 19:44   ` [PATCH 4/4] CIFS: Add strictcache mount option Pavel Shilovsky
2010-11-04 11:23   ` [PATCH 1/4] CIFS: Invalidate inode pages on the last close 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.