NetApp CIFS

Regarding:

https://bugzilla.samba.org/show_bug.cgi?id=7860

Unfortunately it's not always sufficiant to provide a simple diff to solve the described issue, since the cifs module has been modified during the last 2 years.
Nevertheless, the major problem is not a bug on the linux kernel but in the way Netapp computes the smb packet length which is being written into the smb header. Since Netapp refuses to support Linux, there seem to be no hope in waiting for a bug fix coming from Netapp itself.

The only way to access the "big" Natapp share is to remove the header length validation in the linux cifs module. Although this seems to be rather dangerous to me, it works without any problem for about 2 years now.

So, here it is:
You'll find the relevant part in file
./fs/cifs/misc.c
in function checkSMB()

At the end of this function you'll find the if-struct comparing rfclen and clc_len beginning with this line:
"if (4 + rfclen < clc_len) {".

Simply remove the whole struct and recompile the module or the whole kernel.

Although it works for me, I have to point out, that this is a *really* dangeorus way to solve the issue. So please be sure not to use it on a production system.

The diff for the misc.c in a 3.2.0 kernel looks like this:


#####################################################
482,499d481
<               if (4 + rfclen < clc_len) {
<                       cERROR(1, "RFC1001 size %u smaller than SMB for mid=%u",
<                                       rfclen, smb->Mid);
<                       return -EIO;
<               } else if (rfclen > clc_len + 512) {
<                       /*
<                        * Some servers (Windows XP in particular) send more
<                        * data than the lengths in the SMB packet would
<                        * indicate on certain calls (byte range locks and
<                        * trans2 find first calls in particular). While the
<                        * client can handle such a frame by ignoring the
<                        * trailing data, we choose limit the amount of extra
<                        * data to 512 bytes.
<                        */
<                       cERROR(1, "RFC1001 size %u more than 512 bytes larger "
<                                 "than SMB for mid=%u", rfclen, smb->Mid);
<                       return -EIO;
<               }
#####################################################