Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
252ec9e2
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
252ec9e2
编写于
11月 20, 2005
作者:
L
Linus Torvalds
浏览文件
操作
浏览文件
下载
差异文件
Merge master.kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6
上级
d4892279
1e6b39fb
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
385 addition
and
176 deletion
+385
-176
fs/cifs/CHANGES
fs/cifs/CHANGES
+2
-0
fs/cifs/cifs_unicode.c
fs/cifs/cifs_unicode.c
+7
-6
fs/cifs/cifs_unicode.h
fs/cifs/cifs_unicode.h
+3
-3
fs/cifs/cifsencrypt.c
fs/cifs/cifsencrypt.c
+1
-1
fs/cifs/cifsfs.c
fs/cifs/cifsfs.c
+60
-47
fs/cifs/cifsfs.h
fs/cifs/cifsfs.h
+2
-0
fs/cifs/cifspdu.h
fs/cifs/cifspdu.h
+9
-1
fs/cifs/cifssmb.c
fs/cifs/cifssmb.c
+23
-20
fs/cifs/connect.c
fs/cifs/connect.c
+41
-50
fs/cifs/dir.c
fs/cifs/dir.c
+30
-2
fs/cifs/file.c
fs/cifs/file.c
+2
-0
fs/cifs/inode.c
fs/cifs/inode.c
+168
-34
fs/cifs/misc.c
fs/cifs/misc.c
+1
-1
fs/cifs/readdir.c
fs/cifs/readdir.c
+34
-9
fs/cifs/transport.c
fs/cifs/transport.c
+2
-2
未找到文件。
fs/cifs/CHANGES
浏览文件 @
252ec9e2
...
...
@@ -3,6 +3,8 @@ Version 1.39
Defer close of a file handle slightly if pending writes depend on that file handle
(this reduces the EBADF bad file handle errors that can be logged under heavy
stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2
Fix SFU style symlinks and mknod needed for servers which do not support the CIFS
Unix Extensions. Fix setfacl/getfacl on bigendian.
Version 1.38
------------
...
...
fs/cifs/cifs_unicode.c
浏览文件 @
252ec9e2
/*
* fs/cifs/cifs_unicode.c
*
* Copyright (c) International Business Machines Corp., 2000,200
2
* Copyright (c) International Business Machines Corp., 2000,200
5
* Modified by Steve French (sfrench@us.ibm.com)
*
* This program is free software; you can redistribute it and/or modify
...
...
@@ -31,7 +31,7 @@
*
*/
int
cifs_strfromUCS_le
(
char
*
to
,
const
wchar_t
*
from
,
/* LITTLE ENDIAN */
cifs_strfromUCS_le
(
char
*
to
,
const
__le16
*
from
,
int
len
,
const
struct
nls_table
*
codepage
)
{
int
i
;
...
...
@@ -60,25 +60,26 @@ cifs_strfromUCS_le(char *to, const wchar_t * from, /* LITTLE ENDIAN */
*
*/
int
cifs_strtoUCS
(
wchar_t
*
to
,
const
char
*
from
,
int
len
,
cifs_strtoUCS
(
__le16
*
to
,
const
char
*
from
,
int
len
,
const
struct
nls_table
*
codepage
)
{
int
charlen
;
int
i
;
wchar_t
*
wchar_to
=
(
wchar_t
*
)
to
;
/* needed to quiet sparse */
for
(
i
=
0
;
len
&&
*
from
;
i
++
,
from
+=
charlen
,
len
-=
charlen
)
{
/* works for 2.4.0 kernel or later */
charlen
=
codepage
->
char2uni
(
from
,
len
,
&
to
[
i
]);
charlen
=
codepage
->
char2uni
(
from
,
len
,
&
wchar_
to
[
i
]);
if
(
charlen
<
1
)
{
cERROR
(
1
,
(
"cifs_strtoUCS: char2uni returned %d"
,
charlen
));
/* A question mark */
to
[
i
]
=
(
wchar_t
)
cpu_to_le16
(
0x003f
);
to
[
i
]
=
cpu_to_le16
(
0x003f
);
charlen
=
1
;
}
else
to
[
i
]
=
(
wchar_t
)
cpu_to_le16
(
to
[
i
]);
to
[
i
]
=
cpu_to_le16
(
wchar_
to
[
i
]);
}
...
...
fs/cifs/cifs_unicode.h
浏览文件 @
252ec9e2
...
...
@@ -5,7 +5,7 @@
* Convert a unicode character to upper or lower case using
* compressed tables.
*
* Copyright (c) International Business Machines Corp., 2000,200
2
* Copyright (c) International Business Machines Corp., 2000,200
5555555555555555555555555555555555555555555555555555555
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -59,8 +59,8 @@ extern struct UniCaseRange UniLowerRange[];
#endif
/* UNIUPR_NOLOWER */
#ifdef __KERNEL__
int
cifs_strfromUCS_le
(
char
*
,
const
wchar_t
*
,
int
,
const
struct
nls_table
*
);
int
cifs_strtoUCS
(
wchar_t
*
,
const
char
*
,
int
,
const
struct
nls_table
*
);
int
cifs_strfromUCS_le
(
char
*
,
const
__le16
*
,
int
,
const
struct
nls_table
*
);
int
cifs_strtoUCS
(
__le16
*
,
const
char
*
,
int
,
const
struct
nls_table
*
);
#endif
/*
...
...
fs/cifs/cifsencrypt.c
浏览文件 @
252ec9e2
...
...
@@ -149,7 +149,7 @@ int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, struct nls_table * nls_
char
temp_hash
[
16
];
struct
HMACMD5Context
ctx
;
char
*
ucase_buf
;
wchar_t
*
unicode_buf
;
__le16
*
unicode_buf
;
unsigned
int
i
,
user_name_len
,
dom_name_len
;
if
(
ses
==
NULL
)
...
...
fs/cifs/cifsfs.c
浏览文件 @
252ec9e2
...
...
@@ -483,57 +483,30 @@ cifs_get_sb(struct file_system_type *fs_type,
return
sb
;
}
static
ssize_t
cifs_read_wrapper
(
struct
file
*
file
,
char
__user
*
read_data
,
size_t
read_size
,
loff_t
*
poffset
)
static
ssize_t
cifs_file_writev
(
struct
file
*
file
,
const
struct
iovec
*
iov
,
unsigned
long
nr_segs
,
loff_t
*
ppos
)
{
if
(
file
->
f_dentry
==
NULL
)
return
-
EIO
;
else
if
(
file
->
f_dentry
->
d_inode
==
NULL
)
return
-
EIO
;
cFYI
(
1
,(
"In read_wrapper size %zd at %lld"
,
read_size
,
*
poffset
));
struct
inode
*
inode
=
file
->
f_dentry
->
d_inode
;
ssize_t
written
;
if
(
CIFS_I
(
file
->
f_dentry
->
d_inode
)
->
clientCanCacheRead
)
{
return
generic_file_read
(
file
,
read_data
,
read_size
,
poffset
);
}
else
{
/* BB do we need to lock inode from here until after invalidate? */
/* if(file->f_dentry->d_inode->i_mapping) {
filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);
filemap_fdatawait(file->f_dentry->d_inode->i_mapping);
}*/
/* cifs_revalidate(file->f_dentry);*/
/* BB fixme */
/* BB we should make timer configurable - perhaps
by simply calling cifs_revalidate here */
/* invalidate_remote_inode(file->f_dentry->d_inode);*/
return
generic_file_read
(
file
,
read_data
,
read_size
,
poffset
);
}
written
=
generic_file_writev
(
file
,
iov
,
nr_segs
,
ppos
);
if
(
!
CIFS_I
(
inode
)
->
clientCanCacheAll
)
filemap_fdatawrite
(
inode
->
i_mapping
);
return
written
;
}
static
ssize_t
cifs_write_wrapper
(
struct
file
*
file
,
const
char
__user
*
write_data
,
size_t
write_size
,
loff_t
*
poffset
)
static
ssize_t
cifs_file_aio_write
(
struct
kiocb
*
iocb
,
const
char
__user
*
buf
,
size_t
count
,
loff_t
pos
)
{
struct
inode
*
inode
=
iocb
->
ki_filp
->
f_dentry
->
d_inode
;
ssize_t
written
;
if
(
file
->
f_dentry
==
NULL
)
return
-
EIO
;
else
if
(
file
->
f_dentry
->
d_inode
==
NULL
)
return
-
EIO
;
cFYI
(
1
,(
"In write_wrapper size %zd at %lld"
,
write_size
,
*
poffset
));
written
=
generic_file_write
(
file
,
write_data
,
write_size
,
poffset
);
if
(
!
CIFS_I
(
file
->
f_dentry
->
d_inode
)
->
clientCanCacheAll
)
{
if
(
file
->
f_dentry
->
d_inode
->
i_mapping
)
{
filemap_fdatawrite
(
file
->
f_dentry
->
d_inode
->
i_mapping
);
}
}
written
=
generic_file_aio_write
(
iocb
,
buf
,
count
,
pos
);
if
(
!
CIFS_I
(
inode
)
->
clientCanCacheAll
)
filemap_fdatawrite
(
inode
->
i_mapping
);
return
written
;
}
static
struct
file_system_type
cifs_fs_type
=
{
.
owner
=
THIS_MODULE
,
.
name
=
"cifs"
,
...
...
@@ -594,8 +567,12 @@ struct inode_operations cifs_symlink_inode_ops = {
};
struct
file_operations
cifs_file_ops
=
{
.
read
=
cifs_read_wrapper
,
.
write
=
cifs_write_wrapper
,
.
read
=
do_sync_read
,
.
write
=
do_sync_write
,
.
readv
=
generic_file_readv
,
.
writev
=
cifs_file_writev
,
.
aio_read
=
generic_file_aio_read
,
.
aio_write
=
cifs_file_aio_write
,
.
open
=
cifs_open
,
.
release
=
cifs_close
,
.
lock
=
cifs_lock
,
...
...
@@ -608,10 +585,6 @@ struct file_operations cifs_file_ops = {
#endif
/* CONFIG_CIFS_POSIX */
#ifdef CONFIG_CIFS_EXPERIMENTAL
.
readv
=
generic_file_readv
,
.
writev
=
generic_file_writev
,
.
aio_read
=
generic_file_aio_read
,
.
aio_write
=
generic_file_aio_write
,
.
dir_notify
=
cifs_dir_notify
,
#endif
/* CONFIG_CIFS_EXPERIMENTAL */
};
...
...
@@ -631,6 +604,46 @@ struct file_operations cifs_file_direct_ops = {
.
ioctl
=
cifs_ioctl
,
#endif
/* CONFIG_CIFS_POSIX */
#ifdef CONFIG_CIFS_EXPERIMENTAL
.
dir_notify
=
cifs_dir_notify
,
#endif
/* CONFIG_CIFS_EXPERIMENTAL */
};
struct
file_operations
cifs_file_nobrl_ops
=
{
.
read
=
do_sync_read
,
.
write
=
do_sync_write
,
.
readv
=
generic_file_readv
,
.
writev
=
cifs_file_writev
,
.
aio_read
=
generic_file_aio_read
,
.
aio_write
=
cifs_file_aio_write
,
.
open
=
cifs_open
,
.
release
=
cifs_close
,
.
fsync
=
cifs_fsync
,
.
flush
=
cifs_flush
,
.
mmap
=
cifs_file_mmap
,
.
sendfile
=
generic_file_sendfile
,
#ifdef CONFIG_CIFS_POSIX
.
ioctl
=
cifs_ioctl
,
#endif
/* CONFIG_CIFS_POSIX */
#ifdef CONFIG_CIFS_EXPERIMENTAL
.
dir_notify
=
cifs_dir_notify
,
#endif
/* CONFIG_CIFS_EXPERIMENTAL */
};
struct
file_operations
cifs_file_direct_nobrl_ops
=
{
/* no mmap, no aio, no readv -
BB reevaluate whether they can be done with directio, no cache */
.
read
=
cifs_user_read
,
.
write
=
cifs_user_write
,
.
open
=
cifs_open
,
.
release
=
cifs_close
,
.
fsync
=
cifs_fsync
,
.
flush
=
cifs_flush
,
.
sendfile
=
generic_file_sendfile
,
/* BB removeme BB */
#ifdef CONFIG_CIFS_POSIX
.
ioctl
=
cifs_ioctl
,
#endif
/* CONFIG_CIFS_POSIX */
#ifdef CONFIG_CIFS_EXPERIMENTAL
.
dir_notify
=
cifs_dir_notify
,
#endif
/* CONFIG_CIFS_EXPERIMENTAL */
...
...
fs/cifs/cifsfs.h
浏览文件 @
252ec9e2
...
...
@@ -63,6 +63,8 @@ extern struct inode_operations cifs_symlink_inode_ops;
/* Functions related to files and directories */
extern
struct
file_operations
cifs_file_ops
;
extern
struct
file_operations
cifs_file_direct_ops
;
/* if directio mount */
extern
struct
file_operations
cifs_file_nobrl_ops
;
extern
struct
file_operations
cifs_file_direct_nobrl_ops
;
/* if directio mount */
extern
int
cifs_open
(
struct
inode
*
inode
,
struct
file
*
file
);
extern
int
cifs_close
(
struct
inode
*
inode
,
struct
file
*
file
);
extern
int
cifs_closedir
(
struct
inode
*
inode
,
struct
file
*
file
);
...
...
fs/cifs/cifspdu.h
浏览文件 @
252ec9e2
...
...
@@ -603,7 +603,9 @@ typedef struct smb_com_logoff_andx_rsp {
__u16
ByteCount
;
}
__attribute__
((
packed
))
LOGOFF_ANDX_RSP
;
typedef
union
smb_com_tree_disconnect
{
/* as an altetnative can use flag on tree_connect PDU to effect disconnect *//* probably the simplest SMB PDU */
typedef
union
smb_com_tree_disconnect
{
/* as an altetnative can use flag on
tree_connect PDU to effect disconnect */
/* tdis is probably simplest SMB PDU */
struct
{
struct
smb_hdr
hdr
;
/* wct = 0 */
__u16
ByteCount
;
/* bcc = 0 */
...
...
@@ -2025,6 +2027,12 @@ typedef struct {
}
__attribute__
((
packed
))
FILE_BOTH_DIRECTORY_INFO
;
/* level 0x104 FF response data area */
struct
win_dev
{
unsigned
char
type
[
8
];
/* IntxCHR or IntxBLK */
__le64
major
;
__le64
minor
;
}
__attribute__
((
packed
));
struct
gea
{
unsigned
char
name_len
;
char
name
[
1
];
...
...
fs/cifs/cifssmb.c
浏览文件 @
252ec9e2
...
...
@@ -1142,7 +1142,9 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
int
bytes_returned
,
wct
;
int
smb_hdr_len
;
cFYI
(
1
,(
"write2 at %lld %d bytes"
,
offset
,
count
));
/* BB removeme BB */
/* BB removeme BB */
cFYI
(
1
,(
"write2 at %lld %d bytes"
,
(
long
long
)
offset
,
count
));
if
(
tcon
->
ses
->
capabilities
&
CAP_LARGE_FILES
)
wct
=
14
;
else
...
...
@@ -1553,7 +1555,7 @@ CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon,
if
(
pSMB
->
hdr
.
Flags2
&
SMBFLG2_UNICODE
)
{
name_len
=
cifs_strtoUCS
((
wchar_t
*
)
pSMB
->
FileName
,
fromName
,
PATH_MAX
cifs_strtoUCS
((
__le16
*
)
pSMB
->
FileName
,
fromName
,
PATH_MAX
/* find define for this maxpathcomponent */
,
nls_codepage
);
name_len
++
;
/* trailing null */
...
...
@@ -1577,7 +1579,7 @@ CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon,
data_offset
=
(
char
*
)
(
&
pSMB
->
hdr
.
Protocol
)
+
offset
;
if
(
pSMB
->
hdr
.
Flags2
&
SMBFLG2_UNICODE
)
{
name_len_target
=
cifs_strtoUCS
((
wchar_t
*
)
data_offset
,
toName
,
PATH_MAX
cifs_strtoUCS
((
__le16
*
)
data_offset
,
toName
,
PATH_MAX
/* find define for this maxpathcomponent */
,
nls_codepage
);
name_len_target
++
;
/* trailing null */
...
...
@@ -1803,7 +1805,7 @@ CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
if
(
pSMB
->
hdr
.
Flags2
&
SMBFLG2_UNICODE
)
{
name_len
=
cifs_strtoUCS
((
wchar_t
*
)
pSMB
->
FileName
,
searchName
,
PATH_MAX
cifs_strtoUCS
((
__le16
*
)
pSMB
->
FileName
,
searchName
,
PATH_MAX
/* find define for this maxpathcomponent */
,
nls_codepage
);
name_len
++
;
/* trailing null */
...
...
@@ -1860,7 +1862,7 @@ CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
min_t
(
const
int
,
buflen
,
count
)
/
2
);
/* BB FIXME investigate remapping reserved chars here */
cifs_strfromUCS_le
(
symlinkinfo
,
(
wchar_t
*
)
((
char
*
)
&
pSMBr
->
hdr
.
Protocol
+
(
__le16
*
)
((
char
*
)
&
pSMBr
->
hdr
.
Protocol
+
data_offset
),
name_len
,
nls_codepage
);
}
else
{
...
...
@@ -1951,7 +1953,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
reparse_buf
->
TargetNameOffset
),
min
(
buflen
/
2
,
reparse_buf
->
TargetNameLen
/
2
));
cifs_strfromUCS_le
(
symlinkinfo
,
(
wchar_t
*
)
(
reparse_buf
->
LinkNamesBuf
+
(
__le16
*
)
(
reparse_buf
->
LinkNamesBuf
+
reparse_buf
->
TargetNameOffset
),
name_len
,
nls_codepage
);
}
else
{
/* ASCII names */
...
...
@@ -1983,9 +1985,9 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
static
void
cifs_convert_ace
(
posix_acl_xattr_entry
*
ace
,
struct
cifs_posix_ace
*
cifs_ace
)
{
/* u8 cifs fields do not need le conversion */
ace
->
e_perm
=
(
__u16
)
cifs_ace
->
cifs_e_perm
;
ace
->
e_tag
=
(
__u16
)
cifs_ace
->
cifs_e_tag
;
ace
->
e_id
=
(
__u32
)
le64_to_cpu
(
cifs_ace
->
cifs_uid
);
ace
->
e_perm
=
cpu_to_le16
(
cifs_ace
->
cifs_e_perm
);
ace
->
e_tag
=
cpu_to_le16
(
cifs_ace
->
cifs_e_tag
)
;
ace
->
e_id
=
cpu_to_le32
(
le64_to_cpu
(
cifs_ace
->
cifs_uid
)
);
/* cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id)); */
return
;
...
...
@@ -2037,7 +2039,7 @@ static int cifs_copy_posix_acl(char * trgt,char * src, const int buflen,
}
else
if
(
size
>
buflen
)
{
return
-
ERANGE
;
}
else
/* buffer big enough */
{
local_acl
->
a_version
=
POSIX_ACL_XATTR_VERSION
;
local_acl
->
a_version
=
cpu_to_le32
(
POSIX_ACL_XATTR_VERSION
)
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
cifs_convert_ace
(
&
local_acl
->
a_entries
[
i
],
pACE
);
pACE
++
;
...
...
@@ -2051,14 +2053,14 @@ static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace * cifs_ace,
{
__u16
rc
=
0
;
/* 0 = ACL converted ok */
cifs_ace
->
cifs_e_perm
=
(
__u8
)
cpu_to_le16
(
local_ace
->
e_perm
);
cifs_ace
->
cifs_e_tag
=
(
__u8
)
cpu_to_le16
(
local_ace
->
e_tag
);
cifs_ace
->
cifs_e_perm
=
le16_to_cpu
(
local_ace
->
e_perm
);
cifs_ace
->
cifs_e_tag
=
le16_to_cpu
(
local_ace
->
e_tag
);
/* BB is there a better way to handle the large uid? */
if
(
local_ace
->
e_id
==
-
1
)
{
if
(
local_ace
->
e_id
==
cpu_to_le32
(
-
1
)
)
{
/* Probably no need to le convert -1 on any arch but can not hurt */
cifs_ace
->
cifs_uid
=
cpu_to_le64
(
-
1
);
}
else
cifs_ace
->
cifs_uid
=
(
__u64
)
cpu_to_le32
(
local_ace
->
e_id
);
cifs_ace
->
cifs_uid
=
cpu_to_le64
(
le32_to_cpu
(
local_ace
->
e_id
)
);
/*cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id));*/
return
rc
;
}
...
...
@@ -2078,16 +2080,17 @@ static __u16 ACL_to_cifs_posix(char * parm_data,const char * pACL,const int bufl
count
=
posix_acl_xattr_count
((
size_t
)
buflen
);
cFYI
(
1
,(
"setting acl with %d entries from buf of length %d and version of %d"
,
count
,
buflen
,
local_acl
->
a_version
));
if
(
local_acl
->
a_version
!=
2
)
{
cFYI
(
1
,(
"unknown POSIX ACL version %d"
,
local_acl
->
a_version
));
count
,
buflen
,
le32_to_cpu
(
local_acl
->
a_version
)));
if
(
le32_to_cpu
(
local_acl
->
a_version
)
!=
2
)
{
cFYI
(
1
,(
"unknown POSIX ACL version %d"
,
le32_to_cpu
(
local_acl
->
a_version
)));
return
0
;
}
cifs_acl
->
version
=
cpu_to_le16
(
1
);
if
(
acl_type
==
ACL_TYPE_ACCESS
)
cifs_acl
->
access_entry_count
=
c
ount
;
cifs_acl
->
access_entry_count
=
c
pu_to_le16
(
count
)
;
else
if
(
acl_type
==
ACL_TYPE_DEFAULT
)
cifs_acl
->
default_entry_count
=
c
ount
;
cifs_acl
->
default_entry_count
=
c
pu_to_le16
(
count
)
;
else
{
cFYI
(
1
,(
"unknown ACL type %d"
,
acl_type
));
return
0
;
...
...
@@ -3203,7 +3206,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
temp
=
((
char
*
)
referrals
)
+
le16_to_cpu
(
referrals
->
DfsPathOffset
);
if
(
pSMBr
->
hdr
.
Flags2
&
SMBFLG2_UNICODE
)
{
cifs_strfromUCS_le
(
*
targetUNCs
,
(
wchar_t
*
)
temp
,
name_len
,
nls_codepage
);
(
__le16
*
)
temp
,
name_len
,
nls_codepage
);
}
else
{
strncpy
(
*
targetUNCs
,
temp
,
name_len
);
}
...
...
fs/cifs/connect.c
浏览文件 @
252ec9e2
...
...
@@ -1986,32 +1986,32 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
bytes_returned
=
0
;
/* skill null user */
else
bytes_returned
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
user
,
100
,
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
user
,
100
,
nls_codepage
);
/* convert number of 16 bit words to bytes */
bcc_ptr
+=
2
*
bytes_returned
;
bcc_ptr
+=
2
;
/* trailing null */
if
(
domain
==
NULL
)
bytes_returned
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
"CIFS_LINUX_DOM"
,
32
,
nls_codepage
);
else
bytes_returned
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
domain
,
64
,
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
domain
,
64
,
nls_codepage
);
bcc_ptr
+=
2
*
bytes_returned
;
bcc_ptr
+=
2
;
bytes_returned
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
"Linux version "
,
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
"Linux version "
,
32
,
nls_codepage
);
bcc_ptr
+=
2
*
bytes_returned
;
bytes_returned
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
system_utsname
.
release
,
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
system_utsname
.
release
,
32
,
nls_codepage
);
bcc_ptr
+=
2
*
bytes_returned
;
bcc_ptr
+=
2
;
bytes_returned
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
CIFS_NETWORK_OPSYS
,
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
CIFS_NETWORK_OPSYS
,
64
,
nls_codepage
);
bcc_ptr
+=
2
*
bytes_returned
;
bcc_ptr
+=
2
;
...
...
@@ -2081,7 +2081,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
if
(
ses
->
serverOS
==
NULL
)
goto
sesssetup_nomem
;
cifs_strfromUCS_le
(
ses
->
serverOS
,
(
wchar_t
*
)
bcc_ptr
,
len
,
nls_codepage
);
(
__le16
*
)
bcc_ptr
,
len
,
nls_codepage
);
bcc_ptr
+=
2
*
(
len
+
1
);
remaining_words
-=
len
+
1
;
ses
->
serverOS
[
2
*
len
]
=
0
;
...
...
@@ -2093,7 +2093,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
if
(
ses
->
serverNOS
==
NULL
)
goto
sesssetup_nomem
;
cifs_strfromUCS_le
(
ses
->
serverNOS
,
(
wchar_t
*
)
bcc_ptr
,
len
,
nls_codepage
);
(
__le16
*
)
bcc_ptr
,
len
,
nls_codepage
);
bcc_ptr
+=
2
*
(
len
+
1
);
ses
->
serverNOS
[
2
*
len
]
=
0
;
ses
->
serverNOS
[
1
+
(
2
*
len
)]
=
0
;
...
...
@@ -2111,7 +2111,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
if
(
ses
->
serverDomain
==
NULL
)
goto
sesssetup_nomem
;
cifs_strfromUCS_le
(
ses
->
serverDomain
,
(
wchar_t
*
)
bcc_ptr
,
len
,
nls_codepage
);
(
__le16
*
)
bcc_ptr
,
len
,
nls_codepage
);
bcc_ptr
+=
2
*
(
len
+
1
);
ses
->
serverDomain
[
2
*
len
]
=
0
;
ses
->
serverDomain
[
1
+
(
2
*
len
)]
=
0
;
...
...
@@ -2255,30 +2255,30 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
bcc_ptr
++
;
}
bytes_returned
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
user
,
100
,
nls_codepage
);
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
user
,
100
,
nls_codepage
);
bcc_ptr
+=
2
*
bytes_returned
;
/* convert num of 16 bit words to bytes */
bcc_ptr
+=
2
;
/* trailing null */
if
(
domain
==
NULL
)
bytes_returned
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
"CIFS_LINUX_DOM"
,
32
,
nls_codepage
);
else
bytes_returned
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
domain
,
64
,
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
domain
,
64
,
nls_codepage
);
bcc_ptr
+=
2
*
bytes_returned
;
bcc_ptr
+=
2
;
bytes_returned
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
"Linux version "
,
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
"Linux version "
,
32
,
nls_codepage
);
bcc_ptr
+=
2
*
bytes_returned
;
bytes_returned
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
system_utsname
.
release
,
32
,
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
system_utsname
.
release
,
32
,
nls_codepage
);
bcc_ptr
+=
2
*
bytes_returned
;
bcc_ptr
+=
2
;
bytes_returned
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
CIFS_NETWORK_OPSYS
,
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
CIFS_NETWORK_OPSYS
,
64
,
nls_codepage
);
bcc_ptr
+=
2
*
bytes_returned
;
bcc_ptr
+=
2
;
...
...
@@ -2357,7 +2357,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
ses
->
serverOS
=
kzalloc
(
2
*
(
len
+
1
),
GFP_KERNEL
);
cifs_strfromUCS_le
(
ses
->
serverOS
,
(
wchar_t
*
)
(
__le16
*
)
bcc_ptr
,
len
,
nls_codepage
);
bcc_ptr
+=
2
*
(
len
+
1
);
...
...
@@ -2372,7 +2372,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
kzalloc
(
2
*
(
len
+
1
),
GFP_KERNEL
);
cifs_strfromUCS_le
(
ses
->
serverNOS
,
(
wchar_t
*
)
bcc_ptr
,
(
__le16
*
)
bcc_ptr
,
len
,
nls_codepage
);
bcc_ptr
+=
2
*
(
len
+
1
);
...
...
@@ -2384,9 +2384,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
/* last string is not always null terminated (for e.g. for Windows XP & 2000) */
ses
->
serverDomain
=
kzalloc
(
2
*
(
len
+
1
),
GFP_KERNEL
);
cifs_strfromUCS_le
(
ses
->
serverDomain
,
(
wchar_t
*
)
bcc_ptr
,
len
,
nls_codepage
);
(
__le16
*
)
bcc_ptr
,
len
,
nls_codepage
);
bcc_ptr
+=
2
*
(
len
+
1
);
ses
->
serverDomain
[
2
*
len
]
=
0
;
ses
->
serverDomain
[
1
+
(
2
*
len
)]
=
0
;
...
...
@@ -2560,16 +2559,16 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
}
bytes_returned
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
"Linux version "
,
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
"Linux version "
,
32
,
nls_codepage
);
bcc_ptr
+=
2
*
bytes_returned
;
bytes_returned
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
system_utsname
.
release
,
32
,
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
system_utsname
.
release
,
32
,
nls_codepage
);
bcc_ptr
+=
2
*
bytes_returned
;
bcc_ptr
+=
2
;
/* null terminate Linux version */
bytes_returned
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
CIFS_NETWORK_OPSYS
,
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
CIFS_NETWORK_OPSYS
,
64
,
nls_codepage
);
bcc_ptr
+=
2
*
bytes_returned
;
*
(
bcc_ptr
+
1
)
=
0
;
...
...
@@ -2673,7 +2672,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
ses
->
serverOS
=
kzalloc
(
2
*
(
len
+
1
),
GFP_KERNEL
);
cifs_strfromUCS_le
(
ses
->
serverOS
,
(
wchar_t
*
)
(
__le16
*
)
bcc_ptr
,
len
,
nls_codepage
);
bcc_ptr
+=
2
*
(
len
+
1
);
...
...
@@ -2690,7 +2689,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
GFP_KERNEL
);
cifs_strfromUCS_le
(
ses
->
serverNOS
,
(
wchar_t
*
)
(
__le16
*
)
bcc_ptr
,
len
,
nls_codepage
);
...
...
@@ -2708,23 +2707,15 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
1
),
GFP_KERNEL
);
cifs_strfromUCS_le
(
ses
->
serverDomain
,
(
wchar_t
*
)
bcc_ptr
,
len
,
nls_codepage
);
(
ses
->
serverDomain
,
(
__le16
*
)
bcc_ptr
,
len
,
nls_codepage
);
bcc_ptr
+=
2
*
(
len
+
1
);
ses
->
serverDomain
[
2
*
len
]
ses
->
serverDomain
[
2
*
len
]
=
0
;
ses
->
serverDomain
[
1
+
(
2
*
len
)]
ses
->
serverDomain
[
1
+
(
2
*
len
)]
=
0
;
}
/* else no more room so create dummy domain string */
else
...
...
@@ -2903,7 +2894,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
SecurityBlob
->
DomainName
.
MaximumLength
=
0
;
}
else
{
__u16
len
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
domain
,
64
,
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
domain
,
64
,
nls_codepage
);
len
*=
2
;
SecurityBlob
->
DomainName
.
MaximumLength
=
...
...
@@ -2921,7 +2912,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
SecurityBlob
->
UserName
.
MaximumLength
=
0
;
}
else
{
__u16
len
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
user
,
64
,
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
user
,
64
,
nls_codepage
);
len
*=
2
;
SecurityBlob
->
UserName
.
MaximumLength
=
...
...
@@ -2934,7 +2925,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
cpu_to_le16
(
len
);
}
/* SecurityBlob->WorkstationName.Length = cifs_strtoUCS((
wchar_t
*) bcc_ptr, "AMACHINE",64, nls_codepage);
/* SecurityBlob->WorkstationName.Length = cifs_strtoUCS((
__le16
*) bcc_ptr, "AMACHINE",64, nls_codepage);
SecurityBlob->WorkstationName.Length *= 2;
SecurityBlob->WorkstationName.MaximumLength = cpu_to_le16(SecurityBlob->WorkstationName.Length);
SecurityBlob->WorkstationName.Buffer = cpu_to_le32(SecurityBlobLength);
...
...
@@ -2947,16 +2938,16 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
bcc_ptr
++
;
}
bytes_returned
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
"Linux version "
,
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
"Linux version "
,
32
,
nls_codepage
);
bcc_ptr
+=
2
*
bytes_returned
;
bytes_returned
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
system_utsname
.
release
,
32
,
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
system_utsname
.
release
,
32
,
nls_codepage
);
bcc_ptr
+=
2
*
bytes_returned
;
bcc_ptr
+=
2
;
/* null term version string */
bytes_returned
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
CIFS_NETWORK_OPSYS
,
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
CIFS_NETWORK_OPSYS
,
64
,
nls_codepage
);
bcc_ptr
+=
2
*
bytes_returned
;
*
(
bcc_ptr
+
1
)
=
0
;
...
...
@@ -3069,7 +3060,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
ses
->
serverOS
=
kzalloc
(
2
*
(
len
+
1
),
GFP_KERNEL
);
cifs_strfromUCS_le
(
ses
->
serverOS
,
(
wchar_t
*
)
(
__le16
*
)
bcc_ptr
,
len
,
nls_codepage
);
bcc_ptr
+=
2
*
(
len
+
1
);
...
...
@@ -3086,7 +3077,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
GFP_KERNEL
);
cifs_strfromUCS_le
(
ses
->
serverNOS
,
(
wchar_t
*
)
(
__le16
*
)
bcc_ptr
,
len
,
nls_codepage
);
...
...
@@ -3105,7 +3096,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
cifs_strfromUCS_le
(
ses
->
serverDomain
,
(
wchar_t
*
)
(
__le16
*
)
bcc_ptr
,
len
,
nls_codepage
);
bcc_ptr
+=
...
...
@@ -3227,7 +3218,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
if
(
ses
->
capabilities
&
CAP_UNICODE
)
{
smb_buffer
->
Flags2
|=
SMBFLG2_UNICODE
;
length
=
cifs_strtoUCS
((
wchar_t
*
)
bcc_ptr
,
tree
,
100
,
nls_codepage
);
cifs_strtoUCS
((
__le16
*
)
bcc_ptr
,
tree
,
100
,
nls_codepage
);
bcc_ptr
+=
2
*
length
;
/* convert num of 16 bit words to bytes */
bcc_ptr
+=
2
;
/* skip trailing null */
}
else
{
/* ASCII */
...
...
@@ -3263,7 +3254,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
tcon
->
nativeFileSystem
=
kzalloc
(
length
+
2
,
GFP_KERNEL
);
cifs_strfromUCS_le
(
tcon
->
nativeFileSystem
,
(
wchar_t
*
)
bcc_ptr
,
(
__le16
*
)
bcc_ptr
,
length
,
nls_codepage
);
bcc_ptr
+=
2
*
length
;
bcc_ptr
[
0
]
=
0
;
/* null terminate the string */
...
...
fs/cifs/dir.c
浏览文件 @
252ec9e2
...
...
@@ -292,7 +292,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
return
rc
;
}
int
cifs_mknod
(
struct
inode
*
inode
,
struct
dentry
*
direntry
,
int
mode
,
dev_t
device_number
)
int
cifs_mknod
(
struct
inode
*
inode
,
struct
dentry
*
direntry
,
int
mode
,
dev_t
device_number
)
{
int
rc
=
-
EPERM
;
int
xid
;
...
...
@@ -368,7 +369,34 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev
if
(
!
rc
)
{
/* BB Do not bother to decode buf since no
local inode yet to put timestamps in */
local inode yet to put timestamps in,
but we can reuse it safely */
int
bytes_written
;
struct
win_dev
*
pdev
;
pdev
=
(
struct
win_dev
*
)
buf
;
if
(
S_ISCHR
(
mode
))
{
memcpy
(
pdev
->
type
,
"IntxCHR"
,
8
);
pdev
->
major
=
cpu_to_le64
(
MAJOR
(
device_number
));
pdev
->
minor
=
cpu_to_le64
(
MINOR
(
device_number
));
rc
=
CIFSSMBWrite
(
xid
,
pTcon
,
fileHandle
,
sizeof
(
struct
win_dev
),
0
,
&
bytes_written
,
(
char
*
)
pdev
,
NULL
,
0
);
}
else
if
(
S_ISBLK
(
mode
))
{
memcpy
(
pdev
->
type
,
"IntxBLK"
,
8
);
pdev
->
major
=
cpu_to_le64
(
MAJOR
(
device_number
));
pdev
->
minor
=
cpu_to_le64
(
MINOR
(
device_number
));
rc
=
CIFSSMBWrite
(
xid
,
pTcon
,
fileHandle
,
sizeof
(
struct
win_dev
),
0
,
&
bytes_written
,
(
char
*
)
pdev
,
NULL
,
0
);
}
/* else if(S_ISFIFO */
CIFSSMBClose
(
xid
,
pTcon
,
fileHandle
);
d_drop
(
direntry
);
}
...
...
fs/cifs/file.c
浏览文件 @
252ec9e2
...
...
@@ -489,8 +489,10 @@ int cifs_close(struct inode *inode, struct file *file)
the struct would be in each open file,
but this should give enough time to
clear the socket */
write_unlock
(
&
file
->
f_owner
.
lock
);
cERROR
(
1
,(
"close with pending writes"
));
msleep
(
timeout
);
write_lock
(
&
file
->
f_owner
.
lock
);
timeout
*=
4
;
}
write_unlock
(
&
file
->
f_owner
.
lock
);
...
...
fs/cifs/inode.c
浏览文件 @
252ec9e2
...
...
@@ -41,7 +41,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
char
*
tmp_path
;
pTcon
=
cifs_sb
->
tcon
;
cFYI
(
1
,
(
"
Getting info on %s "
,
search_path
));
cFYI
(
1
,
(
"Getting info on %s "
,
search_path
));
/* could have done a find first instead but this returns more info */
rc
=
CIFSSMBUnixQPathInfo
(
xid
,
pTcon
,
search_path
,
&
findData
,
cifs_sb
->
local_nls
,
cifs_sb
->
mnt_cifs_flags
&
...
...
@@ -97,9 +97,9 @@ int cifs_get_inode_info_unix(struct inode **pinode,
inode
=
*
pinode
;
cifsInfo
=
CIFS_I
(
inode
);
cFYI
(
1
,
(
"
Old time %ld "
,
cifsInfo
->
time
));
cFYI
(
1
,
(
"Old time %ld "
,
cifsInfo
->
time
));
cifsInfo
->
time
=
jiffies
;
cFYI
(
1
,
(
"
New time %ld "
,
cifsInfo
->
time
));
cFYI
(
1
,
(
"New time %ld "
,
cifsInfo
->
time
));
/* this is ok to set on every inode revalidate */
atomic_set
(
&
cifsInfo
->
inUse
,
1
);
...
...
@@ -111,6 +111,9 @@ int cifs_get_inode_info_unix(struct inode **pinode,
inode
->
i_ctime
=
cifs_NTtimeToUnix
(
le64_to_cpu
(
findData
.
LastStatusChange
));
inode
->
i_mode
=
le64_to_cpu
(
findData
.
Permissions
);
/* since we set the inode type below we need to mask off
to avoid strange results if bits set above */
inode
->
i_mode
&=
~
S_IFMT
;
if
(
type
==
UNIX_FILE
)
{
inode
->
i_mode
|=
S_IFREG
;
}
else
if
(
type
==
UNIX_SYMLINK
)
{
...
...
@@ -129,6 +132,10 @@ int cifs_get_inode_info_unix(struct inode **pinode,
inode
->
i_mode
|=
S_IFIFO
;
}
else
if
(
type
==
UNIX_SOCKET
)
{
inode
->
i_mode
|=
S_IFSOCK
;
}
else
{
/* safest to call it a file if we do not know */
inode
->
i_mode
|=
S_IFREG
;
cFYI
(
1
,(
"unknown type %d"
,
type
));
}
inode
->
i_uid
=
le64_to_cpu
(
findData
.
Uid
);
inode
->
i_gid
=
le64_to_cpu
(
findData
.
Gid
);
...
...
@@ -155,34 +162,39 @@ int cifs_get_inode_info_unix(struct inode **pinode,
}
if
(
num_of_bytes
<
end_of_file
)
cFYI
(
1
,
(
"allocation size less than end of file
"
));
cFYI
(
1
,
(
"allocation size less than end of file"
));
cFYI
(
1
,
(
"Size %ld and blocks %ld"
,
(
unsigned
long
)
inode
->
i_size
,
inode
->
i_blocks
));
if
(
S_ISREG
(
inode
->
i_mode
))
{
cFYI
(
1
,
(
"
File inode
"
));
cFYI
(
1
,
(
"
File inode
"
));
inode
->
i_op
=
&
cifs_file_inode_ops
;
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_DIRECT_IO
)
inode
->
i_fop
=
&
cifs_file_direct_ops
;
else
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_DIRECT_IO
)
{
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NO_BRL
)
inode
->
i_fop
=
&
cifs_file_direct_nobrl_ops
;
else
inode
->
i_fop
=
&
cifs_file_direct_ops
;
}
else
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NO_BRL
)
inode
->
i_fop
=
&
cifs_file_nobrl_ops
;
else
/* not direct, send byte range locks */
inode
->
i_fop
=
&
cifs_file_ops
;
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NO_BRL
)
inode
->
i_fop
->
lock
=
NULL
;
inode
->
i_data
.
a_ops
=
&
cifs_addr_ops
;
/* check if server can support readpages */
if
(
pTcon
->
ses
->
server
->
maxBuf
<
4096
+
MAX_CIFS_HDR_SIZE
)
inode
->
i_data
.
a_ops
->
readpages
=
NULL
;
}
else
if
(
S_ISDIR
(
inode
->
i_mode
))
{
cFYI
(
1
,
(
"
Directory inode"
));
cFYI
(
1
,
(
"Directory inode"
));
inode
->
i_op
=
&
cifs_dir_inode_ops
;
inode
->
i_fop
=
&
cifs_dir_ops
;
}
else
if
(
S_ISLNK
(
inode
->
i_mode
))
{
cFYI
(
1
,
(
"
Symbolic Link inode
"
));
cFYI
(
1
,
(
"
Symbolic Link inode
"
));
inode
->
i_op
=
&
cifs_symlink_inode_ops
;
/* tmp_inode->i_fop = */
/* do not need to set to anything */
}
else
{
cFYI
(
1
,
(
"
Init special inode
"
));
cFYI
(
1
,
(
"
Init special inode
"
));
init_special_inode
(
inode
,
inode
->
i_mode
,
inode
->
i_rdev
);
}
...
...
@@ -190,6 +202,111 @@ int cifs_get_inode_info_unix(struct inode **pinode,
return
rc
;
}
static
int
decode_sfu_inode
(
struct
inode
*
inode
,
__u64
size
,
const
unsigned
char
*
path
,
struct
cifs_sb_info
*
cifs_sb
,
int
xid
)
{
int
rc
;
int
oplock
=
FALSE
;
__u16
netfid
;
struct
cifsTconInfo
*
pTcon
=
cifs_sb
->
tcon
;
char
buf
[
24
];
unsigned
int
bytes_read
;
char
*
pbuf
;
pbuf
=
buf
;
if
(
size
==
0
)
{
inode
->
i_mode
|=
S_IFIFO
;
return
0
;
}
else
if
(
size
<
8
)
{
return
-
EINVAL
;
/* EOPNOTSUPP? */
}
rc
=
CIFSSMBOpen
(
xid
,
pTcon
,
path
,
FILE_OPEN
,
GENERIC_READ
,
CREATE_NOT_DIR
,
&
netfid
,
&
oplock
,
NULL
,
cifs_sb
->
local_nls
,
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_MAP_SPECIAL_CHR
);
if
(
rc
==
0
)
{
/* Read header */
rc
=
CIFSSMBRead
(
xid
,
pTcon
,
netfid
,
24
/* length */
,
0
/* offset */
,
&
bytes_read
,
&
pbuf
);
if
((
rc
==
0
)
&&
(
bytes_read
>=
8
))
{
if
(
memcmp
(
"IntxBLK"
,
pbuf
,
8
)
==
0
)
{
cFYI
(
1
,(
"Block device"
));
inode
->
i_mode
|=
S_IFBLK
;
if
(
bytes_read
==
24
)
{
/* we have enough to decode dev num */
__u64
mjr
;
/* major */
__u64
mnr
;
/* minor */
mjr
=
le64_to_cpu
(
*
(
__le64
*
)(
pbuf
+
8
));
mnr
=
le64_to_cpu
(
*
(
__le64
*
)(
pbuf
+
16
));
inode
->
i_rdev
=
MKDEV
(
mjr
,
mnr
);
}
}
else
if
(
memcmp
(
"IntxCHR"
,
pbuf
,
8
)
==
0
)
{
cFYI
(
1
,(
"Char device"
));
inode
->
i_mode
|=
S_IFCHR
;
if
(
bytes_read
==
24
)
{
/* we have enough to decode dev num */
__u64
mjr
;
/* major */
__u64
mnr
;
/* minor */
mjr
=
le64_to_cpu
(
*
(
__le64
*
)(
pbuf
+
8
));
mnr
=
le64_to_cpu
(
*
(
__le64
*
)(
pbuf
+
16
));
inode
->
i_rdev
=
MKDEV
(
mjr
,
mnr
);
}
}
else
if
(
memcmp
(
"IntxLNK"
,
pbuf
,
7
)
==
0
)
{
cFYI
(
1
,(
"Symlink"
));
inode
->
i_mode
|=
S_IFLNK
;
}
else
{
inode
->
i_mode
|=
S_IFREG
;
/* file? */
rc
=
-
EOPNOTSUPP
;
}
}
else
{
inode
->
i_mode
|=
S_IFREG
;
/* then it is a file */
rc
=
-
EOPNOTSUPP
;
/* or some unknown SFU type */
}
CIFSSMBClose
(
xid
,
pTcon
,
netfid
);
}
return
rc
;
}
#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID)
/* SETFILEBITS valid bits */
static
int
get_sfu_uid_mode
(
struct
inode
*
inode
,
const
unsigned
char
*
path
,
struct
cifs_sb_info
*
cifs_sb
,
int
xid
)
{
#ifdef CONFIG_CIFS_XATTR
ssize_t
rc
;
char
ea_value
[
4
];
__u32
mode
;
rc
=
CIFSSMBQueryEA
(
xid
,
cifs_sb
->
tcon
,
path
,
"SETFILEBITS"
,
ea_value
,
4
/* size of buf */
,
cifs_sb
->
local_nls
,
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_MAP_SPECIAL_CHR
);
if
(
rc
<
0
)
return
(
int
)
rc
;
else
if
(
rc
>
3
)
{
mode
=
le32_to_cpu
(
*
((
__le32
*
)
ea_value
));
inode
->
i_mode
&=
~
SFBITS_MASK
;
cFYI
(
1
,(
"special bits 0%o org mode 0%o"
,
mode
,
inode
->
i_mode
));
inode
->
i_mode
=
(
mode
&
SFBITS_MASK
)
|
inode
->
i_mode
;
cFYI
(
1
,(
"special mode bits 0%o"
,
mode
));
return
0
;
}
else
{
return
0
;
}
#else
return
-
EOPNOTSUPP
;
#endif
}
int
cifs_get_inode_info
(
struct
inode
**
pinode
,
const
unsigned
char
*
search_path
,
FILE_ALL_INFO
*
pfindData
,
struct
super_block
*
sb
,
int
xid
)
...
...
@@ -202,7 +319,7 @@ int cifs_get_inode_info(struct inode **pinode,
char
*
buf
=
NULL
;
pTcon
=
cifs_sb
->
tcon
;
cFYI
(
1
,(
"Getting info on %s
"
,
search_path
));
cFYI
(
1
,(
"Getting info on %s"
,
search_path
));
if
((
pfindData
==
NULL
)
&&
(
*
pinode
!=
NULL
))
{
if
(
CIFS_I
(
*
pinode
)
->
clientCanCacheRead
)
{
...
...
@@ -303,9 +420,9 @@ int cifs_get_inode_info(struct inode **pinode,
inode
=
*
pinode
;
cifsInfo
=
CIFS_I
(
inode
);
cifsInfo
->
cifsAttrs
=
attr
;
cFYI
(
1
,
(
"
Old time %ld "
,
cifsInfo
->
time
));
cFYI
(
1
,
(
"Old time %ld "
,
cifsInfo
->
time
));
cifsInfo
->
time
=
jiffies
;
cFYI
(
1
,
(
"
New time %ld "
,
cifsInfo
->
time
));
cFYI
(
1
,
(
"New time %ld "
,
cifsInfo
->
time
));
/* blksize needs to be multiple of two. So safer to default to
blksize and blkbits set in superblock so 2**blkbits and blksize
...
...
@@ -319,13 +436,15 @@ int cifs_get_inode_info(struct inode **pinode,
cifs_NTtimeToUnix
(
le64_to_cpu
(
pfindData
->
LastWriteTime
));
inode
->
i_ctime
=
cifs_NTtimeToUnix
(
le64_to_cpu
(
pfindData
->
ChangeTime
));
cFYI
(
0
,
(
"
Attributes came in as 0x%x "
,
attr
));
cFYI
(
0
,
(
"Attributes came in as 0x%x "
,
attr
));
/* set default mode. will override for dirs below */
if
(
atomic_read
(
&
cifsInfo
->
inUse
)
==
0
)
/* new inode, can safely set these fields */
inode
->
i_mode
=
cifs_sb
->
mnt_file_mode
;
else
/* since we set the inode type below we need to mask off
to avoid strange results if type changes and both get orred in */
inode
->
i_mode
&=
~
S_IFMT
;
/* if (attr & ATTR_REPARSE) */
/* We no longer handle these as symlinks because we could not
follow them due to the absolute path with drive letter */
...
...
@@ -340,10 +459,16 @@ int cifs_get_inode_info(struct inode **pinode,
(
pfindData
->
EndOfFile
==
0
))
{
inode
->
i_mode
=
cifs_sb
->
mnt_file_mode
;
inode
->
i_mode
|=
S_IFIFO
;
/* BB Finish for SFU style symlinks and devies */
/* } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
(cifsInfo->cifsAttrs & ATTR_SYSTEM) && ) */
/* BB Finish for SFU style symlinks and devices */
}
else
if
((
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_UNX_EMUL
)
&&
(
cifsInfo
->
cifsAttrs
&
ATTR_SYSTEM
))
{
if
(
decode_sfu_inode
(
inode
,
le64_to_cpu
(
pfindData
->
EndOfFile
),
search_path
,
cifs_sb
,
xid
))
{
cFYI
(
1
,(
"Unrecognized sfu inode type"
));
}
cFYI
(
1
,(
"sfu mode 0%o"
,
inode
->
i_mode
));
}
else
{
inode
->
i_mode
|=
S_IFREG
;
/* treat the dos attribute of read-only as read-only
...
...
@@ -368,7 +493,10 @@ int cifs_get_inode_info(struct inode **pinode,
/* BB fill in uid and gid here? with help from winbind?
or retrieve from NTFS stream extended attribute */
if
(
atomic_read
(
&
cifsInfo
->
inUse
)
==
0
)
{
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_UNX_EMUL
)
{
/* fill in uid, gid, mode from server ACL */
get_sfu_uid_mode
(
inode
,
search_path
,
cifs_sb
,
xid
);
}
else
if
(
atomic_read
(
&
cifsInfo
->
inUse
)
==
0
)
{
inode
->
i_uid
=
cifs_sb
->
mnt_uid
;
inode
->
i_gid
=
cifs_sb
->
mnt_gid
;
/* set so we do not keep refreshing these fields with
...
...
@@ -377,24 +505,29 @@ int cifs_get_inode_info(struct inode **pinode,
}
if
(
S_ISREG
(
inode
->
i_mode
))
{
cFYI
(
1
,
(
"
File inode
"
));
cFYI
(
1
,
(
"
File inode
"
));
inode
->
i_op
=
&
cifs_file_inode_ops
;
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_DIRECT_IO
)
inode
->
i_fop
=
&
cifs_file_direct_ops
;
else
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_DIRECT_IO
)
{
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NO_BRL
)
inode
->
i_fop
=
&
cifs_file_direct_nobrl_ops
;
else
inode
->
i_fop
=
&
cifs_file_direct_ops
;
}
else
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NO_BRL
)
inode
->
i_fop
=
&
cifs_file_nobrl_ops
;
else
/* not direct, send byte range locks */
inode
->
i_fop
=
&
cifs_file_ops
;
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NO_BRL
)
inode
->
i_fop
->
lock
=
NULL
;
inode
->
i_data
.
a_ops
=
&
cifs_addr_ops
;
if
(
pTcon
->
ses
->
server
->
maxBuf
<
4096
+
MAX_CIFS_HDR_SIZE
)
inode
->
i_data
.
a_ops
->
readpages
=
NULL
;
}
else
if
(
S_ISDIR
(
inode
->
i_mode
))
{
cFYI
(
1
,
(
"
Directory inode
"
));
cFYI
(
1
,
(
"
Directory inode
"
));
inode
->
i_op
=
&
cifs_dir_inode_ops
;
inode
->
i_fop
=
&
cifs_dir_ops
;
}
else
if
(
S_ISLNK
(
inode
->
i_mode
))
{
cFYI
(
1
,
(
"
Symbolic Link inode
"
));
cFYI
(
1
,
(
"
Symbolic Link inode
"
));
inode
->
i_op
=
&
cifs_symlink_inode_ops
;
}
else
{
init_special_inode
(
inode
,
inode
->
i_mode
,
...
...
@@ -431,7 +564,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
struct
cifsInodeInfo
*
cifsInode
;
FILE_BASIC_INFO
*
pinfo_buf
;
cFYI
(
1
,
(
"
cifs_unlink, inode = 0x%p with "
,
inode
));
cFYI
(
1
,
(
"cifs_unlink, inode = 0x%p with "
,
inode
));
xid
=
GetXid
();
...
...
@@ -651,7 +784,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
char
*
full_path
=
NULL
;
struct
cifsInodeInfo
*
cifsInode
;
cFYI
(
1
,
(
"
cifs_rmdir, inode = 0x%p with "
,
inode
));
cFYI
(
1
,
(
"cifs_rmdir, inode = 0x%p with "
,
inode
));
xid
=
GetXid
();
...
...
@@ -970,7 +1103,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
xid
=
GetXid
();
cFYI
(
1
,
(
"
In cifs_setattr, name = %s attrs->iavalid 0x%x "
,
cFYI
(
1
,
(
"In cifs_setattr, name = %s attrs->iavalid 0x%x "
,
direntry
->
d_name
.
name
,
attrs
->
ia_valid
));
cifs_sb
=
CIFS_SB
(
direntry
->
d_inode
->
i_sb
);
pTcon
=
cifs_sb
->
tcon
;
...
...
@@ -1086,6 +1219,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_MAP_SPECIAL_CHR
);
else
if
(
attrs
->
ia_valid
&
ATTR_MODE
)
{
rc
=
0
;
if
((
mode
&
S_IWUGO
)
==
0
)
/* not writeable */
{
if
((
cifsInode
->
cifsAttrs
&
ATTR_READONLY
)
==
0
)
time_buf
.
Attributes
=
...
...
fs/cifs/misc.c
浏览文件 @
252ec9e2
...
...
@@ -678,7 +678,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
__u16
temp
;
if
(
!
mapChars
)
return
cifs_strtoUCS
(
(
wchar_t
*
)
target
,
source
,
PATH_MAX
,
cp
);
return
cifs_strtoUCS
(
target
,
source
,
PATH_MAX
,
cp
);
for
(
i
=
0
,
j
=
0
;
i
<
maxlen
;
j
++
)
{
src_char
=
source
[
i
];
...
...
fs/cifs/readdir.c
浏览文件 @
252ec9e2
...
...
@@ -142,6 +142,11 @@ static void fill_in_inode(struct inode *tmp_inode,
tmp_inode
->
i_gid
=
cifs_sb
->
mnt_gid
;
/* set default mode. will override for dirs below */
tmp_inode
->
i_mode
=
cifs_sb
->
mnt_file_mode
;
}
else
{
/* mask off the type bits since it gets set
below and we do not want to get two type
bits set */
tmp_inode
->
i_mode
&=
~
S_IFMT
;
}
if
(
attr
&
ATTR_DIRECTORY
)
{
...
...
@@ -152,12 +157,18 @@ static void fill_in_inode(struct inode *tmp_inode,
}
tmp_inode
->
i_mode
|=
S_IFDIR
;
}
else
if
((
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_UNX_EMUL
)
&&
(
attr
&
ATTR_SYSTEM
)
&&
(
end_of_file
==
0
))
{
*
pobject_type
=
DT_FIFO
;
tmp_inode
->
i_mode
|=
S_IFIFO
;
/* BB Finish for SFU style symlinks and devies */
/* } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
(attr & ATTR_SYSTEM) && ) { */
(
attr
&
ATTR_SYSTEM
))
{
if
(
end_of_file
==
0
)
{
*
pobject_type
=
DT_FIFO
;
tmp_inode
->
i_mode
|=
S_IFIFO
;
}
else
{
/* rather than get the type here, we mark the
inode as needing revalidate and get the real type
(blk vs chr vs. symlink) later ie in lookup */
*
pobject_type
=
DT_REG
;
tmp_inode
->
i_mode
|=
S_IFREG
;
cifsInfo
->
time
=
0
;
}
/* we no longer mark these because we could not follow them */
/* } else if (attr & ATTR_REPARSE) {
*pobject_type = DT_LNK;
...
...
@@ -193,8 +204,14 @@ static void fill_in_inode(struct inode *tmp_inode,
if
(
S_ISREG
(
tmp_inode
->
i_mode
))
{
cFYI
(
1
,
(
"File inode"
));
tmp_inode
->
i_op
=
&
cifs_file_inode_ops
;
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_DIRECT_IO
)
tmp_inode
->
i_fop
=
&
cifs_file_direct_ops
;
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_DIRECT_IO
)
{
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NO_BRL
)
tmp_inode
->
i_fop
=
&
cifs_file_direct_nobrl_ops
;
else
tmp_inode
->
i_fop
=
&
cifs_file_direct_ops
;
}
else
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NO_BRL
)
tmp_inode
->
i_fop
=
&
cifs_file_nobrl_ops
;
else
tmp_inode
->
i_fop
=
&
cifs_file_ops
;
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NO_BRL
)
...
...
@@ -258,6 +275,9 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
cifs_NTtimeToUnix
(
le64_to_cpu
(
pfindData
->
LastStatusChange
));
tmp_inode
->
i_mode
=
le64_to_cpu
(
pfindData
->
Permissions
);
/* since we set the inode type below we need to mask off type
to avoid strange results if bits above were corrupt */
tmp_inode
->
i_mode
&=
~
S_IFMT
;
if
(
type
==
UNIX_FILE
)
{
*
pobject_type
=
DT_REG
;
tmp_inode
->
i_mode
|=
S_IFREG
;
...
...
@@ -283,6 +303,11 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
}
else
if
(
type
==
UNIX_SOCKET
)
{
*
pobject_type
=
DT_SOCK
;
tmp_inode
->
i_mode
|=
S_IFSOCK
;
}
else
{
/* safest to just call it a file */
*
pobject_type
=
DT_REG
;
tmp_inode
->
i_mode
|=
S_IFREG
;
cFYI
(
1
,(
"unknown inode type %d"
,
type
));
}
tmp_inode
->
i_uid
=
le64_to_cpu
(
pfindData
->
Uid
);
...
...
@@ -699,7 +724,7 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
(
__le16
*
)
filename
,
len
/
2
,
nlt
);
else
pqst
->
len
=
cifs_strfromUCS_le
((
char
*
)
pqst
->
name
,
(
wchar_t
*
)
filename
,
len
/
2
,
nlt
);
(
__le16
*
)
filename
,
len
/
2
,
nlt
);
}
else
{
pqst
->
name
=
filename
;
pqst
->
len
=
len
;
...
...
fs/cifs/transport.c
浏览文件 @
252ec9e2
...
...
@@ -522,7 +522,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
sizeof
(
struct
smb_hdr
)
-
4
/* do not count RFC1001 header */
+
(
2
*
in_buf
->
WordCount
)
+
2
/* bcc */
)
BCC
(
in_buf
)
=
le16_to_cpu
(
BCC
(
in_buf
));
BCC
(
in_buf
)
=
le16_to_cpu
(
BCC
_LE
(
in_buf
));
}
else
{
rc
=
-
EIO
;
cFYI
(
1
,(
"Bad MID state?"
));
...
...
@@ -786,7 +786,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
sizeof
(
struct
smb_hdr
)
-
4
/* do not count RFC1001 header */
+
(
2
*
out_buf
->
WordCount
)
+
2
/* bcc */
)
BCC
(
out_buf
)
=
le16_to_cpu
(
BCC
(
out_buf
));
BCC
(
out_buf
)
=
le16_to_cpu
(
BCC
_LE
(
out_buf
));
}
else
{
rc
=
-
EIO
;
cERROR
(
1
,(
"Bad MID state? "
));
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录