On Tue, 23 Aug 2011 22:16:54 -0500
Steve French <[email protected]> wrote:

> From 9b7b518633fd3187c7efe260fe20a0961e4a5f0b Mon Sep 17 00:00:00 2001
> From: Steve French <[email protected]>
> Date: Tue, 23 Aug 2011 22:00:26 -0500
> Subject: [CIFS] ls on mounts to WindowsCE failing with invalid level message
> 
> Mount succeeds to WindowsCE but when user tries
> to access the contents of the directory gets "NT Status:
> STATUS_INVALID_LEVEL" according to wireshark.
> 
> This server does not support the common windows
> readdir (Findfirst) level 257 nor level 258, so "fall back"
> to level 260 if get an EOPNOTSUPP on level FIND_FILE_DIRECTORY_INFO
> and while we are at it fall back to level 1 (FILE_INFO_STANDARD)
> for very old servers if we get an EOPNOTSUPP on level 260.
> (Note that the server returned errors on queries for inode
> numbers via QueryPathInfo so we don't use the infolevel
> SMB_FIND_FILE_ID_FULL_DIR_INFO)
> 
> Reported-and-tested-by: Bryan James <[email protected]>
> Signed-off-by: Steve French <[email protected]>
> ---
>  fs/cifs/readdir.c |   17 +++++++++++++++++
>  1 files changed, 17 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
> index 5de03ec..ed29706 100644
> --- a/fs/cifs/readdir.c
> +++ b/fs/cifs/readdir.c
> @@ -270,6 +270,7 @@ ffirst_retry:
>               cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO;
>       }
> 
> +ffirst_retry_with_std_level:
>       rc = CIFSFindFirst(xid, pTcon, full_path, cifs_sb->local_nls,
>               &cifsFile->netfid, &cifsFile->srch_inf,
>               cifs_sb->mnt_cifs_flags &
> @@ -283,7 +284,23 @@ ffirst_retry:
>               (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
>               cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
>               goto ffirst_retry;
> +     } else if ((rc == -EOPNOTSUPP) && (cifsFile->srch_inf.info_level ==
> +                                     SMB_FIND_FILE_DIRECTORY_INFO)) {

                ^^^^ there's no need for the extra sets of parenthesis
                here. That violates kernel coding conventions and makes this
                harder to read.

> +             /* Windows CE can return EOPNOTSUPP on FILE_DIRECTORY_INFO */
> +             cifsFile->srch_inf.info_level =
> +                             SMB_FIND_FILE_BOTH_DIRECTORY_INFO;
                                ^^^^
                        The code doesn't currently use
                        BOTH_DIRECTORY_INFO anywhere. Would it be
                        better to skip this step?
 
> +             goto ffirst_retry_with_std_level;
> +     } else if ((rc == -EOPNOTSUPP) && (cifsFile->srch_inf.info_level ==
> +                                     SMB_FIND_FILE_BOTH_DIRECTORY_INFO)) {
> +             cifsFile->srch_inf.info_level =
> +                             SMB_FIND_FILE_FULL_DIRECTORY_INFO;

                                ^^^^
                        Ditto here. Would it be best to just fall back
                        to the lowest common denominator here? I'm not sure
                        I see a lot of benefit in using any of these
                        other infolevels. We'll basically get the same
                        info out of SMB_FIND_FILE_INFO_STANDARD and it's
                        more widely supported.

> +             goto ffirst_retry_with_std_level;
> +     } else if ((rc == -EOPNOTSUPP) && (cifsFile->srch_inf.info_level ==
> +                                     SMB_FIND_FILE_FULL_DIRECTORY_INFO)) {
> +             cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD;
> +             goto ffirst_retry_with_std_level;
>       }
> +
>  error_exit:
>       kfree(full_path);
>       cifs_put_tlink(tlink);


-- 
Jeff Layton <[email protected]>
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to