<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux.git/fs/cifs, branch v5.7</title>
<subtitle>Linux kernel source tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/'/>
<entry>
<title>cifs: fix leaked reference on requeued write</title>
<updated>2020-05-14T22:47:01+00:00</updated>
<author>
<name>Adam McCoy</name>
<email>adam@forsedomani.com</email>
</author>
<published>2020-05-13T11:53:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=a48137996063d22ffba77e077425f49873856ca5'/>
<id>a48137996063d22ffba77e077425f49873856ca5</id>
<content type='text'>
Failed async writes that are requeued may not clean up a refcount
on the file, which can result in a leaked open. This scenario arises
very reliably when using persistent handles and a reconnect occurs
while writing.

cifs_writev_requeue only releases the reference if the write fails
(rc != 0). The server-&gt;ops-&gt;async_writev operation will take its own
reference, so the initial reference can always be released.

Signed-off-by: Adam McCoy &lt;adam@forsedomani.com&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
CC: Stable &lt;stable@vger.kernel.org&gt;
Reviewed-by: Pavel Shilovsky &lt;pshilov@microsoft.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Failed async writes that are requeued may not clean up a refcount
on the file, which can result in a leaked open. This scenario arises
very reliably when using persistent handles and a reconnect occurs
while writing.

cifs_writev_requeue only releases the reference if the write fails
(rc != 0). The server-&gt;ops-&gt;async_writev operation will take its own
reference, so the initial reference can always be released.

Signed-off-by: Adam McCoy &lt;adam@forsedomani.com&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
CC: Stable &lt;stable@vger.kernel.org&gt;
Reviewed-by: Pavel Shilovsky &lt;pshilov@microsoft.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>cifs: Fix null pointer check in cifs_read</title>
<updated>2020-05-14T15:30:03+00:00</updated>
<author>
<name>Steve French</name>
<email>stfrench@microsoft.com</email>
</author>
<published>2020-05-13T15:27:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=9bd21d4b1a767c3abebec203342f3820dcb84662'/>
<id>9bd21d4b1a767c3abebec203342f3820dcb84662</id>
<content type='text'>
Coverity scan noted a redundant null check

Coverity-id: 728517
Reported-by: Coverity &lt;scan-admin@coverity.com&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
Reviewed-by: Shyam Prasad N &lt;nspmangalore@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Coverity scan noted a redundant null check

Coverity-id: 728517
Reported-by: Coverity &lt;scan-admin@coverity.com&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
Reviewed-by: Shyam Prasad N &lt;nspmangalore@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>CIFS: Spelling s/EACCESS/EACCES/</title>
<updated>2020-05-06T15:21:40+00:00</updated>
<author>
<name>Geert Uytterhoeven</name>
<email>geert+renesas@glider.be</email>
</author>
<published>2020-05-05T13:43:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=3dc58df0e2436829971c41ffbb07167dda0979f8'/>
<id>3dc58df0e2436829971c41ffbb07167dda0979f8</id>
<content type='text'>
As per POSIX, the correct spelling is EACCES:

include/uapi/asm-generic/errno-base.h:#define EACCES 13 /* Permission denied */

Fixes: b8f7442bc46e48fb ("CIFS: refactor cifs_get_inode_info()")
Signed-off-by: Geert Uytterhoeven &lt;geert+renesas@glider.be&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
As per POSIX, the correct spelling is EACCES:

include/uapi/asm-generic/errno-base.h:#define EACCES 13 /* Permission denied */

Fixes: b8f7442bc46e48fb ("CIFS: refactor cifs_get_inode_info()")
Signed-off-by: Geert Uytterhoeven &lt;geert+renesas@glider.be&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>cifs: fix uninitialised lease_key in open_shroot()</title>
<updated>2020-04-23T01:29:11+00:00</updated>
<author>
<name>Paulo Alcantara</name>
<email>pc@cjr.nz</email>
</author>
<published>2020-04-21T02:44:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=0fe0781f29dd8ab618999e6bda33c782ebbdb109'/>
<id>0fe0781f29dd8ab618999e6bda33c782ebbdb109</id>
<content type='text'>
SMB2_open_init() expects a pre-initialised lease_key when opening a
file with a lease, so set pfid-&gt;lease_key prior to calling it in
open_shroot().

