David Howells <dhowells@xxxxxxxxxx> writes: > If read() is done in an unbuffered manner, such that, say, > cifs_strict_readv() goes through cifs_user_readv() and thence > __cifs_readv(), it doesn't recognise the EOF and keeps indicating to > userspace that it returning full buffers of data. > > This is due to ctx->iter being advanced in cifs_send_async_read() as the > buffer is split up amongst a number of rdata objects. The iterator count > is then used in collect_uncached_read_data() in the non-DIO case to set the > total length read - and thus the return value of sys_read(). But since the > iterator normally gets used up completely during splitting, ctx->total_len > gets overridden to the full amount. > > However, prior to that in collect_uncached_read_data(), we've gone through > the list of rdatas and added up the amount of data we actually received > (which we then throw away). > > Fix this by removing the bit that overrides the amount read in the non-DIO > case and just going with the total added up in the aforementioned loop. > > This was observed by mounting a cifs share with multiple channels, e.g.: > > mount //192.168.6.1/test /test/ -o user=shares,pass=...,max_channels=6 > > and then reading a 1MiB file on the share: > > strace cat /xfstest.test/1M >/dev/null > > Through strace, the same data can be seen being read again and again. > > Fixes: d08089f649a0 ("cifs: Change the I/O paths to use an iterator rather than a page list") > Signed-off-by: David Howells <dhowells@xxxxxxxxxx> > cc: Steve French <smfrench@xxxxxxxxx> > cc: Paulo Alcantara <pc@xxxxxxxxxxxxx> > cc: Jérôme Glisse <jglisse@xxxxxxxxxx> > cc: Long Li <longli@xxxxxxxxxxxxx> > cc: Enzo Matsumiya <ematsumiya@xxxxxxx> > cc: Shyam Prasad N <nspmangalore@xxxxxxxxx> > cc: Rohith Surabattula <rohiths.msft@xxxxxxxxx> > cc: Jeff Layton <jlayton@xxxxxxxxxx> > cc: linux-cifs@xxxxxxxxxxxxxxx > --- > fs/cifs/file.c | 4 ---- > 1 file changed, 4 deletions(-) Acked-by: Paulo Alcantara (SUSE) <pc@xxxxxxxxxxxxx>