Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
a9d02ad4
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
a9d02ad4
编写于
8月 24, 2005
作者:
S
Steve French
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[CIFS] Support for legacy servers part 3 - Add support for Open and most
of Read support. Signed-off-by:
N
Steve French
<
sfrench@us.ibm.com
>
上级
e22cb8bc
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
330 addition
and
2 deletion
+330
-2
fs/cifs/cifspdu.h
fs/cifs/cifspdu.h
+73
-0
fs/cifs/cifsproto.h
fs/cifs/cifsproto.h
+8
-0
fs/cifs/cifssmb.c
fs/cifs/cifssmb.c
+215
-0
fs/cifs/dir.c
fs/cifs/dir.c
+7
-0
fs/cifs/file.c
fs/cifs/file.c
+27
-2
未找到文件。
fs/cifs/cifspdu.h
浏览文件 @
a9d02ad4
...
...
@@ -40,6 +40,7 @@
#define SMB_COM_SETATTR 0x09
/* trivial response */
#define SMB_COM_LOCKING_ANDX 0x24
/* trivial response */
#define SMB_COM_COPY 0x29
/* trivial rsp, fail filename ignrd*/
#define SMB_COM_OPEN_ANDX 0x2D
/* Legacy open for old servers */
#define SMB_COM_READ_ANDX 0x2E
#define SMB_COM_WRITE_ANDX 0x2F
#define SMB_COM_TRANSACTION2 0x32
...
...
@@ -625,6 +626,7 @@ typedef struct smb_com_findclose_req {
}
FINDCLOSE_REQ
;
/* OpenFlags */
#define REQ_MORE_INFO 0x00000001
/* legacy (OPEN_AND_X) only */
#define REQ_OPLOCK 0x00000002
#define REQ_BATCHOPLOCK 0x00000004
#define REQ_OPENDIRONLY 0x00000008
...
...
@@ -680,6 +682,62 @@ typedef struct smb_com_open_rsp {
__u16
ByteCount
;
/* bct = 0 */
}
OPEN_RSP
;
/* format of legacy open request */
typedef
struct
smb_com_openx_req
{
struct
smb_hdr
hdr
;
/* wct = 15 */
__u8
AndXCommand
;
__u8
AndXReserved
;
__le16
AndXOffset
;
__le16
OpenFlags
;
__le16
Mode
;
__le16
Sattr
;
/* search attributes */
__le16
FileAttributes
;
/* dos attrs */
__le32
CreateTime
;
/* os2 format */
__le16
OpenFunction
;
__le32
EndOfFile
;
__le32
Timeout
;
__le32
Reserved
;
__u16
ByteCount
;
/* file name follows */
char
fileName
[
1
];
}
OPENX_REQ
;
typedef
struct
smb_com_openx_rsp
{
struct
smb_hdr
hdr
;
/* wct = 15 */
__u8
AndXCommand
;
__u8
AndXReserved
;
__le16
AndXOffset
;
__u16
Fid
;
__le16
FileAttributes
;
__le32
LastWriteTime
;
/* os2 format */
__le32
EndOfFile
;
__le16
Access
;
__le16
FileType
;
__le16
IPCState
;
__le16
Action
;
__u32
FileId
;
__u16
Reserved
;
__u16
ByteCount
;
}
OPENX_RSP
;
/* Legacy write request for older servers */
typedef
struct
smb_com_writex_req
{
struct
smb_hdr
hdr
;
/* wct = 12 */
__u8
AndXCommand
;
__u8
AndXReserved
;
__le16
AndXOffset
;
__u16
Fid
;
__le32
OffsetLow
;
__u32
Reserved
;
/* Timeout */
__le16
WriteMode
;
/* 1 = write through */
__le16
Remaining
;
__le16
Reserved2
;
__le16
DataLengthLow
;
__le16
DataOffset
;
__le16
ByteCount
;
__u8
Pad
;
/* BB check for whether padded to DWORD boundary and optimum performance here */
char
Data
[
0
];
}
WRITEX_REQ
;
typedef
struct
smb_com_write_req
{
struct
smb_hdr
hdr
;
/* wct = 14 */
__u8
AndXCommand
;
...
...
@@ -711,6 +769,21 @@ typedef struct smb_com_write_rsp {
__u16
ByteCount
;
}
WRITE_RSP
;
/* legacy read request for older servers */
typedef
struct
smb_com_readx_req
{
struct
smb_hdr
hdr
;
/* wct = 10 */
__u8
AndXCommand
;
__u8
AndXReserved
;
__le16
AndXOffset
;
__u16
Fid
;
__le32
OffsetLow
;
__le16
MaxCount
;
__le16
MinCount
;
/* obsolete */
__le32
Reserved
;
__le16
Remaining
;
__le16
ByteCount
;
}
READX_REQ
;
typedef
struct
smb_com_read_req
{
struct
smb_hdr
hdr
;
/* wct = 12 */
__u8
AndXCommand
;
...
...
fs/cifs/cifsproto.h
浏览文件 @
a9d02ad4
...
...
@@ -218,9 +218,17 @@ extern int CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
const
int
access_flags
,
const
int
omode
,
__u16
*
netfid
,
int
*
pOplock
,
FILE_ALL_INFO
*
,
const
struct
nls_table
*
nls_codepage
,
int
remap
);
extern
int
SMBLegacyOpen
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
char
*
fileName
,
const
int
disposition
,
const
int
access_flags
,
const
int
omode
,
__u16
*
netfid
,
int
*
pOplock
,
FILE_ALL_INFO
*
,
const
struct
nls_table
*
nls_codepage
,
int
remap
);
extern
int
CIFSSMBClose
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
int
smb_file_id
);
extern
int
SMBLegacyRead
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
int
netfid
,
unsigned
int
count
,
const
__u64
lseek
,
unsigned
int
*
nbytes
,
char
**
buf
);
extern
int
CIFSSMBRead
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
int
netfid
,
unsigned
int
count
,
const
__u64
lseek
,
unsigned
int
*
nbytes
,
char
**
buf
);
...
...
fs/cifs/cifssmb.c
浏览文件 @
a9d02ad4
...
...
@@ -680,6 +680,146 @@ CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
return
rc
;
}
static
__u16
convert_disposition
(
int
disposition
)
{
__u16
ofun
=
0
;
switch
(
disposition
)
{
case
FILE_SUPERSEDE
:
ofun
=
SMBOPEN_OCREATE
|
SMBOPEN_OTRUNC
;
break
;
case
FILE_OPEN
:
ofun
=
SMBOPEN_OAPPEND
;
break
;
case
FILE_CREATE
:
ofun
=
SMBOPEN_OCREATE
;
break
;
case
FILE_OPEN_IF
:
ofun
=
SMBOPEN_OCREATE
|
SMBOPEN_OAPPEND
;
break
;
case
FILE_OVERWRITE
:
ofun
=
SMBOPEN_OTRUNC
;
break
;
case
FILE_OVERWRITE_IF
:
ofun
=
SMBOPEN_OCREATE
|
SMBOPEN_OTRUNC
;
break
;
default:
cFYI
(
1
,(
"unknown disposition %d"
,
disposition
));
ofun
=
SMBOPEN_OAPPEND
;
/* regular open */
}
return
ofun
;
}
int
SMBLegacyOpen
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
char
*
fileName
,
const
int
openDisposition
,
const
int
access_flags
,
const
int
create_options
,
__u16
*
netfid
,
int
*
pOplock
,
FILE_ALL_INFO
*
pfile_info
,
const
struct
nls_table
*
nls_codepage
,
int
remap
)
{
int
rc
=
-
EACCES
;
OPENX_REQ
*
pSMB
=
NULL
;
OPENX_RSP
*
pSMBr
=
NULL
;
int
bytes_returned
;
int
name_len
;
__u16
count
;
OldOpenRetry:
rc
=
smb_init
(
SMB_COM_OPEN_ANDX
,
15
,
tcon
,
(
void
**
)
&
pSMB
,
(
void
**
)
&
pSMBr
);
if
(
rc
)
return
rc
;
pSMB
->
AndXCommand
=
0xFF
;
/* none */
if
(
pSMB
->
hdr
.
Flags2
&
SMBFLG2_UNICODE
)
{
count
=
1
;
/* account for one byte pad to word boundary */
name_len
=
cifsConvertToUCS
((
__le16
*
)
(
pSMB
->
fileName
+
1
),
fileName
,
PATH_MAX
,
nls_codepage
,
remap
);
name_len
++
;
/* trailing null */
name_len
*=
2
;
}
else
{
/* BB improve check for buffer overruns BB */
count
=
0
;
/* no pad */
name_len
=
strnlen
(
fileName
,
PATH_MAX
);
name_len
++
;
/* trailing null */
strncpy
(
pSMB
->
fileName
,
fileName
,
name_len
);
}
if
(
*
pOplock
&
REQ_OPLOCK
)
pSMB
->
OpenFlags
=
cpu_to_le16
(
REQ_OPLOCK
);
else
if
(
*
pOplock
&
REQ_BATCHOPLOCK
)
{
pSMB
->
OpenFlags
=
cpu_to_le16
(
REQ_BATCHOPLOCK
);
}
pSMB
->
OpenFlags
|=
cpu_to_le16
(
REQ_MORE_INFO
);
/* BB fixme add conversion for access_flags to bits 0 - 2 of mode */
/* 0 = read
1 = write
2 = rw
3 = execute
*/
pSMB
->
Mode
=
cpu_to_le16
(
2
);
pSMB
->
Mode
|=
cpu_to_le16
(
0x40
);
/* deny none */
/* set file as system file if special file such
as fifo and server expecting SFU style and
no Unix extensions */
if
(
create_options
&
CREATE_OPTION_SPECIAL
)
pSMB
->
FileAttributes
=
cpu_to_le16
(
ATTR_SYSTEM
);
else
pSMB
->
FileAttributes
=
cpu_to_le16
(
ATTR_NORMAL
);
/* if ((omode & S_IWUGO) == 0)
pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/
/* Above line causes problems due to vfs splitting create into two
pieces - need to set mode after file created not while it is
being created */
/* BB FIXME BB */
/* pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK); */
/* BB FIXME END BB */
pSMB
->
OpenFunction
=
convert_disposition
(
openDisposition
);
count
+=
name_len
;
pSMB
->
hdr
.
smb_buf_length
+=
count
;
pSMB
->
ByteCount
=
cpu_to_le16
(
count
);
/* long_op set to 1 to allow for oplock break timeouts */
rc
=
SendReceive
(
xid
,
tcon
->
ses
,
(
struct
smb_hdr
*
)
pSMB
,
(
struct
smb_hdr
*
)
pSMBr
,
&
bytes_returned
,
1
);
cifs_stats_inc
(
&
tcon
->
num_opens
);
if
(
rc
)
{
cFYI
(
1
,
(
"Error in Open = %d"
,
rc
));
}
else
{
/* BB verify if wct == 15 */
/* *pOplock = pSMBr->OplockLevel; */
/* BB take from action field BB */
*
netfid
=
pSMBr
->
Fid
;
/* cifs fid stays in le */
/* Let caller know file was created so we can set the mode. */
/* Do we care about the CreateAction in any other cases? */
/* BB FIXME BB */
/* if(cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
*pOplock |= CIFS_CREATE_ACTION; */
/* BB FIXME END */
if
(
pfile_info
)
{
pfile_info
->
CreationTime
=
0
;
/* BB convert CreateTime*/
pfile_info
->
LastAccessTime
=
0
;
/* BB fixme */
pfile_info
->
LastWriteTime
=
0
;
/* BB fixme */
pfile_info
->
ChangeTime
=
0
;
/* BB fixme */
pfile_info
->
Attributes
=
pSMBr
->
FileAttributes
;
/* the file_info buf is endian converted by caller */
pfile_info
->
AllocationSize
=
pSMBr
->
EndOfFile
;
pfile_info
->
EndOfFile
=
pSMBr
->
EndOfFile
;
pfile_info
->
NumberOfLinks
=
cpu_to_le32
(
1
);
}
}
cifs_buf_release
(
pSMB
);
if
(
rc
==
-
EAGAIN
)
goto
OldOpenRetry
;
return
rc
;
}
int
CIFSSMBOpen
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
char
*
fileName
,
const
int
openDisposition
,
...
...
@@ -783,6 +923,81 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
return
rc
;
}
int
SMBLegacyRead
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
int
netfid
,
unsigned
int
count
,
const
__u64
lseek
,
unsigned
int
*
nbytes
,
char
**
buf
)
{
int
rc
=
-
EACCES
;
READX_REQ
*
pSMB
=
NULL
;
READ_RSP
*
pSMBr
=
NULL
;
char
*
pReadData
=
NULL
;
int
bytes_returned
;
cFYI
(
1
,(
"Legacy read %d bytes fid %d"
,
count
,
netfid
));
/* field is shorter in legacy read, only 16 bits */
if
(
count
>
2048
)
count
=
2048
;
/* BB FIXME make this configurable */
if
(
lseek
>
0xFFFFFFFF
)
return
-
EIO
;
/* can not read that far into file on old server */
*
nbytes
=
0
;
rc
=
smb_init
(
SMB_COM_READ_ANDX
,
10
,
tcon
,
(
void
**
)
&
pSMB
,
(
void
**
)
&
pSMBr
);
if
(
rc
)
return
rc
;
/* tcon and ses pointer are checked in smb_init */
if
(
tcon
->
ses
->
server
==
NULL
)
return
-
ECONNABORTED
;
pSMB
->
AndXCommand
=
0xFF
;
/* none */
pSMB
->
Fid
=
netfid
;
pSMB
->
OffsetLow
=
cpu_to_le32
(
lseek
&
0xFFFFFFFF
);
pSMB
->
Remaining
=
0
;
pSMB
->
MaxCount
=
cpu_to_le16
(
count
);
pSMB
->
Reserved
=
0
;
/* Must Be Zero */
pSMB
->
ByteCount
=
0
;
/* no need to do le conversion since it is 0 */
rc
=
SendReceive
(
xid
,
tcon
->
ses
,
(
struct
smb_hdr
*
)
pSMB
,
(
struct
smb_hdr
*
)
pSMBr
,
&
bytes_returned
,
0
);
cifs_stats_inc
(
&
tcon
->
num_reads
);
if
(
rc
)
{
cERROR
(
1
,
(
"Send error in legacy read = %d"
,
rc
));
}
else
{
int
data_length
=
le16_to_cpu
(
pSMBr
->
DataLengthHigh
);
data_length
=
data_length
<<
16
;
data_length
+=
le16_to_cpu
(
pSMBr
->
DataLength
);
*
nbytes
=
data_length
;
/*check that DataLength would not go beyond end of SMB */
if
((
data_length
>
CIFSMaxBufSize
)
||
(
data_length
>
count
))
{
cFYI
(
1
,(
"bad length %d for count %d"
,
data_length
,
count
));
rc
=
-
EIO
;
*
nbytes
=
0
;
}
else
{
pReadData
=
(
char
*
)
(
&
pSMBr
->
hdr
.
Protocol
)
+
le16_to_cpu
(
pSMBr
->
DataOffset
);
/* if(rc = copy_to_user(buf, pReadData, data_length)) {
cERROR(1,("Faulting on read rc = %d",rc));
rc = -EFAULT;
}*/
/* can not use copy_to_user when using page cache*/
if
(
*
buf
)
memcpy
(
*
buf
,
pReadData
,
data_length
);
}
}
if
(
*
buf
)
cifs_buf_release
(
pSMB
);
else
*
buf
=
(
char
*
)
pSMB
;
/* Note: On -EAGAIN error only caller can retry on handle based calls
since file handle passed in no longer valid */
return
rc
;
}
/* If no buffer passed in, then caller wants to do the copy
as in the case of readpages so the SMB buffer must be
freed by the caller */
...
...
fs/cifs/dir.c
浏览文件 @
a9d02ad4
...
...
@@ -184,6 +184,13 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
desiredAccess
,
CREATE_NOT_DIR
,
&
fileHandle
,
&
oplock
,
buf
,
cifs_sb
->
local_nls
,
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_MAP_SPECIAL_CHR
);
if
(
rc
==
-
EIO
)
{
/* old server, retry the open legacy style */
rc
=
SMBLegacyOpen
(
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
);
}
if
(
rc
)
{
cFYI
(
1
,
(
"cifs_create returned 0x%x "
,
rc
));
}
else
{
...
...
fs/cifs/file.c
浏览文件 @
a9d02ad4
...
...
@@ -256,6 +256,13 @@ int cifs_open(struct inode *inode, struct file *file)
CREATE_NOT_DIR
,
&
netfid
,
&
oplock
,
buf
,
cifs_sb
->
local_nls
,
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_MAP_SPECIAL_CHR
);
if
(
rc
==
-
EIO
)
{
/* Old server, try legacy style OpenX */
rc
=
SMBLegacyOpen
(
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
);
}
if
(
rc
)
{
cFYI
(
1
,
(
"cifs_open returned 0x%x "
,
rc
));
goto
out
;
...
...
@@ -1210,7 +1217,12 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
open_file
->
netfid
,
current_read_size
,
*
poffset
,
&
bytes_read
,
&
smb_read_data
);
if
(
rc
==
-
EINVAL
)
{
rc
=
SMBLegacyRead
(
xid
,
pTcon
,
open_file
->
netfid
,
current_read_size
,
*
poffset
,
&
bytes_read
,
&
smb_read_data
);
}
pSMBr
=
(
struct
smb_com_read_rsp
*
)
smb_read_data
;
if
(
copy_to_user
(
current_offset
,
smb_read_data
+
4
/* RFC1001 hdr */
...
...
@@ -1287,6 +1299,12 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
open_file
->
netfid
,
current_read_size
,
*
poffset
,
&
bytes_read
,
&
current_offset
);
if
(
rc
==
-
EINVAL
)
{
rc
=
SMBLegacyRead
(
xid
,
pTcon
,
open_file
->
netfid
,
current_read_size
,
*
poffset
,
&
bytes_read
,
&
current_offset
);
}
}
if
(
rc
||
(
bytes_read
==
0
))
{
if
(
total_read
)
{
...
...
@@ -1443,7 +1461,14 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
open_file
->
netfid
,
read_size
,
offset
,
&
bytes_read
,
&
smb_read_data
);
/* BB need to check return code here */
if
(
rc
==
-
EINVAL
)
{
rc
=
SMBLegacyRead
(
xid
,
pTcon
,
open_file
->
netfid
,
read_size
,
offset
,
&
bytes_read
,
&
smb_read_data
);
}
/* BB more RC checks ? */
if
(
rc
==
-
EAGAIN
)
{
if
(
smb_read_data
)
{
cifs_buf_release
(
smb_read_data
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录