This issue was observed when performing some DFS failover tests and
the lease key was never randomly generated.

Signed-off-by: Paulo Alcantara (SUSE) &lt;pc@cjr.nz&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
Reviewed-by: Ronnie Sahlberg &lt;lsahlber@redhat.com&gt;
Reviewed-by: Aurelien Aptel &lt;aaptel@suse.com&gt;
CC: Stable &lt;stable@vger.kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
SMB2_open_init() expects a pre-initialised lease_key when opening a
file with a lease, so set pfid-&gt;lease_key prior to calling it in
open_shroot().

This issue was observed when performing some DFS failover tests and
the lease key was never randomly generated.

Signed-off-by: Paulo Alcantara (SUSE) &lt;pc@cjr.nz&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
Reviewed-by: Ronnie Sahlberg &lt;lsahlber@redhat.com&gt;
Reviewed-by: Aurelien Aptel &lt;aaptel@suse.com&gt;
CC: Stable &lt;stable@vger.kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>cifs: ensure correct super block for DFS reconnect</title>
<updated>2020-04-23T01:27:30+00:00</updated>
<author>
<name>Paulo Alcantara</name>
<email>pc@cjr.nz</email>
</author>
<published>2020-04-20T22:43:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=3786f4bddc7b8c6e90cbf5f52c2443a8d8e1dede'/>
<id>3786f4bddc7b8c6e90cbf5f52c2443a8d8e1dede</id>
<content type='text'>
This patch is basically fixing the lookup of tcons (DFS specific) during
reconnect (smb2pdu.c:__smb2_reconnect) to update their prefix paths.

Previously, we relied on the TCP_Server_Info pointer
(misc.c:tcp_super_cb) to determine which tcon to update the prefix path

We could not rely on TCP server pointer to determine which super block
to update the prefix path when reconnecting tcons since it might map
to different tcons that share same TCP connection.

Instead, walk through all cifs super blocks and compare their DFS full
paths with the tcon being updated to.

Signed-off-by: Paulo Alcantara (SUSE) &lt;pc@cjr.nz&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
Reviewed-by: Ronnie Sahlberg &lt;lsahlber@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This patch is basically fixing the lookup of tcons (DFS specific) during
reconnect (smb2pdu.c:__smb2_reconnect) to update their prefix paths.

Previously, we relied on the TCP_Server_Info pointer
(misc.c:tcp_super_cb) to determine which tcon to update the prefix path

We could not rely on TCP server pointer to determine which super block
to update the prefix path when reconnecting tcons since it might map
to different tcons that share same TCP connection.

Instead, walk through all cifs super blocks and compare their DFS full
paths with the tcon being updated to.

Signed-off-by: Paulo Alcantara (SUSE) &lt;pc@cjr.nz&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
Reviewed-by: Ronnie Sahlberg &lt;lsahlber@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>cifs: do not share tcons with DFS</title>
<updated>2020-04-23T01:22:08+00:00</updated>
<author>
<name>Paulo Alcantara</name>
<email>pc@cjr.nz</email>
</author>
<published>2020-04-20T22:42:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=65303de829dd6d291a4947c1a31de31896f8a060'/>
<id>65303de829dd6d291a4947c1a31de31896f8a060</id>
<content type='text'>
This disables tcon re-use for DFS shares.

tcon-&gt;dfs_path stores the path that the tcon should connect to when
doing failing over.

If that tcon is used multiple times e.g. 2 mounts using it with
different prefixpath, each will need a different dfs_path but there is
only one tcon. The other solution would be to split the tcon in 2
tcons during failover but that is much harder.

tcons could not be shared with DFS in cifs.ko because in a
DFS namespace like:

          //domain/dfsroot -&gt; /serverA/dfsroot, /serverB/dfsroot

          //serverA/dfsroot/link -&gt; /serverA/target1/aa/bb

          //serverA/dfsroot/link2 -&gt; /serverA/target1/cc/dd

you can see that link and link2 are two DFS links that both resolve to
the same target share (/serverA/target1), so cifs.ko will only contain a
single tcon for both link and link2.

The problem with that is, if we (auto)mount "link" and "link2", cifs.ko
will only contain a single tcon for both DFS links so we couldn't
perform failover or refresh the DFS cache for both links because
tcon-&gt;dfs_path was set to either "link" or "link2", but not both --
which is wrong.

Signed-off-by: Paulo Alcantara (SUSE) &lt;pc@cjr.nz&gt;
Reviewed-by: Aurelien Aptel &lt;aaptel@suse.com&gt;
Reviewed-by: Ronnie Sahlberg &lt;lsahlber@redhat.com&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This disables tcon re-use for DFS shares.

tcon-&gt;dfs_path stores the path that the tcon should connect to when
doing failing over.

If that tcon is used multiple times e.g. 2 mounts using it with
different prefixpath, each will need a different dfs_path but there is
only one tcon. The other solution would be to split the tcon in 2
tcons during failover but that is much harder.

tcons could not be shared with DFS in cifs.ko because in a
DFS namespace like:

          //domain/dfsroot -&gt; /serverA/dfsroot, /serverB/dfsroot

          //serverA/dfsroot/link -&gt; /serverA/target1/aa/bb

          //serverA/dfsroot/link2 -&gt; /serverA/target1/cc/dd

you can see that link and link2 are two DFS links that both resolve to
the same target share (/serverA/target1), so cifs.ko will only contain a
single tcon for both link and link2.

The problem with that is, if we (auto)mount "link" and "link2", cifs.ko
will only contain a single tcon for both DFS links so we couldn't
perform failover or refresh the DFS cache for both links because
tcon-&gt;dfs_path was set to either "link" or "link2", but not both --
which is wrong.

Signed-off-by: Paulo Alcantara (SUSE) &lt;pc@cjr.nz&gt;
Reviewed-by: Aurelien Aptel &lt;aaptel@suse.com&gt;
Reviewed-by: Ronnie Sahlberg &lt;lsahlber@redhat.com&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>cifs: minor update to comments around the cifs_tcp_ses_lock mutex</title>
<updated>2020-04-22T04:51:18+00:00</updated>
<author>
<name>Steve French</name>
<email>stfrench@microsoft.com</email>
</author>
<published>2020-04-22T04:51:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=d92c7ce41eb7f5d7d9f680a935d59552c5518d3c'/>
<id>d92c7ce41eb7f5d7d9f680a935d59552c5518d3c</id>
<content type='text'>
Update comment to note that it protects server-&gt;dstaddr

Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Update comment to note that it protects server-&gt;dstaddr

Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>cifs: protect updating server-&gt;dstaddr with a spinlock</title>
<updated>2020-04-21T14:57:56+00:00</updated>
<author>
<name>Ronnie Sahlberg</name>
<email>lsahlber@redhat.com</email>
</author>
<published>2020-04-21T02:37:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=fada37f6f62995cc449b36ebba1220594bfe55fe'/>
<id>fada37f6f62995cc449b36ebba1220594bfe55fe</id>
<content type='text'>
We use a spinlock while we are reading and accessing the destination address for a server.
We need to also use this spinlock to protect when we are modifying this address from
reconn_set_ipaddr().

Signed-off-by: Ronnie Sahlberg &lt;lsahlber@redhat.com&gt;
Reviewed-by: Jeff Layton &lt;jlayton@kernel.org&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We use a spinlock while we are reading and accessing the destination address for a server.
We need to also use this spinlock to protect when we are modifying this address from
reconn_set_ipaddr().

