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
8506be1f
Commit
8506be1f
authored
Aug 08, 2014
by
Pavel Shilovsky
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update 3.14 sources from stable (v3.14.16)
parent
4b53bc45
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
169 additions
and
13 deletions
+169
-13
cifs_unicode.c
sources/3.14/cifs_unicode.c
+4
-3
cifsfs.c
sources/3.14/cifsfs.c
+13
-1
cifsglob.h
sources/3.14/cifsglob.h
+8
-0
cifsproto.h
sources/3.14/cifsproto.h
+3
-0
file.c
sources/3.14/file.c
+28
-3
link.c
sources/3.14/link.c
+1
-1
misc.c
sources/3.14/misc.c
+72
-2
smb1ops.c
sources/3.14/smb1ops.c
+11
-0
smb2misc.c
sources/3.14/smb2misc.c
+15
-3
smb2ops.c
sources/3.14/smb2ops.c
+14
-0
No files found.
sources/3.14/cifs_unicode.c
View file @
8506be1f
...
...
@@ -290,7 +290,8 @@ int
cifsConvertToUTF16
(
__le16
*
target
,
const
char
*
source
,
int
srclen
,
const
struct
nls_table
*
cp
,
int
mapChars
)
{
int
i
,
j
,
charlen
;
int
i
,
charlen
;
int
j
=
0
;
char
src_char
;
__le16
dst_char
;
wchar_t
tmp
;
...
...
@@ -298,12 +299,11 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
if
(
!
mapChars
)
return
cifs_strtoUTF16
(
target
,
source
,
PATH_MAX
,
cp
);
for
(
i
=
0
,
j
=
0
;
i
<
srclen
;
j
++
)
{
for
(
i
=
0
;
i
<
srclen
;
j
++
)
{
src_char
=
source
[
i
];
charlen
=
1
;
switch
(
src_char
)
{
case
0
:
put_unaligned
(
0
,
&
target
[
j
]);
goto
ctoUTF16_out
;
case
':'
:
dst_char
=
cpu_to_le16
(
UNI_COLON
);
...
...
@@ -350,6 +350,7 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
}
ctoUTF16_out:
put_unaligned
(
0
,
&
target
[
j
]);
/* Null terminate target unicode string */
return
j
;
}
...
...
sources/3.14/cifsfs.c
View file @
8506be1f
...
...
@@ -253,6 +253,11 @@ cifs_alloc_inode(struct super_block *sb)
cifs_set_oplock_level
(
cifs_inode
,
0
);
cifs_inode
->
delete_pending
=
false
;
cifs_inode
->
invalid_mapping
=
false
;
clear_bit
(
CIFS_INODE_PENDING_OPLOCK_BREAK
,
&
cifs_inode
->
flags
);
clear_bit
(
CIFS_INODE_PENDING_WRITERS
,
&
cifs_inode
->
flags
);
clear_bit
(
CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2
,
&
cifs_inode
->
flags
);
spin_lock_init
(
&
cifs_inode
->
writers_lock
);
cifs_inode
->
writers
=
0
;
cifs_inode
->
vfs_inode
.
i_blkbits
=
14
;
/* 2**14 = CIFS_MAX_MSGSIZE */
cifs_inode
->
server_eof
=
0
;
cifs_inode
->
uniqueid
=
0
;
...
...
@@ -734,19 +739,26 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned
long
nr_segs
,
loff_t
pos
)
{
struct
inode
*
inode
=
file_inode
(
iocb
->
ki_filp
);
struct
cifsInodeInfo
*
cinode
=
CIFS_I
(
inode
);
ssize_t
written
;
int
rc
;
written
=
cifs_get_writer
(
cinode
);
if
(
written
)
return
written
;
written
=
generic_file_aio_write
(
iocb
,
iov
,
nr_segs
,
pos
);
if
(
CIFS_CACHE_WRITE
(
CIFS_I
(
inode
)))
return
written
;
goto
out
;
rc
=
filemap_fdatawrite
(
inode
->
i_mapping
);
if
(
rc
)
cifs_dbg
(
FYI
,
"cifs_file_aio_write: %d rc on %p inode
\n
"
,
rc
,
inode
);
out:
cifs_put_writer
(
cinode
);
return
written
;
}
...
...
sources/3.14/cifsglob.h
View file @
8506be1f
...
...
@@ -228,6 +228,8 @@ struct smb_version_operations {
/* verify the message */
int
(
*
check_message
)(
char
*
,
unsigned
int
);
bool
(
*
is_oplock_break
)(
char
*
,
struct
TCP_Server_Info
*
);
void
(
*
downgrade_oplock
)(
struct
TCP_Server_Info
*
,
struct
cifsInodeInfo
*
,
bool
);
/* process transaction2 response */
bool
(
*
check_trans2
)(
struct
mid_q_entry
*
,
struct
TCP_Server_Info
*
,
char
*
,
int
);
...
...
@@ -1121,6 +1123,12 @@ struct cifsInodeInfo {
unsigned
int
epoch
;
/* used to track lease state changes */
bool
delete_pending
;
/* DELETE_ON_CLOSE is set */
bool
invalid_mapping
;
/* pagecache is invalid */
unsigned
long
flags
;
#define CIFS_INODE_PENDING_OPLOCK_BREAK (0)
/* oplock break in progress */
#define CIFS_INODE_PENDING_WRITERS (1)
/* Writes in progress */
#define CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2 (2)
/* Downgrade oplock to L2 */
spinlock_t
writers_lock
;
unsigned
int
writers
;
/* Number of writers on this inode */
unsigned
long
time
;
/* jiffies of last update of inode */
u64
server_eof
;
/* current file size on server -- protected by i_lock */
u64
uniqueid
;
/* server inode number */
...
...
sources/3.14/cifsproto.h
View file @
8506be1f
...
...
@@ -127,6 +127,9 @@ extern u64 cifs_UnixTimeToNT(struct timespec);
extern
struct
timespec
cnvrtDosUnixTm
(
__le16
le_date
,
__le16
le_time
,
int
offset
);
extern
void
cifs_set_oplock_level
(
struct
cifsInodeInfo
*
cinode
,
__u32
oplock
);
extern
int
cifs_get_writer
(
struct
cifsInodeInfo
*
cinode
);
extern
void
cifs_put_writer
(
struct
cifsInodeInfo
*
cinode
);
extern
void
cifs_done_oplock_break
(
struct
cifsInodeInfo
*
cinode
);
extern
int
cifs_unlock_range
(
struct
cifsFileInfo
*
cfile
,
struct
file_lock
*
flock
,
const
unsigned
int
xid
);
extern
int
cifs_push_mandatory_locks
(
struct
cifsFileInfo
*
cfile
);
...
...
sources/3.14/file.c
View file @
8506be1f
...
...
@@ -2616,12 +2616,20 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
struct
cifs_tcon
*
tcon
=
tlink_tcon
(
cfile
->
tlink
);
ssize_t
written
;
written
=
cifs_get_writer
(
cinode
);
if
(
written
)
return
written
;
if
(
CIFS_CACHE_WRITE
(
cinode
))
{
if
(
cap_unix
(
tcon
->
ses
)
&&
(
CIFS_UNIX_FCNTL_CAP
&
le64_to_cpu
(
tcon
->
fsUnixInfo
.
Capability
))
&&
((
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NOPOSIXBRL
)
==
0
))
return
generic_file_aio_write
(
iocb
,
iov
,
nr_segs
,
pos
);
return
cifs_writev
(
iocb
,
iov
,
nr_segs
,
pos
);
&&
((
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NOPOSIXBRL
)
==
0
))
{
written
=
generic_file_aio_write
(
iocb
,
iov
,
nr_segs
,
pos
);
goto
out
;
}
written
=
cifs_writev
(
iocb
,
iov
,
nr_segs
,
pos
);
goto
out
;
}
/*
* For non-oplocked files in strict cache mode we need to write the data
...
...
@@ -2641,6 +2649,8 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
inode
);
cinode
->
oplock
=
0
;
}
out:
cifs_put_writer
(
cinode
);
return
written
;
}
...
...
@@ -3652,6 +3662,13 @@ static int cifs_launder_page(struct page *page)
return
rc
;
}
static
int
cifs_pending_writers_wait
(
void
*
unused
)
{
schedule
();
return
0
;
}
void
cifs_oplock_break
(
struct
work_struct
*
work
)
{
struct
cifsFileInfo
*
cfile
=
container_of
(
work
,
struct
cifsFileInfo
,
...
...
@@ -3659,8 +3676,15 @@ void cifs_oplock_break(struct work_struct *work)
struct
inode
*
inode
=
cfile
->
dentry
->
d_inode
;
struct
cifsInodeInfo
*
cinode
=
CIFS_I
(
inode
);
struct
cifs_tcon
*
tcon
=
tlink_tcon
(
cfile
->
tlink
);
struct
TCP_Server_Info
*
server
=
tcon
->
ses
->
server
;
int
rc
=
0
;
wait_on_bit
(
&
cinode
->
flags
,
CIFS_INODE_PENDING_WRITERS
,
cifs_pending_writers_wait
,
TASK_UNINTERRUPTIBLE
);
server
->
ops
->
downgrade_oplock
(
server
,
cinode
,
test_bit
(
CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2
,
&
cinode
->
flags
));
if
(
!
CIFS_CACHE_WRITE
(
cinode
)
&&
CIFS_CACHE_READ
(
cinode
)
&&
cifs_has_mand_locks
(
cinode
))
{
cifs_dbg
(
FYI
,
"Reset oplock to None for inode=%p due to mand locks
\n
"
,
...
...
@@ -3697,6 +3721,7 @@ void cifs_oplock_break(struct work_struct *work)
cinode
);
cifs_dbg
(
FYI
,
"Oplock release rc = %d
\n
"
,
rc
);
}
cifs_done_oplock_break
(
cinode
);
}
/*
...
...
sources/3.14/link.c
View file @
8506be1f
...
...
@@ -376,7 +376,7 @@ cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
oparms
.
desired_access
=
GENERIC_WRITE
;
oparms
.
share_access
=
FILE_SHARE_ALL
;
oparms
.
create_options
=
create_options
;
oparms
.
disposition
=
FILE_
OPEN
;
oparms
.
disposition
=
FILE_
CREATE
;
oparms
.
path
=
path
;
oparms
.
fid
=
&
fid
;
oparms
.
reconnect
=
false
;
...
...
sources/3.14/misc.c
View file @
8506be1f
...
...
@@ -466,8 +466,22 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
cifs_dbg
(
FYI
,
"file id match, oplock break
\n
"
);
pCifsInode
=
CIFS_I
(
netfile
->
dentry
->
d_inode
);
cifs_set_oplock_level
(
pCifsInode
,
pSMB
->
OplockLevel
?
OPLOCK_READ
:
0
);
set_bit
(
CIFS_INODE_PENDING_OPLOCK_BREAK
,
&
pCifsInode
->
flags
);
/*
* Set flag if the server downgrades the oplock
* to L2 else clear.
*/
if
(
pSMB
->
OplockLevel
)
set_bit
(
CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2
,
&
pCifsInode
->
flags
);
else
clear_bit
(
CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2
,
&
pCifsInode
->
flags
);
queue_work
(
cifsiod_wq
,
&
netfile
->
oplock_break
);
netfile
->
oplock_break_cancelled
=
false
;
...
...
@@ -551,6 +565,62 @@ void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock)
cinode
->
oplock
=
0
;
}
static
int
cifs_oplock_break_wait
(
void
*
unused
)
{
schedule
();
return
signal_pending
(
current
)
?
-
ERESTARTSYS
:
0
;
}
/*
* We wait for oplock breaks to be processed before we attempt to perform
* writes.
*/
int
cifs_get_writer
(
struct
cifsInodeInfo
*
cinode
)
{
int
rc
;
start:
rc
=
wait_on_bit
(
&
cinode
->
flags
,
CIFS_INODE_PENDING_OPLOCK_BREAK
,
cifs_oplock_break_wait
,
TASK_KILLABLE
);
if
(
rc
)
return
rc
;
spin_lock
(
&
cinode
->
writers_lock
);
if
(
!
cinode
->
writers
)
set_bit
(
CIFS_INODE_PENDING_WRITERS
,
&
cinode
->
flags
);
cinode
->
writers
++
;
/* Check to see if we have started servicing an oplock break */
if
(
test_bit
(
CIFS_INODE_PENDING_OPLOCK_BREAK
,
&
cinode
->
flags
))
{
cinode
->
writers
--
;
if
(
cinode
->
writers
==
0
)
{
clear_bit
(
CIFS_INODE_PENDING_WRITERS
,
&
cinode
->
flags
);
wake_up_bit
(
&
cinode
->
flags
,
CIFS_INODE_PENDING_WRITERS
);
}
spin_unlock
(
&
cinode
->
writers_lock
);
goto
start
;
}
spin_unlock
(
&
cinode
->
writers_lock
);
return
0
;
}
void
cifs_put_writer
(
struct
cifsInodeInfo
*
cinode
)
{
spin_lock
(
&
cinode
->
writers_lock
);
cinode
->
writers
--
;
if
(
cinode
->
writers
==
0
)
{
clear_bit
(
CIFS_INODE_PENDING_WRITERS
,
&
cinode
->
flags
);
wake_up_bit
(
&
cinode
->
flags
,
CIFS_INODE_PENDING_WRITERS
);
}
spin_unlock
(
&
cinode
->
writers_lock
);
}
void
cifs_done_oplock_break
(
struct
cifsInodeInfo
*
cinode
)
{
clear_bit
(
CIFS_INODE_PENDING_OPLOCK_BREAK
,
&
cinode
->
flags
);
wake_up_bit
(
&
cinode
->
flags
,
CIFS_INODE_PENDING_OPLOCK_BREAK
);
}
bool
backup_cred
(
struct
cifs_sb_info
*
cifs_sb
)
{
...
...
sources/3.14/smb1ops.c
View file @
8506be1f
...
...
@@ -372,6 +372,16 @@ coalesce_t2(char *second_buf, struct smb_hdr *target_hdr)
return
0
;
}
static
void
cifs_downgrade_oplock
(
struct
TCP_Server_Info
*
server
,
struct
cifsInodeInfo
*
cinode
,
bool
set_level2
)
{
if
(
set_level2
)
cifs_set_oplock_level
(
cinode
,
OPLOCK_READ
);
else
cifs_set_oplock_level
(
cinode
,
0
);
}
static
bool
cifs_check_trans2
(
struct
mid_q_entry
*
mid
,
struct
TCP_Server_Info
*
server
,
char
*
buf
,
int
malformed
)
...
...
@@ -1022,6 +1032,7 @@ struct smb_version_operations smb1_operations = {
.
clear_stats
=
cifs_clear_stats
,
.
print_stats
=
cifs_print_stats
,
.
is_oplock_break
=
is_valid_oplock_break
,
.
downgrade_oplock
=
cifs_downgrade_oplock
,
.
check_trans2
=
cifs_check_trans2
,
.
need_neg
=
cifs_need_neg
,
.
negotiate
=
cifs_negotiate
,
...
...
sources/3.14/smb2misc.c
View file @
8506be1f
...
...
@@ -575,9 +575,21 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
else
cfile
->
oplock_break_cancelled
=
false
;
server
->
ops
->
set_oplock_level
(
cinode
,
rsp
->
OplockLevel
?
SMB2_OPLOCK_LEVEL_II
:
0
,
0
,
NULL
);
set_bit
(
CIFS_INODE_PENDING_OPLOCK_BREAK
,
&
cinode
->
flags
);
/*
* Set flag if the server downgrades the oplock
* to L2 else clear.
*/
if
(
rsp
->
OplockLevel
)
set_bit
(
CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2
,
&
cinode
->
flags
);
else
clear_bit
(
CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2
,
&
cinode
->
flags
);
queue_work
(
cifsiod_wq
,
&
cfile
->
oplock_break
);
...
...
sources/3.14/smb2ops.c
View file @
8506be1f
...
...
@@ -911,6 +911,17 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
}
static
void
smb2_downgrade_oplock
(
struct
TCP_Server_Info
*
server
,
struct
cifsInodeInfo
*
cinode
,
bool
set_level2
)
{
if
(
set_level2
)
server
->
ops
->
set_oplock_level
(
cinode
,
SMB2_OPLOCK_LEVEL_II
,
0
,
NULL
);
else
server
->
ops
->
set_oplock_level
(
cinode
,
0
,
0
,
NULL
);
}
static
void
smb2_set_oplock_level
(
struct
cifsInodeInfo
*
cinode
,
__u32
oplock
,
unsigned
int
epoch
,
bool
*
purge_cache
)
{
...
...
@@ -1116,6 +1127,7 @@ struct smb_version_operations smb20_operations = {
.
clear_stats
=
smb2_clear_stats
,
.
print_stats
=
smb2_print_stats
,
.
is_oplock_break
=
smb2_is_valid_oplock_break
,
.
downgrade_oplock
=
smb2_downgrade_oplock
,
.
need_neg
=
smb2_need_neg
,
.
negotiate
=
smb2_negotiate
,
.
negotiate_wsize
=
smb2_negotiate_wsize
,
...
...
@@ -1190,6 +1202,7 @@ struct smb_version_operations smb21_operations = {
.
clear_stats
=
smb2_clear_stats
,
.
print_stats
=
smb2_print_stats
,
.
is_oplock_break
=
smb2_is_valid_oplock_break
,
.
downgrade_oplock
=
smb2_downgrade_oplock
,
.
need_neg
=
smb2_need_neg
,
.
negotiate
=
smb2_negotiate
,
.
negotiate_wsize
=
smb2_negotiate_wsize
,
...
...
@@ -1265,6 +1278,7 @@ struct smb_version_operations smb30_operations = {
.
print_stats
=
smb2_print_stats
,
.
dump_share_caps
=
smb2_dump_share_caps
,
.
is_oplock_break
=
smb2_is_valid_oplock_break
,
.
downgrade_oplock
=
smb2_downgrade_oplock
,
.
need_neg
=
smb2_need_neg
,
.
negotiate
=
smb2_negotiate
,
.
negotiate_wsize
=
smb2_negotiate_wsize
,
...
...
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