CIFS: O_DIRECT opens should work on directio mounts

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>From dca692880e887739a669f6c41a80ca68ce2b09fc Mon Sep 17 00:00:00 2001
From: Steve French <smfrench@xxxxxxxxx>
Date: Mon, 11 Nov 2013 16:42:37 -0600
Subject: [CIFS] O_DIRECT opens should work on directio mounts

Opens on current cifs/smb2/smb3 mounts with O_DIRECT flag fail
even when caching is disabled on the mount.  This was
reported by those running SMB2 benchmarks who need to
be able to pass O_DIRECT on many of their open calls to
reduce caching effects, but would also be needed by other
applications.

When mounting with forcedirectio ("cache=none") cifs and smb2/smb3
do not go through the page cache and thus opens with O_DIRECT flag
should work (when posix extensions are negotiated we even are
able to send the flag to the server). This patch fixes that
in a simple way.

The 9P client has a similar situation (caching is often disabled)
and takes the same approach to O_DIRECT support ie works if caching
disabled, but if client caching enabled it fails with EINVAL.

A followon idea for a future patch as Pavel noted, could
be that files opened with O_DIRECT could cause us to change
inode->i_fop on the fly from

cifs_file_strict_ops

to

cifs_file_direct_ops

which would allow us to support this on non-forcedirectio mounts
(cache=strict and cache=loose) as well.

Reviewed-by: Pavel Shilovsky <piastry@xxxxxxxxxxx>
Signed-off-by: Steve French <smfrench@xxxxxxxxx>
---
 fs/cifs/file.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 7ddddf2..5a5a872 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -3663,6 +3663,27 @@ void cifs_oplock_break(struct work_struct *work)
  }
 }

+/*
+ * The presence of cifs_direct_io() in the address space ops vector
+ * allowes open() O_DIRECT flags which would have failed otherwise.
+ *
+ * In the non-cached mode (mount with cache=none), we shunt off
direct read and write requests
+ * so this method should never be called.
+ *
+ * Direct IO is not yet supported in the cached mode.
+ */
+static ssize_t
+cifs_direct_io(int rw, struct kiocb *iocb, const struct iovec *iov,
+               loff_t pos, unsigned long nr_segs)
+{
+        /*
+         * FIXME
+         * Eventually need to support direct IO for non forcedirectio mounts
+         */
+        return -EINVAL;
+}
+
+
 const struct address_space_operations cifs_addr_ops = {
  .readpage = cifs_readpage,
  .readpages = cifs_readpages,
@@ -3672,6 +3693,7 @@ const struct address_space_operations cifs_addr_ops = {
  .write_end = cifs_write_end,
  .set_page_dirty = __set_page_dirty_nobuffers,
  .releasepage = cifs_release_page,
+ .direct_IO = cifs_direct_io,
  .invalidatepage = cifs_invalidate_page,
  .launder_page = cifs_launder_page,
 };
-- 
1.8.3.1


-- 
Thanks,

Steve
From dca692880e887739a669f6c41a80ca68ce2b09fc Mon Sep 17 00:00:00 2001
From: Steve French <smfrench@xxxxxxxxx>
Date: Mon, 11 Nov 2013 16:42:37 -0600
Subject: [PATCH 1/2] [CIFS] O_DIRECT opens should work on directio mounts

Opens on current cifs/smb2/smb3 mounts with O_DIRECT flag fail
even when caching is disabled on the mount.  This was
reported by those running SMB2 benchmarks who need to
be able to pass O_DIRECT on many of their open calls to
reduce caching effects, but would also be needed by other
applications.

When mounting with forcedirectio ("cache=none") cifs and smb2/smb3
do not go through the page cache and thus opens with O_DIRECT flag
should work (when posix extensions are negotiated we even are
able to send the flag to the server). This patch fixes that
in a simple way.

The 9P client has a similar situation (caching is often disabled)
and takes the same approach to O_DIRECT support ie works if caching
disabled, but if client caching enabled it fails with EINVAL.

A followon idea for a future patch as Pavel noted, could
be that files opened with O_DIRECT could cause us to change
inode->i_fop on the fly from

cifs_file_strict_ops

to

cifs_file_direct_ops

which would allow us to support this on non-forcedirectio mounts
(cache=strict and cache=loose) as well.

Reviewed-by: Pavel Shilovsky <piastry@xxxxxxxxxxx>
Signed-off-by: Steve French <smfrench@xxxxxxxxx>
---
 fs/cifs/file.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 7ddddf2..5a5a872 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -3663,6 +3663,27 @@ void cifs_oplock_break(struct work_struct *work)
 	}
 }
 
+/*
+ * The presence of cifs_direct_io() in the address space ops vector
+ * allowes open() O_DIRECT flags which would have failed otherwise.
+ *
+ * In the non-cached mode (mount with cache=none), we shunt off direct read and write requests
+ * so this method should never be called.
+ *
+ * Direct IO is not yet supported in the cached mode. 
+ */
+static ssize_t
+cifs_direct_io(int rw, struct kiocb *iocb, const struct iovec *iov,
+               loff_t pos, unsigned long nr_segs)
+{
+        /*
+         * FIXME
+         * Eventually need to support direct IO for non forcedirectio mounts
+         */
+        return -EINVAL;
+}
+
+
 const struct address_space_operations cifs_addr_ops = {
 	.readpage = cifs_readpage,
 	.readpages = cifs_readpages,
@@ -3672,6 +3693,7 @@ const struct address_space_operations cifs_addr_ops = {
 	.write_end = cifs_write_end,
 	.set_page_dirty = __set_page_dirty_nobuffers,
 	.releasepage = cifs_release_page,
+	.direct_IO = cifs_direct_io,
 	.invalidatepage = cifs_invalidate_page,
 	.launder_page = cifs_launder_page,
 };
-- 
1.8.3.1


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux