Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
9ad61b1d
Commit
9ad61b1d
authored
Apr 15, 2003
by
Steve French
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://linux.bkbits.net/linux-2.5
into hostme.bitkeeper.com:/ua/repos/c/cifs/linux-2.5cifs
parents
18550640
2dc51bdf
Changes
13
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
520 additions
and
150 deletions
+520
-150
fs/cifs/CHANGES
fs/cifs/CHANGES
+17
-0
fs/cifs/cifs_debug.c
fs/cifs/cifs_debug.c
+46
-0
fs/cifs/cifsfs.c
fs/cifs/cifsfs.c
+66
-7
fs/cifs/cifsglob.h
fs/cifs/cifsglob.h
+20
-6
fs/cifs/cifspdu.h
fs/cifs/cifspdu.h
+10
-3
fs/cifs/cifsproto.h
fs/cifs/cifsproto.h
+7
-1
fs/cifs/cifssmb.c
fs/cifs/cifssmb.c
+46
-10
fs/cifs/connect.c
fs/cifs/connect.c
+1
-2
fs/cifs/file.c
fs/cifs/file.c
+222
-96
fs/cifs/inode.c
fs/cifs/inode.c
+12
-12
fs/cifs/link.c
fs/cifs/link.c
+28
-13
fs/cifs/misc.c
fs/cifs/misc.c
+11
-0
fs/cifs/transport.c
fs/cifs/transport.c
+34
-0
No files found.
fs/cifs/CHANGES
View file @
9ad61b1d
Version 0.73
------------
unload nls if mount fails.
Version 0.72
------------
Add resume key support to search (readdir) code to workaround
Windows bug. Add /proc/fs/cifs/LookupCacheEnable which
allows disabling caching of attribute information for
lookups.
Version 0.71
------------
Add more oplock handling (distributed caching code). Remove
dead code. Remove excessive stack space utilization from
symlink routines.
Version 0.70
------------
Fix oops in get dfs referral (triggered when null path sent in to
...
...
fs/cifs/cifs_debug.c
View file @
9ad61b1d
...
...
@@ -185,6 +185,8 @@ static read_proc_t cifsFYI_read;
static
write_proc_t
cifsFYI_write
;
static
read_proc_t
oplockEnabled_read
;
static
write_proc_t
oplockEnabled_write
;
static
read_proc_t
lookupFlag_read
;
static
write_proc_t
lookupFlag_write
;
static
read_proc_t
traceSMB_read
;
static
write_proc_t
traceSMB_write
;
static
read_proc_t
multiuser_mount_read
;
...
...
@@ -243,6 +245,12 @@ cifs_proc_init(void)
if
(
pde
)
pde
->
write_proc
=
extended_security_write
;
pde
=
create_proc_read_entry
(
"LookupCacheEnable"
,
0
,
proc_fs_cifs
,
lookupFlag_read
,
0
);
if
(
pde
)
pde
->
write_proc
=
lookupFlag_write
;
pde
=
create_proc_read_entry
(
"NTLMV2Enabled"
,
0
,
proc_fs_cifs
,
ntlmv2_enabled_read
,
0
);
...
...
@@ -353,6 +361,44 @@ oplockEnabled_write(struct file *file, const char *buffer,
return
count
;
}
static
int
lookupFlag_read
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
int
len
;
len
=
sprintf
(
page
,
"%d
\n
"
,
lookupCacheEnabled
);
len
-=
off
;
*
start
=
page
+
off
;
if
(
len
>
count
)
len
=
count
;
else
*
eof
=
1
;
if
(
len
<
0
)
len
=
0
;
return
len
;
}
static
int
lookupFlag_write
(
struct
file
*
file
,
const
char
*
buffer
,
unsigned
long
count
,
void
*
data
)
{
char
c
;
int
rc
;
rc
=
get_user
(
c
,
buffer
);
if
(
rc
)
return
rc
;
if
(
c
==
'0'
||
c
==
'n'
||
c
==
'N'
)
lookupCacheEnabled
=
0
;
else
if
(
c
==
'1'
||
c
==
'y'
||
c
==
'Y'
)
lookupCacheEnabled
=
1
;
return
count
;
}
static
int
traceSMB_read
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
...
...
fs/cifs/cifsfs.c
View file @
9ad61b1d
...
...
@@ -48,11 +48,13 @@ int cifsFYI = 0;
int
cifsERROR
=
1
;
int
traceSMB
=
0
;
unsigned
int
oplockEnabled
=
0
;
unsigned
int
lookupCacheEnabled
=
1
;
unsigned
int
multiuser_mount
=
0
;
unsigned
int
extended_security
=
0
;
unsigned
int
ntlmv2_support
=
0
;
unsigned
int
sign_CIFS_PDUs
=
0
;
unsigned
int
CIFSMaximumBufferSize
=
CIFS_MAX_MSGSIZE
;
struct
task_struct
*
oplockThread
=
NULL
;
extern
int
cifs_mount
(
struct
super_block
*
,
struct
cifs_sb_info
*
,
char
*
,
char
*
);
...
...
@@ -107,6 +109,8 @@ cifs_read_super(struct super_block *sb, void *data, char *devname, int silent)
iput
(
inode
);
out_mount_failed:
if
(
cifs_sb
->
local_nls
)
unload_nls
(
cifs_sb
->
local_nls
);
if
(
cifs_sb
)
kfree
(
cifs_sb
);
return
-
EINVAL
;
...
...
@@ -175,6 +179,7 @@ static int cifs_permission(struct inode * inode, int mask)
static
kmem_cache_t
*
cifs_inode_cachep
;
kmem_cache_t
*
cifs_req_cachep
;
kmem_cache_t
*
cifs_mid_cachep
;
kmem_cache_t
*
cifs_oplock_cachep
;
static
struct
inode
*
cifs_alloc_inode
(
struct
super_block
*
sb
)
...
...
@@ -390,10 +395,17 @@ int
cifs_init_mids
(
void
)
{
cifs_mid_cachep
=
kmem_cache_create
(
"cifs_mpx_ids"
,
sizeof
(
struct
mid_q_entry
),
0
,
SLAB_HWCACHE_ALIGN
,
NULL
,
NULL
);
sizeof
(
struct
mid_q_entry
),
0
,
SLAB_HWCACHE_ALIGN
,
NULL
,
NULL
);
if
(
cifs_mid_cachep
==
NULL
)
return
-
ENOMEM
;
cifs_oplock_cachep
=
kmem_cache_create
(
"cifs_oplock_structs"
,
sizeof
(
struct
oplock_q_entry
),
0
,
SLAB_HWCACHE_ALIGN
,
NULL
,
NULL
);
if
(
cifs_oplock_cachep
==
NULL
)
{
kmem_cache_destroy
(
cifs_mid_cachep
);
return
-
ENOMEM
;
}
return
0
;
}
...
...
@@ -404,6 +416,49 @@ cifs_destroy_mids(void)
if
(
kmem_cache_destroy
(
cifs_mid_cachep
))
printk
(
KERN_WARNING
"cifs_destroy_mids: error not all structures were freed
\n
"
);
if
(
kmem_cache_destroy
(
cifs_oplock_cachep
))
printk
(
KERN_WARNING
"error not all oplock structures were freed
\n
"
);}
static
int
cifs_oplock_thread
(
void
*
dummyarg
)
{
struct
list_head
*
tmp
;
struct
oplock_q_entry
*
oplock_item
;
struct
file
*
pfile
;
struct
cifsTconInfo
*
pTcon
;
int
rc
;
daemonize
(
"cifsoplockd"
);
allow_signal
(
SIGKILL
);
oplockThread
=
current
;
while
(
1
)
{
set_current_state
(
TASK_INTERRUPTIBLE
);
schedule_timeout
(
100
*
HZ
);
/* BB add missing code */
cFYI
(
1
,(
"oplock thread woken up - flush inode"
));
/* BB remove */
write_lock
(
&
GlobalMid_Lock
);
list_for_each
(
tmp
,
&
GlobalOplock_Q
)
{
oplock_item
=
list_entry
(
tmp
,
struct
oplock_q_entry
,
qhead
);
if
(
oplock_item
)
{
pTcon
=
oplock_item
->
tcon
;
pfile
=
oplock_item
->
file_to_flush
;
cFYI
(
1
,(
"process item on queue"
));
/* BB remove */
DeleteOplockQEntry
(
oplock_item
);
write_unlock
(
&
GlobalMid_Lock
);
rc
=
filemap_fdatawrite
(
pfile
->
f_dentry
->
d_inode
->
i_mapping
);
cFYI
(
1
,(
"Oplock flush file %p rc %d"
,
pfile
,
rc
));
/* send oplock break */
write_lock
(
&
GlobalMid_Lock
);
}
else
break
;
cFYI
(
1
,(
"next time through list"
));
/* BB remove */
}
write_unlock
(
&
GlobalMid_Lock
);
cFYI
(
1
,(
"next time through while loop"
));
/* BB remove */
}
}
static
int
__init
...
...
@@ -416,7 +471,7 @@ init_cifs(void)
INIT_LIST_HEAD
(
&
GlobalServerList
);
/* BB not implemented yet */
INIT_LIST_HEAD
(
&
GlobalSMBSessionList
);
INIT_LIST_HEAD
(
&
GlobalTreeConnectionList
);
INIT_LIST_HEAD
(
&
GlobalOplock_Q
);
/*
* Initialize Global counters
*/
...
...
@@ -437,9 +492,11 @@ init_cifs(void)
rc
=
cifs_init_request_bufs
();
if
(
!
rc
)
{
rc
=
register_filesystem
(
&
cifs_fs_type
);
if
(
!
rc
)
return
rc
;
/* Success */
else
if
(
!
rc
)
{
kernel_thread
(
cifs_oplock_thread
,
NULL
,
CLONE_FS
|
CLONE_FILES
|
CLONE_VM
);
return
rc
;
/* Success */
}
else
cifs_destroy_request_bufs
();
}
cifs_destroy_mids
();
...
...
@@ -459,10 +516,12 @@ exit_cifs(void)
#if CONFIG_PROC_FS
cifs_proc_clean
();
#endif
unregister_filesystem
(
&
cifs_fs_type
);
unregister_filesystem
(
&
cifs_fs_type
);
cifs_destroy_inodecache
();
cifs_destroy_mids
();
cifs_destroy_request_bufs
();
if
(
oplockThread
)
send_sig
(
SIGKILL
,
oplockThread
,
1
);
}
MODULE_AUTHOR
(
"Steve French <sfrench@us.ibm.com>"
);
...
...
fs/cifs/cifsglob.h
View file @
9ad61b1d
...
...
@@ -199,14 +199,18 @@ struct cifsLockInfo {
struct
cifsFileInfo
{
struct
list_head
tlist
;
/* pointer to next fid owned by tcon */
struct
list_head
flist
;
/* next fid (file instance) for this inode */
unsigned
int
uid
;
/* allows
you to find
which FileInfo structure */
unsigned
int
uid
;
/* allows
finding
which FileInfo structure */
__u32
pid
;
/* process id who opened file */
__u16
netfid
;
/* file id from remote */
/* BB add lock scope info here if needed */
;
/* lock scope id (0 if none) */
struct
file
*
pfile
;
/* needed for writepage */
struct
file
*
pfile
;
/* needed for writepage */
int
endOfSearch
:
1
;
/* we have reached end of search */
int
closePend
:
1
;
/* file is marked to close */
int
emptyDir
:
1
;
char
*
search_resume_name
;
unsigned
int
resume_name_length
;
__u32
resume_key
;
};
/*
...
...
@@ -221,7 +225,8 @@ struct cifsInodeInfo {
atomic_t
inUse
;
/* num concurrent users (local openers cifs) of file*/
unsigned
long
time
;
/* jiffies of last update/check of inode */
int
clientCanCacheRead
:
1
;
/* read oplock */
int
clientCanCacheAll
:
1
;
/* read and writebehind oplock */
int
clientCanCacheAll
:
1
;
/* read and writebehind oplock */
int
oplockPending
:
1
;
struct
inode
vfs_inode
;
};
...
...
@@ -251,14 +256,20 @@ struct mid_q_entry {
int
midState
;
/* wish this were enum but can not pass to wait_event */
};
struct
oplock_q_entry
{
struct
list_head
qhead
;
struct
file
*
file_to_flush
;
struct
cifsTconInfo
*
tcon
;
};
#define MID_FREE 0
#define MID_REQUEST_ALLOCATED 1
#define MID_REQUEST_SUBMITTED 2
#define MID_RESPONSE_RECEIVED 4
struct
servers_not_supported
{
/* @z4a */
struct
servers_not_supported
*
next1
;
/* @z4a */
char
server_Name
[
SERVER_NAME_LEN_WITH_NULL
];
/* @z4a */
struct
servers_not_supported
{
/* @z4a */
struct
servers_not_supported
*
next1
;
/* @z4a */
char
server_Name
[
SERVER_NAME_LEN_WITH_NULL
];
/* @z4a */
/* Server Names in SMB protocol are 15 chars + X'20' */
/* in 16th byte... @z4a */
};
...
...
@@ -301,6 +312,8 @@ GLOBAL_EXTERN struct list_head GlobalSMBSessionList;
GLOBAL_EXTERN
struct
list_head
GlobalTreeConnectionList
;
GLOBAL_EXTERN
rwlock_t
GlobalSMBSeslock
;
/* protects list inserts on 3 above */
GLOBAL_EXTERN
struct
list_head
GlobalOplock_Q
;
/*
* Global transaction id (XID) information
*/
...
...
@@ -327,6 +340,7 @@ GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions
have the uid/password or Kerberos credential
or equivalent for current user */
GLOBAL_EXTERN
unsigned
int
oplockEnabled
;
GLOBAL_EXTERN
unsigned
int
lookupCacheEnabled
;
GLOBAL_EXTERN
unsigned
int
extended_security
;
/* if on, session setup sent
with more secure ntlmssp2 challenge/resp */
GLOBAL_EXTERN
unsigned
int
ntlmv2_support
;
/* better optional password hash */
...
...
fs/cifs/cifspdu.h
View file @
9ad61b1d
...
...
@@ -38,6 +38,7 @@
#define SMB_COM_WRITE_ANDX 0x2F
#define SMB_COM_TRANSACTION2 0x32
#define SMB_COM_TRANSACTION2_SECONDARY 0x33
#define SMB_COM_FIND_CLOSE2 0x34
#define SMB_COM_TREE_DISCONNECT 0x71
#define SMB_COM_NEGOTIATE 0x72
#define SMB_COM_SESSION_SETUP_ANDX 0x73
...
...
@@ -584,7 +585,7 @@ typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on tre
typedef
struct
smb_com_close_req
{
struct
smb_hdr
hdr
;
/* wct = 3 */
__u16
FileID
;
/* target file attributes */
__u16
FileID
;
__u32
LastWriteTime
;
/* should be zero */
__u16
ByteCount
;
/* 0 */
}
CLOSE_REQ
;
...
...
@@ -594,6 +595,12 @@ typedef struct smb_com_close_rsp {
__u16
ByteCount
;
/* bct = 0 */
}
CLOSE_RSP
;
typedef
struct
smb_com_findclose_req
{
struct
smb_hdr
hdr
;
/* wct = 1 */
__u16
FileID
;
__u16
ByteCount
;
/* 0 */
}
FINDCLOSE_REQ
;
/* OpenFlags */
#define REQ_OPLOCK 0x00000002
#define REQ_BATCHOPLOCK 0x00000004
...
...
@@ -1152,7 +1159,7 @@ typedef struct smb_com_transaction2_fnext_req {
__u16
InformationLevel
;
__u32
ResumeKey
;
__u16
SearchFlags
;
char
ResumeFileName
[
1
];
/* will be null string actually since we set bit 3 - resume from previous ending place */
char
ResumeFileName
[
1
];
}
TRANSACTION2_FNEXT_REQ
;
typedef
struct
smb_com_transaction2_fnext_rsp
{
...
...
@@ -1509,7 +1516,7 @@ typedef struct {
__u32
ExtFileAttributes
;
__u32
FileNameLength
;
char
FileName
[
1
];
}
FILE_DIRECTORY_INFO
;
/* level 257 FF response data area */
}
FILE_DIRECTORY_INFO
;
/* level 257 FF response data area */
struct
gea
{
unsigned
char
cbName
;
...
...
fs/cifs/cifsproto.h
View file @
9ad61b1d
...
...
@@ -57,6 +57,8 @@ extern void header_assemble(struct smb_hdr *, char /* command */ ,
const
struct
cifsTconInfo
*
,
int
/* length of fixed section (word count) in two byte units */
);
struct
oplock_q_entry
*
AllocOplockQEntry
(
struct
file
*
,
struct
cifsTconInfo
*
);
void
DeleteOplockQEntry
(
struct
oplock_q_entry
*
);
extern
struct
timespec
cifs_NTtimeToUnix
(
u64
/* utc nanoseconds since 1601 */
);
extern
u64
cifs_UnixTimeToNT
(
struct
timespec
);
extern
void
RevUcode_to_Ucode
(
char
*
revUnicode
,
char
*
UnicodeName
);
...
...
@@ -104,9 +106,13 @@ extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
extern
int
CIFSFindNext
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
FILE_DIRECTORY_INFO
*
findData
,
T2_FNEXT_RSP_PARMS
*
findParms
,
const
__u16
searchHandle
,
const
__u32
resumeKey
,
const
__u16
searchHandle
,
char
*
resume_name
,
int
name_length
,
__u32
resume_key
,
int
*
UnicodeFlag
,
int
*
pUnixFlag
);
extern
int
CIFSFindClose
(
const
int
,
struct
cifsTconInfo
*
tcon
,
const
__u16
search_handle
);
extern
int
CIFSSMBQPathInfo
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
unsigned
char
*
searchName
,
FILE_ALL_INFO
*
findData
,
...
...
fs/cifs/cifssmb.c
View file @
9ad61b1d
...
...
@@ -1449,7 +1449,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
cpu_to_le16
(
ATTR_READONLY
|
ATTR_HIDDEN
|
ATTR_SYSTEM
|
ATTR_DIRECTORY
);
pSMB
->
SearchCount
=
cpu_to_le16
(
CIFS_MAX_MSGSIZE
/
sizeof
(
FILE_DIRECTORY_INFO
));
/* should this be shrunk even more ? */
pSMB
->
SearchFlags
=
cpu_to_le16
(
CIFS_SEARCH_CLOSE_AT_END
);
pSMB
->
SearchFlags
=
cpu_to_le16
(
CIFS_SEARCH_CLOSE_AT_END
|
CIFS_SEARCH_RETURN_RESUME
);
/* test for Unix extensions */
if
(
tcon
->
ses
->
capabilities
&
CAP_UNIX
)
{
...
...
@@ -1496,9 +1496,9 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
int
CIFSFindNext
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
FILE_DIRECTORY_INFO
*
findData
,
T2_FNEXT_RSP_PARMS
*
findParms
,
const
__u16
searchHandle
,
__u32
resumeK
ey
,
int
*
pUnicodeFlag
,
int
*
pUnixFlag
)
FILE_DIRECTORY_INFO
*
findData
,
T2_FNEXT_RSP_PARMS
*
findParms
,
const
__u16
searchHandle
,
char
*
resume_file_name
,
int
name_len
,
__u32
resume_k
ey
,
int
*
pUnicodeFlag
,
int
*
pUnixFlag
)
{
/* level 257 SMB_ */
TRANSACTION2_FNEXT_REQ
*
pSMB
=
NULL
;
...
...
@@ -1508,6 +1508,9 @@ CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
int
bytes_returned
;
cFYI
(
1
,
(
"In FindNext"
));
if
(
resume_file_name
==
NULL
)
{
return
-
EIO
;
}
rc
=
smb_init
(
SMB_COM_TRANSACTION2
,
15
,
tcon
,
(
void
**
)
&
pSMB
,
(
void
**
)
&
pSMBr
);
if
(
rc
)
...
...
@@ -1530,9 +1533,6 @@ CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
pSMB
->
SetupCount
=
1
;
pSMB
->
Reserved3
=
0
;
pSMB
->
SubCommand
=
cpu_to_le16
(
TRANS2_FIND_NEXT
);
pSMB
->
ByteCount
=
pSMB
->
TotalParameterCount
+
1
/* pad */
;
pSMB
->
TotalParameterCount
=
cpu_to_le16
(
pSMB
->
TotalParameterCount
);
pSMB
->
ParameterCount
=
pSMB
->
TotalParameterCount
;
pSMB
->
SearchHandle
=
searchHandle
;
/* always kept as le */
findParms
->
SearchCount
=
0
;
/* set to zero in case of error */
pSMB
->
SearchCount
=
...
...
@@ -1546,10 +1546,19 @@ CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
cpu_to_le16
(
SMB_FIND_FILE_DIRECTORY_INFO
);
*
pUnixFlag
=
FALSE
;
}
pSMB
->
ResumeKey
=
resume
Key
;
/* always kept as le */
pSMB
->
ResumeKey
=
resume
_key
;
pSMB
->
SearchFlags
=
cpu_to_le16
(
CIFS_SEARCH_CLOSE_AT_END
|
CIFS_SEARCH_CONTINUE_FROM_LAST
);
cpu_to_le16
(
CIFS_SEARCH_CLOSE_AT_END
|
CIFS_SEARCH_RETURN_RESUME
);
/* BB add check to make sure we do not cross end of smb */
if
(
name_len
<
CIFS_MAX_MSGSIZE
)
{
memcpy
(
pSMB
->
ResumeFileName
,
resume_file_name
,
name_len
);
pSMB
->
ByteCount
+=
name_len
;
}
pSMB
->
TotalParameterCount
+=
name_len
;
pSMB
->
ByteCount
=
pSMB
->
TotalParameterCount
+
1
/* pad */
;
pSMB
->
TotalParameterCount
=
cpu_to_le16
(
pSMB
->
TotalParameterCount
);
pSMB
->
ParameterCount
=
pSMB
->
TotalParameterCount
;
/* BB improve error handling here */
pSMB
->
hdr
.
smb_buf_length
+=
pSMB
->
ByteCount
;
pSMB
->
ByteCount
=
cpu_to_le16
(
pSMB
->
ByteCount
);
...
...
@@ -1585,6 +1594,33 @@ CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
return
rc
;
}
int
CIFSFindClose
(
const
int
xid
,
struct
cifsTconInfo
*
tcon
,
const
__u16
searchHandle
)
{
int
rc
=
0
;
FINDCLOSE_REQ
*
pSMB
=
NULL
;
CLOSE_RSP
*
pSMBr
=
NULL
;
int
bytes_returned
;
cFYI
(
1
,
(
"In CIFSSMBFindClose"
));
rc
=
smb_init
(
SMB_COM_FIND_CLOSE2
,
1
,
tcon
,
(
void
**
)
&
pSMB
,
(
void
**
)
&
pSMBr
);
if
(
rc
)
return
rc
;
pSMB
->
FileID
=
searchHandle
;
pSMB
->
ByteCount
=
0
;
rc
=
SendReceive
(
xid
,
tcon
->
ses
,
(
struct
smb_hdr
*
)
pSMB
,
(
struct
smb_hdr
*
)
pSMBr
,
&
bytes_returned
,
0
);
if
(
rc
)
{
cERROR
(
1
,
(
"Send error in FindClose = %d"
,
rc
));
}
if
(
pSMB
)
buf_release
(
pSMB
);
return
rc
;
}
int
CIFSGetDFSRefer
(
const
int
xid
,
struct
cifsSesInfo
*
ses
,
const
unsigned
char
*
searchName
,
...
...
fs/cifs/connect.c
View file @
9ad61b1d
...
...
@@ -850,8 +850,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
init_waitqueue_head
(
&
srvTcp
->
response_q
);
INIT_LIST_HEAD
(
&
srvTcp
->
pending_mid_q
);
srvTcp
->
tcpStatus
=
CifsGood
;
kernel_thread
((
void
*
)
(
void
*
)
cifs_demultiplex_thread
,
srvTcp
,
kernel_thread
((
void
*
)(
void
*
)
cifs_demultiplex_thread
,
srvTcp
,
CLONE_FS
|
CLONE_FILES
|
CLONE_VM
);
}
}
...
...
fs/cifs/file.c
View file @
9ad61b1d
This diff is collapsed.
Click to expand it.
fs/cifs/inode.c
View file @
9ad61b1d
...
...
@@ -450,10 +450,10 @@ cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
cifs_sb_source
=
CIFS_SB
(
source_inode
->
i_sb
);
pTcon
=
cifs_sb_source
->
tcon
;
if
(
pTcon
!=
cifs_sb_target
->
tcon
)
{
if
(
pTcon
!=
cifs_sb_target
->
tcon
)
{
FreeXid
(
xid
);
return
-
EXDEV
;
/* BB actually could be allowed if same server, but
different share. Might eventually add support for this */
FreeXid
(
xid
);
}
fromName
=
build_path_from_dentry
(
source_direntry
);
...
...
@@ -471,7 +471,7 @@ cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
if
(
toName
)
kfree
(
toName
);
FreeXid
(
xid
);
FreeXid
(
xid
);
return
rc
;
}
...
...
@@ -500,15 +500,15 @@ cifs_revalidate(struct dentry *direntry)
if
(
time_before
(
jiffies
,
cifsInode
->
time
+
HZ
))
{
if
((
S_ISREG
(
direntry
->
d_inode
->
i_mode
)
==
0
)
||
(
direntry
->
d_inode
->
i_nlink
==
1
))
{
if
(
full_path
)
kfree
(
full_path
);
FreeXid
(
xid
);
return
rc
;
}
else
{
cFYI
(
1
,(
"Have to revalidate file due to hardlinks"
));
}
(
direntry
->
d_inode
->
i_nlink
==
1
)
||
(
lookupCacheEnabled
==
0
))
{
if
(
full_path
)
kfree
(
full_path
);
FreeXid
(
xid
)
;
return
rc
;
}
else
{
cFYI
(
1
,(
"Have to revalidate file due to hardlinks"
));
}
}
if
(
cifs_sb
->
tcon
->
ses
->
capabilities
&
CAP_UNIX
)
...
...
fs/cifs/link.c
View file @
9ad61b1d
...
...
@@ -82,7 +82,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
int
rc
=
-
EACCES
;
int
xid
;
char
*
full_path
=
NULL
;
char
target_path
[
257
]
;
char
*
target_path
;
struct
cifs_sb_info
*
cifs_sb
;
struct
cifsTconInfo
*
pTcon
;
...
...
@@ -91,7 +91,11 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
cFYI
(
1
,
(
"Full path: %s inode = 0x%p"
,
full_path
,
inode
));
cifs_sb
=
CIFS_SB
(
inode
->
i_sb
);
pTcon
=
cifs_sb
->
tcon
;
target_path
=
kmalloc
(
PATH_MAX
,
GFP_KERNEL
);
if
(
target_path
==
NULL
)
{
FreeXid
(
xid
);
return
-
ENOMEM
;
}
/* can not call the following line due to EFAULT in vfs_readlink which is presumably expecting a user space buffer */
/* length = cifs_readlink(direntry,target_path, sizeof(target_path) - 1); */
...
...
@@ -99,7 +103,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
if
(
pTcon
->
ses
->
capabilities
&
CAP_UNIX
)
rc
=
CIFSSMBUnixQuerySymLink
(
xid
,
pTcon
,
full_path
,
target_path
,
sizeof
(
target_path
)
-
1
,
PATH_MAX
-
1
,
cifs_sb
->
local_nls
);
else
{
/* rc = CIFSSMBQueryReparseLinkInfo */
...
...
@@ -109,11 +113,13 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
/* BB Should we be using page symlink ops here? */
if
(
rc
==
0
)
{
target_path
[
256
]
=
0
;
target_path
[
PATH_MAX
-
1
]
=
0
;
rc
=
vfs_follow_link
(
nd
,
target_path
);
}
/* else EACCESS */
if
(
target_path
)
kfree
(
target_path
);
if
(
full_path
)
kfree
(
full_path
);
FreeXid
(
xid
);
...
...
@@ -180,7 +186,8 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen)
struct
cifs_sb_info
*
cifs_sb
;
struct
cifsTconInfo
*
pTcon
;
char
*
full_path
=
NULL
;
char
tmpbuffer
[
256
];
char
*
tmpbuffer
;
int
len
;
__u16
fid
;
xid
=
GetXid
();
...
...
@@ -190,20 +197,28 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen)
cFYI
(
1
,
(
"Full path: %s inode = 0x%p pBuffer = 0x%p buflen = %d"
,
full_path
,
inode
,
pBuffer
,
buflen
));
if
(
buflen
>
PATH_MAX
)
len
=
PATH_MAX
;
else
len
=
buflen
;
tmpbuffer
=
kmalloc
(
len
,
GFP_KERNEL
);
if
(
tmpbuffer
==
NULL
)
{
FreeXid
(
xid
);
return
-
ENOMEM
;
}
/* BB add read reparse point symlink code and Unix extensions symlink code here BB */
if
(
cifs_sb
->
tcon
->
ses
->
capabilities
&
CAP_UNIX
)
rc
=
CIFSSMBUnixQuerySymLink
(
xid
,
pTcon
,
full_path
,
tmpbuffer
,
sizeof
(
tmpbuffer
)
-
1
,
cifs_sb
->
local_nls
);
tmpbuffer
,
len
-
1
,
cifs_sb
->
local_nls
);
else
{
rc
=
CIFSSMBOpen
(
xid
,
pTcon
,
full_path
,
FILE_OPEN
,
GENERIC_READ
,
OPEN_REPARSE_POINT
,
&
fid
,
&
oplock
,
cifs_sb
->
local_nls
);
if
(
!
rc
)
{
rc
=
CIFSSMBQueryReparseLinkInfo
(
xid
,
pTcon
,
full_path
,
tmpbuffer
,
sizeof
(
tmpbuffer
)
-
1
,
len
-
1
,
fid
,
cifs_sb
->
local_nls
);
if
(
CIFSSMBClose
(
xid
,
pTcon
,
fid
))
{
...
...
@@ -216,15 +231,15 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen)
/* BB Should we be using page ops here? */
/* BB null terminate returned string in pBuffer? BB */
if
(
buflen
>
sizeof
(
tmpbuffer
))
buflen
=
sizeof
(
tmpbuffer
);
if
(
rc
==
0
)
{
rc
=
vfs_readlink
(
direntry
,
pBuffer
,
buf
len
,
tmpbuffer
);
rc
=
vfs_readlink
(
direntry
,
pBuffer
,
len
,
tmpbuffer
);
cFYI
(
1
,
(
"vfs_readlink called from cifs_readlink returned %d"
,
rc
));
}
if
(
tmpbuffer
)
kfree
(
tmpbuffer
);
if
(
full_path
)
kfree
(
full_path
);
FreeXid
(
xid
);
...
...
fs/cifs/misc.c
View file @
9ad61b1d
...
...
@@ -27,6 +27,7 @@
#include "cifs_debug.h"
extern
kmem_cache_t
*
cifs_req_cachep
;
extern
struct
task_struct
*
oplockThread
;
__u16
GlobalMid
;
/* multiplex id - rotating counter */
...
...
@@ -336,6 +337,7 @@ is_valid_oplock_break(struct smb_hdr *buf)
list_for_each
(
tmp1
,
&
tcon
->
openFileList
){
netfile
=
list_entry
(
tmp1
,
struct
cifsFileInfo
,
tlist
);
if
(
pSMB
->
Fid
==
netfile
->
netfid
)
{
struct
cifsInodeInfo
*
pCifsInode
;
/* BB Add following logic:
2) look up inode from tcon->openFileList->file->f_dentry->d_inode
3) flush dirty pages and cached byte range locks and mark inode
...
...
@@ -345,6 +347,15 @@ is_valid_oplock_break(struct smb_hdr *buf)
6) send oplock break response to server */
read_unlock
(
&
GlobalSMBSeslock
);
cFYI
(
1
,(
"Matching file id, processing oplock break"
));
pCifsInode
=
CIFS_I
(
netfile
->
pfile
->
f_dentry
->
d_inode
);
pCifsInode
->
clientCanCacheAll
=
FALSE
;
if
(
pSMB
->
OplockLevel
==
0
)
pCifsInode
->
clientCanCacheRead
=
FALSE
;
pCifsInode
->
oplockPending
=
TRUE
;
AllocOplockQEntry
(
netfile
->
pfile
,
tcon
);
cFYI
(
1
,(
"about to wake up oplock thd"
));
wake_up_process
(
oplockThread
);
return
TRUE
;
}
}
...
...
fs/cifs/transport.c
View file @
9ad61b1d
...
...
@@ -32,6 +32,7 @@
#include "cifs_debug.h"
extern
kmem_cache_t
*
cifs_mid_cachep
;
extern
kmem_cache_t
*
cifs_oplock_cachep
;
struct
mid_q_entry
*
AllocMidQEntry
(
struct
smb_hdr
*
smb_buffer
,
struct
cifsSesInfo
*
ses
)
...
...
@@ -95,6 +96,39 @@ DeleteMidQEntry(struct mid_q_entry *midEntry)
kmem_cache_free
(
cifs_mid_cachep
,
midEntry
);
}
struct
oplock_q_entry
*
AllocOplockQEntry
(
struct
file
*
file
,
struct
cifsTconInfo
*
tcon
)
{
struct
oplock_q_entry
*
temp
;
if
((
file
==
NULL
)
||
(
tcon
==
NULL
))
{
cERROR
(
1
,
(
"Null parms passed to AllocOplockQEntry"
));
return
NULL
;
}
temp
=
(
struct
oplock_q_entry
*
)
kmem_cache_alloc
(
cifs_oplock_cachep
,
SLAB_KERNEL
);
if
(
temp
==
NULL
)
return
temp
;
else
{
temp
->
file_to_flush
=
file
;
temp
->
tcon
=
tcon
;
write_lock
(
&
GlobalMid_Lock
);
list_add_tail
(
&
temp
->
qhead
,
&
GlobalOplock_Q
);
write_unlock
(
&
GlobalMid_Lock
);
}
return
temp
;
}
void
DeleteOplockQEntry
(
struct
oplock_q_entry
*
oplockEntry
)
{
/* BB add spinlock to protect midq for each session BB */
write_lock
(
&
GlobalMid_Lock
);
/* should we check if list empty first? */
list_del
(
&
oplockEntry
->
qhead
);
write_unlock
(
&
GlobalMid_Lock
);
kmem_cache_free
(
cifs_oplock_cachep
,
oplockEntry
);
}
int
smb_send
(
struct
socket
*
ssocket
,
struct
smb_hdr
*
smb_buffer
,
unsigned
int
smb_buf_length
,
struct
sockaddr
*
sin
)
...
...
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