Signed-off-by: Ronnie Sahlberg &lt;lsahlber@redhat.com&gt;
Reviewed-by: Jeff Layton &lt;jlayton@kernel.org&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>smb3: remove overly noisy debug line in signing errors</title>
<updated>2020-04-16T17:23:40+00:00</updated>
<author>
<name>Steve French</name>
<email>stfrench@microsoft.com</email>
</author>
<published>2020-04-15T06:12:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=9692ea9d3288a201df762868a52552b2e07e1c55'/>
<id>9692ea9d3288a201df762868a52552b2e07e1c55</id>
<content type='text'>
A dump_stack call for signature related errors can be too noisy
and not of much value in debugging such problems.

Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
Reviewed-by: Shyam Prasad N &lt;nspmangalore@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
A dump_stack call for signature related errors can be too noisy
and not of much value in debugging such problems.

Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
Reviewed-by: Shyam Prasad N &lt;nspmangalore@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>cifs: improve read performance for page size 64KB &amp; cache=strict &amp; vers=2.1+</title>
<updated>2020-04-16T02:15:11+00:00</updated>
<author>
<name>Jones Syue</name>
<email>jonessyue@qnap.com</email>
</author>
<published>2020-04-13T01:37:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=1f641d9410c3c4edd4ce9136bd2dbe0c00af9770'/>
<id>1f641d9410c3c4edd4ce9136bd2dbe0c00af9770</id>
<content type='text'>
Found a read performance issue when linux kernel page size is 64KB.
If linux kernel page size is 64KB and mount options cache=strict &amp;
vers=2.1+, it does not support cifs_readpages(). Instead, it is using
cifs_readpage() and cifs_read() with maximum read IO size 16KB, which is
much slower than read IO size 1MB when negotiated SMB 2.1+. Since modern
SMB server supported SMB 2.1+ and Max Read Size can reach more than 64KB
(for example 1MB ~ 8MB), this patch check max_read instead of maxBuf to
determine whether server support readpages() and improve read performance
for page size 64KB &amp; cache=strict &amp; vers=2.1+, and for SMB1 it is more
cleaner to initialize server-&gt;max_read to server-&gt;maxBuf.

The client is a linux box with linux kernel 4.2.8,
page size 64KB (CONFIG_ARM64_64K_PAGES=y),
cpu arm 1.7GHz, and use mount.cifs as smb client.
The server is another linux box with linux kernel 4.2.8,
share a file '10G.img' with size 10GB,
and use samba-4.7.12 as smb server.

The client mount a share from the server with different
cache options: cache=strict and cache=none,
mount -tcifs //&lt;server_ip&gt;/Public /cache_strict -overs=3.0,cache=strict,username=&lt;xxx&gt;,password=&lt;yyy&gt;
mount -tcifs //&lt;server_ip&gt;/Public /cache_none -overs=3.0,cache=none,username=&lt;xxx&gt;,password=&lt;yyy&gt;

The client download a 10GbE file from the server across 1GbE network,
dd if=/cache_strict/10G.img of=/dev/null bs=1M count=10240
dd if=/cache_none/10G.img of=/dev/null bs=1M count=10240

Found that cache=strict (without patch) is slower read throughput and
smaller read IO size than cache=none.
cache=strict (without patch): read throughput 40MB/s, read IO size is 16KB
cache=strict (with patch): read throughput 113MB/s, read IO size is 1MB
cache=none: read throughput 109MB/s, read IO size is 1MB

Looks like if page size is 64KB,
cifs_set_ops() would use cifs_addr_ops_smallbuf instead of cifs_addr_ops,

	/* check if server can support readpages */
	if (cifs_sb_master_tcon(cifs_sb)-&gt;ses-&gt;server-&gt;maxBuf &lt;
			PAGE_SIZE + MAX_CIFS_HDR_SIZE)
		inode-&gt;i_data.a_ops = &amp;cifs_addr_ops_smallbuf;
	else
		inode-&gt;i_data.a_ops = &amp;cifs_addr_ops;

maxBuf is came from 2 places, SMB2_negotiate() and CIFSSMBNegotiate(),
(SMB2_MAX_BUFFER_SIZE is 64KB)
SMB2_negotiate():
	/* set it to the maximum buffer size value we can send with 1 credit */
	server-&gt;maxBuf = min_t(unsigned int, le32_to_cpu(rsp-&gt;MaxTransactSize),
			       SMB2_MAX_BUFFER_SIZE);
CIFSSMBNegotiate():
	server-&gt;maxBuf = le32_to_cpu(pSMBr-&gt;MaxBufferSize);

Page size 64KB and cache=strict lead to read_pages() use cifs_readpage()
instead of cifs_readpages(), and then cifs_read() using maximum read IO
size 16KB, which is much slower than maximum read IO size 1MB.
(CIFSMaxBufSize is 16KB by default)

	/* FIXME: set up handlers for larger reads and/or convert to async */
	rsize = min_t(unsigned int, cifs_sb-&gt;rsize, CIFSMaxBufSize);
Reviewed-by: Pavel Shilovsky &lt;pshilov@microsoft.com&gt;
Signed-off-by: Jones Syue &lt;jonessyue@qnap.com&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Found a read performance issue when linux kernel page size is 64KB.
If linux kernel page size is 64KB and mount options cache=strict &amp;
vers=2.1+, it does not support cifs_readpages(). Instead, it is using
cifs_readpage() and cifs_read() with maximum read IO size 16KB, which is
much slower than read IO size 1MB when negotiated SMB 2.1+. Since modern
SMB server supported SMB 2.1+ and Max Read Size can reach more than 64KB
(for example 1MB ~ 8MB), this patch check max_read instead of maxBuf to
determine whether server support readpages() and improve read performance
for page size 64KB &amp; cache=strict &amp; vers=2.1+, and for SMB1 it is more
cleaner to initialize server-&gt;max_read to server-&gt;maxBuf.

The client is a linux box with linux kernel 4.2.8,
page size 64KB (CONFIG_ARM64_64K_PAGES=y),
cpu arm 1.7GHz, and use mount.cifs as smb client.
The server is another linux box with linux kernel 4.2.8,
share a file '10G.img' with size 10GB,
and use samba-4.7.12 as smb server.

The client mount a share from the server with different
cache options: cache=strict and cache=none,
mount -tcifs //&lt;server_ip&gt;/Public /cache_strict -overs=3.0,cache=strict,username=&lt;xxx&gt;,password=&lt;yyy&gt;
mount -tcifs //&lt;server_ip&gt;/Public /cache_none -overs=3.0,cache=none,username=&lt;xxx&gt;,password=&lt;yyy&gt;

The client download a 10GbE file from the server across 1GbE network,
dd if=/cache_strict/10G.img of=/dev/null bs=1M count=10240
dd if=/cache_none/10G.img of=/dev/null bs=1M count=10240

Found that cache=strict (without patch) is slower read throughput and
smaller read IO size than cache=none.
cache=strict (without patch): read throughput 40MB/s, read IO size is 16KB
cache=strict (with patch): read throughput 113MB/s, read IO size is 1MB
cache=none: read throughput 109MB/s, read IO size is 1MB

Looks like if page size is 64KB,
cifs_set_ops() would use cifs_addr_ops_smallbuf instead of cifs_addr_ops,

	/* check if server can support readpages */
	if (cifs_sb_master_tcon(cifs_sb)-&gt;ses-&gt;server-&gt;maxBuf &lt;
			PAGE_SIZE + MAX_CIFS_HDR_SIZE)
		inode-&gt;i_data.a_ops = &amp;cifs_addr_ops_smallbuf;
	else
		inode-&gt;i_data.a_ops = &amp;cifs_addr_ops;

maxBuf is came from 2 places, SMB2_negotiate() and CIFSSMBNegotiate(),
(SMB2_MAX_BUFFER_SIZE is 64KB)
SMB2_negotiate():
	/* set it to the maximum buffer size value we can send with 1 credit */
	server-&gt;maxBuf = min_t(unsigned int, le32_to_cpu(rsp-&gt;MaxTransactSize),
			       SMB2_MAX_BUFFER_SIZE);
CIFSSMBNegotiate():
	server-&gt;maxBuf = le32_to_cpu(pSMBr-&gt;MaxBufferSize);

Page size 64KB and cache=strict lead to read_pages() use cifs_readpage()
instead of cifs_readpages(), and then cifs_read() using maximum read IO
size 16KB, which is much slower than maximum read IO size 1MB.
(CIFSMaxBufSize is 16KB by default)

	/* FIXME: set up handlers for larger reads and/or convert to async */
	rsize = min_t(unsigned int, cifs_sb-&gt;rsize, CIFSMaxBufSize);
Reviewed-by: Pavel Shilovsky &lt;pshilov@microsoft.com&gt;
Signed-off-by: Jones Syue &lt;jonessyue@qnap.com&gt;
Signed-off-by: Steve French &lt;stfrench@microsoft.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
