Skip to content

Commit

Permalink
[CIFS] Add support for readdir to legacy servers
Browse files Browse the repository at this point in the history
Fixes oops to OS/2 on ls and removes redundant NTCreateX calls to servers
which do not support NT SMBs.  Key operations to OS/2 work.

Signed-off-by: Steve French <sfrench@us.ibm.com>
  • Loading branch information
Steve French committed Jun 7, 2006
1 parent a8ee034 commit 5bafd76
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 50 deletions.
4 changes: 4 additions & 0 deletions fs/cifs/CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ Version 1.44
------------
Rewritten sessionsetup support, including support for legacy SMB
session setup needed for OS/2 and older servers such as Windows 95 and 98.
Fix oops on ls to OS/2 servers. Add support for level 1 FindFirst
so we can do search (ls etc.) to OS/2. Do not send NTCreateX
or recent levels of FindFirst unless server says it supports NT SMBs
(instead use legacy equivalents from LANMAN dialect).

Version 1.43
------------
Expand Down
29 changes: 24 additions & 5 deletions fs/cifs/cifspdu.h
Original file line number Diff line number Diff line change
Expand Up @@ -1374,6 +1374,9 @@ struct smb_t2_rsp {
#define SMB_FILE_MAXIMUM_INFO 0x40d

/* Find File infolevels */
#define SMB_FIND_FILE_INFO_STANDARD 0x001
#define SMB_FIND_FILE_QUERY_EA_SIZE 0x002
#define SMB_FIND_FILE_QUERY_EAS_FROM_LIST 0x003
#define SMB_FIND_FILE_DIRECTORY_INFO 0x101
#define SMB_FIND_FILE_FULL_DIRECTORY_INFO 0x102
#define SMB_FIND_FILE_NAMES_INFO 0x103
Expand Down Expand Up @@ -1998,7 +2001,8 @@ typedef struct {

struct file_allocation_info {
__le64 AllocationSize; /* Note old Samba srvr rounds this up too much */
} __attribute__((packed)); /* size used on disk, level 0x103 for set, 0x105 for query */
} __attribute__((packed)); /* size used on disk, for level 0x103 for set,
0x105 for query */

struct file_end_of_file_info {
__le64 FileSize; /* offset to end of file */
Expand Down Expand Up @@ -2105,7 +2109,7 @@ typedef struct {
__le32 ExtFileAttributes;
__le32 FileNameLength;
char FileName[1];
} __attribute__((packed)) FILE_DIRECTORY_INFO; /* level 0x101 FF response data area */
} __attribute__((packed)) FILE_DIRECTORY_INFO; /* level 0x101 FF resp data */

typedef struct {
__le32 NextEntryOffset;
Expand All @@ -2120,7 +2124,7 @@ typedef struct {
__le32 FileNameLength;
__le32 EaSize; /* length of the xattrs */
char FileName[1];
} __attribute__((packed)) FILE_FULL_DIRECTORY_INFO; /* level 0x102 FF response data area */
} __attribute__((packed)) FILE_FULL_DIRECTORY_INFO; /* level 0x102 rsp data */

typedef struct {
__le32 NextEntryOffset;
Expand All @@ -2137,7 +2141,7 @@ typedef struct {
__le32 Reserved;
__u64 UniqueId; /* inode num - le since Samba puts ino in low 32 bit*/
char FileName[1];
} __attribute__((packed)) SEARCH_ID_FULL_DIR_INFO; /* level 0x105 FF response data area */
} __attribute__((packed)) SEARCH_ID_FULL_DIR_INFO; /* level 0x105 FF rsp data */

typedef struct {
__le32 NextEntryOffset;
Expand All @@ -2155,7 +2159,22 @@ typedef struct {
__u8 Reserved;
__u8 ShortName[12];
char FileName[1];
} __attribute__((packed)) FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FF response data area */
} __attribute__((packed)) FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FFrsp data */

typedef struct {
__u32 ResumeKey;
__le16 CreationDate; /* SMB Date */
__le16 CreationTime; /* SMB Time */
__le16 LastAccessDate;
__le16 LastAccessTime;
__le16 LastWriteDate;
__le16 LastWriteTime;
__le32 DataSize; /* File Size (EOF) */
__le32 AllocationSize;
__le16 Attributes; /* verify not u32 */
__u8 FileNameLength;
char FileName[1];
} __attribute__((packed)) FIND_FILE_STANDARD_INFO; /* level 0x1 FF resp data */


struct win_dev {
Expand Down
11 changes: 9 additions & 2 deletions fs/cifs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
FreeXid(xid);
return -ENOMEM;
}

rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS)
rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
desiredAccess, CREATE_NOT_DIR,
&fileHandle, &oplock, buf, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
else
rc = -EIO; /* no NT SMB support fall into legacy open below */

if(rc == -EIO) {
/* old server, retry the open legacy style */
rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
Expand Down Expand Up @@ -369,6 +372,10 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);

/* BB FIXME - add handling for backlevel servers
which need legacy open and check for all
calls to SMBOpen for fallback to
SMBLeagcyOpen */
if(!rc) {
/* BB Do not bother to decode buf since no
local inode yet to put timestamps in,
Expand Down
9 changes: 7 additions & 2 deletions fs/cifs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,15 @@ int cifs_open(struct inode *inode, struct file *file)
rc = -ENOMEM;
goto out;
}
rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
CREATE_NOT_DIR, &netfid, &oplock, buf,

if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS)
rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf,
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR);
else
rc = -EIO; /* no NT SMB support fall into legacy open below */

if (rc == -EIO) {
/* Old server, try legacy style OpenX */
rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
Expand Down
Loading

0 comments on commit 5bafd76

Please sign in to comment.