Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
etercifs
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
etersoft
etercifs
Commits
f03c86f7
Commit
f03c86f7
authored
Aug 13, 2012
by
Pavel Shilovsky
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update 3.2 sources from stable (v3.2.27)
parent
b8fbf88f
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
127 additions
and
46 deletions
+127
-46
cifsfs.c
sources/3.2/cifsfs.c
+1
-1
cifsglob.h
sources/3.2/cifsglob.h
+1
-0
cifsproto.h
sources/3.2/cifsproto.h
+4
-2
cifssmb.c
sources/3.2/cifssmb.c
+40
-8
connect.c
sources/3.2/connect.c
+21
-6
file.c
sources/3.2/file.c
+42
-25
readdir.c
sources/3.2/readdir.c
+18
-4
No files found.
sources/3.2/cifsfs.c
View file @
f03c86f7
...
...
@@ -706,7 +706,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
* origin == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate
* the cached file length
*/
if
(
origin
!=
SEEK_SET
||
origin
!=
SEEK_CUR
)
{
if
(
origin
!=
SEEK_SET
&&
origin
!=
SEEK_CUR
)
{
int
rc
;
struct
inode
*
inode
=
file
->
f_path
.
dentry
->
d_inode
;
...
...
sources/3.2/cifsglob.h
View file @
f03c86f7
...
...
@@ -43,6 +43,7 @@
#define CIFS_MIN_RCV_POOL 4
#define MAX_REOPEN_ATT 5
/* these many maximum attempts to reopen a file */
/*
* default attribute cache timeout (jiffies)
*/
...
...
sources/3.2/cifsproto.h
View file @
f03c86f7
...
...
@@ -184,11 +184,13 @@ extern int CIFSTCon(unsigned int xid, struct cifs_ses *ses,
extern
int
CIFSFindFirst
(
const
int
xid
,
struct
cifs_tcon
*
tcon
,
const
char
*
searchName
,
const
struct
nls_table
*
nls_codepage
,
__u16
*
searchHandle
,
struct
cifs_search_info
*
psrch_inf
,
__u16
*
searchHandle
,
__u16
search_flags
,
struct
cifs_search_info
*
psrch_inf
,
int
map
,
const
char
dirsep
);
extern
int
CIFSFindNext
(
const
int
xid
,
struct
cifs_tcon
*
tcon
,
__u16
searchHandle
,
struct
cifs_search_info
*
psrch_inf
);
__u16
searchHandle
,
__u16
search_flags
,
struct
cifs_search_info
*
psrch_inf
);
extern
int
CIFSFindClose
(
const
int
,
struct
cifs_tcon
*
tcon
,
const
__u16
search_handle
);
...
...
sources/3.2/cifssmb.c
View file @
f03c86f7
...
...
@@ -89,6 +89,32 @@ static struct {
/* Forward declarations */
static
void
cifs_readv_complete
(
struct
work_struct
*
work
);
#ifdef CONFIG_HIGHMEM
/*
* On arches that have high memory, kmap address space is limited. By
* serializing the kmap operations on those arches, we ensure that we don't
* end up with a bunch of threads in writeback with partially mapped page
* arrays, stuck waiting for kmap to come back. That situation prevents
* progress and can deadlock.
*/
static
DEFINE_MUTEX
(
cifs_kmap_mutex
);
static
inline
void
cifs_kmap_lock
(
void
)
{
mutex_lock
(
&
cifs_kmap_mutex
);
}
static
inline
void
cifs_kmap_unlock
(
void
)
{
mutex_unlock
(
&
cifs_kmap_mutex
);
}
#else
/* !CONFIG_HIGHMEM */
#define cifs_kmap_lock() do { ; } while(0)
#define cifs_kmap_unlock() do { ; } while(0)
#endif
/* CONFIG_HIGHMEM */
/* Mark as invalid, all open files on tree connections since they
were closed when session to server was lost */
static
void
mark_open_files_invalid
(
struct
cifs_tcon
*
pTcon
)
...
...
@@ -1547,6 +1573,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
eof_index
=
eof
?
(
eof
-
1
)
>>
PAGE_CACHE_SHIFT
:
0
;
cFYI
(
1
,
"eof=%llu eof_index=%lu"
,
eof
,
eof_index
);
cifs_kmap_lock
();
list_for_each_entry_safe
(
page
,
tpage
,
&
rdata
->
pages
,
lru
)
{
if
(
remaining
>=
PAGE_CACHE_SIZE
)
{
/* enough data to fill the page */
...
...
@@ -1596,6 +1623,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
page_cache_release
(
page
);
}
}
cifs_kmap_unlock
();
/* issue the read if we have any iovecs left to fill */
if
(
rdata
->
nr_iov
>
1
)
{
...
...
@@ -2178,6 +2206,7 @@ cifs_async_writev(struct cifs_writedata *wdata)
iov
[
0
].
iov_base
=
smb
;
/* marshal up the pages into iov array */
cifs_kmap_lock
();
wdata
->
bytes
=
0
;
for
(
i
=
0
;
i
<
wdata
->
nr_pages
;
i
++
)
{
iov
[
i
+
1
].
iov_len
=
min
(
inode
->
i_size
-
...
...
@@ -2186,6 +2215,7 @@ cifs_async_writev(struct cifs_writedata *wdata)
iov
[
i
+
1
].
iov_base
=
kmap
(
wdata
->
pages
[
i
]);
wdata
->
bytes
+=
iov
[
i
+
1
].
iov_len
;
}
cifs_kmap_unlock
();
cFYI
(
1
,
"async write at %llu %u bytes"
,
wdata
->
offset
,
wdata
->
bytes
);
...
...
@@ -4334,7 +4364,7 @@ int
CIFSFindFirst
(
const
int
xid
,
struct
cifs_tcon
*
tcon
,
const
char
*
searchName
,
const
struct
nls_table
*
nls_codepage
,
__u16
*
pnetfid
,
__u16
*
pnetfid
,
__u16
search_flags
,
struct
cifs_search_info
*
psrch_inf
,
int
remap
,
const
char
dirsep
)
{
/* level 257 SMB_ */
...
...
@@ -4406,8 +4436,7 @@ findFirstRetry:
cpu_to_le16
(
ATTR_READONLY
|
ATTR_HIDDEN
|
ATTR_SYSTEM
|
ATTR_DIRECTORY
);
pSMB
->
SearchCount
=
cpu_to_le16
(
CIFSMaxBufSize
/
sizeof
(
FILE_UNIX_INFO
));
pSMB
->
SearchFlags
=
cpu_to_le16
(
CIFS_SEARCH_CLOSE_AT_END
|
CIFS_SEARCH_RETURN_RESUME
);
pSMB
->
SearchFlags
=
cpu_to_le16
(
search_flags
);
pSMB
->
InformationLevel
=
cpu_to_le16
(
psrch_inf
->
info_level
);
/* BB what should we set StorageType to? Does it matter? BB */
...
...
@@ -4477,8 +4506,8 @@ findFirstRetry:
return
rc
;
}
int
CIFSFindNext
(
const
int
xid
,
struct
cifs_tcon
*
tcon
,
__u16
search
Handle
,
struct
cifs_search_info
*
psrch_inf
)
int
CIFSFindNext
(
const
int
xid
,
struct
cifs_tcon
*
tcon
,
__u16
searchHandle
,
__u16
search
_flags
,
struct
cifs_search_info
*
psrch_inf
)
{
TRANSACTION2_FNEXT_REQ
*
pSMB
=
NULL
;
TRANSACTION2_FNEXT_RSP
*
pSMBr
=
NULL
;
...
...
@@ -4521,8 +4550,7 @@ int CIFSFindNext(const int xid, struct cifs_tcon *tcon,
cpu_to_le16
(
CIFSMaxBufSize
/
sizeof
(
FILE_UNIX_INFO
));
pSMB
->
InformationLevel
=
cpu_to_le16
(
psrch_inf
->
info_level
);
pSMB
->
ResumeKey
=
psrch_inf
->
resume_key
;
pSMB
->
SearchFlags
=
cpu_to_le16
(
CIFS_SEARCH_CLOSE_AT_END
|
CIFS_SEARCH_RETURN_RESUME
);
pSMB
->
SearchFlags
=
cpu_to_le16
(
search_flags
);
name_len
=
psrch_inf
->
resume_name_len
;
params
+=
name_len
;
...
...
@@ -4833,8 +4861,12 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
max_len
=
data_end
-
temp
;
node
->
node_name
=
cifs_strndup_from_ucs
(
temp
,
max_len
,
is_unicode
,
nls_codepage
);
if
(
!
node
->
node_name
)
if
(
!
node
->
node_name
)
{
rc
=
-
ENOMEM
;
goto
parse_DFS_referrals_exit
;
}
ref
++
;
}
parse_DFS_referrals_exit:
...
...
sources/3.2/connect.c
View file @
f03c86f7
...
...
@@ -2929,6 +2929,18 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
#define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024)
#define CIFS_DEFAULT_NON_POSIX_WSIZE (65536)
/*
* On hosts with high memory, we can't currently support wsize/rsize that are
* larger than we can kmap at once. Cap the rsize/wsize at
* LAST_PKMAP * PAGE_SIZE. We'll never be able to fill a read or write request
* larger than that anyway.
*/
#ifdef CONFIG_HIGHMEM
#define CIFS_KMAP_SIZE_LIMIT (LAST_PKMAP * PAGE_CACHE_SIZE)
#else
/* CONFIG_HIGHMEM */
#define CIFS_KMAP_SIZE_LIMIT (1<<24)
#endif
/* CONFIG_HIGHMEM */
static
unsigned
int
cifs_negotiate_wsize
(
struct
cifs_tcon
*
tcon
,
struct
smb_vol
*
pvolume_info
)
{
...
...
@@ -2959,6 +2971,9 @@ cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
wsize
=
min_t
(
unsigned
int
,
wsize
,
server
->
maxBuf
-
sizeof
(
WRITE_REQ
)
+
4
);
/* limit to the amount that we can kmap at once */
wsize
=
min_t
(
unsigned
int
,
wsize
,
CIFS_KMAP_SIZE_LIMIT
);
/* hard limit of CIFS_MAX_WSIZE */
wsize
=
min_t
(
unsigned
int
,
wsize
,
CIFS_MAX_WSIZE
);
...
...
@@ -2979,18 +2994,15 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
* MS-CIFS indicates that servers are only limited by the client's
* bufsize for reads, testing against win98se shows that it throws
* INVALID_PARAMETER errors if you try to request too large a read.
* OS/2 just sends back short reads.
*
* If the server advertises a MaxBufferSize of less than one page,
* assume that it also can't satisfy reads larger than that either.
*
* FIXME: Is there a better heuristic for this?
* If the server doesn't advertise CAP_LARGE_READ_X, then assume that
* it can't handle a read request larger than its MaxBufferSize either.
*/
if
(
tcon
->
unix_ext
&&
(
unix_cap
&
CIFS_UNIX_LARGE_READ_CAP
))
defsize
=
CIFS_DEFAULT_IOSIZE
;
else
if
(
server
->
capabilities
&
CAP_LARGE_READ_X
)
defsize
=
CIFS_DEFAULT_NON_POSIX_RSIZE
;
else
if
(
server
->
maxBuf
>=
PAGE_CACHE_SIZE
)
defsize
=
CIFSMaxBufSize
;
else
defsize
=
server
->
maxBuf
-
sizeof
(
READ_RSP
);
...
...
@@ -3003,6 +3015,9 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
if
(
!
(
server
->
capabilities
&
CAP_LARGE_READ_X
))
rsize
=
min_t
(
unsigned
int
,
CIFSMaxBufSize
,
rsize
);
/* limit to the amount that we can kmap at once */
rsize
=
min_t
(
unsigned
int
,
rsize
,
CIFS_KMAP_SIZE_LIMIT
);
/* hard limit of CIFS_MAX_RSIZE */
rsize
=
min_t
(
unsigned
int
,
rsize
,
CIFS_MAX_RSIZE
);
...
...
sources/3.2/file.c
View file @
f03c86f7
...
...
@@ -841,13 +841,21 @@ cifs_posix_lock_set(struct file *file, struct file_lock *flock)
if
((
flock
->
fl_flags
&
FL_POSIX
)
==
0
)
return
rc
;
try_again:
mutex_lock
(
&
cinode
->
lock_mutex
);
if
(
!
cinode
->
can_cache_brlcks
)
{
mutex_unlock
(
&
cinode
->
lock_mutex
);
return
rc
;
}
rc
=
posix_lock_file_wait
(
file
,
flock
);
rc
=
posix_lock_file
(
file
,
flock
,
NULL
);
mutex_unlock
(
&
cinode
->
lock_mutex
);
if
(
rc
==
FILE_LOCK_DEFERRED
)
{
rc
=
wait_event_interruptible
(
flock
->
fl_wait
,
!
flock
->
fl_next
);
if
(
!
rc
)
goto
try_again
;
locks_delete_block
(
flock
);
}
return
rc
;
}
...
...
@@ -1532,10 +1540,11 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
struct
cifsFileInfo
*
find_writable_file
(
struct
cifsInodeInfo
*
cifs_inode
,
bool
fsuid_only
)
{
struct
cifsFileInfo
*
open_file
;
struct
cifsFileInfo
*
open_file
,
*
inv_file
=
NULL
;
struct
cifs_sb_info
*
cifs_sb
;
bool
any_available
=
false
;
int
rc
;
unsigned
int
refind
=
0
;
/* Having a null inode here (because mapping->host was set to zero by
the VFS or MM) should not happen but we had reports of on oops (due to
...
...
@@ -1555,40 +1564,25 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
spin_lock
(
&
cifs_file_list_lock
);
refind_writable:
if
(
refind
>
MAX_REOPEN_ATT
)
{
spin_unlock
(
&
cifs_file_list_lock
);
return
NULL
;
}
list_for_each_entry
(
open_file
,
&
cifs_inode
->
openFileList
,
flist
)
{
if
(
!
any_available
&&
open_file
->
pid
!=
current
->
tgid
)
continue
;
if
(
fsuid_only
&&
open_file
->
uid
!=
current_fsuid
())
continue
;
if
(
OPEN_FMODE
(
open_file
->
f_flags
)
&
FMODE_WRITE
)
{
cifsFileInfo_get
(
open_file
);
if
(
!
open_file
->
invalidHandle
)
{
/* found a good writable file */
cifsFileInfo_get
(
open_file
);
spin_unlock
(
&
cifs_file_list_lock
);
return
open_file
;
}
else
{
if
(
!
inv_file
)
inv_file
=
open_file
;
}
spin_unlock
(
&
cifs_file_list_lock
);
/* Had to unlock since following call can block */
rc
=
cifs_reopen_file
(
open_file
,
false
);
if
(
!
rc
)
return
open_file
;
/* if it fails, try another handle if possible */
cFYI
(
1
,
"wp failed on reopen file"
);
cifsFileInfo_put
(
open_file
);
spin_lock
(
&
cifs_file_list_lock
);
/* else we simply continue to the next entry. Thus
we do not loop on reopen errors. If we
can not reopen the file, for example if we
reconnected to a server with another client
racing to delete or lock the file we would not
make progress if we restarted before the beginning
of the loop here. */
}
}
/* couldn't find useable FH with same pid, try any available */
...
...
@@ -1596,7 +1590,30 @@ refind_writable:
any_available
=
true
;
goto
refind_writable
;
}
if
(
inv_file
)
{
any_available
=
false
;
cifsFileInfo_get
(
inv_file
);
}
spin_unlock
(
&
cifs_file_list_lock
);
if
(
inv_file
)
{
rc
=
cifs_reopen_file
(
inv_file
,
false
);
if
(
!
rc
)
return
inv_file
;
else
{
spin_lock
(
&
cifs_file_list_lock
);
list_move_tail
(
&
inv_file
->
flist
,
&
cifs_inode
->
openFileList
);
spin_unlock
(
&
cifs_file_list_lock
);
cifsFileInfo_put
(
inv_file
);
spin_lock
(
&
cifs_file_list_lock
);
++
refind
;
goto
refind_writable
;
}
}
return
NULL
;
}
...
...
sources/3.2/readdir.c
View file @
f03c86f7
...
...
@@ -86,9 +86,12 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
dentry
=
d_lookup
(
parent
,
name
);
if
(
dentry
)
{
/* FIXME: check for inode number changes? */
if
(
dentry
->
d_inode
!=
NULL
)
inode
=
dentry
->
d_inode
;
/* update inode in place if i_ino didn't change */
if
(
inode
&&
CIFS_I
(
inode
)
->
uniqueid
==
fattr
->
cf_uniqueid
)
{
cifs_fattr_to_inode
(
inode
,
fattr
);
return
dentry
;
}
d_drop
(
dentry
);
dput
(
dentry
);
}
...
...
@@ -219,6 +222,7 @@ int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb,
static
int
initiate_cifs_search
(
const
int
xid
,
struct
file
*
file
)
{
__u16
search_flags
;
int
rc
=
0
;
char
*
full_path
=
NULL
;
struct
cifsFileInfo
*
cifsFile
;
...
...
@@ -270,8 +274,12 @@ ffirst_retry:
cifsFile
->
srch_inf
.
info_level
=
SMB_FIND_FILE_DIRECTORY_INFO
;
}
search_flags
=
CIFS_SEARCH_CLOSE_AT_END
|
CIFS_SEARCH_RETURN_RESUME
;
if
(
backup_cred
(
cifs_sb
))
search_flags
|=
CIFS_SEARCH_BACKUP_SEARCH
;
rc
=
CIFSFindFirst
(
xid
,
pTcon
,
full_path
,
cifs_sb
->
local_nls
,
&
cifsFile
->
netfid
,
&
cifsFile
->
srch_inf
,
&
cifsFile
->
netfid
,
search_flags
,
&
cifsFile
->
srch_inf
,
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_MAP_SPECIAL_CHR
,
CIFS_DIR_SEP
(
cifs_sb
));
if
(
rc
==
0
)
...
...
@@ -502,11 +510,13 @@ static int cifs_save_resume_key(const char *current_entry,
static
int
find_cifs_entry
(
const
int
xid
,
struct
cifs_tcon
*
pTcon
,
struct
file
*
file
,
char
**
ppCurrentEntry
,
int
*
num_to_ret
)
{
__u16
search_flags
;
int
rc
=
0
;
int
pos_in_buf
=
0
;
loff_t
first_entry_in_buffer
;
loff_t
index_to_find
=
file
->
f_pos
;
struct
cifsFileInfo
*
cifsFile
=
file
->
private_data
;
struct
cifs_sb_info
*
cifs_sb
=
CIFS_SB
(
file
->
f_path
.
dentry
->
d_sb
);
/* check if index in the buffer */
if
((
cifsFile
==
NULL
)
||
(
ppCurrentEntry
==
NULL
)
||
...
...
@@ -560,10 +570,14 @@ static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon,
cifsFile
);
}
search_flags
=
CIFS_SEARCH_CLOSE_AT_END
|
CIFS_SEARCH_RETURN_RESUME
;
if
(
backup_cred
(
cifs_sb
))
search_flags
|=
CIFS_SEARCH_BACKUP_SEARCH
;
while
((
index_to_find
>=
cifsFile
->
srch_inf
.
index_of_last_entry
)
&&
(
rc
==
0
)
&&
!
cifsFile
->
srch_inf
.
endOfSearch
)
{
cFYI
(
1
,
"calling findnext2"
);
rc
=
CIFSFindNext
(
xid
,
pTcon
,
cifsFile
->
netfid
,
rc
=
CIFSFindNext
(
xid
,
pTcon
,
cifsFile
->
netfid
,
search_flags
,
&
cifsFile
->
srch_inf
);
/* FindFirst/Next set last_entry to NULL on malformed reply */
if
(
cifsFile
->
srch_inf
.
last_entry
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment