Commit 40efeb4d authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
  [CIFS] Fix endian error comparing authusers when cifsacl enabled
  [CIFS] Rename three structures to avoid camel case
  Fix extended security auth failure
  CIFS: Add rwpidforward mount option
  CIFS: Migrate to shared superblock model
  [CIFS] Migrate from prefixpath logic
  CIFS: Fix memory leak in cifs_do_mount
  [CIFS] When mandatory encryption on share, fail mount
  CIFS: Use pid saved from cifsFileInfo in writepages and set_file_size
  cifs: add cifs_async_writev
  cifs: clean up wsize negotiation and allow for larger wsize
  cifs: convert cifs_writepages to use async writes
  CIFS: Fix undefined behavior when mount fails
  cifs: don't call mid_q_entry->callback under the Global_MidLock (try #5)
  CIFS: Simplify mount code for further shared sb capability
  CIFS: Simplify connection structure search calls
  cifs: remove unused SMB2 config and mount options
  cifs: add ignore_pend flag to cifs_call_async
  cifs: make cifs_send_async take a kvec array
  cifs: consolidate SendReceive response checks
parents 81faae7f 383c5535
...@@ -153,26 +153,6 @@ config CIFS_ACL ...@@ -153,26 +153,6 @@ config CIFS_ACL
Allows to fetch CIFS/NTFS ACL from the server. The DACL blob Allows to fetch CIFS/NTFS ACL from the server. The DACL blob
is handed over to the application/caller. is handed over to the application/caller.
config CIFS_SMB2
bool "SMB2 network file system support (EXPERIMENTAL)"
depends on EXPERIMENTAL && INET && BROKEN
select NLS
select KEYS
select FSCACHE
select DNS_RESOLVER
help
This enables experimental support for the SMB2 (Server Message Block
version 2) protocol. The SMB2 protocol is the successor to the
popular CIFS and SMB network file sharing protocols. SMB2 is the
native file sharing mechanism for recent versions of Windows
operating systems (since Vista). SMB2 enablement will eventually
allow users better performance, security and features, than would be
possible with cifs. Note that smb2 mount options also are simpler
(compared to cifs) due to protocol improvements.
Unless you are a developer or tester, say N.
config CIFS_NFSD_EXPORT config CIFS_NFSD_EXPORT
bool "Allow nfsd to export CIFS file system (EXPERIMENTAL)" bool "Allow nfsd to export CIFS file system (EXPERIMENTAL)"
depends on CIFS && EXPERIMENTAL depends on CIFS && EXPERIMENTAL
......
...@@ -457,6 +457,9 @@ A partial list of the supported mount options follows: ...@@ -457,6 +457,9 @@ A partial list of the supported mount options follows:
otherwise - read from the server. All written data are stored otherwise - read from the server. All written data are stored
in the cache, but if the client doesn't have Exclusive Oplock, in the cache, but if the client doesn't have Exclusive Oplock,
it writes the data to the server. it writes the data to the server.
rwpidforward Forward pid of a process who opened a file to any read or write
operation on that file. This prevent applications like WINE
from failing on read and write if we use mandatory brlock style.
acl Allow setfacl and getfacl to manage posix ACLs if server acl Allow setfacl and getfacl to manage posix ACLs if server
supports them. (default) supports them. (default)
noacl Do not allow setfacl and getfacl calls on this mount noacl Do not allow setfacl and getfacl calls on this mount
......
...@@ -146,7 +146,7 @@ static char *extract_sharename(const char *treename) ...@@ -146,7 +146,7 @@ static char *extract_sharename(const char *treename)
static uint16_t cifs_super_get_key(const void *cookie_netfs_data, void *buffer, static uint16_t cifs_super_get_key(const void *cookie_netfs_data, void *buffer,
uint16_t maxbuf) uint16_t maxbuf)
{ {
const struct cifsTconInfo *tcon = cookie_netfs_data; const struct cifs_tcon *tcon = cookie_netfs_data;
char *sharename; char *sharename;
uint16_t len; uint16_t len;
...@@ -173,7 +173,7 @@ cifs_fscache_super_get_aux(const void *cookie_netfs_data, void *buffer, ...@@ -173,7 +173,7 @@ cifs_fscache_super_get_aux(const void *cookie_netfs_data, void *buffer,
uint16_t maxbuf) uint16_t maxbuf)
{ {
struct cifs_fscache_super_auxdata auxdata; struct cifs_fscache_super_auxdata auxdata;
const struct cifsTconInfo *tcon = cookie_netfs_data; const struct cifs_tcon *tcon = cookie_netfs_data;
memset(&auxdata, 0, sizeof(auxdata)); memset(&auxdata, 0, sizeof(auxdata));
auxdata.resource_id = tcon->resource_id; auxdata.resource_id = tcon->resource_id;
...@@ -192,7 +192,7 @@ fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data, ...@@ -192,7 +192,7 @@ fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data,
uint16_t datalen) uint16_t datalen)
{ {
struct cifs_fscache_super_auxdata auxdata; struct cifs_fscache_super_auxdata auxdata;
const struct cifsTconInfo *tcon = cookie_netfs_data; const struct cifs_tcon *tcon = cookie_netfs_data;
if (datalen != sizeof(auxdata)) if (datalen != sizeof(auxdata))
return FSCACHE_CHECKAUX_OBSOLETE; return FSCACHE_CHECKAUX_OBSOLETE;
......
...@@ -110,8 +110,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) ...@@ -110,8 +110,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
struct list_head *tmp1, *tmp2, *tmp3; struct list_head *tmp1, *tmp2, *tmp3;
struct mid_q_entry *mid_entry; struct mid_q_entry *mid_entry;
struct TCP_Server_Info *server; struct TCP_Server_Info *server;
struct cifsSesInfo *ses; struct cifs_ses *ses;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
int i, j; int i, j;
__u32 dev_type; __u32 dev_type;
...@@ -152,7 +152,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) ...@@ -152,7 +152,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
tcp_ses_list); tcp_ses_list);
i++; i++;
list_for_each(tmp2, &server->smb_ses_list) { list_for_each(tmp2, &server->smb_ses_list) {
ses = list_entry(tmp2, struct cifsSesInfo, ses = list_entry(tmp2, struct cifs_ses,
smb_ses_list); smb_ses_list);
if ((ses->serverDomain == NULL) || if ((ses->serverDomain == NULL) ||
(ses->serverOS == NULL) || (ses->serverOS == NULL) ||
...@@ -171,7 +171,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) ...@@ -171,7 +171,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
seq_printf(m, "TCP status: %d\n\tLocal Users To " seq_printf(m, "TCP status: %d\n\tLocal Users To "
"Server: %d SecMode: 0x%x Req On Wire: %d", "Server: %d SecMode: 0x%x Req On Wire: %d",
server->tcpStatus, server->srv_count, server->tcpStatus, server->srv_count,
server->secMode, server->sec_mode,
atomic_read(&server->inFlight)); atomic_read(&server->inFlight));
#ifdef CONFIG_CIFS_STATS2 #ifdef CONFIG_CIFS_STATS2
...@@ -183,7 +183,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) ...@@ -183,7 +183,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
seq_puts(m, "\n\tShares:"); seq_puts(m, "\n\tShares:");
j = 0; j = 0;
list_for_each(tmp3, &ses->tcon_list) { list_for_each(tmp3, &ses->tcon_list) {
tcon = list_entry(tmp3, struct cifsTconInfo, tcon = list_entry(tmp3, struct cifs_tcon,
tcon_list); tcon_list);
++j; ++j;
dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType); dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
...@@ -256,8 +256,8 @@ static ssize_t cifs_stats_proc_write(struct file *file, ...@@ -256,8 +256,8 @@ static ssize_t cifs_stats_proc_write(struct file *file,
int rc; int rc;
struct list_head *tmp1, *tmp2, *tmp3; struct list_head *tmp1, *tmp2, *tmp3;
struct TCP_Server_Info *server; struct TCP_Server_Info *server;
struct cifsSesInfo *ses; struct cifs_ses *ses;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
rc = get_user(c, buffer); rc = get_user(c, buffer);
if (rc) if (rc)
...@@ -273,11 +273,11 @@ static ssize_t cifs_stats_proc_write(struct file *file, ...@@ -273,11 +273,11 @@ static ssize_t cifs_stats_proc_write(struct file *file,
server = list_entry(tmp1, struct TCP_Server_Info, server = list_entry(tmp1, struct TCP_Server_Info,
tcp_ses_list); tcp_ses_list);
list_for_each(tmp2, &server->smb_ses_list) { list_for_each(tmp2, &server->smb_ses_list) {
ses = list_entry(tmp2, struct cifsSesInfo, ses = list_entry(tmp2, struct cifs_ses,
smb_ses_list); smb_ses_list);
list_for_each(tmp3, &ses->tcon_list) { list_for_each(tmp3, &ses->tcon_list) {
tcon = list_entry(tmp3, tcon = list_entry(tmp3,
struct cifsTconInfo, struct cifs_tcon,
tcon_list); tcon_list);
atomic_set(&tcon->num_smbs_sent, 0); atomic_set(&tcon->num_smbs_sent, 0);
atomic_set(&tcon->num_writes, 0); atomic_set(&tcon->num_writes, 0);
...@@ -312,8 +312,8 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v) ...@@ -312,8 +312,8 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
int i; int i;
struct list_head *tmp1, *tmp2, *tmp3; struct list_head *tmp1, *tmp2, *tmp3;
struct TCP_Server_Info *server; struct TCP_Server_Info *server;
struct cifsSesInfo *ses; struct cifs_ses *ses;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
seq_printf(m, seq_printf(m,
"Resources in use\nCIFS Session: %d\n", "Resources in use\nCIFS Session: %d\n",
...@@ -346,11 +346,11 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v) ...@@ -346,11 +346,11 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
server = list_entry(tmp1, struct TCP_Server_Info, server = list_entry(tmp1, struct TCP_Server_Info,
tcp_ses_list); tcp_ses_list);
list_for_each(tmp2, &server->smb_ses_list) { list_for_each(tmp2, &server->smb_ses_list) {
ses = list_entry(tmp2, struct cifsSesInfo, ses = list_entry(tmp2, struct cifs_ses,
smb_ses_list); smb_ses_list);
list_for_each(tmp3, &ses->tcon_list) { list_for_each(tmp3, &ses->tcon_list) {
tcon = list_entry(tmp3, tcon = list_entry(tmp3,
struct cifsTconInfo, struct cifs_tcon,
tcon_list); tcon_list);
i++; i++;
seq_printf(m, "\n%d) %s", i, tcon->treeName); seq_printf(m, "\n%d) %s", i, tcon->treeName);
......
...@@ -272,7 +272,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt) ...@@ -272,7 +272,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
struct dfs_info3_param *referrals = NULL; struct dfs_info3_param *referrals = NULL;
unsigned int num_referrals = 0; unsigned int num_referrals = 0;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifsSesInfo *ses; struct cifs_ses *ses;
char *full_path; char *full_path;
int xid, i; int xid, i;
int rc; int rc;
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#define CIFS_MOUNT_MF_SYMLINKS 0x10000 /* Minshall+French Symlinks enabled */ #define CIFS_MOUNT_MF_SYMLINKS 0x10000 /* Minshall+French Symlinks enabled */
#define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */ #define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */
#define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */ #define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */
#define CIFS_MOUNT_RWPIDFORWARD 0x80000 /* use pid forwarding for rw */
struct cifs_sb_info { struct cifs_sb_info {
struct rb_root tlink_tree; struct rb_root tlink_tree;
...@@ -56,8 +57,6 @@ struct cifs_sb_info { ...@@ -56,8 +57,6 @@ struct cifs_sb_info {
mode_t mnt_file_mode; mode_t mnt_file_mode;
mode_t mnt_dir_mode; mode_t mnt_dir_mode;
unsigned int mnt_cifs_flags; unsigned int mnt_cifs_flags;
int prepathlen;
char *prepath; /* relative path under the share to mount to */
char *mountdata; /* options received at mount time or via DFS refs */ char *mountdata; /* options received at mount time or via DFS refs */
struct backing_dev_info bdi; struct backing_dev_info bdi;
struct delayed_work prune_tlinks; struct delayed_work prune_tlinks;
......
...@@ -95,7 +95,7 @@ struct key_type cifs_spnego_key_type = { ...@@ -95,7 +95,7 @@ struct key_type cifs_spnego_key_type = {
/* get a key struct with a SPNEGO security blob, suitable for session setup */ /* get a key struct with a SPNEGO security blob, suitable for session setup */
struct key * struct key *
cifs_get_spnego_key(struct cifsSesInfo *sesInfo) cifs_get_spnego_key(struct cifs_ses *sesInfo)
{ {
struct TCP_Server_Info *server = sesInfo->server; struct TCP_Server_Info *server = sesInfo->server;
struct sockaddr_in *sa = (struct sockaddr_in *) &server->dstaddr; struct sockaddr_in *sa = (struct sockaddr_in *) &server->dstaddr;
......
...@@ -41,7 +41,7 @@ struct cifs_spnego_msg { ...@@ -41,7 +41,7 @@ struct cifs_spnego_msg {
#ifdef __KERNEL__ #ifdef __KERNEL__
extern struct key_type cifs_spnego_key_type; extern struct key_type cifs_spnego_key_type;
extern struct key *cifs_get_spnego_key(struct cifsSesInfo *sesInfo); extern struct key *cifs_get_spnego_key(struct cifs_ses *sesInfo);
#endif /* KERNEL */ #endif /* KERNEL */
#endif /* _CIFS_SPNEGO_H */ #endif /* _CIFS_SPNEGO_H */
...@@ -38,7 +38,7 @@ static const struct cifs_sid sid_everyone = { ...@@ -38,7 +38,7 @@ static const struct cifs_sid sid_everyone = {
1, 1, {0, 0, 0, 0, 0, 1}, {0} }; 1, 1, {0, 0, 0, 0, 0, 1}, {0} };
/* security id for Authenticated Users system group */ /* security id for Authenticated Users system group */
static const struct cifs_sid sid_authusers = { static const struct cifs_sid sid_authusers = {
1, 1, {0, 0, 0, 0, 0, 5}, {11} }; 1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
/* group users */ /* group users */
static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
...@@ -458,7 +458,8 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) ...@@ -458,7 +458,8 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
if (num_subauth) { if (num_subauth) {
for (i = 0; i < num_subauth; ++i) { for (i = 0; i < num_subauth; ++i) {
if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) { if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
if (ctsid->sub_auth[i] > cwsid->sub_auth[i]) if (le32_to_cpu(ctsid->sub_auth[i]) >
le32_to_cpu(cwsid->sub_auth[i]))
return 1; return 1;
else else
return -1; return -1;
...@@ -945,7 +946,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, ...@@ -945,7 +946,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
int oplock = 0; int oplock = 0;
int xid, rc; int xid, rc;
__u16 fid; __u16 fid;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink)) if (IS_ERR(tlink))
...@@ -1013,7 +1014,7 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path, ...@@ -1013,7 +1014,7 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
int oplock = 0; int oplock = 0;
int xid, rc; int xid, rc;
__u16 fid; __u16 fid;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink)) if (IS_ERR(tlink))
......
...@@ -229,7 +229,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, ...@@ -229,7 +229,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
} }
/* first calculate 24 bytes ntlm response and then 16 byte session key */ /* first calculate 24 bytes ntlm response and then 16 byte session key */
int setup_ntlm_response(struct cifsSesInfo *ses) int setup_ntlm_response(struct cifs_ses *ses)
{ {
int rc = 0; int rc = 0;
unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE; unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
...@@ -312,7 +312,7 @@ int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt, ...@@ -312,7 +312,7 @@ int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
* Allocate domain name which gets freed when session struct is deallocated. * Allocate domain name which gets freed when session struct is deallocated.
*/ */
static int static int
build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp) build_avpair_blob(struct cifs_ses *ses, const struct nls_table *nls_cp)
{ {
unsigned int dlen; unsigned int dlen;
unsigned int wlen; unsigned int wlen;
...@@ -400,7 +400,7 @@ build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp) ...@@ -400,7 +400,7 @@ build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
* about target string i.e. for some, just user name might suffice. * about target string i.e. for some, just user name might suffice.
*/ */
static int static int
find_domain_name(struct cifsSesInfo *ses, const struct nls_table *nls_cp) find_domain_name(struct cifs_ses *ses, const struct nls_table *nls_cp)
{ {
unsigned int attrsize; unsigned int attrsize;
unsigned int type; unsigned int type;
...@@ -445,7 +445,7 @@ find_domain_name(struct cifsSesInfo *ses, const struct nls_table *nls_cp) ...@@ -445,7 +445,7 @@ find_domain_name(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
return 0; return 0;
} }
static int calc_ntlmv2_hash(struct cifsSesInfo *ses, char *ntlmv2_hash, static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
const struct nls_table *nls_cp) const struct nls_table *nls_cp)
{ {
int rc = 0; int rc = 0;
...@@ -527,7 +527,7 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses, char *ntlmv2_hash, ...@@ -527,7 +527,7 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses, char *ntlmv2_hash,
} }
static int static int
CalcNTLMv2_response(const struct cifsSesInfo *ses, char *ntlmv2_hash) CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
{ {
int rc; int rc;
unsigned int offset = CIFS_SESS_KEY_SIZE + 8; unsigned int offset = CIFS_SESS_KEY_SIZE + 8;
...@@ -563,7 +563,7 @@ CalcNTLMv2_response(const struct cifsSesInfo *ses, char *ntlmv2_hash) ...@@ -563,7 +563,7 @@ CalcNTLMv2_response(const struct cifsSesInfo *ses, char *ntlmv2_hash)
int int
setup_ntlmv2_rsp(struct cifsSesInfo *ses, const struct nls_table *nls_cp) setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
{ {
int rc; int rc;
int baselen; int baselen;
...@@ -649,7 +649,7 @@ setup_ntlmv2_rsp(struct cifsSesInfo *ses, const struct nls_table *nls_cp) ...@@ -649,7 +649,7 @@ setup_ntlmv2_rsp(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
} }
int int
calc_seckey(struct cifsSesInfo *ses) calc_seckey(struct cifs_ses *ses)
{ {
int rc; int rc;
struct crypto_blkcipher *tfm_arc4; struct crypto_blkcipher *tfm_arc4;
......
...@@ -104,46 +104,25 @@ cifs_sb_deactive(struct super_block *sb) ...@@ -104,46 +104,25 @@ cifs_sb_deactive(struct super_block *sb)
} }
static int static int
cifs_read_super(struct super_block *sb, void *data, cifs_read_super(struct super_block *sb, struct smb_vol *volume_info,
const char *devname, int silent) const char *devname, int silent)
{ {
struct inode *inode; struct inode *inode;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
int rc = 0; int rc = 0;
/* BB should we make this contingent on mount parm? */
sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
cifs_sb = CIFS_SB(sb); cifs_sb = CIFS_SB(sb);
if (cifs_sb == NULL)
return -ENOMEM;
spin_lock_init(&cifs_sb->tlink_tree_lock); spin_lock_init(&cifs_sb->tlink_tree_lock);
cifs_sb->tlink_tree = RB_ROOT; cifs_sb->tlink_tree = RB_ROOT;
rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY);
if (rc) { if (rc)
kfree(cifs_sb);
return rc; return rc;
}
cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages;
/* cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages;
* Copy mount params to sb for use in submounts. Better to do
* the copy here and deal with the error before cleanup gets
* complicated post-mount.
*/
if (data) {
cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL);
if (cifs_sb->mountdata == NULL) {
bdi_destroy(&cifs_sb->bdi);
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
return -ENOMEM;
}
}
rc = cifs_mount(sb, cifs_sb, devname); rc = cifs_mount(sb, cifs_sb, volume_info, devname);
if (rc) { if (rc) {
if (!silent) if (!silent)
...@@ -194,15 +173,7 @@ cifs_read_super(struct super_block *sb, void *data, ...@@ -194,15 +173,7 @@ cifs_read_super(struct super_block *sb, void *data,
cifs_umount(sb, cifs_sb); cifs_umount(sb, cifs_sb);
out_mount_failed: out_mount_failed:
if (cifs_sb) { bdi_destroy(&cifs_sb->bdi);
if (cifs_sb->mountdata) {
kfree(cifs_sb->mountdata);
cifs_sb->mountdata = NULL;
}
unload_nls(cifs_sb->local_nls);
bdi_destroy(&cifs_sb->bdi);
kfree(cifs_sb);
}
return rc; return rc;
} }
...@@ -237,7 +208,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) ...@@ -237,7 +208,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
{ {
struct super_block *sb = dentry->d_sb; struct super_block *sb = dentry->d_sb;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
int rc = -EOPNOTSUPP; int rc = -EOPNOTSUPP;
int xid; int xid;
...@@ -390,7 +361,7 @@ static int ...@@ -390,7 +361,7 @@ static int
cifs_show_options(struct seq_file *s, struct vfsmount *m) cifs_show_options(struct seq_file *s, struct vfsmount *m)
{ {
struct cifs_sb_info *cifs_sb = CIFS_SB(m->mnt_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(m->mnt_sb);
struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
struct sockaddr *srcaddr; struct sockaddr *srcaddr;
srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr; srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr;
...@@ -444,14 +415,20 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) ...@@ -444,14 +415,20 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
seq_printf(s, ",nocase"); seq_printf(s, ",nocase");
if (tcon->retry) if (tcon->retry)
seq_printf(s, ",hard"); seq_printf(s, ",hard");
if (cifs_sb->prepath) if (tcon->unix_ext)
seq_printf(s, ",prepath=%s", cifs_sb->prepath); seq_printf(s, ",unix");
else
seq_printf(s, ",nounix");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
seq_printf(s, ",posixpaths"); seq_printf(s, ",posixpaths");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
seq_printf(s, ",setuids"); seq_printf(s, ",setuids");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
seq_printf(s, ",serverino"); seq_printf(s, ",serverino");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
seq_printf(s, ",rwpidforward");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL)
seq_printf(s, ",forcemand");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
seq_printf(s, ",directio"); seq_printf(s, ",directio");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
...@@ -484,7 +461,7 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) ...@@ -484,7 +461,7 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
static void cifs_umount_begin(struct super_block *sb) static void cifs_umount_begin(struct super_block *sb)
{ {
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
if (cifs_sb == NULL) if (cifs_sb == NULL)
return; return;
...@@ -559,29 +536,189 @@ static const struct super_operations cifs_super_ops = { ...@@ -559,29 +536,189 @@ static const struct super_operations cifs_super_ops = {
#endif #endif
}; };
/*
* Get root dentry from superblock according to prefix path mount option.
* Return dentry with refcount + 1 on success and NULL otherwise.
*/
static struct dentry *
cifs_get_root(struct smb_vol *vol, struct super_block *sb)
{
int xid, rc;
struct inode *inode;
struct qstr name;
struct dentry *dparent = NULL, *dchild = NULL, *alias;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
unsigned int i, full_len, len;
char *full_path = NULL, *pstart;
char sep;
full_path = cifs_build_path_to_root(vol, cifs_sb,
cifs_sb_master_tcon(cifs_sb));
if (full_path == NULL)
return NULL;
cFYI(1, "Get root dentry for %s", full_path);
xid = GetXid();
sep = CIFS_DIR_SEP(cifs_sb);
dparent = dget(sb->s_root);
full_len = strlen(full_path);
full_path[full_len] = sep;
pstart = full_path + 1;
for (i = 1, len = 0; i <= full_len; i++) {
if (full_path[i] != sep || !len) {
len++;
continue;
}
full_path[i] = 0;
cFYI(1, "get dentry for %s", pstart);
name.name = pstart;
name.len = len;
name.hash = full_name_hash(pstart, len);
dchild = d_lookup(dparent, &name);
if (dchild == NULL) {
cFYI(1, "not exists");
dchild = d_alloc(dparent, &name);
if (dchild == NULL) {
dput(dparent);
dparent = NULL;
goto out;
}
}
cFYI(1, "get inode");
if (dchild->d_inode == NULL) {
cFYI(1, "not exists");
inode = NULL;
if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
rc = cifs_get_inode_info_unix(&inode, full_path,
sb, xid);
else
rc = cifs_get_inode_info(&inode, full_path,
NULL, sb, xid, NULL);
if (rc) {
dput(dchild);
dput(dparent);
dparent = NULL;
goto out;
}
alias = d_materialise_unique(dchild, inode);
if (alias != NULL) {
dput(dchild);
if (IS_ERR(alias)) {
dput(dparent);
dparent = NULL;
goto out;
}
dchild = alias;
}
}
cFYI(1, "parent %p, child %p", dparent, dchild);
dput(dparent);
dparent = dchild;
len = 0;
pstart = full_path + i + 1;
full_path[i] = sep;
}
out:
_FreeXid(xid);
kfree(full_path);
return dparent;
}
static struct dentry * static struct dentry *
cifs_do_mount(struct file_system_type *fs_type, cifs_do_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data) int flags, const char *dev_name, void *data)
{ {
int rc; int rc;
struct super_block *sb; struct super_block *sb;
struct cifs_sb_info *cifs_sb;
sb = sget(fs_type, NULL, set_anon_super, NULL); struct smb_vol *volume_info;
struct cifs_mnt_data mnt_data;
struct dentry *root;
cFYI(1, "Devname: %s flags: %d ", dev_name, flags); cFYI(1, "Devname: %s flags: %d ", dev_name, flags);
if (IS_ERR(sb)) rc = cifs_setup_volume_info(&volume_info, (char *)data, dev_name);
return ERR_CAST(sb); if (rc)
return ERR_PTR(rc);
cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
if (cifs_sb == NULL) {
root = ERR_PTR(-ENOMEM);
goto out;
}
cifs_setup_cifs_sb(volume_info, cifs_sb);
mnt_data.vol = volume_info;
mnt_data.cifs_sb = cifs_sb;
mnt_data.flags = flags;
sb = sget(fs_type, cifs_match_super, set_anon_super, &mnt_data);
if (IS_ERR(sb)) {
root = ERR_CAST(sb);
goto out_cifs_sb;
}
if (sb->s_fs_info) {
cFYI(1, "Use existing superblock");
goto out_shared;
}
/*
* Copy mount params for use in submounts. Better to do
* the copy here and deal with the error before cleanup gets
* complicated post-mount.
*/
cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL);
if (cifs_sb->mountdata == NULL) {
root = ERR_PTR(-ENOMEM);
goto out_super;
}
sb->s_flags = flags; sb->s_flags = flags;
/* BB should we make this contingent on mount parm? */
sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
sb->s_fs_info = cifs_sb;
rc = cifs_read_super(sb, data, dev_name, flags & MS_SILENT ? 1 : 0); rc = cifs_read_super(sb, volume_info, dev_name,
flags & MS_SILENT ? 1 : 0);
if (rc) { if (rc) {
deactivate_locked_super(sb); root = ERR_PTR(rc);
return ERR_PTR(rc); goto out_super;
} }
sb->s_flags |= MS_ACTIVE; sb->s_flags |= MS_ACTIVE;
return dget(sb->s_root);
root = cifs_get_root(volume_info, sb);
if (root == NULL)
goto out_super;
cFYI(1, "dentry root is: %p", root);
goto out;
out_shared:
root = cifs_get_root(volume_info, sb);
if (root)
cFYI(1, "dentry root is: %p", root);
goto out;
out_super:
kfree(cifs_sb->mountdata);
deactivate_locked_super(sb);
out_cifs_sb:
unload_nls(cifs_sb->local_nls);
kfree(cifs_sb);
out:
cifs_cleanup_volume_info(&volume_info);
return root;
} }
static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
......
...@@ -155,6 +155,81 @@ struct cifs_cred { ...@@ -155,6 +155,81 @@ struct cifs_cred {
***************************************************************** *****************************************************************
*/ */
struct smb_vol {
char *username;
char *password;
char *domainname;
char *UNC;
char *UNCip;
char *iocharset; /* local code page for mapping to and from Unicode */
char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
uid_t cred_uid;
uid_t linux_uid;
gid_t linux_gid;
mode_t file_mode;
mode_t dir_mode;
unsigned secFlg;
bool retry:1;
bool intr:1;
bool setuids:1;
bool override_uid:1;
bool override_gid:1;
bool dynperm:1;
bool noperm:1;
bool no_psx_acl:1; /* set if posix acl support should be disabled */
bool cifs_acl:1;
bool no_xattr:1; /* set if xattr (EA) support should be disabled*/
bool server_ino:1; /* use inode numbers from server ie UniqueId */
bool direct_io:1;
bool strict_io:1; /* strict cache behavior */
bool remap:1; /* set to remap seven reserved chars in filenames */
bool posix_paths:1; /* unset to not ask for posix pathnames. */
bool no_linux_ext:1;
bool sfu_emul:1;
bool nullauth:1; /* attempt to authenticate with null user */
bool nocase:1; /* request case insensitive filenames */
bool nobrl:1; /* disable sending byte range locks to srv */
bool mand_lock:1; /* send mandatory not posix byte range lock reqs */
bool seal:1; /* request transport encryption on share */
bool nodfs:1; /* Do not request DFS, even if available */
bool local_lease:1; /* check leases only on local system, not remote */
bool noblocksnd:1;
bool noautotune:1;
bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
bool fsc:1; /* enable fscache */
bool mfsymlinks:1; /* use Minshall+French Symlinks */
bool multiuser:1;
bool rwpidforward:1; /* pid forward for read/write operations */
unsigned int rsize;
unsigned int wsize;
bool sockopt_tcp_nodelay:1;
unsigned short int port;
unsigned long actimeo; /* attribute cache timeout (jiffies) */
char *prepath;
struct sockaddr_storage srcaddr; /* allow binding to a local IP */
struct nls_table *local_nls;
};
#define CIFS_MOUNT_MASK (CIFS_MOUNT_NO_PERM | CIFS_MOUNT_SET_UID | \
CIFS_MOUNT_SERVER_INUM | CIFS_MOUNT_DIRECT_IO | \
CIFS_MOUNT_NO_XATTR | CIFS_MOUNT_MAP_SPECIAL_CHR | \
CIFS_MOUNT_UNX_EMUL | CIFS_MOUNT_NO_BRL | \
CIFS_MOUNT_CIFS_ACL | CIFS_MOUNT_OVERR_UID | \
CIFS_MOUNT_OVERR_GID | CIFS_MOUNT_DYNPERM | \
CIFS_MOUNT_NOPOSIXBRL | CIFS_MOUNT_NOSSYNC | \
CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \
CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO)
#define CIFS_MS_MASK (MS_RDONLY | MS_MANDLOCK | MS_NOEXEC | MS_NOSUID | \
MS_NODEV | MS_SYNCHRONOUS)
struct cifs_mnt_data {
struct cifs_sb_info *cifs_sb;
struct smb_vol *vol;
int flags;
};
struct TCP_Server_Info { struct TCP_Server_Info {
struct list_head tcp_ses_list; struct list_head tcp_ses_list;
struct list_head smb_ses_list; struct list_head smb_ses_list;
...@@ -179,7 +254,7 @@ struct TCP_Server_Info { ...@@ -179,7 +254,7 @@ struct TCP_Server_Info {
struct mutex srv_mutex; struct mutex srv_mutex;
struct task_struct *tsk; struct task_struct *tsk;
char server_GUID[16]; char server_GUID[16];
char secMode; char sec_mode;
bool session_estab; /* mark when very first sess is established */ bool session_estab; /* mark when very first sess is established */
u16 dialect; /* dialect index that server chose */ u16 dialect; /* dialect index that server chose */
enum securityEnum secType; enum securityEnum secType;
...@@ -254,7 +329,7 @@ static inline void cifs_set_net_ns(struct TCP_Server_Info *srv, struct net *net) ...@@ -254,7 +329,7 @@ static inline void cifs_set_net_ns(struct TCP_Server_Info *srv, struct net *net)
/* /*
* Session structure. One of these for each uid session with a particular host * Session structure. One of these for each uid session with a particular host
*/ */
struct cifsSesInfo { struct cifs_ses {
struct list_head smb_ses_list; struct list_head smb_ses_list;
struct list_head tcon_list; struct list_head tcon_list;
struct mutex session_mutex; struct mutex session_mutex;
...@@ -294,11 +369,11 @@ struct cifsSesInfo { ...@@ -294,11 +369,11 @@ struct cifsSesInfo {
* there is one of these for each connection to a resource on a particular * there is one of these for each connection to a resource on a particular
* session * session
*/ */
struct cifsTconInfo { struct cifs_tcon {
struct list_head tcon_list; struct list_head tcon_list;
int tc_count; int tc_count;
struct list_head openFileList; struct list_head openFileList;
struct cifsSesInfo *ses; /* pointer to session associated with */ struct cifs_ses *ses; /* pointer to session associated with */
char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */ char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */
char *nativeFileSystem; char *nativeFileSystem;
char *password; /* for share-level security */ char *password; /* for share-level security */
...@@ -380,12 +455,12 @@ struct tcon_link { ...@@ -380,12 +455,12 @@ struct tcon_link {
#define TCON_LINK_IN_TREE 2 #define TCON_LINK_IN_TREE 2
unsigned long tl_time; unsigned long tl_time;
atomic_t tl_count; atomic_t tl_count;
struct cifsTconInfo *tl_tcon; struct cifs_tcon *tl_tcon;
}; };
extern struct tcon_link *cifs_sb_tlink(struct cifs_sb_info *cifs_sb); extern struct tcon_link *cifs_sb_tlink(struct cifs_sb_info *cifs_sb);
static inline struct cifsTconInfo * static inline struct cifs_tcon *
tlink_tcon(struct tcon_link *tlink) tlink_tcon(struct tcon_link *tlink)
{ {
return tlink->tl_tcon; return tlink->tl_tcon;
...@@ -402,7 +477,7 @@ cifs_get_tlink(struct tcon_link *tlink) ...@@ -402,7 +477,7 @@ cifs_get_tlink(struct tcon_link *tlink)
} }
/* This function is always expected to succeed */ /* This function is always expected to succeed */
extern struct cifsTconInfo *cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb); extern struct cifs_tcon *cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb);
/* /*
* This info hangs off the cifsFileInfo structure, pointed to by llist. * This info hangs off the cifsFileInfo structure, pointed to by llist.
...@@ -455,6 +530,14 @@ struct cifsFileInfo { ...@@ -455,6 +530,14 @@ struct cifsFileInfo {
struct work_struct oplock_break; /* work for oplock breaks */ struct work_struct oplock_break; /* work for oplock breaks */
}; };
struct cifs_io_parms {
__u16 netfid;
__u32 pid;
__u64 offset;
unsigned int length;
struct cifs_tcon *tcon;
};
/* /*
* Take a reference on the file private data. Must be called with * Take a reference on the file private data. Must be called with
* cifs_file_list_lock held. * cifs_file_list_lock held.
...@@ -509,10 +592,30 @@ static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb) ...@@ -509,10 +592,30 @@ static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb)
return '\\'; return '\\';
} }
static inline void
convert_delimiter(char *path, char delim)
{
int i;
char old_delim;
if (path == NULL)
return;
if (delim == '/')
old_delim = '\\';
else
old_delim = '/';
for (i = 0; path[i] != '\0'; i++) {
if (path[i] == old_delim)
path[i] = delim;
}
}
#ifdef CONFIG_CIFS_STATS #ifdef CONFIG_CIFS_STATS
#define cifs_stats_inc atomic_inc #define cifs_stats_inc atomic_inc
static inline void cifs_stats_bytes_written(struct cifsTconInfo *tcon, static inline void cifs_stats_bytes_written(struct cifs_tcon *tcon,
unsigned int bytes) unsigned int bytes)
{ {
if (bytes) { if (bytes) {
...@@ -522,7 +625,7 @@ static inline void cifs_stats_bytes_written(struct cifsTconInfo *tcon, ...@@ -522,7 +625,7 @@ static inline void cifs_stats_bytes_written(struct cifsTconInfo *tcon,
} }
} }
static inline void cifs_stats_bytes_read(struct cifsTconInfo *tcon, static inline void cifs_stats_bytes_read(struct cifs_tcon *tcon,
unsigned int bytes) unsigned int bytes)
{ {
spin_lock(&tcon->stat_lock); spin_lock(&tcon->stat_lock);
...@@ -543,9 +646,8 @@ struct mid_q_entry; ...@@ -543,9 +646,8 @@ struct mid_q_entry;
* This is the prototype for the mid callback function. When creating one, * This is the prototype for the mid callback function. When creating one,
* take special care to avoid deadlocks. Things to bear in mind: * take special care to avoid deadlocks. Things to bear in mind:
* *
* - it will be called by cifsd * - it will be called by cifsd, with no locks held
* - the GlobalMid_Lock will be held * - the mid will be removed from any lists
* - the mid will be removed from the pending_mid_q list
*/ */
typedef void (mid_callback_t)(struct mid_q_entry *mid); typedef void (mid_callback_t)(struct mid_q_entry *mid);
...@@ -573,7 +675,7 @@ struct mid_q_entry { ...@@ -573,7 +675,7 @@ struct mid_q_entry {
struct oplock_q_entry { struct oplock_q_entry {
struct list_head qhead; struct list_head qhead;
struct inode *pinode; struct inode *pinode;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
__u16 netfid; __u16 netfid;
}; };
...@@ -656,6 +758,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param, ...@@ -656,6 +758,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
#define MID_RESPONSE_RECEIVED 4 #define MID_RESPONSE_RECEIVED 4
#define MID_RETRY_NEEDED 8 /* session closed while this request out */ #define MID_RETRY_NEEDED 8 /* session closed while this request out */
#define MID_RESPONSE_MALFORMED 0x10 #define MID_RESPONSE_MALFORMED 0x10
#define MID_SHUTDOWN 0x20
/* Types of response buffer returned from SendReceive2 */ /* Types of response buffer returned from SendReceive2 */
#define CIFS_NO_BUFFER 0 /* Response buffer not returned */ #define CIFS_NO_BUFFER 0 /* Response buffer not returned */
......
...@@ -57,8 +57,9 @@ extern int init_cifs_idmap(void); ...@@ -57,8 +57,9 @@ extern int init_cifs_idmap(void);
extern void exit_cifs_idmap(void); extern void exit_cifs_idmap(void);
extern void cifs_destroy_idmaptrees(void); extern void cifs_destroy_idmaptrees(void);
extern char *build_path_from_dentry(struct dentry *); extern char *build_path_from_dentry(struct dentry *);
extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb, extern char *cifs_build_path_to_root(struct smb_vol *vol,
struct cifsTconInfo *tcon); struct cifs_sb_info *cifs_sb,
struct cifs_tcon *tcon);
extern char *build_wildcard_path_from_dentry(struct dentry *direntry); extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
extern char *cifs_compose_mount_options(const char *sb_mountdata, extern char *cifs_compose_mount_options(const char *sb_mountdata,
const char *fullpath, const struct dfs_info3_param *ref, const char *fullpath, const struct dfs_info3_param *ref,
...@@ -67,20 +68,22 @@ extern char *cifs_compose_mount_options(const char *sb_mountdata, ...@@ -67,20 +68,22 @@ extern char *cifs_compose_mount_options(const char *sb_mountdata,
extern struct mid_q_entry *AllocMidQEntry(const struct smb_hdr *smb_buffer, extern struct mid_q_entry *AllocMidQEntry(const struct smb_hdr *smb_buffer,
struct TCP_Server_Info *server); struct TCP_Server_Info *server);
extern void DeleteMidQEntry(struct mid_q_entry *midEntry); extern void DeleteMidQEntry(struct mid_q_entry *midEntry);
extern int cifs_call_async(struct TCP_Server_Info *server, extern int cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov,
struct smb_hdr *in_buf, mid_callback_t *callback, unsigned int nvec, mid_callback_t *callback,
void *cbdata); void *cbdata, bool ignore_pend);
extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, extern int SendReceive(const unsigned int /* xid */ , struct cifs_ses *,
struct smb_hdr * /* input */ , struct smb_hdr * /* input */ ,
struct smb_hdr * /* out */ , struct smb_hdr * /* out */ ,
int * /* bytes returned */ , const int long_op); int * /* bytes returned */ , const int long_op);
extern int SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses, extern int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
struct smb_hdr *in_buf, int flags); struct smb_hdr *in_buf, int flags);
extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, extern int cifs_check_receive(struct mid_q_entry *mid,
struct TCP_Server_Info *server, bool log_error);
extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *,
struct kvec *, int /* nvec to send */, struct kvec *, int /* nvec to send */,
int * /* type of buf returned */ , const int flags); int * /* type of buf returned */ , const int flags);
extern int SendReceiveBlockingLock(const unsigned int xid, extern int SendReceiveBlockingLock(const unsigned int xid,
struct cifsTconInfo *ptcon, struct cifs_tcon *ptcon,
struct smb_hdr *in_buf , struct smb_hdr *in_buf ,
struct smb_hdr *out_buf, struct smb_hdr *out_buf,
int *bytes_returned); int *bytes_returned);
...@@ -99,14 +102,14 @@ extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len); ...@@ -99,14 +102,14 @@ extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
extern int cifs_set_port(struct sockaddr *addr, const unsigned short int port); extern int cifs_set_port(struct sockaddr *addr, const unsigned short int port);
extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len, extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len,
const unsigned short int port); const unsigned short int port);
extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr); extern int map_smb_to_linux_error(struct smb_hdr *smb, bool logErr);
extern void header_assemble(struct smb_hdr *, char /* command */ , extern void header_assemble(struct smb_hdr *, char /* command */ ,
const struct cifsTconInfo *, int /* length of const struct cifs_tcon *, int /* length of
fixed section (word count) in two byte units */); fixed section (word count) in two byte units */);
extern int small_smb_init_no_tc(const int smb_cmd, const int wct, extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
struct cifsSesInfo *ses, struct cifs_ses *ses,
void **request_buf); void **request_buf);
extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, extern int CIFS_SessSetup(unsigned int xid, struct cifs_ses *ses,
const struct nls_table *nls_cp); const struct nls_table *nls_cp);
extern __u16 GetNextMid(struct TCP_Server_Info *server); extern __u16 GetNextMid(struct TCP_Server_Info *server);
extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
...@@ -148,102 +151,108 @@ extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *, ...@@ -148,102 +151,108 @@ extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *,
extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *, extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *,
const char *); const char *);
extern void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
struct cifs_sb_info *cifs_sb);
extern int cifs_match_super(struct super_block *, void *);
extern void cifs_cleanup_volume_info(struct smb_vol **pvolume_info);
extern int cifs_setup_volume_info(struct smb_vol **pvolume_info,
char *mount_data, const char *devname);
extern int cifs_mount(struct super_block *, struct cifs_sb_info *, extern int cifs_mount(struct super_block *, struct cifs_sb_info *,
const char *); struct smb_vol *, const char *);
extern int cifs_umount(struct super_block *, struct cifs_sb_info *); extern int cifs_umount(struct super_block *, struct cifs_sb_info *);
extern void cifs_dfs_release_automount_timer(void); extern void cifs_dfs_release_automount_timer(void);
void cifs_proc_init(void); void cifs_proc_init(void);
void cifs_proc_clean(void); void cifs_proc_clean(void);
extern int cifs_negotiate_protocol(unsigned int xid, extern int cifs_negotiate_protocol(unsigned int xid,
struct cifsSesInfo *ses); struct cifs_ses *ses);
extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses, extern int cifs_setup_session(unsigned int xid, struct cifs_ses *ses,
struct nls_table *nls_info); struct nls_table *nls_info);
extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses); extern int CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses);
extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, extern int CIFSTCon(unsigned int xid, struct cifs_ses *ses,
const char *tree, struct cifsTconInfo *tcon, const char *tree, struct cifs_tcon *tcon,
const struct nls_table *); const struct nls_table *);
extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, extern int CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
const char *searchName, const struct nls_table *nls_codepage, const char *searchName, const struct nls_table *nls_codepage,
__u16 *searchHandle, struct cifs_search_info *psrch_inf, __u16 *searchHandle, struct cifs_search_info *psrch_inf,
int map, const char dirsep); int map, const char dirsep);
extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, extern int CIFSFindNext(const int xid, struct cifs_tcon *tcon,
__u16 searchHandle, struct cifs_search_info *psrch_inf); __u16 searchHandle, struct cifs_search_info *psrch_inf);
extern int CIFSFindClose(const int, struct cifsTconInfo *tcon, extern int CIFSFindClose(const int, struct cifs_tcon *tcon,
const __u16 search_handle); const __u16 search_handle);
extern int CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBQFileInfo(const int xid, struct cifs_tcon *tcon,
u16 netfid, FILE_ALL_INFO *pFindData); u16 netfid, FILE_ALL_INFO *pFindData);
extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBQPathInfo(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, const unsigned char *searchName,
FILE_ALL_INFO *findData, FILE_ALL_INFO *findData,
int legacy /* whether to use old info level */, int legacy /* whether to use old info level */,
const struct nls_table *nls_codepage, int remap); const struct nls_table *nls_codepage, int remap);
extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, extern int SMBQueryInformation(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, const unsigned char *searchName,
FILE_ALL_INFO *findData, FILE_ALL_INFO *findData,
const struct nls_table *nls_codepage, int remap); const struct nls_table *nls_codepage, int remap);
extern int CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBUnixQFileInfo(const int xid, struct cifs_tcon *tcon,
u16 netfid, FILE_UNIX_BASIC_INFO *pFindData); u16 netfid, FILE_UNIX_BASIC_INFO *pFindData);
extern int CIFSSMBUnixQPathInfo(const int xid, extern int CIFSSMBUnixQPathInfo(const int xid,
struct cifsTconInfo *tcon, struct cifs_tcon *tcon,
const unsigned char *searchName, const unsigned char *searchName,
FILE_UNIX_BASIC_INFO *pFindData, FILE_UNIX_BASIC_INFO *pFindData,
const struct nls_table *nls_codepage, int remap); const struct nls_table *nls_codepage, int remap);
extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, extern int CIFSGetDFSRefer(const int xid, struct cifs_ses *ses,
const unsigned char *searchName, const unsigned char *searchName,
struct dfs_info3_param **target_nodes, struct dfs_info3_param **target_nodes,
unsigned int *number_of_nodes_in_array, unsigned int *number_of_nodes_in_array,
const struct nls_table *nls_codepage, int remap); const struct nls_table *nls_codepage, int remap);
extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, extern int get_dfs_path(int xid, struct cifs_ses *pSesInfo,
const char *old_path, const char *old_path,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
unsigned int *pnum_referrals, unsigned int *pnum_referrals,
struct dfs_info3_param **preferrals, struct dfs_info3_param **preferrals,
int remap); int remap);
extern void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, extern void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon,
struct super_block *sb, struct smb_vol *vol); struct super_block *sb, struct smb_vol *vol);
extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon,
struct kstatfs *FSData); struct kstatfs *FSData);
extern int SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, extern int SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon,
struct kstatfs *FSData); struct kstatfs *FSData);
extern int CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBSetFSUnixInfo(const int xid, struct cifs_tcon *tcon,
__u64 cap); __u64 cap);
extern int CIFSSMBQFSAttributeInfo(const int xid, extern int CIFSSMBQFSAttributeInfo(const int xid,
struct cifsTconInfo *tcon); struct cifs_tcon *tcon);
extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon); extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon);
extern int CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon); extern int CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon);
extern int CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
struct kstatfs *FSData); struct kstatfs *FSData);
extern int CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBSetPathInfo(const int xid, struct cifs_tcon *tcon,
const char *fileName, const FILE_BASIC_INFO *data, const char *fileName, const FILE_BASIC_INFO *data,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
int remap_special_chars); int remap_special_chars);
extern int CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
const FILE_BASIC_INFO *data, __u16 fid, const FILE_BASIC_INFO *data, __u16 fid,
__u32 pid_of_opener); __u32 pid_of_opener);
extern int CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon,
bool delete_file, __u16 fid, __u32 pid_of_opener); bool delete_file, __u16 fid, __u32 pid_of_opener);
#if 0 #if 0
extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, extern int CIFSSMBSetAttrLegacy(int xid, struct cifs_tcon *tcon,
char *fileName, __u16 dos_attributes, char *fileName, __u16 dos_attributes,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
#endif /* possibly unneeded function */ #endif /* possibly unneeded function */
extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBSetEOF(const int xid, struct cifs_tcon *tcon,
const char *fileName, __u64 size, const char *fileName, __u64 size,
bool setAllocationSizeFlag, bool setAllocationSizeFlag,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
int remap_special_chars); int remap_special_chars);
extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon,
__u64 size, __u16 fileHandle, __u32 opener_pid, __u64 size, __u16 fileHandle, __u32 opener_pid,
bool AllocSizeFlag); bool AllocSizeFlag);
...@@ -257,120 +266,116 @@ struct cifs_unix_set_info_args { ...@@ -257,120 +266,116 @@ struct cifs_unix_set_info_args {
dev_t device; dev_t device;
}; };
extern int CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
const struct cifs_unix_set_info_args *args, const struct cifs_unix_set_info_args *args,
u16 fid, u32 pid_of_opener); u16 fid, u32 pid_of_opener);
extern int CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *pTcon, extern int CIFSSMBUnixSetPathInfo(const int xid, struct cifs_tcon *pTcon,
char *fileName, char *fileName,
const struct cifs_unix_set_info_args *args, const struct cifs_unix_set_info_args *args,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
int remap_special_chars); int remap_special_chars);
extern int CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBMkDir(const int xid, struct cifs_tcon *tcon,
const char *newName, const char *newName,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
int remap_special_chars); int remap_special_chars);
extern int CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBRmDir(const int xid, struct cifs_tcon *tcon,
const char *name, const struct nls_table *nls_codepage, const char *name, const struct nls_table *nls_codepage,
int remap_special_chars); int remap_special_chars);
extern int CIFSPOSIXDelFile(const int xid, struct cifsTconInfo *tcon, extern int CIFSPOSIXDelFile(const int xid, struct cifs_tcon *tcon,
const char *name, __u16 type, const char *name, __u16 type,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
int remap_special_chars); int remap_special_chars);
extern int CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBDelFile(const int xid, struct cifs_tcon *tcon,
const char *name, const char *name,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
int remap_special_chars); int remap_special_chars);
extern int CIFSSMBRename(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBRename(const int xid, struct cifs_tcon *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
int remap_special_chars); int remap_special_chars);
extern int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon, extern int CIFSSMBRenameOpenFile(const int xid, struct cifs_tcon *pTcon,
int netfid, const char *target_name, int netfid, const char *target_name,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
int remap_special_chars); int remap_special_chars);
extern int CIFSCreateHardLink(const int xid, extern int CIFSCreateHardLink(const int xid,
struct cifsTconInfo *tcon, struct cifs_tcon *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
int remap_special_chars); int remap_special_chars);
extern int CIFSUnixCreateHardLink(const int xid, extern int CIFSUnixCreateHardLink(const int xid,
struct cifsTconInfo *tcon, struct cifs_tcon *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
int remap_special_chars); int remap_special_chars);
extern int CIFSUnixCreateSymLink(const int xid, extern int CIFSUnixCreateSymLink(const int xid,
struct cifsTconInfo *tcon, struct cifs_tcon *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBUnixQuerySymLink(const int xid, extern int CIFSSMBUnixQuerySymLink(const int xid,
struct cifsTconInfo *tcon, struct cifs_tcon *tcon,
const unsigned char *searchName, char **syminfo, const unsigned char *searchName, char **syminfo,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
#ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL #ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
extern int CIFSSMBQueryReparseLinkInfo(const int xid, extern int CIFSSMBQueryReparseLinkInfo(const int xid,
struct cifsTconInfo *tcon, struct cifs_tcon *tcon,
const unsigned char *searchName, const unsigned char *searchName,
char *symlinkinfo, const int buflen, __u16 fid, char *symlinkinfo, const int buflen, __u16 fid,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
#endif /* temporarily unused until cifs_symlink fixed */ #endif /* temporarily unused until cifs_symlink fixed */
extern int CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBOpen(const int xid, struct cifs_tcon *tcon,
const char *fileName, const int disposition, const char *fileName, const int disposition,
const int access_flags, const int omode, const int access_flags, const int omode,
__u16 *netfid, int *pOplock, FILE_ALL_INFO *, __u16 *netfid, int *pOplock, FILE_ALL_INFO *,
const struct nls_table *nls_codepage, int remap); const struct nls_table *nls_codepage, int remap);
extern int SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, extern int SMBLegacyOpen(const int xid, struct cifs_tcon *tcon,
const char *fileName, const int disposition, const char *fileName, const int disposition,
const int access_flags, const int omode, const int access_flags, const int omode,
__u16 *netfid, int *pOplock, FILE_ALL_INFO *, __u16 *netfid, int *pOplock, FILE_ALL_INFO *,
const struct nls_table *nls_codepage, int remap); const struct nls_table *nls_codepage, int remap);
extern int CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, extern int CIFSPOSIXCreate(const int xid, struct cifs_tcon *tcon,
u32 posix_flags, __u64 mode, __u16 *netfid, u32 posix_flags, __u64 mode, __u16 *netfid,
FILE_UNIX_BASIC_INFO *pRetData, FILE_UNIX_BASIC_INFO *pRetData,
__u32 *pOplock, const char *name, __u32 *pOplock, const char *name,
const struct nls_table *nls_codepage, int remap); const struct nls_table *nls_codepage, int remap);
extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBClose(const int xid, struct cifs_tcon *tcon,
const int smb_file_id); const int smb_file_id);
extern int CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBFlush(const int xid, struct cifs_tcon *tcon,
const int smb_file_id); const int smb_file_id);
extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms,
const int netfid, unsigned int count, unsigned int *nbytes, char **buf,
const __u64 lseek, unsigned int *nbytes, char **buf,
int *return_buf_type); int *return_buf_type);
extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
const int netfid, const unsigned int count, unsigned int *nbytes, const char *buf,
const __u64 lseek, unsigned int *nbytes, const char __user *ubuf, const int long_op);
const char *buf, const char __user *ubuf, extern int CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
unsigned int *nbytes, struct kvec *iov, const int nvec,
const int long_op); const int long_op);
extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, extern int CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
const int netfid, const unsigned int count,
const __u64 offset, unsigned int *nbytes,
struct kvec *iov, const int nvec, const int long_op);
extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName, __u64 *inode_number, const unsigned char *searchName, __u64 *inode_number,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
int remap_special_chars); int remap_special_chars);
extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
const __u16 netfid, const __u64 len, const __u16 netfid, const __u64 len,
const __u64 offset, const __u32 numUnlock, const __u64 offset, const __u32 numUnlock,
const __u32 numLock, const __u8 lockType, const __u32 numLock, const __u8 lockType,
const bool waitFlag, const __u8 oplock_level); const bool waitFlag, const __u8 oplock_level);
extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon,
const __u16 smb_file_id, const int get_flag, const __u16 smb_file_id, const int get_flag,
const __u64 len, struct file_lock *, const __u64 len, struct file_lock *,
const __u16 lock_type, const bool waitFlag); const __u16 lock_type, const bool waitFlag);
extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); extern int CIFSSMBTDis(const int xid, struct cifs_tcon *tcon);
extern int CIFSSMBEcho(struct TCP_Server_Info *server); extern int CIFSSMBEcho(struct TCP_Server_Info *server);
extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses); extern int CIFSSMBLogoff(const int xid, struct cifs_ses *ses);
extern struct cifsSesInfo *sesInfoAlloc(void); extern struct cifs_ses *sesInfoAlloc(void);
extern void sesInfoFree(struct cifsSesInfo *); extern void sesInfoFree(struct cifs_ses *);
extern struct cifsTconInfo *tconInfoAlloc(void); extern struct cifs_tcon *tconInfoAlloc(void);
extern void tconInfoFree(struct cifsTconInfo *); extern void tconInfoFree(struct cifs_tcon *);
extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *); extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
...@@ -379,51 +384,51 @@ extern int cifs_verify_signature(struct smb_hdr *, ...@@ -379,51 +384,51 @@ extern int cifs_verify_signature(struct smb_hdr *,
struct TCP_Server_Info *server, struct TCP_Server_Info *server,
__u32 expected_sequence_number); __u32 expected_sequence_number);
extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *); extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *);
extern int setup_ntlm_response(struct cifsSesInfo *); extern int setup_ntlm_response(struct cifs_ses *);
extern int setup_ntlmv2_rsp(struct cifsSesInfo *, const struct nls_table *); extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *);
extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *);
extern void cifs_crypto_shash_release(struct TCP_Server_Info *); extern void cifs_crypto_shash_release(struct TCP_Server_Info *);
extern int calc_seckey(struct cifsSesInfo *); extern int calc_seckey(struct cifs_ses *);
#ifdef CONFIG_CIFS_WEAK_PW_HASH #ifdef CONFIG_CIFS_WEAK_PW_HASH
extern int calc_lanman_hash(const char *password, const char *cryptkey, extern int calc_lanman_hash(const char *password, const char *cryptkey,
bool encrypt, char *lnm_session_key); bool encrypt, char *lnm_session_key);
#endif /* CIFS_WEAK_PW_HASH */ #endif /* CIFS_WEAK_PW_HASH */
#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */ #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBNotify(const int xid, struct cifs_tcon *tcon,
const int notify_subdirs, const __u16 netfid, const int notify_subdirs, const __u16 netfid,
__u32 filter, struct file *file, int multishot, __u32 filter, struct file *file, int multishot,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */ #endif /* was needed for dnotify, and will be needed for inotify when VFS fix */
extern int CIFSSMBCopy(int xid, extern int CIFSSMBCopy(int xid,
struct cifsTconInfo *source_tcon, struct cifs_tcon *source_tcon,
const char *fromName, const char *fromName,
const __u16 target_tid, const __u16 target_tid,
const char *toName, const int flags, const char *toName, const int flags,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
int remap_special_chars); int remap_special_chars);
extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, const unsigned char *searchName,
const unsigned char *ea_name, char *EAData, const unsigned char *ea_name, char *EAData,
size_t bufsize, const struct nls_table *nls_codepage, size_t bufsize, const struct nls_table *nls_codepage,
int remap_special_chars); int remap_special_chars);
extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBSetEA(const int xid, struct cifs_tcon *tcon,
const char *fileName, const char *ea_name, const char *fileName, const char *ea_name,
const void *ea_value, const __u16 ea_value_len, const void *ea_value, const __u16 ea_value_len,
const struct nls_table *nls_codepage, int remap_special_chars); const struct nls_table *nls_codepage, int remap_special_chars);
extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBGetCIFSACL(const int xid, struct cifs_tcon *tcon,
__u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen); __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen);
extern int CIFSSMBSetCIFSACL(const int, struct cifsTconInfo *, __u16, extern int CIFSSMBSetCIFSACL(const int, struct cifs_tcon *, __u16,
struct cifs_ntsd *, __u32); struct cifs_ntsd *, __u32);
extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBGetPosixACL(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, const unsigned char *searchName,
char *acl_inf, const int buflen, const int acl_type, char *acl_inf, const int buflen, const int acl_type,
const struct nls_table *nls_codepage, int remap_special_chars); const struct nls_table *nls_codepage, int remap_special_chars);
extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBSetPosixACL(const int xid, struct cifs_tcon *tcon,
const unsigned char *fileName, const unsigned char *fileName,
const char *local_acl, const int buflen, const int acl_type, const char *local_acl, const int buflen, const int acl_type,
const struct nls_table *nls_codepage, int remap_special_chars); const struct nls_table *nls_codepage, int remap_special_chars);
extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, extern int CIFSGetExtAttr(const int xid, struct cifs_tcon *tcon,
const int netfid, __u64 *pExtAttrBits, __u64 *pMask); const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb); extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
extern bool CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr); extern bool CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr);
...@@ -434,4 +439,22 @@ extern int mdfour(unsigned char *, unsigned char *, int); ...@@ -434,4 +439,22 @@ extern int mdfour(unsigned char *, unsigned char *, int);
extern int E_md4hash(const unsigned char *passwd, unsigned char *p16); extern int E_md4hash(const unsigned char *passwd, unsigned char *p16);
extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8, extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8,
unsigned char *p24); unsigned char *p24);
/* asynchronous write support */
struct cifs_writedata {
struct kref refcount;
enum writeback_sync_modes sync_mode;
struct work_struct work;
struct cifsFileInfo *cfile;
__u64 offset;
unsigned int bytes;
int result;
unsigned int nr_pages;
struct page *pages[1];
};
int cifs_async_writev(struct cifs_writedata *wdata);
struct cifs_writedata *cifs_writedata_alloc(unsigned int nr_pages);
void cifs_writedata_release(struct kref *refcount);
#endif /* _CIFSPROTO_H */ #endif /* _CIFSPROTO_H */
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <linux/vfs.h> #include <linux/vfs.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/posix_acl_xattr.h> #include <linux/posix_acl_xattr.h>
#include <linux/pagemap.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "cifspdu.h" #include "cifspdu.h"
#include "cifsglob.h" #include "cifsglob.h"
...@@ -84,7 +85,7 @@ static struct { ...@@ -84,7 +85,7 @@ static struct {
/* Mark as invalid, all open files on tree connections since they /* Mark as invalid, all open files on tree connections since they
were closed when session to server was lost */ were closed when session to server was lost */
static void mark_open_files_invalid(struct cifsTconInfo *pTcon) static void mark_open_files_invalid(struct cifs_tcon *pTcon)
{ {
struct cifsFileInfo *open_file = NULL; struct cifsFileInfo *open_file = NULL;
struct list_head *tmp; struct list_head *tmp;
...@@ -104,10 +105,10 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon) ...@@ -104,10 +105,10 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon)
/* reconnect the socket, tcon, and smb session if needed */ /* reconnect the socket, tcon, and smb session if needed */
static int static int
cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command) cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
{ {
int rc = 0; int rc = 0;
struct cifsSesInfo *ses; struct cifs_ses *ses;
struct TCP_Server_Info *server; struct TCP_Server_Info *server;
struct nls_table *nls_codepage; struct nls_table *nls_codepage;
...@@ -226,7 +227,7 @@ cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command) ...@@ -226,7 +227,7 @@ cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command)
SMB information in the SMB header. If the return code is zero, this SMB information in the SMB header. If the return code is zero, this
function must have filled in request_buf pointer */ function must have filled in request_buf pointer */
static int static int
small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
void **request_buf) void **request_buf)
{ {
int rc; int rc;
...@@ -252,7 +253,7 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, ...@@ -252,7 +253,7 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
int int
small_smb_init_no_tc(const int smb_command, const int wct, small_smb_init_no_tc(const int smb_command, const int wct,
struct cifsSesInfo *ses, void **request_buf) struct cifs_ses *ses, void **request_buf)
{ {
int rc; int rc;
struct smb_hdr *buffer; struct smb_hdr *buffer;
...@@ -278,7 +279,7 @@ small_smb_init_no_tc(const int smb_command, const int wct, ...@@ -278,7 +279,7 @@ small_smb_init_no_tc(const int smb_command, const int wct,
/* If the return code is zero, this function must fill in request_buf pointer */ /* If the return code is zero, this function must fill in request_buf pointer */
static int static int
__smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
void **request_buf, void **response_buf) void **request_buf, void **response_buf)
{ {
*request_buf = cifs_buf_get(); *request_buf = cifs_buf_get();
...@@ -304,7 +305,7 @@ __smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, ...@@ -304,7 +305,7 @@ __smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
/* If the return code is zero, this function must fill in request_buf pointer */ /* If the return code is zero, this function must fill in request_buf pointer */
static int static int
smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
void **request_buf, void **response_buf) void **request_buf, void **response_buf)
{ {
int rc; int rc;
...@@ -317,7 +318,7 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, ...@@ -317,7 +318,7 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
} }
static int static int
smb_init_no_reconnect(int smb_command, int wct, struct cifsTconInfo *tcon, smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
void **request_buf, void **response_buf) void **request_buf, void **response_buf)
{ {
if (tcon->ses->need_reconnect || tcon->need_reconnect) if (tcon->ses->need_reconnect || tcon->need_reconnect)
...@@ -366,7 +367,7 @@ static inline void inc_rfc1001_len(void *pSMB, int count) ...@@ -366,7 +367,7 @@ static inline void inc_rfc1001_len(void *pSMB, int count)
} }
int int
CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
{ {
NEGOTIATE_REQ *pSMB; NEGOTIATE_REQ *pSMB;
NEGOTIATE_RSP *pSMBr; NEGOTIATE_RSP *pSMBr;
...@@ -450,7 +451,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) ...@@ -450,7 +451,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
goto neg_err_exit; goto neg_err_exit;
} }
server->secMode = (__u8)le16_to_cpu(rsp->SecurityMode); server->sec_mode = (__u8)le16_to_cpu(rsp->SecurityMode);
server->maxReq = le16_to_cpu(rsp->MaxMpxCount); server->maxReq = le16_to_cpu(rsp->MaxMpxCount);
server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize), server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize),
(__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); (__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);
...@@ -504,7 +505,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) ...@@ -504,7 +505,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) { cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
memcpy(ses->server->cryptkey, rsp->EncryptionKey, memcpy(ses->server->cryptkey, rsp->EncryptionKey,
CIFS_CRYPTO_KEY_SIZE); CIFS_CRYPTO_KEY_SIZE);
} else if (server->secMode & SECMODE_PW_ENCRYPT) { } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
rc = -EIO; /* need cryptkey unless plain text */ rc = -EIO; /* need cryptkey unless plain text */
goto neg_err_exit; goto neg_err_exit;
} }
...@@ -526,11 +527,11 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) ...@@ -526,11 +527,11 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
goto neg_err_exit; goto neg_err_exit;
} }
/* else wct == 17 NTLM */ /* else wct == 17 NTLM */
server->secMode = pSMBr->SecurityMode; server->sec_mode = pSMBr->SecurityMode;
if ((server->secMode & SECMODE_USER) == 0) if ((server->sec_mode & SECMODE_USER) == 0)
cFYI(1, "share mode security"); cFYI(1, "share mode security");
if ((server->secMode & SECMODE_PW_ENCRYPT) == 0) if ((server->sec_mode & SECMODE_PW_ENCRYPT) == 0)
#ifdef CONFIG_CIFS_WEAK_PW_HASH #ifdef CONFIG_CIFS_WEAK_PW_HASH
if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0) if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
#endif /* CIFS_WEAK_PW_HASH */ #endif /* CIFS_WEAK_PW_HASH */
...@@ -570,18 +571,10 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) ...@@ -570,18 +571,10 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey, memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
CIFS_CRYPTO_KEY_SIZE); CIFS_CRYPTO_KEY_SIZE);
} else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
&& (pSMBr->EncryptionKeyLength == 0)) { server->capabilities & CAP_EXTENDED_SECURITY) &&
(pSMBr->EncryptionKeyLength == 0)) {
/* decode security blob */ /* decode security blob */
} else if (server->secMode & SECMODE_PW_ENCRYPT) {
rc = -EIO; /* no crypt key only if plain text pwd */
goto neg_err_exit;
}
/* BB might be helpful to save off the domain of server here */
if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) &&
(server->capabilities & CAP_EXTENDED_SECURITY)) {
count = get_bcc(&pSMBr->hdr); count = get_bcc(&pSMBr->hdr);
if (count < 16) { if (count < 16) {
rc = -EIO; rc = -EIO;
...@@ -624,6 +617,9 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) ...@@ -624,6 +617,9 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
} else } else
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
} }
} else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
rc = -EIO; /* no crypt key only if plain text pwd */
goto neg_err_exit;
} else } else
server->capabilities &= ~CAP_EXTENDED_SECURITY; server->capabilities &= ~CAP_EXTENDED_SECURITY;
...@@ -634,27 +630,27 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) ...@@ -634,27 +630,27 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
/* MUST_SIGN already includes the MAY_SIGN FLAG /* MUST_SIGN already includes the MAY_SIGN FLAG
so if this is zero it means that signing is disabled */ so if this is zero it means that signing is disabled */
cFYI(1, "Signing disabled"); cFYI(1, "Signing disabled");
if (server->secMode & SECMODE_SIGN_REQUIRED) { if (server->sec_mode & SECMODE_SIGN_REQUIRED) {
cERROR(1, "Server requires " cERROR(1, "Server requires "
"packet signing to be enabled in " "packet signing to be enabled in "
"/proc/fs/cifs/SecurityFlags."); "/proc/fs/cifs/SecurityFlags.");
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
} }
server->secMode &= server->sec_mode &=
~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
} else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) { } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
/* signing required */ /* signing required */
cFYI(1, "Must sign - secFlags 0x%x", secFlags); cFYI(1, "Must sign - secFlags 0x%x", secFlags);
if ((server->secMode & if ((server->sec_mode &
(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) { (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
cERROR(1, "signing required but server lacks support"); cERROR(1, "signing required but server lacks support");
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
} else } else
server->secMode |= SECMODE_SIGN_REQUIRED; server->sec_mode |= SECMODE_SIGN_REQUIRED;
} else { } else {
/* signing optional ie CIFSSEC_MAY_SIGN */ /* signing optional ie CIFSSEC_MAY_SIGN */
if ((server->secMode & SECMODE_SIGN_REQUIRED) == 0) if ((server->sec_mode & SECMODE_SIGN_REQUIRED) == 0)
server->secMode &= server->sec_mode &=
~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
} }
...@@ -666,7 +662,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) ...@@ -666,7 +662,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
} }
int int
CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon) CIFSSMBTDis(const int xid, struct cifs_tcon *tcon)
{ {
struct smb_hdr *smb_buffer; struct smb_hdr *smb_buffer;
int rc = 0; int rc = 0;
...@@ -725,6 +721,7 @@ CIFSSMBEcho(struct TCP_Server_Info *server) ...@@ -725,6 +721,7 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
{ {
ECHO_REQ *smb; ECHO_REQ *smb;
int rc = 0; int rc = 0;
struct kvec iov;
cFYI(1, "In echo request"); cFYI(1, "In echo request");
...@@ -739,9 +736,10 @@ CIFSSMBEcho(struct TCP_Server_Info *server) ...@@ -739,9 +736,10 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
put_bcc(1, &smb->hdr); put_bcc(1, &smb->hdr);
smb->Data[0] = 'a'; smb->Data[0] = 'a';
inc_rfc1001_len(smb, 3); inc_rfc1001_len(smb, 3);
iov.iov_base = smb;
iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
rc = cifs_call_async(server, (struct smb_hdr *)smb, rc = cifs_call_async(server, &iov, 1, cifs_echo_callback, server, true);
cifs_echo_callback, server);
if (rc) if (rc)
cFYI(1, "Echo request failed: %d", rc); cFYI(1, "Echo request failed: %d", rc);
...@@ -751,7 +749,7 @@ CIFSSMBEcho(struct TCP_Server_Info *server) ...@@ -751,7 +749,7 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
} }
int int
CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) CIFSSMBLogoff(const int xid, struct cifs_ses *ses)
{ {
LOGOFF_ANDX_REQ *pSMB; LOGOFF_ANDX_REQ *pSMB;
int rc = 0; int rc = 0;
...@@ -778,7 +776,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) ...@@ -778,7 +776,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
pSMB->hdr.Mid = GetNextMid(ses->server); pSMB->hdr.Mid = GetNextMid(ses->server);
if (ses->server->secMode & if (ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
...@@ -798,7 +796,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) ...@@ -798,7 +796,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
} }
int int
CIFSPOSIXDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName, CIFSPOSIXDelFile(const int xid, struct cifs_tcon *tcon, const char *fileName,
__u16 type, const struct nls_table *nls_codepage, int remap) __u16 type, const struct nls_table *nls_codepage, int remap)
{ {
TRANSACTION2_SPI_REQ *pSMB = NULL; TRANSACTION2_SPI_REQ *pSMB = NULL;
...@@ -873,7 +871,7 @@ CIFSPOSIXDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName, ...@@ -873,7 +871,7 @@ CIFSPOSIXDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName,
} }
int int
CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName, CIFSSMBDelFile(const int xid, struct cifs_tcon *tcon, const char *fileName,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
{ {
DELETE_FILE_REQ *pSMB = NULL; DELETE_FILE_REQ *pSMB = NULL;
...@@ -918,7 +916,7 @@ CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName, ...@@ -918,7 +916,7 @@ CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName,
} }
int int
CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, const char *dirName, CIFSSMBRmDir(const int xid, struct cifs_tcon *tcon, const char *dirName,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
{ {
DELETE_DIRECTORY_REQ *pSMB = NULL; DELETE_DIRECTORY_REQ *pSMB = NULL;
...@@ -961,7 +959,7 @@ CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, const char *dirName, ...@@ -961,7 +959,7 @@ CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, const char *dirName,
} }
int int
CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon, CIFSSMBMkDir(const int xid, struct cifs_tcon *tcon,
const char *name, const struct nls_table *nls_codepage, int remap) const char *name, const struct nls_table *nls_codepage, int remap)
{ {
int rc = 0; int rc = 0;
...@@ -1004,7 +1002,7 @@ CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon, ...@@ -1004,7 +1002,7 @@ CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags, CIFSPOSIXCreate(const int xid, struct cifs_tcon *tcon, __u32 posix_flags,
__u64 mode, __u16 *netfid, FILE_UNIX_BASIC_INFO *pRetData, __u64 mode, __u16 *netfid, FILE_UNIX_BASIC_INFO *pRetData,
__u32 *pOplock, const char *name, __u32 *pOplock, const char *name,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
...@@ -1170,7 +1168,7 @@ access_flags_to_smbopen_mode(const int access_flags) ...@@ -1170,7 +1168,7 @@ access_flags_to_smbopen_mode(const int access_flags)
} }
int int
SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, SMBLegacyOpen(const int xid, struct cifs_tcon *tcon,
const char *fileName, const int openDisposition, const char *fileName, const int openDisposition,
const int access_flags, const int create_options, __u16 *netfid, const int access_flags, const int create_options, __u16 *netfid,
int *pOplock, FILE_ALL_INFO *pfile_info, int *pOplock, FILE_ALL_INFO *pfile_info,
...@@ -1277,7 +1275,7 @@ SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, ...@@ -1277,7 +1275,7 @@ SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, CIFSSMBOpen(const int xid, struct cifs_tcon *tcon,
const char *fileName, const int openDisposition, const char *fileName, const int openDisposition,
const int access_flags, const int create_options, __u16 *netfid, const int access_flags, const int create_options, __u16 *netfid,
int *pOplock, FILE_ALL_INFO *pfile_info, int *pOplock, FILE_ALL_INFO *pfile_info,
...@@ -1379,8 +1377,7 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, ...@@ -1379,8 +1377,7 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid, CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms, unsigned int *nbytes,
const unsigned int count, const __u64 lseek, unsigned int *nbytes,
char **buf, int *pbuf_type) char **buf, int *pbuf_type)
{ {
int rc = -EACCES; int rc = -EACCES;
...@@ -1390,13 +1387,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid, ...@@ -1390,13 +1387,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
int wct; int wct;
int resp_buf_type = 0; int resp_buf_type = 0;
struct kvec iov[1]; struct kvec iov[1];
__u32 pid = io_parms->pid;
__u16 netfid = io_parms->netfid;
__u64 offset = io_parms->offset;
struct cifs_tcon *tcon = io_parms->tcon;
unsigned int count = io_parms->length;
cFYI(1, "Reading %d bytes on fid %d", count, netfid); cFYI(1, "Reading %d bytes on fid %d", count, netfid);
if (tcon->ses->capabilities & CAP_LARGE_FILES) if (tcon->ses->capabilities & CAP_LARGE_FILES)
wct = 12; wct = 12;
else { else {
wct = 10; /* old style read */ wct = 10; /* old style read */
if ((lseek >> 32) > 0) { if ((offset >> 32) > 0) {
/* can not handle this big offset for old */ /* can not handle this big offset for old */
return -EIO; return -EIO;
} }
...@@ -1407,15 +1409,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid, ...@@ -1407,15 +1409,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
if (rc) if (rc)
return rc; return rc;
pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
/* tcon and ses pointer are checked in smb_init */ /* tcon and ses pointer are checked in smb_init */
if (tcon->ses->server == NULL) if (tcon->ses->server == NULL)
return -ECONNABORTED; return -ECONNABORTED;
pSMB->AndXCommand = 0xFF; /* none */ pSMB->AndXCommand = 0xFF; /* none */
pSMB->Fid = netfid; pSMB->Fid = netfid;
pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF); pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
if (wct == 12) if (wct == 12)
pSMB->OffsetHigh = cpu_to_le32(lseek >> 32); pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
pSMB->Remaining = 0; pSMB->Remaining = 0;
pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
...@@ -1484,9 +1489,8 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid, ...@@ -1484,9 +1489,8 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
int int
CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
const int netfid, const unsigned int count, unsigned int *nbytes, const char *buf,
const __u64 offset, unsigned int *nbytes, const char *buf,
const char __user *ubuf, const int long_op) const char __user *ubuf, const int long_op)
{ {
int rc = -EACCES; int rc = -EACCES;
...@@ -1495,6 +1499,11 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, ...@@ -1495,6 +1499,11 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
int bytes_returned, wct; int bytes_returned, wct;
__u32 bytes_sent; __u32 bytes_sent;
__u16 byte_count; __u16 byte_count;
__u32 pid = io_parms->pid;
__u16 netfid = io_parms->netfid;
__u64 offset = io_parms->offset;
struct cifs_tcon *tcon = io_parms->tcon;
unsigned int count = io_parms->length;
*nbytes = 0; *nbytes = 0;
...@@ -1516,6 +1525,10 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, ...@@ -1516,6 +1525,10 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
(void **) &pSMBr); (void **) &pSMBr);
if (rc) if (rc)
return rc; return rc;
pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
/* tcon and ses pointer are checked in smb_init */ /* tcon and ses pointer are checked in smb_init */
if (tcon->ses->server == NULL) if (tcon->ses->server == NULL)
return -ECONNABORTED; return -ECONNABORTED;
...@@ -1602,17 +1615,259 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, ...@@ -1602,17 +1615,259 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
return rc; return rc;
} }
void
cifs_writedata_release(struct kref *refcount)
{
struct cifs_writedata *wdata = container_of(refcount,
struct cifs_writedata, refcount);
if (wdata->cfile)
cifsFileInfo_put(wdata->cfile);
kfree(wdata);
}
/*
* Write failed with a retryable error. Resend the write request. It's also
* possible that the page was redirtied so re-clean the page.
*/
static void
cifs_writev_requeue(struct cifs_writedata *wdata)
{
int i, rc;
struct inode *inode = wdata->cfile->dentry->d_inode;
for (i = 0; i < wdata->nr_pages; i++) {
lock_page(wdata->pages[i]);
clear_page_dirty_for_io(wdata->pages[i]);
}
do {
rc = cifs_async_writev(wdata);
} while (rc == -EAGAIN);
for (i = 0; i < wdata->nr_pages; i++) {
if (rc != 0)
SetPageError(wdata->pages[i]);
unlock_page(wdata->pages[i]);
}
mapping_set_error(inode->i_mapping, rc);
kref_put(&wdata->refcount, cifs_writedata_release);
}
static void
cifs_writev_complete(struct work_struct *work)
{
struct cifs_writedata *wdata = container_of(work,
struct cifs_writedata, work);
struct inode *inode = wdata->cfile->dentry->d_inode;
int i = 0;
if (wdata->result == 0) {
cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
wdata->bytes);
} else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
return cifs_writev_requeue(wdata);
for (i = 0; i < wdata->nr_pages; i++) {
struct page *page = wdata->pages[i];
if (wdata->result == -EAGAIN)
__set_page_dirty_nobuffers(page);
else if (wdata->result < 0)
SetPageError(page);
end_page_writeback(page);
page_cache_release(page);
}
if (wdata->result != -EAGAIN)
mapping_set_error(inode->i_mapping, wdata->result);
kref_put(&wdata->refcount, cifs_writedata_release);
}
struct cifs_writedata *
cifs_writedata_alloc(unsigned int nr_pages)
{
struct cifs_writedata *wdata;
/* this would overflow */
if (nr_pages == 0) {
cERROR(1, "%s: called with nr_pages == 0!", __func__);
return NULL;
}
/* writedata + number of page pointers */
wdata = kzalloc(sizeof(*wdata) +
sizeof(struct page *) * (nr_pages - 1), GFP_NOFS);
if (wdata != NULL) {
INIT_WORK(&wdata->work, cifs_writev_complete);
kref_init(&wdata->refcount);
}
return wdata;
}
/*
* Check the midState and signature on received buffer (if any), and queue the
* workqueue completion task.
*/
static void
cifs_writev_callback(struct mid_q_entry *mid)
{
struct cifs_writedata *wdata = mid->callback_data;
struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
unsigned int written;
WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
switch (mid->midState) {
case MID_RESPONSE_RECEIVED:
wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
if (wdata->result != 0)
break;
written = le16_to_cpu(smb->CountHigh);
written <<= 16;
written += le16_to_cpu(smb->Count);
/*
* Mask off high 16 bits when bytes written as returned
* by the server is greater than bytes requested by the
* client. OS/2 servers are known to set incorrect
* CountHigh values.
*/
if (written > wdata->bytes)
written &= 0xFFFF;
if (written < wdata->bytes)
wdata->result = -ENOSPC;
else
wdata->bytes = written;
break;
case MID_REQUEST_SUBMITTED:
case MID_RETRY_NEEDED:
wdata->result = -EAGAIN;
break;
default:
wdata->result = -EIO;
break;
}
queue_work(system_nrt_wq, &wdata->work);
DeleteMidQEntry(mid);
atomic_dec(&tcon->ses->server->inFlight);
wake_up(&tcon->ses->server->request_q);
}
/* cifs_async_writev - send an async write, and set up mid to handle result */
int
cifs_async_writev(struct cifs_writedata *wdata)
{
int i, rc = -EACCES;
WRITE_REQ *smb = NULL;
int wct;
struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
struct inode *inode = wdata->cfile->dentry->d_inode;
struct kvec *iov = NULL;
if (tcon->ses->capabilities & CAP_LARGE_FILES) {
wct = 14;
} else {
wct = 12;
if (wdata->offset >> 32 > 0) {
/* can not handle big offset for old srv */
return -EIO;
}
}
rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
if (rc)
goto async_writev_out;
/* 1 iov per page + 1 for header */
iov = kzalloc((wdata->nr_pages + 1) * sizeof(*iov), GFP_NOFS);
if (iov == NULL) {
rc = -ENOMEM;
goto async_writev_out;
}
smb->hdr.Pid = cpu_to_le16((__u16)wdata->cfile->pid);
smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->cfile->pid >> 16));
smb->AndXCommand = 0xFF; /* none */
smb->Fid = wdata->cfile->netfid;
smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
if (wct == 14)
smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
smb->Reserved = 0xFFFFFFFF;
smb->WriteMode = 0;
smb->Remaining = 0;
smb->DataOffset =
cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
/* 4 for RFC1001 length + 1 for BCC */
iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1;
iov[0].iov_base = smb;
/* marshal up the pages into iov array */
wdata->bytes = 0;
for (i = 0; i < wdata->nr_pages; i++) {
iov[i + 1].iov_len = min(inode->i_size -
page_offset(wdata->pages[i]),
(loff_t)PAGE_CACHE_SIZE);
iov[i + 1].iov_base = kmap(wdata->pages[i]);
wdata->bytes += iov[i + 1].iov_len;
}
cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes);
smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
if (wct == 14) {
inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
put_bcc(wdata->bytes + 1, &smb->hdr);
} else {
/* wct == 12 */
struct smb_com_writex_req *smbw =
(struct smb_com_writex_req *)smb;
inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
put_bcc(wdata->bytes + 5, &smbw->hdr);
iov[0].iov_len += 4; /* pad bigger by four bytes */
}
kref_get(&wdata->refcount);
rc = cifs_call_async(tcon->ses->server, iov, wdata->nr_pages + 1,
cifs_writev_callback, wdata, false);
if (rc == 0)
cifs_stats_inc(&tcon->num_writes);
else
kref_put(&wdata->refcount, cifs_writedata_release);
/* send is done, unmap pages */
for (i = 0; i < wdata->nr_pages; i++)
kunmap(wdata->pages[i]);
async_writev_out:
cifs_small_buf_release(smb);
kfree(iov);
return rc;
}
int int
CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
const int netfid, const unsigned int count, unsigned int *nbytes, struct kvec *iov, int n_vec,
const __u64 offset, unsigned int *nbytes, struct kvec *iov, const int long_op)
int n_vec, const int long_op)
{ {
int rc = -EACCES; int rc = -EACCES;
WRITE_REQ *pSMB = NULL; WRITE_REQ *pSMB = NULL;
int wct; int wct;
int smb_hdr_len; int smb_hdr_len;
int resp_buf_type = 0; int resp_buf_type = 0;
__u32 pid = io_parms->pid;
__u16 netfid = io_parms->netfid;
__u64 offset = io_parms->offset;
struct cifs_tcon *tcon = io_parms->tcon;
unsigned int count = io_parms->length;
*nbytes = 0; *nbytes = 0;
...@@ -1630,6 +1885,10 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, ...@@ -1630,6 +1885,10 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB); rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
if (rc) if (rc)
return rc; return rc;
pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
/* tcon and ses pointer are checked in smb_init */ /* tcon and ses pointer are checked in smb_init */
if (tcon->ses->server == NULL) if (tcon->ses->server == NULL)
return -ECONNABORTED; return -ECONNABORTED;
...@@ -1705,7 +1964,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, ...@@ -1705,7 +1964,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
int int
CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
const __u16 smb_file_id, const __u64 len, const __u16 smb_file_id, const __u64 len,
const __u64 offset, const __u32 numUnlock, const __u64 offset, const __u32 numUnlock,
const __u32 numLock, const __u8 lockType, const __u32 numLock, const __u8 lockType,
...@@ -1775,7 +2034,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, ...@@ -1775,7 +2034,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon,
const __u16 smb_file_id, const int get_flag, const __u64 len, const __u16 smb_file_id, const int get_flag, const __u64 len,
struct file_lock *pLockData, const __u16 lock_type, struct file_lock *pLockData, const __u16 lock_type,
const bool waitFlag) const bool waitFlag)
...@@ -1913,7 +2172,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, ...@@ -1913,7 +2172,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
int int
CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id) CIFSSMBClose(const int xid, struct cifs_tcon *tcon, int smb_file_id)
{ {
int rc = 0; int rc = 0;
CLOSE_REQ *pSMB = NULL; CLOSE_REQ *pSMB = NULL;
...@@ -1946,7 +2205,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id) ...@@ -1946,7 +2205,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
} }
int int
CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, int smb_file_id) CIFSSMBFlush(const int xid, struct cifs_tcon *tcon, int smb_file_id)
{ {
int rc = 0; int rc = 0;
FLUSH_REQ *pSMB = NULL; FLUSH_REQ *pSMB = NULL;
...@@ -1967,7 +2226,7 @@ CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, int smb_file_id) ...@@ -1967,7 +2226,7 @@ CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
} }
int int
CIFSSMBRename(const int xid, struct cifsTconInfo *tcon, CIFSSMBRename(const int xid, struct cifs_tcon *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
{ {
...@@ -2034,7 +2293,7 @@ CIFSSMBRename(const int xid, struct cifsTconInfo *tcon, ...@@ -2034,7 +2293,7 @@ CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
return rc; return rc;
} }
int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon, int CIFSSMBRenameOpenFile(const int xid, struct cifs_tcon *pTcon,
int netfid, const char *target_name, int netfid, const char *target_name,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
{ {
...@@ -2114,7 +2373,7 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon, ...@@ -2114,7 +2373,7 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
} }
int int
CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char *fromName, CIFSSMBCopy(const int xid, struct cifs_tcon *tcon, const char *fromName,
const __u16 target_tid, const char *toName, const int flags, const __u16 target_tid, const char *toName, const int flags,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
{ {
...@@ -2182,7 +2441,7 @@ CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char *fromName, ...@@ -2182,7 +2441,7 @@ CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char *fromName,
} }
int int
CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon, CIFSUnixCreateSymLink(const int xid, struct cifs_tcon *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
const struct nls_table *nls_codepage) const struct nls_table *nls_codepage)
{ {
...@@ -2271,7 +2530,7 @@ CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon, ...@@ -2271,7 +2530,7 @@ CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *tcon, CIFSUnixCreateHardLink(const int xid, struct cifs_tcon *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
{ {
...@@ -2356,7 +2615,7 @@ CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *tcon, ...@@ -2356,7 +2615,7 @@ CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon, CIFSCreateHardLink(const int xid, struct cifs_tcon *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
{ {
...@@ -2428,7 +2687,7 @@ CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon, ...@@ -2428,7 +2687,7 @@ CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon, CIFSSMBUnixQuerySymLink(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, char **symlinkinfo, const unsigned char *searchName, char **symlinkinfo,
const struct nls_table *nls_codepage) const struct nls_table *nls_codepage)
{ {
...@@ -2533,7 +2792,7 @@ CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon, ...@@ -2533,7 +2792,7 @@ CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
* it is not compiled in by default until callers fixed up and more tested. * it is not compiled in by default until callers fixed up and more tested.
*/ */
int int
CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, CIFSSMBQueryReparseLinkInfo(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, const unsigned char *searchName,
char *symlinkinfo, const int buflen, __u16 fid, char *symlinkinfo, const int buflen, __u16 fid,
const struct nls_table *nls_codepage) const struct nls_table *nls_codepage)
...@@ -2771,7 +3030,7 @@ static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL, ...@@ -2771,7 +3030,7 @@ static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
} }
int int
CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, CIFSSMBGetPosixACL(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, const unsigned char *searchName,
char *acl_inf, const int buflen, const int acl_type, char *acl_inf, const int buflen, const int acl_type,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
...@@ -2859,7 +3118,7 @@ CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, ...@@ -2859,7 +3118,7 @@ CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon, CIFSSMBSetPosixACL(const int xid, struct cifs_tcon *tcon,
const unsigned char *fileName, const unsigned char *fileName,
const char *local_acl, const int buflen, const char *local_acl, const int buflen,
const int acl_type, const int acl_type,
...@@ -2939,7 +3198,7 @@ CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon, ...@@ -2939,7 +3198,7 @@ CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
/* BB fix tabs in this function FIXME BB */ /* BB fix tabs in this function FIXME BB */
int int
CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, CIFSGetExtAttr(const int xid, struct cifs_tcon *tcon,
const int netfid, __u64 *pExtAttrBits, __u64 *pMask) const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
{ {
int rc = 0; int rc = 0;
...@@ -3032,7 +3291,7 @@ CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, ...@@ -3032,7 +3291,7 @@ CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
*/ */
static int static int
smb_init_nttransact(const __u16 sub_command, const int setup_count, smb_init_nttransact(const __u16 sub_command, const int setup_count,
const int parm_len, struct cifsTconInfo *tcon, const int parm_len, struct cifs_tcon *tcon,
void **ret_buf) void **ret_buf)
{ {
int rc; int rc;
...@@ -3115,7 +3374,7 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata, ...@@ -3115,7 +3374,7 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
/* Get Security Descriptor (by handle) from remote server for a file or dir */ /* Get Security Descriptor (by handle) from remote server for a file or dir */
int int
CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, CIFSSMBGetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
struct cifs_ntsd **acl_inf, __u32 *pbuflen) struct cifs_ntsd **acl_inf, __u32 *pbuflen)
{ {
int rc = 0; int rc = 0;
...@@ -3207,7 +3466,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, ...@@ -3207,7 +3466,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
} }
int int
CIFSSMBSetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, CIFSSMBSetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
struct cifs_ntsd *pntsd, __u32 acllen) struct cifs_ntsd *pntsd, __u32 acllen)
{ {
__u16 byte_count, param_count, data_count, param_offset, data_offset; __u16 byte_count, param_count, data_count, param_offset, data_offset;
...@@ -3273,7 +3532,7 @@ CIFSSMBSetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, ...@@ -3273,7 +3532,7 @@ CIFSSMBSetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
/* Legacy Query Path Information call for lookup to old servers such /* Legacy Query Path Information call for lookup to old servers such
as Win9x/WinME */ as Win9x/WinME */
int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, int SMBQueryInformation(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, const unsigned char *searchName,
FILE_ALL_INFO *pFinfo, FILE_ALL_INFO *pFinfo,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
...@@ -3341,7 +3600,7 @@ int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, ...@@ -3341,7 +3600,7 @@ int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon, CIFSSMBQFileInfo(const int xid, struct cifs_tcon *tcon,
u16 netfid, FILE_ALL_INFO *pFindData) u16 netfid, FILE_ALL_INFO *pFindData)
{ {
struct smb_t2_qfi_req *pSMB = NULL; struct smb_t2_qfi_req *pSMB = NULL;
...@@ -3408,7 +3667,7 @@ CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon, ...@@ -3408,7 +3667,7 @@ CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, CIFSSMBQPathInfo(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, const unsigned char *searchName,
FILE_ALL_INFO *pFindData, FILE_ALL_INFO *pFindData,
int legacy /* old style infolevel */, int legacy /* old style infolevel */,
...@@ -3509,7 +3768,7 @@ CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, ...@@ -3509,7 +3768,7 @@ CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon, CIFSSMBUnixQFileInfo(const int xid, struct cifs_tcon *tcon,
u16 netfid, FILE_UNIX_BASIC_INFO *pFindData) u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
{ {
struct smb_t2_qfi_req *pSMB = NULL; struct smb_t2_qfi_req *pSMB = NULL;
...@@ -3578,7 +3837,7 @@ CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon, ...@@ -3578,7 +3837,7 @@ CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon, CIFSSMBUnixQPathInfo(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, const unsigned char *searchName,
FILE_UNIX_BASIC_INFO *pFindData, FILE_UNIX_BASIC_INFO *pFindData,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
...@@ -3664,7 +3923,7 @@ CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon, ...@@ -3664,7 +3923,7 @@ CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon,
/* xid, tcon, searchName and codepage are input parms, rest are returned */ /* xid, tcon, searchName and codepage are input parms, rest are returned */
int int
CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
const char *searchName, const char *searchName,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
__u16 *pnetfid, __u16 *pnetfid,
...@@ -3812,7 +4071,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, ...@@ -3812,7 +4071,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
return rc; return rc;
} }
int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, int CIFSFindNext(const int xid, struct cifs_tcon *tcon,
__u16 searchHandle, struct cifs_search_info *psrch_inf) __u16 searchHandle, struct cifs_search_info *psrch_inf)
{ {
TRANSACTION2_FNEXT_REQ *pSMB = NULL; TRANSACTION2_FNEXT_REQ *pSMB = NULL;
...@@ -3950,7 +4209,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, ...@@ -3950,7 +4209,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSFindClose(const int xid, struct cifsTconInfo *tcon, CIFSFindClose(const int xid, struct cifs_tcon *tcon,
const __u16 searchHandle) const __u16 searchHandle)
{ {
int rc = 0; int rc = 0;
...@@ -3982,7 +4241,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, ...@@ -3982,7 +4241,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, const unsigned char *searchName,
__u64 *inode_number, __u64 *inode_number,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
...@@ -4184,7 +4443,7 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr, ...@@ -4184,7 +4443,7 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
} }
int int
CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, CIFSGetDFSRefer(const int xid, struct cifs_ses *ses,
const unsigned char *searchName, const unsigned char *searchName,
struct dfs_info3_param **target_nodes, struct dfs_info3_param **target_nodes,
unsigned int *num_of_nodes, unsigned int *num_of_nodes,
...@@ -4233,7 +4492,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, ...@@ -4233,7 +4492,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
} }
if (ses->server) { if (ses->server) {
if (ses->server->secMode & if (ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
} }
...@@ -4298,7 +4557,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, ...@@ -4298,7 +4557,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
/* Query File System Info such as free space to old servers such as Win 9x */ /* Query File System Info such as free space to old servers such as Win 9x */
int int
SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData) SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
{ {
/* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */ /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
TRANSACTION2_QFSI_REQ *pSMB = NULL; TRANSACTION2_QFSI_REQ *pSMB = NULL;
...@@ -4377,7 +4636,7 @@ SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData) ...@@ -4377,7 +4636,7 @@ SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
} }
int int
CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData) CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
{ {
/* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */ /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
TRANSACTION2_QFSI_REQ *pSMB = NULL; TRANSACTION2_QFSI_REQ *pSMB = NULL;
...@@ -4456,7 +4715,7 @@ CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData) ...@@ -4456,7 +4715,7 @@ CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
} }
int int
CIFSSMBQFSAttributeInfo(const int xid, struct cifsTconInfo *tcon) CIFSSMBQFSAttributeInfo(const int xid, struct cifs_tcon *tcon)
{ {
/* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */ /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
TRANSACTION2_QFSI_REQ *pSMB = NULL; TRANSACTION2_QFSI_REQ *pSMB = NULL;
...@@ -4526,7 +4785,7 @@ CIFSSMBQFSAttributeInfo(const int xid, struct cifsTconInfo *tcon) ...@@ -4526,7 +4785,7 @@ CIFSSMBQFSAttributeInfo(const int xid, struct cifsTconInfo *tcon)
} }
int int
CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon) CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon)
{ {
/* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */ /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
TRANSACTION2_QFSI_REQ *pSMB = NULL; TRANSACTION2_QFSI_REQ *pSMB = NULL;
...@@ -4597,7 +4856,7 @@ CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon) ...@@ -4597,7 +4856,7 @@ CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon)
} }
int int
CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon) CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon)
{ {
/* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */ /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
TRANSACTION2_QFSI_REQ *pSMB = NULL; TRANSACTION2_QFSI_REQ *pSMB = NULL;
...@@ -4667,7 +4926,7 @@ CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon) ...@@ -4667,7 +4926,7 @@ CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon)
} }
int int
CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap) CIFSSMBSetFSUnixInfo(const int xid, struct cifs_tcon *tcon, __u64 cap)
{ {
/* level 0x200 SMB_SET_CIFS_UNIX_INFO */ /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
TRANSACTION2_SETFSI_REQ *pSMB = NULL; TRANSACTION2_SETFSI_REQ *pSMB = NULL;
...@@ -4741,7 +5000,7 @@ CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap) ...@@ -4741,7 +5000,7 @@ CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap)
int int
CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
struct kstatfs *FSData) struct kstatfs *FSData)
{ {
/* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */ /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
...@@ -4834,7 +5093,7 @@ CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, ...@@ -4834,7 +5093,7 @@ CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
in Samba which this routine can run into */ in Samba which this routine can run into */
int int
CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName, CIFSSMBSetEOF(const int xid, struct cifs_tcon *tcon, const char *fileName,
__u64 size, bool SetAllocation, __u64 size, bool SetAllocation,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
{ {
...@@ -4923,7 +5182,7 @@ CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName, ...@@ -4923,7 +5182,7 @@ CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName,
} }
int int
CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon, __u64 size,
__u16 fid, __u32 pid_of_opener, bool SetAllocation) __u16 fid, __u32 pid_of_opener, bool SetAllocation)
{ {
struct smb_com_transaction2_sfi_req *pSMB = NULL; struct smb_com_transaction2_sfi_req *pSMB = NULL;
...@@ -5005,7 +5264,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, ...@@ -5005,7 +5264,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
time and resort to the original setpathinfo level which takes the ancient time and resort to the original setpathinfo level which takes the ancient
DOS time format with 2 second granularity */ DOS time format with 2 second granularity */
int int
CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon, CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener) const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
{ {
struct smb_com_transaction2_sfi_req *pSMB = NULL; struct smb_com_transaction2_sfi_req *pSMB = NULL;
...@@ -5067,7 +5326,7 @@ CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon, ...@@ -5067,7 +5326,7 @@ CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon, CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon,
bool delete_file, __u16 fid, __u32 pid_of_opener) bool delete_file, __u16 fid, __u32 pid_of_opener)
{ {
struct smb_com_transaction2_sfi_req *pSMB = NULL; struct smb_com_transaction2_sfi_req *pSMB = NULL;
...@@ -5123,7 +5382,7 @@ CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon, ...@@ -5123,7 +5382,7 @@ CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon, CIFSSMBSetPathInfo(const int xid, struct cifs_tcon *tcon,
const char *fileName, const FILE_BASIC_INFO *data, const char *fileName, const FILE_BASIC_INFO *data,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
{ {
...@@ -5207,7 +5466,7 @@ CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon, ...@@ -5207,7 +5466,7 @@ CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon,
handling it anyway and NT4 was what we thought it would be needed for handling it anyway and NT4 was what we thought it would be needed for
Do not delete it until we prove whether needed for Win9x though */ Do not delete it until we prove whether needed for Win9x though */
int int
CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, char *fileName, CIFSSMBSetAttrLegacy(int xid, struct cifs_tcon *tcon, char *fileName,
__u16 dos_attrs, const struct nls_table *nls_codepage) __u16 dos_attrs, const struct nls_table *nls_codepage)
{ {
SETATTR_REQ *pSMB = NULL; SETATTR_REQ *pSMB = NULL;
...@@ -5295,7 +5554,7 @@ cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset, ...@@ -5295,7 +5554,7 @@ cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
} }
int int
CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon, CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
const struct cifs_unix_set_info_args *args, const struct cifs_unix_set_info_args *args,
u16 fid, u32 pid_of_opener) u16 fid, u32 pid_of_opener)
{ {
...@@ -5358,7 +5617,7 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon, ...@@ -5358,7 +5617,7 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *tcon, char *fileName, CIFSSMBUnixSetPathInfo(const int xid, struct cifs_tcon *tcon, char *fileName,
const struct cifs_unix_set_info_args *args, const struct cifs_unix_set_info_args *args,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
{ {
...@@ -5445,7 +5704,7 @@ CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *tcon, char *fileName, ...@@ -5445,7 +5704,7 @@ CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *tcon, char *fileName,
* the data isn't copied to it, but the length is returned. * the data isn't copied to it, but the length is returned.
*/ */
ssize_t ssize_t
CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, CIFSSMBQAllEAs(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, const unsigned char *ea_name, const unsigned char *searchName, const unsigned char *ea_name,
char *EAData, size_t buf_size, char *EAData, size_t buf_size,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
...@@ -5626,7 +5885,7 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, ...@@ -5626,7 +5885,7 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, const char *fileName, CIFSSMBSetEA(const int xid, struct cifs_tcon *tcon, const char *fileName,
const char *ea_name, const void *ea_value, const char *ea_name, const void *ea_value,
const __u16 ea_value_len, const struct nls_table *nls_codepage, const __u16 ea_value_len, const struct nls_table *nls_codepage,
int remap) int remap)
...@@ -5753,7 +6012,7 @@ CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, const char *fileName, ...@@ -5753,7 +6012,7 @@ CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, const char *fileName,
* incompatible for network fs clients, we could instead simply * incompatible for network fs clients, we could instead simply
* expose this config flag by adding a future cifs (and smb2) notify ioctl. * expose this config flag by adding a future cifs (and smb2) notify ioctl.
*/ */
int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, int CIFSSMBNotify(const int xid, struct cifs_tcon *tcon,
const int notify_subdirs, const __u16 netfid, const int notify_subdirs, const __u16 netfid,
__u32 filter, struct file *pfile, int multishot, __u32 filter, struct file *pfile, int multishot,
const struct nls_table *nls_codepage) const struct nls_table *nls_codepage)
......
...@@ -57,62 +57,6 @@ ...@@ -57,62 +57,6 @@
extern mempool_t *cifs_req_poolp; extern mempool_t *cifs_req_poolp;
struct smb_vol {
char *username;
char *password;
char *domainname;
char *UNC;
char *UNCip;
char *iocharset; /* local code page for mapping to and from Unicode */
char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
uid_t cred_uid;
uid_t linux_uid;
gid_t linux_gid;
mode_t file_mode;
mode_t dir_mode;
unsigned secFlg;
bool retry:1;
bool intr:1;
bool setuids:1;
bool override_uid:1;
bool override_gid:1;
bool dynperm:1;
bool noperm:1;
bool no_psx_acl:1; /* set if posix acl support should be disabled */
bool cifs_acl:1;
bool no_xattr:1; /* set if xattr (EA) support should be disabled*/
bool server_ino:1; /* use inode numbers from server ie UniqueId */
bool direct_io:1;
bool strict_io:1; /* strict cache behavior */
bool remap:1; /* set to remap seven reserved chars in filenames */
bool posix_paths:1; /* unset to not ask for posix pathnames. */
bool no_linux_ext:1;
bool sfu_emul:1;
bool nullauth:1; /* attempt to authenticate with null user */
bool nocase:1; /* request case insensitive filenames */
bool nobrl:1; /* disable sending byte range locks to srv */
bool mand_lock:1; /* send mandatory not posix byte range lock reqs */
bool seal:1; /* request transport encryption on share */
bool nodfs:1; /* Do not request DFS, even if available */
bool local_lease:1; /* check leases only on local system, not remote */
bool noblocksnd:1;
bool noautotune:1;
bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
bool fsc:1; /* enable fscache */
bool mfsymlinks:1; /* use Minshall+French Symlinks */
bool multiuser:1;
bool use_smb2:1; /* force smb2 use on mount instead of cifs */
unsigned int rsize;
unsigned int wsize;
bool sockopt_tcp_nodelay:1;
unsigned short int port;
unsigned long actimeo; /* attribute cache timeout (jiffies) */
char *prepath;
struct sockaddr_storage srcaddr; /* allow binding to a local IP */
struct nls_table *local_nls;
};
/* FIXME: should these be tunable? */ /* FIXME: should these be tunable? */
#define TLINK_ERROR_EXPIRE (1 * HZ) #define TLINK_ERROR_EXPIRE (1 * HZ)
#define TLINK_IDLE_EXPIRE (600 * HZ) #define TLINK_IDLE_EXPIRE (600 * HZ)
...@@ -135,9 +79,10 @@ cifs_reconnect(struct TCP_Server_Info *server) ...@@ -135,9 +79,10 @@ cifs_reconnect(struct TCP_Server_Info *server)
{ {
int rc = 0; int rc = 0;
struct list_head *tmp, *tmp2; struct list_head *tmp, *tmp2;
struct cifsSesInfo *ses; struct cifs_ses *ses;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
struct mid_q_entry *mid_entry; struct mid_q_entry *mid_entry;
struct list_head retry_list;
spin_lock(&GlobalMid_Lock); spin_lock(&GlobalMid_Lock);
if (server->tcpStatus == CifsExiting) { if (server->tcpStatus == CifsExiting) {
...@@ -157,11 +102,11 @@ cifs_reconnect(struct TCP_Server_Info *server) ...@@ -157,11 +102,11 @@ cifs_reconnect(struct TCP_Server_Info *server)
cFYI(1, "%s: marking sessions and tcons for reconnect", __func__); cFYI(1, "%s: marking sessions and tcons for reconnect", __func__);
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
list_for_each(tmp, &server->smb_ses_list) { list_for_each(tmp, &server->smb_ses_list) {
ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list); ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
ses->need_reconnect = true; ses->need_reconnect = true;
ses->ipc_tid = 0; ses->ipc_tid = 0;
list_for_each(tmp2, &ses->tcon_list) { list_for_each(tmp2, &ses->tcon_list) {
tcon = list_entry(tmp2, struct cifsTconInfo, tcon_list); tcon = list_entry(tmp2, struct cifs_tcon, tcon_list);
tcon->need_reconnect = true; tcon->need_reconnect = true;
} }
} }
...@@ -189,16 +134,23 @@ cifs_reconnect(struct TCP_Server_Info *server) ...@@ -189,16 +134,23 @@ cifs_reconnect(struct TCP_Server_Info *server)
mutex_unlock(&server->srv_mutex); mutex_unlock(&server->srv_mutex);
/* mark submitted MIDs for retry and issue callback */ /* mark submitted MIDs for retry and issue callback */
cFYI(1, "%s: issuing mid callbacks", __func__); INIT_LIST_HEAD(&retry_list);
cFYI(1, "%s: moving mids to private list", __func__);
spin_lock(&GlobalMid_Lock); spin_lock(&GlobalMid_Lock);
list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
mid_entry = list_entry(tmp, struct mid_q_entry, qhead); mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
if (mid_entry->midState == MID_REQUEST_SUBMITTED) if (mid_entry->midState == MID_REQUEST_SUBMITTED)
mid_entry->midState = MID_RETRY_NEEDED; mid_entry->midState = MID_RETRY_NEEDED;
list_move(&mid_entry->qhead, &retry_list);
}
spin_unlock(&GlobalMid_Lock);
cFYI(1, "%s: issuing mid callbacks", __func__);
list_for_each_safe(tmp, tmp2, &retry_list) {
mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
list_del_init(&mid_entry->qhead); list_del_init(&mid_entry->qhead);
mid_entry->callback(mid_entry); mid_entry->callback(mid_entry);
} }
spin_unlock(&GlobalMid_Lock);
while (server->tcpStatus == CifsNeedReconnect) { while (server->tcpStatus == CifsNeedReconnect) {
try_to_freeze(); try_to_freeze();
...@@ -672,12 +624,12 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -672,12 +624,12 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
mid_entry->when_received = jiffies; mid_entry->when_received = jiffies;
#endif #endif
list_del_init(&mid_entry->qhead); list_del_init(&mid_entry->qhead);
mid_entry->callback(mid_entry);
break; break;
} }
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
if (mid_entry != NULL) { if (mid_entry != NULL) {
mid_entry->callback(mid_entry);
/* Was previous buf put in mpx struct for multi-rsp? */ /* Was previous buf put in mpx struct for multi-rsp? */
if (!isMultiRsp) { if (!isMultiRsp) {
/* smb buffer will be freed by user thread */ /* smb buffer will be freed by user thread */
...@@ -741,15 +693,25 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -741,15 +693,25 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
cifs_small_buf_release(smallbuf); cifs_small_buf_release(smallbuf);
if (!list_empty(&server->pending_mid_q)) { if (!list_empty(&server->pending_mid_q)) {
struct list_head dispose_list;
INIT_LIST_HEAD(&dispose_list);
spin_lock(&GlobalMid_Lock); spin_lock(&GlobalMid_Lock);
list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
mid_entry = list_entry(tmp, struct mid_q_entry, qhead); mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
cFYI(1, "Clearing Mid 0x%x - issuing callback", cFYI(1, "Clearing mid 0x%x", mid_entry->mid);
mid_entry->mid); mid_entry->midState = MID_SHUTDOWN;
list_move(&mid_entry->qhead, &dispose_list);
}
spin_unlock(&GlobalMid_Lock);
/* now walk dispose list and issue callbacks */
list_for_each_safe(tmp, tmp2, &dispose_list) {
mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
cFYI(1, "Callback mid 0x%x", mid_entry->mid);
list_del_init(&mid_entry->qhead); list_del_init(&mid_entry->qhead);
mid_entry->callback(mid_entry); mid_entry->callback(mid_entry);
} }
spin_unlock(&GlobalMid_Lock);
/* 1/8th of sec is more than enough time for them to exit */ /* 1/8th of sec is more than enough time for them to exit */
msleep(125); msleep(125);
} }
...@@ -1062,13 +1024,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, ...@@ -1062,13 +1024,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
(strnicmp(value, "1", 1) == 0)) { (strnicmp(value, "1", 1) == 0)) {
/* this is the default */ /* this is the default */
continue; continue;
} else if ((strnicmp(value, "smb2", 4) == 0) ||
(strnicmp(value, "2", 1) == 0)) {
#ifdef CONFIG_CIFS_SMB2
vol->use_smb2 = true;
#else
cERROR(1, "smb2 support not enabled");
#endif /* CONFIG_CIFS_SMB2 */
} }
} else if ((strnicmp(data, "unc", 3) == 0) } else if ((strnicmp(data, "unc", 3) == 0)
|| (strnicmp(data, "target", 6) == 0) || (strnicmp(data, "target", 6) == 0)
...@@ -1404,6 +1359,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, ...@@ -1404,6 +1359,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
vol->server_ino = 1; vol->server_ino = 1;
} else if (strnicmp(data, "noserverino", 9) == 0) { } else if (strnicmp(data, "noserverino", 9) == 0) {
vol->server_ino = 0; vol->server_ino = 0;
} else if (strnicmp(data, "rwpidforward", 4) == 0) {
vol->rwpidforward = 1;
} else if (strnicmp(data, "cifsacl", 7) == 0) { } else if (strnicmp(data, "cifsacl", 7) == 0) {
vol->cifs_acl = 1; vol->cifs_acl = 1;
} else if (strnicmp(data, "nocifsacl", 9) == 0) { } else if (strnicmp(data, "nocifsacl", 9) == 0) {
...@@ -1640,16 +1597,35 @@ match_security(struct TCP_Server_Info *server, struct smb_vol *vol) ...@@ -1640,16 +1597,35 @@ match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
/* now check if signing mode is acceptable */ /* now check if signing mode is acceptable */
if ((secFlags & CIFSSEC_MAY_SIGN) == 0 && if ((secFlags & CIFSSEC_MAY_SIGN) == 0 &&
(server->secMode & SECMODE_SIGN_REQUIRED)) (server->sec_mode & SECMODE_SIGN_REQUIRED))
return false; return false;
else if (((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) && else if (((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) &&
(server->secMode & (server->sec_mode &
(SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)) == 0) (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)) == 0)
return false; return false;
return true; return true;
} }
static int match_server(struct TCP_Server_Info *server, struct sockaddr *addr,
struct smb_vol *vol)
{
if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns))
return 0;
if (!match_address(server, addr,
(struct sockaddr *)&vol->srcaddr))
return 0;
if (!match_port(server, addr))
return 0;
if (!match_security(server, vol))
return 0;
return 1;
}
static struct TCP_Server_Info * static struct TCP_Server_Info *
cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol) cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
{ {
...@@ -1657,17 +1633,7 @@ cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol) ...@@ -1657,17 +1633,7 @@ cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns)) if (!match_server(server, addr, vol))
continue;
if (!match_address(server, addr,
(struct sockaddr *)&vol->srcaddr))
continue;
if (!match_port(server, addr))
continue;
if (!match_security(server, vol))
continue; continue;
++server->srv_count; ++server->srv_count;
...@@ -1861,32 +1827,39 @@ cifs_get_tcp_session(struct smb_vol *volume_info) ...@@ -1861,32 +1827,39 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
return ERR_PTR(rc); return ERR_PTR(rc);
} }
static struct cifsSesInfo * static int match_session(struct cifs_ses *ses, struct smb_vol *vol)
{
switch (ses->server->secType) {
case Kerberos:
if (vol->cred_uid != ses->cred_uid)
return 0;
break;
default:
/* anything else takes username/password */
if (ses->user_name == NULL)
return 0;
if (strncmp(ses->user_name, vol->username,
MAX_USERNAME_SIZE))
return 0;
if (strlen(vol->username) != 0 &&
ses->password != NULL &&
strncmp(ses->password,
vol->password ? vol->password : "",
MAX_PASSWORD_SIZE))
return 0;
}
return 1;
}
static struct cifs_ses *
cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol) cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
{ {
struct cifsSesInfo *ses; struct cifs_ses *ses;
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
switch (server->secType) { if (!match_session(ses, vol))
case Kerberos: continue;
if (vol->cred_uid != ses->cred_uid)
continue;
break;
default:
/* anything else takes username/password */
if (ses->user_name == NULL)
continue;
if (strncmp(ses->user_name, vol->username,
MAX_USERNAME_SIZE))
continue;
if (strlen(vol->username) != 0 &&
ses->password != NULL &&
strncmp(ses->password,
vol->password ? vol->password : "",
MAX_PASSWORD_SIZE))
continue;
}
++ses->ses_count; ++ses->ses_count;
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
return ses; return ses;
...@@ -1896,7 +1869,7 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol) ...@@ -1896,7 +1869,7 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
} }
static void static void
cifs_put_smb_ses(struct cifsSesInfo *ses) cifs_put_smb_ses(struct cifs_ses *ses)
{ {
int xid; int xid;
struct TCP_Server_Info *server = ses->server; struct TCP_Server_Info *server = ses->server;
...@@ -1922,11 +1895,11 @@ cifs_put_smb_ses(struct cifsSesInfo *ses) ...@@ -1922,11 +1895,11 @@ cifs_put_smb_ses(struct cifsSesInfo *ses)
static bool warned_on_ntlm; /* globals init to false automatically */ static bool warned_on_ntlm; /* globals init to false automatically */
static struct cifsSesInfo * static struct cifs_ses *
cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
{ {
int rc = -ENOMEM, xid; int rc = -ENOMEM, xid;
struct cifsSesInfo *ses; struct cifs_ses *ses;
struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr; struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr; struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
...@@ -2029,20 +2002,26 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) ...@@ -2029,20 +2002,26 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
return ERR_PTR(rc); return ERR_PTR(rc);
} }
static struct cifsTconInfo * static int match_tcon(struct cifs_tcon *tcon, const char *unc)
cifs_find_tcon(struct cifsSesInfo *ses, const char *unc) {
if (tcon->tidStatus == CifsExiting)
return 0;
if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
return 0;
return 1;
}
static struct cifs_tcon *
cifs_find_tcon(struct cifs_ses *ses, const char *unc)
{ {
struct list_head *tmp; struct list_head *tmp;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
list_for_each(tmp, &ses->tcon_list) { list_for_each(tmp, &ses->tcon_list) {
tcon = list_entry(tmp, struct cifsTconInfo, tcon_list); tcon = list_entry(tmp, struct cifs_tcon, tcon_list);
if (tcon->tidStatus == CifsExiting) if (!match_tcon(tcon, unc))
continue;
if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
continue; continue;
++tcon->tc_count; ++tcon->tc_count;
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
return tcon; return tcon;
...@@ -2052,10 +2031,10 @@ cifs_find_tcon(struct cifsSesInfo *ses, const char *unc) ...@@ -2052,10 +2031,10 @@ cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
} }
static void static void
cifs_put_tcon(struct cifsTconInfo *tcon) cifs_put_tcon(struct cifs_tcon *tcon)
{ {
int xid; int xid;
struct cifsSesInfo *ses = tcon->ses; struct cifs_ses *ses = tcon->ses;
cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count); cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count);
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
...@@ -2076,11 +2055,11 @@ cifs_put_tcon(struct cifsTconInfo *tcon) ...@@ -2076,11 +2055,11 @@ cifs_put_tcon(struct cifsTconInfo *tcon)
cifs_put_smb_ses(ses); cifs_put_smb_ses(ses);
} }
static struct cifsTconInfo * static struct cifs_tcon *
cifs_get_tcon(struct cifsSesInfo *ses, struct smb_vol *volume_info) cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
{ {
int rc, xid; int rc, xid;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
tcon = cifs_find_tcon(ses, volume_info->UNC); tcon = cifs_find_tcon(ses, volume_info->UNC);
if (tcon) { if (tcon) {
...@@ -2169,8 +2148,102 @@ cifs_put_tlink(struct tcon_link *tlink) ...@@ -2169,8 +2148,102 @@ cifs_put_tlink(struct tcon_link *tlink)
return; return;
} }
static inline struct tcon_link *
cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb);
static int
compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
{
struct cifs_sb_info *old = CIFS_SB(sb);
struct cifs_sb_info *new = mnt_data->cifs_sb;
if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK))
return 0;
if ((old->mnt_cifs_flags & CIFS_MOUNT_MASK) !=
(new->mnt_cifs_flags & CIFS_MOUNT_MASK))
return 0;
if (old->rsize != new->rsize)
return 0;
/*
* We want to share sb only if we don't specify wsize or specified wsize
* is greater or equal than existing one.
*/
if (new->wsize && new->wsize < old->wsize)
return 0;
if (old->mnt_uid != new->mnt_uid || old->mnt_gid != new->mnt_gid)
return 0;
if (old->mnt_file_mode != new->mnt_file_mode ||
old->mnt_dir_mode != new->mnt_dir_mode)
return 0;
if (strcmp(old->local_nls->charset, new->local_nls->charset))
return 0;
if (old->actimeo != new->actimeo)
return 0;
return 1;
}
int int
get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, cifs_match_super(struct super_block *sb, void *data)
{
struct cifs_mnt_data *mnt_data = (struct cifs_mnt_data *)data;
struct smb_vol *volume_info;
struct cifs_sb_info *cifs_sb;
struct TCP_Server_Info *tcp_srv;
struct cifs_ses *ses;
struct cifs_tcon *tcon;
struct tcon_link *tlink;
struct sockaddr_storage addr;
int rc = 0;
memset(&addr, 0, sizeof(struct sockaddr_storage));
spin_lock(&cifs_tcp_ses_lock);
cifs_sb = CIFS_SB(sb);
tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
if (IS_ERR(tlink)) {
spin_unlock(&cifs_tcp_ses_lock);
return rc;
}
tcon = tlink_tcon(tlink);
ses = tcon->ses;
tcp_srv = ses->server;
volume_info = mnt_data->vol;
if (!volume_info->UNCip || !volume_info->UNC)
goto out;
rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
volume_info->UNCip,
strlen(volume_info->UNCip),
volume_info->port);
if (!rc)
goto out;
if (!match_server(tcp_srv, (struct sockaddr *)&addr, volume_info) ||
!match_session(ses, volume_info) ||
!match_tcon(tcon, volume_info->UNC)) {
rc = 0;
goto out;
}
rc = compare_mount_options(sb, mnt_data);
out:
cifs_put_tlink(tlink);
spin_unlock(&cifs_tcp_ses_lock);
return rc;
}
int
get_dfs_path(int xid, struct cifs_ses *pSesInfo, const char *old_path,
const struct nls_table *nls_codepage, unsigned int *pnum_referrals, const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
struct dfs_info3_param **preferrals, int remap) struct dfs_info3_param **preferrals, int remap)
{ {
...@@ -2469,7 +2542,7 @@ ip_connect(struct TCP_Server_Info *server) ...@@ -2469,7 +2542,7 @@ ip_connect(struct TCP_Server_Info *server)
return generic_ip_connect(server); return generic_ip_connect(server);
} }
void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon,
struct super_block *sb, struct smb_vol *vol_info) struct super_block *sb, struct smb_vol *vol_info)
{ {
/* if we are reconnecting then should we check to see if /* if we are reconnecting then should we check to see if
...@@ -2498,7 +2571,7 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, ...@@ -2498,7 +2571,7 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
if (!CIFSSMBQFSUnixInfo(xid, tcon)) { if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
__u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability); __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
cFYI(1, "unix caps which server supports %lld", cap);
/* check for reconnect case in which we do not /* check for reconnect case in which we do not
want to change the mount behavior if we can avoid it */ want to change the mount behavior if we can avoid it */
if (vol_info == NULL) { if (vol_info == NULL) {
...@@ -2516,6 +2589,9 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, ...@@ -2516,6 +2589,9 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
} }
} }
if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
cERROR(1, "per-share encryption not supported yet");
cap &= CIFS_UNIX_CAP_MASK; cap &= CIFS_UNIX_CAP_MASK;
if (vol_info && vol_info->no_psx_acl) if (vol_info && vol_info->no_psx_acl)
cap &= ~CIFS_UNIX_POSIX_ACL_CAP; cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
...@@ -2534,12 +2610,6 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, ...@@ -2534,12 +2610,6 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
CIFS_MOUNT_POSIX_PATHS; CIFS_MOUNT_POSIX_PATHS;
} }
/* We might be setting the path sep back to a different
form if we are reconnecting and the server switched its
posix path capability for this share */
if (sb && (CIFS_SB(sb)->prepathlen > 0))
CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) { if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) { if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
CIFS_SB(sb)->rsize = 127 * 1024; CIFS_SB(sb)->rsize = 127 * 1024;
...@@ -2564,6 +2634,10 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, ...@@ -2564,6 +2634,10 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
cFYI(1, "very large read cap"); cFYI(1, "very large read cap");
if (cap & CIFS_UNIX_LARGE_WRITE_CAP) if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
cFYI(1, "very large write cap"); cFYI(1, "very large write cap");
if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)
cFYI(1, "transport encryption cap");
if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
cFYI(1, "mandatory transport encryption cap");
#endif /* CIFS_DEBUG2 */ #endif /* CIFS_DEBUG2 */
if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
if (vol_info == NULL) { if (vol_info == NULL) {
...@@ -2580,28 +2654,8 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, ...@@ -2580,28 +2654,8 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
} }
} }
static void void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
convert_delimiter(char *path, char delim) struct cifs_sb_info *cifs_sb)
{
int i;
char old_delim;
if (path == NULL)
return;
if (delim == '/')
old_delim = '\\';
else
old_delim = '/';
for (i = 0; path[i] != '\0'; i++) {
if (path[i] == old_delim)
path[i] = delim;
}
}
static void setup_cifs_sb(struct smb_vol *pvolume_info,
struct cifs_sb_info *cifs_sb)
{ {
INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks); INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks);
...@@ -2615,40 +2669,19 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info, ...@@ -2615,40 +2669,19 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
else /* default */ else /* default */
cifs_sb->rsize = CIFSMaxBufSize; cifs_sb->rsize = CIFSMaxBufSize;
if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
cERROR(1, "wsize %d too large, using 4096 instead",
pvolume_info->wsize);
cifs_sb->wsize = 4096;
} else if (pvolume_info->wsize)
cifs_sb->wsize = pvolume_info->wsize;
else
cifs_sb->wsize = min_t(const int,
PAGEVEC_SIZE * PAGE_CACHE_SIZE,
127*1024);
/* old default of CIFSMaxBufSize was too small now
that SMB Write2 can send multiple pages in kvec.
RFC1001 does not describe what happens when frame
bigger than 128K is sent so use that as max in
conjunction with 52K kvec constraint on arch with 4K
page size */
if (cifs_sb->rsize < 2048) { if (cifs_sb->rsize < 2048) {
cifs_sb->rsize = 2048; cifs_sb->rsize = 2048;
/* Windows ME may prefer this */ /* Windows ME may prefer this */
cFYI(1, "readsize set to minimum: 2048"); cFYI(1, "readsize set to minimum: 2048");
} }
/* calculate prepath */
cifs_sb->prepath = pvolume_info->prepath; /*
if (cifs_sb->prepath) { * Temporarily set wsize for matching superblock. If we end up using
cifs_sb->prepathlen = strlen(cifs_sb->prepath); * new sb then cifs_negotiate_wsize will later negotiate it downward
/* we can not convert the / to \ in the path * if needed.
separators in the prefixpath yet because we do not */
know (until reset_cifs_unix_caps is called later) cifs_sb->wsize = pvolume_info->wsize;
whether POSIX PATH CAP is available. We normalize
the / to \ after reset_cifs_unix_caps is called */
pvolume_info->prepath = NULL;
} else
cifs_sb->prepathlen = 0;
cifs_sb->mnt_uid = pvolume_info->linux_uid; cifs_sb->mnt_uid = pvolume_info->linux_uid;
cifs_sb->mnt_gid = pvolume_info->linux_gid; cifs_sb->mnt_gid = pvolume_info->linux_gid;
cifs_sb->mnt_file_mode = pvolume_info->file_mode; cifs_sb->mnt_file_mode = pvolume_info->file_mode;
...@@ -2657,6 +2690,7 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info, ...@@ -2657,6 +2690,7 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode); cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
cifs_sb->actimeo = pvolume_info->actimeo; cifs_sb->actimeo = pvolume_info->actimeo;
cifs_sb->local_nls = pvolume_info->local_nls;
if (pvolume_info->noperm) if (pvolume_info->noperm)
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
...@@ -2676,6 +2710,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info, ...@@ -2676,6 +2710,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC; cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
if (pvolume_info->mand_lock) if (pvolume_info->mand_lock)
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL; cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
if (pvolume_info->rwpidforward)
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
if (pvolume_info->cifs_acl) if (pvolume_info->cifs_acl)
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
if (pvolume_info->override_uid) if (pvolume_info->override_uid)
...@@ -2709,8 +2745,55 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info, ...@@ -2709,8 +2745,55 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
"mount option supported"); "mount option supported");
} }
/*
* When the server supports very large writes via POSIX extensions, we can
* allow up to 2^24 - PAGE_CACHE_SIZE.
*
* Note that this might make for "interesting" allocation problems during
* writeback however (as we have to allocate an array of pointers for the
* pages). A 16M write means ~32kb page array with PAGE_CACHE_SIZE == 4096.
*/
#define CIFS_MAX_WSIZE ((1<<24) - PAGE_CACHE_SIZE)
/*
* When the server doesn't allow large posix writes, default to a wsize of
* 128k - PAGE_CACHE_SIZE -- one page less than the largest frame size
* described in RFC1001. This allows space for the header without going over
* that by default.
*/
#define CIFS_MAX_RFC1001_WSIZE (128 * 1024 - PAGE_CACHE_SIZE)
/*
* The default wsize is 1M. find_get_pages seems to return a maximum of 256
* pages in a single call. With PAGE_CACHE_SIZE == 4k, this means we can fill
* a single wsize request with a single call.
*/
#define CIFS_DEFAULT_WSIZE (1024 * 1024)
static unsigned int
cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
{
__u64 unix_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
struct TCP_Server_Info *server = tcon->ses->server;
unsigned int wsize = pvolume_info->wsize ? pvolume_info->wsize :
CIFS_DEFAULT_WSIZE;
/* can server support 24-bit write sizes? (via UNIX extensions) */
if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP))
wsize = min_t(unsigned int, wsize, CIFS_MAX_RFC1001_WSIZE);
/* no CAP_LARGE_WRITE_X? Limit it to 16 bits */
if (!(server->capabilities & CAP_LARGE_WRITE_X))
wsize = min_t(unsigned int, wsize, USHRT_MAX);
/* hard limit of CIFS_MAX_WSIZE */
wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE);
return wsize;
}
static int static int
is_path_accessible(int xid, struct cifsTconInfo *tcon, is_path_accessible(int xid, struct cifs_tcon *tcon,
struct cifs_sb_info *cifs_sb, const char *full_path) struct cifs_sb_info *cifs_sb, const char *full_path)
{ {
int rc; int rc;
...@@ -2733,8 +2816,8 @@ is_path_accessible(int xid, struct cifsTconInfo *tcon, ...@@ -2733,8 +2816,8 @@ is_path_accessible(int xid, struct cifsTconInfo *tcon,
return rc; return rc;
} }
static void void
cleanup_volume_info(struct smb_vol **pvolume_info) cifs_cleanup_volume_info(struct smb_vol **pvolume_info)
{ {
struct smb_vol *volume_info; struct smb_vol *volume_info;
...@@ -2764,24 +2847,13 @@ build_unc_path_to_root(const struct smb_vol *volume_info, ...@@ -2764,24 +2847,13 @@ build_unc_path_to_root(const struct smb_vol *volume_info,
char *full_path; char *full_path;
int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1); int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1);
full_path = kmalloc(unc_len + cifs_sb->prepathlen + 1, GFP_KERNEL); full_path = kmalloc(unc_len + 1, GFP_KERNEL);
if (full_path == NULL) if (full_path == NULL)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
strncpy(full_path, volume_info->UNC, unc_len); strncpy(full_path, volume_info->UNC, unc_len);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { full_path[unc_len] = 0; /* add trailing null */
int i; convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
for (i = 0; i < unc_len; i++) {
if (full_path[i] == '\\')
full_path[i] = '/';
}
}
if (cifs_sb->prepathlen)
strncpy(full_path + unc_len, cifs_sb->prepath,
cifs_sb->prepathlen);
full_path[unc_len + cifs_sb->prepathlen] = 0; /* add trailing null */
return full_path; return full_path;
} }
...@@ -2796,7 +2868,7 @@ build_unc_path_to_root(const struct smb_vol *volume_info, ...@@ -2796,7 +2868,7 @@ build_unc_path_to_root(const struct smb_vol *volume_info,
* determine whether there were referrals. * determine whether there were referrals.
*/ */
static int static int
expand_dfs_referral(int xid, struct cifsSesInfo *pSesInfo, expand_dfs_referral(int xid, struct cifs_ses *pSesInfo,
struct smb_vol *volume_info, struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info, struct cifs_sb_info *cifs_sb,
int check_prefix) int check_prefix)
{ {
...@@ -2840,40 +2912,13 @@ expand_dfs_referral(int xid, struct cifsSesInfo *pSesInfo, ...@@ -2840,40 +2912,13 @@ expand_dfs_referral(int xid, struct cifsSesInfo *pSesInfo,
} }
#endif #endif
int int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data,
cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, const char *devname)
const char *devname)
{ {
int rc;
int xid;
struct smb_vol *volume_info; struct smb_vol *volume_info;
struct cifsSesInfo *pSesInfo; int rc = 0;
struct cifsTconInfo *tcon;
struct TCP_Server_Info *srvTcp;
char *full_path;
struct tcon_link *tlink;
#ifdef CONFIG_CIFS_DFS_UPCALL
int referral_walks_count = 0;
try_mount_again:
/* cleanup activities if we're chasing a referral */
if (referral_walks_count) {
if (tcon)
cifs_put_tcon(tcon);
else if (pSesInfo)
cifs_put_smb_ses(pSesInfo);
cleanup_volume_info(&volume_info);
FreeXid(xid);
}
#endif
rc = 0;
tcon = NULL;
pSesInfo = NULL;
srvTcp = NULL;
full_path = NULL;
tlink = NULL;
xid = GetXid(); *pvolume_info = NULL;
volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL); volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL);
if (!volume_info) { if (!volume_info) {
...@@ -2881,7 +2926,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -2881,7 +2926,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
goto out; goto out;
} }
if (cifs_parse_mount_options(cifs_sb->mountdata, devname, if (cifs_parse_mount_options(mount_data, devname,
volume_info)) { volume_info)) {
rc = -EINVAL; rc = -EINVAL;
goto out; goto out;
...@@ -2914,7 +2959,46 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -2914,7 +2959,46 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
goto out; goto out;
} }
} }
cifs_sb->local_nls = volume_info->local_nls;
*pvolume_info = volume_info;
return rc;
out:
cifs_cleanup_volume_info(&volume_info);
return rc;
}
int
cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
struct smb_vol *volume_info, const char *devname)
{
int rc = 0;
int xid;
struct cifs_ses *pSesInfo;
struct cifs_tcon *tcon;
struct TCP_Server_Info *srvTcp;
char *full_path;
struct tcon_link *tlink;
#ifdef CONFIG_CIFS_DFS_UPCALL
int referral_walks_count = 0;
try_mount_again:
/* cleanup activities if we're chasing a referral */
if (referral_walks_count) {
if (tcon)
cifs_put_tcon(tcon);
else if (pSesInfo)
cifs_put_smb_ses(pSesInfo);
cifs_cleanup_volume_info(&volume_info);
FreeXid(xid);
}
#endif
tcon = NULL;
pSesInfo = NULL;
srvTcp = NULL;
full_path = NULL;
tlink = NULL;
xid = GetXid();
/* get a reference to a tcp session */ /* get a reference to a tcp session */
srvTcp = cifs_get_tcp_session(volume_info); srvTcp = cifs_get_tcp_session(volume_info);
...@@ -2931,7 +3015,6 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -2931,7 +3015,6 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
goto mount_fail_check; goto mount_fail_check;
} }
setup_cifs_sb(volume_info, cifs_sb);
if (pSesInfo->capabilities & CAP_LARGE_FILES) if (pSesInfo->capabilities & CAP_LARGE_FILES)
sb->s_maxbytes = MAX_LFS_FILESIZE; sb->s_maxbytes = MAX_LFS_FILESIZE;
else else
...@@ -2948,35 +3031,36 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -2948,35 +3031,36 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
goto remote_path_check; goto remote_path_check;
} }
/* do not care if following two calls succeed - informational */
if (!tcon->ipc) {
CIFSSMBQFSDeviceInfo(xid, tcon);
CIFSSMBQFSAttributeInfo(xid, tcon);
}
/* tell server which Unix caps we support */ /* tell server which Unix caps we support */
if (tcon->ses->capabilities & CAP_UNIX) if (tcon->ses->capabilities & CAP_UNIX) {
/* reset of caps checks mount to see if unix extensions /* reset of caps checks mount to see if unix extensions
disabled for just this mount */ disabled for just this mount */
reset_cifs_unix_caps(xid, tcon, sb, volume_info); reset_cifs_unix_caps(xid, tcon, sb, volume_info);
else if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) &&
(le64_to_cpu(tcon->fsUnixInfo.Capability) &
CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) {
rc = -EACCES;
goto mount_fail_check;
}
} else
tcon->unix_ext = 0; /* server does not support them */ tcon->unix_ext = 0; /* server does not support them */
/* convert forward to back slashes in prepath here if needed */ /* do not care if following two calls succeed - informational */
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0) if (!tcon->ipc) {
convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb)); CIFSSMBQFSDeviceInfo(xid, tcon);
CIFSSMBQFSAttributeInfo(xid, tcon);
}
if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) { if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
cifs_sb->rsize = 1024 * 127; cifs_sb->rsize = 1024 * 127;
cFYI(DBG2, "no very large read support, rsize now 127K"); cFYI(DBG2, "no very large read support, rsize now 127K");
} }
if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
cifs_sb->wsize = min(cifs_sb->wsize,
(tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
if (!(tcon->ses->capabilities & CAP_LARGE_READ_X)) if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
cifs_sb->rsize = min(cifs_sb->rsize, cifs_sb->rsize = min(cifs_sb->rsize,
(tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
cifs_sb->wsize = cifs_negotiate_wsize(tcon, volume_info);
remote_path_check: remote_path_check:
#ifdef CONFIG_CIFS_DFS_UPCALL #ifdef CONFIG_CIFS_DFS_UPCALL
/* /*
...@@ -2996,10 +3080,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -2996,10 +3080,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
} }
#endif #endif
/* check if a whole path (including prepath) is not remote */ /* check if a whole path is not remote */
if (!rc && tcon) { if (!rc && tcon) {
/* build_path_to_root works only when we have a valid tcon */ /* build_path_to_root works only when we have a valid tcon */
full_path = cifs_build_path_to_root(cifs_sb, tcon); full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon);
if (full_path == NULL) { if (full_path == NULL) {
rc = -ENOMEM; rc = -ENOMEM;
goto mount_fail_check; goto mount_fail_check;
...@@ -3025,10 +3109,6 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -3025,10 +3109,6 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
rc = -ELOOP; rc = -ELOOP;
goto mount_fail_check; goto mount_fail_check;
} }
/* convert forward to back slashes in prepath here if needed */
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
convert_delimiter(cifs_sb->prepath,
CIFS_DIR_SEP(cifs_sb));
rc = expand_dfs_referral(xid, pSesInfo, volume_info, cifs_sb, rc = expand_dfs_referral(xid, pSesInfo, volume_info, cifs_sb,
true); true);
...@@ -3087,14 +3167,13 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -3087,14 +3167,13 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
password will be freed at unmount time) */ password will be freed at unmount time) */
out: out:
/* zero out password before freeing */ /* zero out password before freeing */
cleanup_volume_info(&volume_info);
FreeXid(xid); FreeXid(xid);
return rc; return rc;
} }
int int
CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, CIFSTCon(unsigned int xid, struct cifs_ses *ses,
const char *tree, struct cifsTconInfo *tcon, const char *tree, struct cifs_tcon *tcon,
const struct nls_table *nls_codepage) const struct nls_table *nls_codepage)
{ {
struct smb_hdr *smb_buffer; struct smb_hdr *smb_buffer;
...@@ -3126,7 +3205,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, ...@@ -3126,7 +3205,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
pSMB->AndXCommand = 0xFF; pSMB->AndXCommand = 0xFF;
pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
bcc_ptr = &pSMB->Password[0]; bcc_ptr = &pSMB->Password[0];
if ((ses->server->secMode) & SECMODE_USER) { if ((ses->server->sec_mode) & SECMODE_USER) {
pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
*bcc_ptr = 0; /* password is null byte */ *bcc_ptr = 0; /* password is null byte */
bcc_ptr++; /* skip password */ bcc_ptr++; /* skip password */
...@@ -3143,7 +3222,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, ...@@ -3143,7 +3222,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
if ((global_secflags & CIFSSEC_MAY_LANMAN) && if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
(ses->server->secType == LANMAN)) (ses->server->secType == LANMAN))
calc_lanman_hash(tcon->password, ses->server->cryptkey, calc_lanman_hash(tcon->password, ses->server->cryptkey,
ses->server->secMode & ses->server->sec_mode &
SECMODE_PW_ENCRYPT ? true : false, SECMODE_PW_ENCRYPT ? true : false,
bcc_ptr); bcc_ptr);
else else
...@@ -3159,7 +3238,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, ...@@ -3159,7 +3238,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
} }
} }
if (ses->server->secMode & if (ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
...@@ -3255,7 +3334,6 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) ...@@ -3255,7 +3334,6 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
struct rb_root *root = &cifs_sb->tlink_tree; struct rb_root *root = &cifs_sb->tlink_tree;
struct rb_node *node; struct rb_node *node;
struct tcon_link *tlink; struct tcon_link *tlink;
char *tmp;
cancel_delayed_work_sync(&cifs_sb->prune_tlinks); cancel_delayed_work_sync(&cifs_sb->prune_tlinks);
...@@ -3272,15 +3350,10 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) ...@@ -3272,15 +3350,10 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
} }
spin_unlock(&cifs_sb->tlink_tree_lock); spin_unlock(&cifs_sb->tlink_tree_lock);
tmp = cifs_sb->prepath;
cifs_sb->prepathlen = 0;
cifs_sb->prepath = NULL;
kfree(tmp);
return 0; return 0;
} }
int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses) int cifs_negotiate_protocol(unsigned int xid, struct cifs_ses *ses)
{ {
int rc = 0; int rc = 0;
struct TCP_Server_Info *server = ses->server; struct TCP_Server_Info *server = ses->server;
...@@ -3310,7 +3383,7 @@ int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses) ...@@ -3310,7 +3383,7 @@ int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
} }
int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses, int cifs_setup_session(unsigned int xid, struct cifs_ses *ses,
struct nls_table *nls_info) struct nls_table *nls_info)
{ {
int rc = 0; int rc = 0;
...@@ -3322,7 +3395,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses, ...@@ -3322,7 +3395,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
ses->capabilities &= (~CAP_UNIX); ses->capabilities &= (~CAP_UNIX);
cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d", cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
server->secMode, server->capabilities, server->timeAdj); server->sec_mode, server->capabilities, server->timeAdj);
rc = CIFS_SessSetup(xid, ses, nls_info); rc = CIFS_SessSetup(xid, ses, nls_info);
if (rc) { if (rc) {
...@@ -3354,12 +3427,12 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses, ...@@ -3354,12 +3427,12 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
return rc; return rc;
} }
static struct cifsTconInfo * static struct cifs_tcon *
cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid) cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
{ {
struct cifsTconInfo *master_tcon = cifs_sb_master_tcon(cifs_sb); struct cifs_tcon *master_tcon = cifs_sb_master_tcon(cifs_sb);
struct cifsSesInfo *ses; struct cifs_ses *ses;
struct cifsTconInfo *tcon = NULL; struct cifs_tcon *tcon = NULL;
struct smb_vol *vol_info; struct smb_vol *vol_info;
char username[28]; /* big enough for "krb50x" + hex of ULONG_MAX 6+16 */ char username[28]; /* big enough for "krb50x" + hex of ULONG_MAX 6+16 */
/* We used to have this as MAX_USERNAME which is */ /* We used to have this as MAX_USERNAME which is */
...@@ -3392,7 +3465,7 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid) ...@@ -3392,7 +3465,7 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info); ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info);
if (IS_ERR(ses)) { if (IS_ERR(ses)) {
tcon = (struct cifsTconInfo *)ses; tcon = (struct cifs_tcon *)ses;
cifs_put_tcp_session(master_tcon->ses->server); cifs_put_tcp_session(master_tcon->ses->server);
goto out; goto out;
} }
...@@ -3417,7 +3490,7 @@ cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb) ...@@ -3417,7 +3490,7 @@ cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb)
return cifs_sb->master_tlink; return cifs_sb->master_tlink;
} }
struct cifsTconInfo * struct cifs_tcon *
cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb) cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
{ {
return tlink_tcon(cifs_sb_master_tlink(cifs_sb)); return tlink_tcon(cifs_sb_master_tlink(cifs_sb));
......
...@@ -50,12 +50,11 @@ build_path_from_dentry(struct dentry *direntry) ...@@ -50,12 +50,11 @@ build_path_from_dentry(struct dentry *direntry)
{ {
struct dentry *temp; struct dentry *temp;
int namelen; int namelen;
int pplen;
int dfsplen; int dfsplen;
char *full_path; char *full_path;
char dirsep; char dirsep;
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
if (direntry == NULL) if (direntry == NULL)
return NULL; /* not much we can do if dentry is freed and return NULL; /* not much we can do if dentry is freed and
...@@ -63,13 +62,12 @@ build_path_from_dentry(struct dentry *direntry) ...@@ -63,13 +62,12 @@ build_path_from_dentry(struct dentry *direntry)
when the server crashed */ when the server crashed */
dirsep = CIFS_DIR_SEP(cifs_sb); dirsep = CIFS_DIR_SEP(cifs_sb);
pplen = cifs_sb->prepathlen;
if (tcon->Flags & SMB_SHARE_IS_IN_DFS) if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1); dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
else else
dfsplen = 0; dfsplen = 0;
cifs_bp_rename_retry: cifs_bp_rename_retry:
namelen = pplen + dfsplen; namelen = dfsplen;
for (temp = direntry; !IS_ROOT(temp);) { for (temp = direntry; !IS_ROOT(temp);) {
namelen += (1 + temp->d_name.len); namelen += (1 + temp->d_name.len);
temp = temp->d_parent; temp = temp->d_parent;
...@@ -100,7 +98,7 @@ build_path_from_dentry(struct dentry *direntry) ...@@ -100,7 +98,7 @@ build_path_from_dentry(struct dentry *direntry)
return NULL; return NULL;
} }
} }
if (namelen != pplen + dfsplen) { if (namelen != dfsplen) {
cERROR(1, "did not end path lookup where expected namelen is %d", cERROR(1, "did not end path lookup where expected namelen is %d",
namelen); namelen);
/* presumably this is only possible if racing with a rename /* presumably this is only possible if racing with a rename
...@@ -126,7 +124,6 @@ build_path_from_dentry(struct dentry *direntry) ...@@ -126,7 +124,6 @@ build_path_from_dentry(struct dentry *direntry)
} }
} }
} }
strncpy(full_path + dfsplen, CIFS_SB(direntry->d_sb)->prepath, pplen);
return full_path; return full_path;
} }
...@@ -152,7 +149,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, ...@@ -152,7 +149,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
__u16 fileHandle; __u16 fileHandle;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
char *full_path = NULL; char *full_path = NULL;
FILE_ALL_INFO *buf = NULL; FILE_ALL_INFO *buf = NULL;
struct inode *newinode = NULL; struct inode *newinode = NULL;
...@@ -356,7 +353,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, ...@@ -356,7 +353,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
int xid; int xid;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
struct cifs_io_parms io_parms;
char *full_path = NULL; char *full_path = NULL;
struct inode *newinode = NULL; struct inode *newinode = NULL;
int oplock = 0; int oplock = 0;
...@@ -439,16 +437,19 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, ...@@ -439,16 +437,19 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
* timestamps in, but we can reuse it safely */ * timestamps in, but we can reuse it safely */
pdev = (struct win_dev *)buf; pdev = (struct win_dev *)buf;
io_parms.netfid = fileHandle;
io_parms.pid = current->tgid;
io_parms.tcon = pTcon;
io_parms.offset = 0;
io_parms.length = sizeof(struct win_dev);
if (S_ISCHR(mode)) { if (S_ISCHR(mode)) {
memcpy(pdev->type, "IntxCHR", 8); memcpy(pdev->type, "IntxCHR", 8);
pdev->major = pdev->major =
cpu_to_le64(MAJOR(device_number)); cpu_to_le64(MAJOR(device_number));
pdev->minor = pdev->minor =
cpu_to_le64(MINOR(device_number)); cpu_to_le64(MINOR(device_number));
rc = CIFSSMBWrite(xid, pTcon, rc = CIFSSMBWrite(xid, &io_parms,
fileHandle, &bytes_written, (char *)pdev,
sizeof(struct win_dev),
0, &bytes_written, (char *)pdev,
NULL, 0); NULL, 0);
} else if (S_ISBLK(mode)) { } else if (S_ISBLK(mode)) {
memcpy(pdev->type, "IntxBLK", 8); memcpy(pdev->type, "IntxBLK", 8);
...@@ -456,10 +457,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, ...@@ -456,10 +457,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
cpu_to_le64(MAJOR(device_number)); cpu_to_le64(MAJOR(device_number));
pdev->minor = pdev->minor =
cpu_to_le64(MINOR(device_number)); cpu_to_le64(MINOR(device_number));
rc = CIFSSMBWrite(xid, pTcon, rc = CIFSSMBWrite(xid, &io_parms,
fileHandle, &bytes_written, (char *)pdev,
sizeof(struct win_dev),
0, &bytes_written, (char *)pdev,
NULL, 0); NULL, 0);
} /* else if (S_ISFIFO) */ } /* else if (S_ISFIFO) */
CIFSSMBClose(xid, pTcon, fileHandle); CIFSSMBClose(xid, pTcon, fileHandle);
...@@ -486,7 +485,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, ...@@ -486,7 +485,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
bool posix_open = false; bool posix_open = false;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
struct cifsFileInfo *cfile; struct cifsFileInfo *cfile;
struct inode *newInode = NULL; struct inode *newInode = NULL;
char *full_path = NULL; char *full_path = NULL;
......
...@@ -114,7 +114,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode, ...@@ -114,7 +114,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifs_fattr fattr; struct cifs_fattr fattr;
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
cFYI(1, "posix open %s", full_path); cFYI(1, "posix open %s", full_path);
...@@ -168,7 +168,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode, ...@@ -168,7 +168,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
static int static int
cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb, cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
struct cifsTconInfo *tcon, unsigned int f_flags, __u32 *poplock, struct cifs_tcon *tcon, unsigned int f_flags, __u32 *poplock,
__u16 *pnetfid, int xid) __u16 *pnetfid, int xid)
{ {
int rc; int rc;
...@@ -285,7 +285,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file, ...@@ -285,7 +285,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
void cifsFileInfo_put(struct cifsFileInfo *cifs_file) void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
{ {
struct inode *inode = cifs_file->dentry->d_inode; struct inode *inode = cifs_file->dentry->d_inode;
struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink); struct cifs_tcon *tcon = tlink_tcon(cifs_file->tlink);
struct cifsInodeInfo *cifsi = CIFS_I(inode); struct cifsInodeInfo *cifsi = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct cifsLockInfo *li, *tmp; struct cifsLockInfo *li, *tmp;
...@@ -343,7 +343,7 @@ int cifs_open(struct inode *inode, struct file *file) ...@@ -343,7 +343,7 @@ int cifs_open(struct inode *inode, struct file *file)
int xid; int xid;
__u32 oplock; __u32 oplock;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsFileInfo *pCifsFile = NULL; struct cifsFileInfo *pCifsFile = NULL;
char *full_path = NULL; char *full_path = NULL;
...@@ -457,7 +457,7 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush) ...@@ -457,7 +457,7 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
int xid; int xid;
__u32 oplock; __u32 oplock;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
struct cifsInodeInfo *pCifsInode; struct cifsInodeInfo *pCifsInode;
struct inode *inode; struct inode *inode;
char *full_path = NULL; char *full_path = NULL;
...@@ -596,7 +596,7 @@ int cifs_closedir(struct inode *inode, struct file *file) ...@@ -596,7 +596,7 @@ int cifs_closedir(struct inode *inode, struct file *file)
xid = GetXid(); xid = GetXid();
if (pCFileStruct) { if (pCFileStruct) {
struct cifsTconInfo *pTcon = tlink_tcon(pCFileStruct->tlink); struct cifs_tcon *pTcon = tlink_tcon(pCFileStruct->tlink);
cFYI(1, "Freeing private data in close dir"); cFYI(1, "Freeing private data in close dir");
spin_lock(&cifs_file_list_lock); spin_lock(&cifs_file_list_lock);
...@@ -653,7 +653,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) ...@@ -653,7 +653,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
__u64 length; __u64 length;
bool wait_flag = false; bool wait_flag = false;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
__u16 netfid; __u16 netfid;
__u8 lockType = LOCKING_ANDX_LARGE_FILES; __u8 lockType = LOCKING_ANDX_LARGE_FILES;
bool posix_locking = 0; bool posix_locking = 0;
...@@ -725,8 +725,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) ...@@ -725,8 +725,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
else else
posix_lock_type = CIFS_WRLCK; posix_lock_type = CIFS_WRLCK;
rc = CIFSSMBPosixLock(xid, tcon, netfid, 1 /* get */, rc = CIFSSMBPosixLock(xid, tcon, netfid, 1 /* get */,
length, pfLock, length, pfLock, posix_lock_type,
posix_lock_type, wait_flag); wait_flag);
FreeXid(xid); FreeXid(xid);
return rc; return rc;
} }
...@@ -797,8 +797,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) ...@@ -797,8 +797,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
posix_lock_type = CIFS_UNLCK; posix_lock_type = CIFS_UNLCK;
rc = CIFSSMBPosixLock(xid, tcon, netfid, 0 /* set */, rc = CIFSSMBPosixLock(xid, tcon, netfid, 0 /* set */,
length, pfLock, length, pfLock, posix_lock_type,
posix_lock_type, wait_flag); wait_flag);
} else { } else {
struct cifsFileInfo *fid = file->private_data; struct cifsFileInfo *fid = file->private_data;
...@@ -857,7 +857,7 @@ cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, ...@@ -857,7 +857,7 @@ cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
cifsi->server_eof = end_of_write; cifsi->server_eof = end_of_write;
} }
static ssize_t cifs_write(struct cifsFileInfo *open_file, static ssize_t cifs_write(struct cifsFileInfo *open_file, __u32 pid,
const char *write_data, size_t write_size, const char *write_data, size_t write_size,
loff_t *poffset) loff_t *poffset)
{ {
...@@ -865,10 +865,11 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file, ...@@ -865,10 +865,11 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
unsigned int bytes_written = 0; unsigned int bytes_written = 0;
unsigned int total_written; unsigned int total_written;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
int xid; int xid;
struct dentry *dentry = open_file->dentry; struct dentry *dentry = open_file->dentry;
struct cifsInodeInfo *cifsi = CIFS_I(dentry->d_inode); struct cifsInodeInfo *cifsi = CIFS_I(dentry->d_inode);
struct cifs_io_parms io_parms;
cifs_sb = CIFS_SB(dentry->d_sb); cifs_sb = CIFS_SB(dentry->d_sb);
...@@ -901,8 +902,13 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file, ...@@ -901,8 +902,13 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
/* iov[0] is reserved for smb header */ /* iov[0] is reserved for smb header */
iov[1].iov_base = (char *)write_data + total_written; iov[1].iov_base = (char *)write_data + total_written;
iov[1].iov_len = len; iov[1].iov_len = len;
rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid, len, io_parms.netfid = open_file->netfid;
*poffset, &bytes_written, iov, 1, 0); io_parms.pid = pid;
io_parms.tcon = pTcon;
io_parms.offset = *poffset;
io_parms.length = len;
rc = CIFSSMBWrite2(xid, &io_parms, &bytes_written, iov,
1, 0);
} }
if (rc || (bytes_written == 0)) { if (rc || (bytes_written == 0)) {
if (total_written) if (total_written)
...@@ -1071,8 +1077,8 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) ...@@ -1071,8 +1077,8 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
open_file = find_writable_file(CIFS_I(mapping->host), false); open_file = find_writable_file(CIFS_I(mapping->host), false);
if (open_file) { if (open_file) {
bytes_written = cifs_write(open_file, write_data, bytes_written = cifs_write(open_file, open_file->pid,
to - from, &offset); write_data, to - from, &offset);
cifsFileInfo_put(open_file); cifsFileInfo_put(open_file);
/* Does mm or vfs already set times? */ /* Does mm or vfs already set times? */
inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb); inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb);
...@@ -1092,58 +1098,20 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) ...@@ -1092,58 +1098,20 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
static int cifs_writepages(struct address_space *mapping, static int cifs_writepages(struct address_space *mapping,
struct writeback_control *wbc) struct writeback_control *wbc)
{ {
unsigned int bytes_to_write; struct cifs_sb_info *cifs_sb = CIFS_SB(mapping->host->i_sb);
unsigned int bytes_written; bool done = false, scanned = false, range_whole = false;
struct cifs_sb_info *cifs_sb; pgoff_t end, index;
int done = 0; struct cifs_writedata *wdata;
pgoff_t end;
pgoff_t index;
int range_whole = 0;
struct kvec *iov;
int len;
int n_iov = 0;
pgoff_t next;
int nr_pages;
__u64 offset = 0;
struct cifsFileInfo *open_file;
struct cifsTconInfo *tcon;
struct cifsInodeInfo *cifsi = CIFS_I(mapping->host);
struct page *page; struct page *page;
struct pagevec pvec;
int rc = 0; int rc = 0;
int scanned = 0;
int xid;
cifs_sb = CIFS_SB(mapping->host->i_sb);
/* /*
* If wsize is smaller that the page cache size, default to writing * If wsize is smaller than the page cache size, default to writing
* one page at a time via cifs_writepage * one page at a time via cifs_writepage
*/ */
if (cifs_sb->wsize < PAGE_CACHE_SIZE) if (cifs_sb->wsize < PAGE_CACHE_SIZE)
return generic_writepages(mapping, wbc); return generic_writepages(mapping, wbc);
iov = kmalloc(32 * sizeof(struct kvec), GFP_KERNEL);
if (iov == NULL)
return generic_writepages(mapping, wbc);
/*
* if there's no open file, then this is likely to fail too,
* but it'll at least handle the return. Maybe it should be
* a BUG() instead?
*/
open_file = find_writable_file(CIFS_I(mapping->host), false);
if (!open_file) {
kfree(iov);
return generic_writepages(mapping, wbc);
}
tcon = tlink_tcon(open_file->tlink);
cifsFileInfo_put(open_file);
xid = GetXid();
pagevec_init(&pvec, 0);
if (wbc->range_cyclic) { if (wbc->range_cyclic) {
index = mapping->writeback_index; /* Start from prev offset */ index = mapping->writeback_index; /* Start from prev offset */
end = -1; end = -1;
...@@ -1151,24 +1119,49 @@ static int cifs_writepages(struct address_space *mapping, ...@@ -1151,24 +1119,49 @@ static int cifs_writepages(struct address_space *mapping,
index = wbc->range_start >> PAGE_CACHE_SHIFT; index = wbc->range_start >> PAGE_CACHE_SHIFT;
end = wbc->range_end >> PAGE_CACHE_SHIFT; end = wbc->range_end >> PAGE_CACHE_SHIFT;
if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
range_whole = 1; range_whole = true;
scanned = 1; scanned = true;
} }
retry: retry:
while (!done && (index <= end) && while (!done && index <= end) {
(nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, unsigned int i, nr_pages, found_pages;
PAGECACHE_TAG_DIRTY, pgoff_t next = 0, tofind;
min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1))) { struct page **pages;
int first;
unsigned int i; tofind = min((cifs_sb->wsize / PAGE_CACHE_SIZE) - 1,
end - index) + 1;
first = -1;
next = 0; wdata = cifs_writedata_alloc((unsigned int)tofind);
n_iov = 0; if (!wdata) {
bytes_to_write = 0; rc = -ENOMEM;
break;
for (i = 0; i < nr_pages; i++) { }
page = pvec.pages[i];
/*
* find_get_pages_tag seems to return a max of 256 on each
* iteration, so we must call it several times in order to
* fill the array or the wsize is effectively limited to
* 256 * PAGE_CACHE_SIZE.
*/
found_pages = 0;
pages = wdata->pages;
do {
nr_pages = find_get_pages_tag(mapping, &index,
PAGECACHE_TAG_DIRTY,
tofind, pages);
found_pages += nr_pages;
tofind -= nr_pages;
pages += nr_pages;
} while (nr_pages && tofind && index <= end);
if (found_pages == 0) {
kref_put(&wdata->refcount, cifs_writedata_release);
break;
}
nr_pages = 0;
for (i = 0; i < found_pages; i++) {
page = wdata->pages[i];
/* /*
* At this point we hold neither mapping->tree_lock nor * At this point we hold neither mapping->tree_lock nor
* lock on the page itself: the page may be truncated or * lock on the page itself: the page may be truncated or
...@@ -1177,7 +1170,7 @@ static int cifs_writepages(struct address_space *mapping, ...@@ -1177,7 +1170,7 @@ static int cifs_writepages(struct address_space *mapping,
* mapping * mapping
*/ */
if (first < 0) if (nr_pages == 0)
lock_page(page); lock_page(page);
else if (!trylock_page(page)) else if (!trylock_page(page))
break; break;
...@@ -1188,7 +1181,7 @@ static int cifs_writepages(struct address_space *mapping, ...@@ -1188,7 +1181,7 @@ static int cifs_writepages(struct address_space *mapping,
} }
if (!wbc->range_cyclic && page->index > end) { if (!wbc->range_cyclic && page->index > end) {
done = 1; done = true;
unlock_page(page); unlock_page(page);
break; break;
} }
...@@ -1215,119 +1208,89 @@ static int cifs_writepages(struct address_space *mapping, ...@@ -1215,119 +1208,89 @@ static int cifs_writepages(struct address_space *mapping,
set_page_writeback(page); set_page_writeback(page);
if (page_offset(page) >= mapping->host->i_size) { if (page_offset(page) >= mapping->host->i_size) {
done = 1; done = true;
unlock_page(page); unlock_page(page);
end_page_writeback(page); end_page_writeback(page);
break; break;
} }
/* wdata->pages[i] = page;
* BB can we get rid of this? pages are held by pvec next = page->index + 1;
*/ ++nr_pages;
page_cache_get(page); }
len = min(mapping->host->i_size - page_offset(page), /* reset index to refind any pages skipped */
(loff_t)PAGE_CACHE_SIZE); if (nr_pages == 0)
index = wdata->pages[0]->index + 1;
/* reserve iov[0] for the smb header */ /* put any pages we aren't going to use */
n_iov++; for (i = nr_pages; i < found_pages; i++) {
iov[n_iov].iov_base = kmap(page); page_cache_release(wdata->pages[i]);
iov[n_iov].iov_len = len; wdata->pages[i] = NULL;
bytes_to_write += len; }
if (first < 0) { /* nothing to write? */
first = i; if (nr_pages == 0) {
offset = page_offset(page); kref_put(&wdata->refcount, cifs_writedata_release);
} continue;
next = page->index + 1;
if (bytes_to_write + PAGE_CACHE_SIZE > cifs_sb->wsize)
break;
} }
if (n_iov) {
retry_write:
open_file = find_writable_file(CIFS_I(mapping->host),
false);
if (!open_file) {
cERROR(1, "No writable handles for inode");
rc = -EBADF;
} else {
rc = CIFSSMBWrite2(xid, tcon, open_file->netfid,
bytes_to_write, offset,
&bytes_written, iov, n_iov,
0);
cifsFileInfo_put(open_file);
}
cFYI(1, "Write2 rc=%d, wrote=%u", rc, bytes_written); wdata->sync_mode = wbc->sync_mode;
wdata->nr_pages = nr_pages;
wdata->offset = page_offset(wdata->pages[0]);
/* do {
* For now, treat a short write as if nothing got if (wdata->cfile != NULL)
* written. A zero length write however indicates cifsFileInfo_put(wdata->cfile);
* ENOSPC or EFBIG. We have no way to know which wdata->cfile = find_writable_file(CIFS_I(mapping->host),
* though, so call it ENOSPC for now. EFBIG would false);
* get translated to AS_EIO anyway. if (!wdata->cfile) {
* cERROR(1, "No writable handles for inode");
* FIXME: make it take into account the data that did rc = -EBADF;
* get written break;
*/
if (rc == 0) {
if (bytes_written == 0)
rc = -ENOSPC;
else if (bytes_written < bytes_to_write)
rc = -EAGAIN;
} }
rc = cifs_async_writev(wdata);
} while (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN);
/* retry on data-integrity flush */ for (i = 0; i < nr_pages; ++i)
if (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN) unlock_page(wdata->pages[i]);
goto retry_write;
/* fix the stats and EOF */
if (bytes_written > 0) {
cifs_stats_bytes_written(tcon, bytes_written);
cifs_update_eof(cifsi, offset, bytes_written);
}
for (i = 0; i < n_iov; i++) { /* send failure -- clean up the mess */
page = pvec.pages[first + i]; if (rc != 0) {
/* on retryable write error, redirty page */ for (i = 0; i < nr_pages; ++i) {
if (rc == -EAGAIN) if (rc == -EAGAIN)
redirty_page_for_writepage(wbc, page); redirty_page_for_writepage(wbc,
else if (rc != 0) wdata->pages[i]);
SetPageError(page); else
kunmap(page); SetPageError(wdata->pages[i]);
unlock_page(page); end_page_writeback(wdata->pages[i]);
end_page_writeback(page); page_cache_release(wdata->pages[i]);
page_cache_release(page);
} }
if (rc != -EAGAIN) if (rc != -EAGAIN)
mapping_set_error(mapping, rc); mapping_set_error(mapping, rc);
else }
rc = 0; kref_put(&wdata->refcount, cifs_writedata_release);
if ((wbc->nr_to_write -= n_iov) <= 0) wbc->nr_to_write -= nr_pages;
done = 1; if (wbc->nr_to_write <= 0)
index = next; done = true;
} else
/* Need to re-find the pages we skipped */
index = pvec.pages[0]->index + 1;
pagevec_release(&pvec); index = next;
} }
if (!scanned && !done) { if (!scanned && !done) {
/* /*
* We hit the last page and there is more work to be done: wrap * We hit the last page and there is more work to be done: wrap
* back to the start of the file * back to the start of the file
*/ */
scanned = 1; scanned = true;
index = 0; index = 0;
goto retry; goto retry;
} }
if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
mapping->writeback_index = index; mapping->writeback_index = index;
FreeXid(xid);
kfree(iov);
return rc; return rc;
} }
...@@ -1383,6 +1346,14 @@ static int cifs_write_end(struct file *file, struct address_space *mapping, ...@@ -1383,6 +1346,14 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
{ {
int rc; int rc;
struct inode *inode = mapping->host; struct inode *inode = mapping->host;
struct cifsFileInfo *cfile = file->private_data;
struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
__u32 pid;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
pid = cfile->pid;
else
pid = current->tgid;
cFYI(1, "write_end for page %p from pos %lld with %d bytes", cFYI(1, "write_end for page %p from pos %lld with %d bytes",
page, pos, copied); page, pos, copied);
...@@ -1406,8 +1377,7 @@ static int cifs_write_end(struct file *file, struct address_space *mapping, ...@@ -1406,8 +1377,7 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
/* BB check if anything else missing out of ppw /* BB check if anything else missing out of ppw
such as updating last write time */ such as updating last write time */
page_data = kmap(page); page_data = kmap(page);
rc = cifs_write(file->private_data, page_data + offset, rc = cifs_write(cfile, pid, page_data + offset, copied, &pos);
copied, &pos);
/* if (rc < 0) should we set writebehind rc? */ /* if (rc < 0) should we set writebehind rc? */
kunmap(page); kunmap(page);
...@@ -1435,7 +1405,7 @@ int cifs_strict_fsync(struct file *file, int datasync) ...@@ -1435,7 +1405,7 @@ int cifs_strict_fsync(struct file *file, int datasync)
{ {
int xid; int xid;
int rc = 0; int rc = 0;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
struct cifsFileInfo *smbfile = file->private_data; struct cifsFileInfo *smbfile = file->private_data;
struct inode *inode = file->f_path.dentry->d_inode; struct inode *inode = file->f_path.dentry->d_inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
...@@ -1465,7 +1435,7 @@ int cifs_fsync(struct file *file, int datasync) ...@@ -1465,7 +1435,7 @@ int cifs_fsync(struct file *file, int datasync)
{ {
int xid; int xid;
int rc = 0; int rc = 0;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
struct cifsFileInfo *smbfile = file->private_data; struct cifsFileInfo *smbfile = file->private_data;
struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
...@@ -1556,9 +1526,11 @@ cifs_iovec_write(struct file *file, const struct iovec *iov, ...@@ -1556,9 +1526,11 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
struct iov_iter it; struct iov_iter it;
struct inode *inode; struct inode *inode;
struct cifsFileInfo *open_file; struct cifsFileInfo *open_file;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifs_io_parms io_parms;
int xid, rc; int xid, rc;
__u32 pid;
len = iov_length(iov, nr_segs); len = iov_length(iov, nr_segs);
if (!len) if (!len)
...@@ -1590,6 +1562,12 @@ cifs_iovec_write(struct file *file, const struct iovec *iov, ...@@ -1590,6 +1562,12 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
xid = GetXid(); xid = GetXid();
open_file = file->private_data; open_file = file->private_data;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
pid = open_file->pid;
else
pid = current->tgid;
pTcon = tlink_tcon(open_file->tlink); pTcon = tlink_tcon(open_file->tlink);
inode = file->f_path.dentry->d_inode; inode = file->f_path.dentry->d_inode;
...@@ -1616,9 +1594,13 @@ cifs_iovec_write(struct file *file, const struct iovec *iov, ...@@ -1616,9 +1594,13 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
if (rc != 0) if (rc != 0)
break; break;
} }
rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid, io_parms.netfid = open_file->netfid;
cur_len, *poffset, &written, io_parms.pid = pid;
to_send, npages, 0); io_parms.tcon = pTcon;
io_parms.offset = *poffset;
io_parms.length = cur_len;
rc = CIFSSMBWrite2(xid, &io_parms, &written, to_send,
npages, 0);
} while (rc == -EAGAIN); } while (rc == -EAGAIN);
for (i = 0; i < npages; i++) for (i = 0; i < npages; i++)
...@@ -1711,10 +1693,12 @@ cifs_iovec_read(struct file *file, const struct iovec *iov, ...@@ -1711,10 +1693,12 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
size_t len, cur_len; size_t len, cur_len;
int iov_offset = 0; int iov_offset = 0;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
struct cifsFileInfo *open_file; struct cifsFileInfo *open_file;
struct smb_com_read_rsp *pSMBr; struct smb_com_read_rsp *pSMBr;
struct cifs_io_parms io_parms;
char *read_data; char *read_data;
__u32 pid;
if (!nr_segs) if (!nr_segs)
return 0; return 0;
...@@ -1729,6 +1713,11 @@ cifs_iovec_read(struct file *file, const struct iovec *iov, ...@@ -1729,6 +1713,11 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
open_file = file->private_data; open_file = file->private_data;
pTcon = tlink_tcon(open_file->tlink); pTcon = tlink_tcon(open_file->tlink);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
pid = open_file->pid;
else
pid = current->tgid;
if ((file->f_flags & O_ACCMODE) == O_WRONLY) if ((file->f_flags & O_ACCMODE) == O_WRONLY)
cFYI(1, "attempting read on write only file instance"); cFYI(1, "attempting read on write only file instance");
...@@ -1744,8 +1733,12 @@ cifs_iovec_read(struct file *file, const struct iovec *iov, ...@@ -1744,8 +1733,12 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
if (rc != 0) if (rc != 0)
break; break;
} }
rc = CIFSSMBRead(xid, pTcon, open_file->netfid, io_parms.netfid = open_file->netfid;
cur_len, *poffset, &bytes_read, io_parms.pid = pid;
io_parms.tcon = pTcon;
io_parms.offset = *poffset;
io_parms.length = len;
rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
&read_data, &buf_type); &read_data, &buf_type);
pSMBr = (struct smb_com_read_rsp *)read_data; pSMBr = (struct smb_com_read_rsp *)read_data;
if (read_data) { if (read_data) {
...@@ -1822,11 +1815,13 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, ...@@ -1822,11 +1815,13 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
unsigned int total_read; unsigned int total_read;
unsigned int current_read_size; unsigned int current_read_size;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
int xid; int xid;
char *current_offset; char *current_offset;
struct cifsFileInfo *open_file; struct cifsFileInfo *open_file;
struct cifs_io_parms io_parms;
int buf_type = CIFS_NO_BUFFER; int buf_type = CIFS_NO_BUFFER;
__u32 pid;
xid = GetXid(); xid = GetXid();
cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
...@@ -1839,6 +1834,11 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, ...@@ -1839,6 +1834,11 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
open_file = file->private_data; open_file = file->private_data;
pTcon = tlink_tcon(open_file->tlink); pTcon = tlink_tcon(open_file->tlink);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
pid = open_file->pid;
else
pid = current->tgid;
if ((file->f_flags & O_ACCMODE) == O_WRONLY) if ((file->f_flags & O_ACCMODE) == O_WRONLY)
cFYI(1, "attempting read on write only file instance"); cFYI(1, "attempting read on write only file instance");
...@@ -1861,11 +1861,13 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, ...@@ -1861,11 +1861,13 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
if (rc != 0) if (rc != 0)
break; break;
} }
rc = CIFSSMBRead(xid, pTcon, io_parms.netfid = open_file->netfid;
open_file->netfid, io_parms.pid = pid;
current_read_size, *poffset, io_parms.tcon = pTcon;
&bytes_read, &current_offset, io_parms.offset = *poffset;
&buf_type); io_parms.length = current_read_size;
rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
&current_offset, &buf_type);
} }
if (rc || (bytes_read == 0)) { if (rc || (bytes_read == 0)) {
if (total_read) { if (total_read) {
...@@ -1996,13 +1998,15 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, ...@@ -1996,13 +1998,15 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
loff_t offset; loff_t offset;
struct page *page; struct page *page;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
unsigned int bytes_read = 0; unsigned int bytes_read = 0;
unsigned int read_size, i; unsigned int read_size, i;
char *smb_read_data = NULL; char *smb_read_data = NULL;
struct smb_com_read_rsp *pSMBr; struct smb_com_read_rsp *pSMBr;
struct cifsFileInfo *open_file; struct cifsFileInfo *open_file;
struct cifs_io_parms io_parms;
int buf_type = CIFS_NO_BUFFER; int buf_type = CIFS_NO_BUFFER;
__u32 pid;
xid = GetXid(); xid = GetXid();
if (file->private_data == NULL) { if (file->private_data == NULL) {
...@@ -2024,6 +2028,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, ...@@ -2024,6 +2028,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
goto read_complete; goto read_complete;
cFYI(DBG2, "rpages: num pages %d", num_pages); cFYI(DBG2, "rpages: num pages %d", num_pages);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
pid = open_file->pid;
else
pid = current->tgid;
for (i = 0; i < num_pages; ) { for (i = 0; i < num_pages; ) {
unsigned contig_pages; unsigned contig_pages;
struct page *tmp_page; struct page *tmp_page;
...@@ -2065,12 +2074,13 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, ...@@ -2065,12 +2074,13 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
if (rc != 0) if (rc != 0)
break; break;
} }
io_parms.netfid = open_file->netfid;
rc = CIFSSMBRead(xid, pTcon, io_parms.pid = pid;
open_file->netfid, io_parms.tcon = pTcon;
read_size, offset, io_parms.offset = offset;
&bytes_read, &smb_read_data, io_parms.length = read_size;
&buf_type); rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
&smb_read_data, &buf_type);
/* BB more RC checks ? */ /* BB more RC checks ? */
if (rc == -EAGAIN) { if (rc == -EAGAIN) {
if (smb_read_data) { if (smb_read_data) {
......
...@@ -40,7 +40,7 @@ void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server) ...@@ -40,7 +40,7 @@ void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server)
server->fscache = NULL; server->fscache = NULL;
} }
void cifs_fscache_get_super_cookie(struct cifsTconInfo *tcon) void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
{ {
struct TCP_Server_Info *server = tcon->ses->server; struct TCP_Server_Info *server = tcon->ses->server;
...@@ -51,7 +51,7 @@ void cifs_fscache_get_super_cookie(struct cifsTconInfo *tcon) ...@@ -51,7 +51,7 @@ void cifs_fscache_get_super_cookie(struct cifsTconInfo *tcon)
server->fscache, tcon->fscache); server->fscache, tcon->fscache);
} }
void cifs_fscache_release_super_cookie(struct cifsTconInfo *tcon) void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon)
{ {
cFYI(1, "CIFS: releasing superblock cookie (0x%p)", tcon->fscache); cFYI(1, "CIFS: releasing superblock cookie (0x%p)", tcon->fscache);
fscache_relinquish_cookie(tcon->fscache, 0); fscache_relinquish_cookie(tcon->fscache, 0);
...@@ -62,7 +62,7 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode) ...@@ -62,7 +62,7 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode)
{ {
struct cifsInodeInfo *cifsi = CIFS_I(inode); struct cifsInodeInfo *cifsi = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
if (cifsi->fscache) if (cifsi->fscache)
return; return;
......
...@@ -40,8 +40,8 @@ extern void cifs_fscache_unregister(void); ...@@ -40,8 +40,8 @@ extern void cifs_fscache_unregister(void);
*/ */
extern void cifs_fscache_get_client_cookie(struct TCP_Server_Info *); extern void cifs_fscache_get_client_cookie(struct TCP_Server_Info *);
extern void cifs_fscache_release_client_cookie(struct TCP_Server_Info *); extern void cifs_fscache_release_client_cookie(struct TCP_Server_Info *);
extern void cifs_fscache_get_super_cookie(struct cifsTconInfo *); extern void cifs_fscache_get_super_cookie(struct cifs_tcon *);
extern void cifs_fscache_release_super_cookie(struct cifsTconInfo *); extern void cifs_fscache_release_super_cookie(struct cifs_tcon *);
extern void cifs_fscache_release_inode_cookie(struct inode *); extern void cifs_fscache_release_inode_cookie(struct inode *);
extern void cifs_fscache_set_inode_cookie(struct inode *, struct file *); extern void cifs_fscache_set_inode_cookie(struct inode *, struct file *);
...@@ -99,9 +99,9 @@ static inline void ...@@ -99,9 +99,9 @@ static inline void
cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) {} cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) {}
static inline void static inline void
cifs_fscache_release_client_cookie(struct TCP_Server_Info *server) {} cifs_fscache_release_client_cookie(struct TCP_Server_Info *server) {}
static inline void cifs_fscache_get_super_cookie(struct cifsTconInfo *tcon) {} static inline void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) {}
static inline void static inline void
cifs_fscache_release_super_cookie(struct cifsTconInfo *tcon) {} cifs_fscache_release_super_cookie(struct cifs_tcon *tcon) {}
static inline void cifs_fscache_release_inode_cookie(struct inode *inode) {} static inline void cifs_fscache_release_inode_cookie(struct inode *inode) {}
static inline void cifs_fscache_set_inode_cookie(struct inode *inode, static inline void cifs_fscache_set_inode_cookie(struct inode *inode,
......
...@@ -295,7 +295,7 @@ int cifs_get_file_info_unix(struct file *filp) ...@@ -295,7 +295,7 @@ int cifs_get_file_info_unix(struct file *filp)
struct inode *inode = filp->f_path.dentry->d_inode; struct inode *inode = filp->f_path.dentry->d_inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct cifsFileInfo *cfile = filp->private_data; struct cifsFileInfo *cfile = filp->private_data;
struct cifsTconInfo *tcon = tlink_tcon(cfile->tlink); struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
xid = GetXid(); xid = GetXid();
rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data); rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data);
...@@ -318,7 +318,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, ...@@ -318,7 +318,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
int rc; int rc;
FILE_UNIX_BASIC_INFO find_data; FILE_UNIX_BASIC_INFO find_data;
struct cifs_fattr fattr; struct cifs_fattr fattr;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
...@@ -373,7 +373,8 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path, ...@@ -373,7 +373,8 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
int oplock = 0; int oplock = 0;
__u16 netfid; __u16 netfid;
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
struct cifs_io_parms io_parms;
char buf[24]; char buf[24];
unsigned int bytes_read; unsigned int bytes_read;
char *pbuf; char *pbuf;
...@@ -405,9 +406,13 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path, ...@@ -405,9 +406,13 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
if (rc == 0) { if (rc == 0) {
int buf_type = CIFS_NO_BUFFER; int buf_type = CIFS_NO_BUFFER;
/* Read header */ /* Read header */
rc = CIFSSMBRead(xid, tcon, netfid, io_parms.netfid = netfid;
24 /* length */, 0 /* offset */, io_parms.pid = current->tgid;
&bytes_read, &pbuf, &buf_type); io_parms.tcon = tcon;
io_parms.offset = 0;
io_parms.length = 24;
rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf,
&buf_type);
if ((rc == 0) && (bytes_read >= 8)) { if ((rc == 0) && (bytes_read >= 8)) {
if (memcmp("IntxBLK", pbuf, 8) == 0) { if (memcmp("IntxBLK", pbuf, 8) == 0) {
cFYI(1, "Block device"); cFYI(1, "Block device");
...@@ -468,7 +473,7 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path, ...@@ -468,7 +473,7 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
char ea_value[4]; char ea_value[4];
__u32 mode; __u32 mode;
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
tlink = cifs_sb_tlink(cifs_sb); tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink)) if (IS_ERR(tlink))
...@@ -502,7 +507,7 @@ static void ...@@ -502,7 +507,7 @@ static void
cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
struct cifs_sb_info *cifs_sb, bool adjust_tz) struct cifs_sb_info *cifs_sb, bool adjust_tz)
{ {
struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
memset(fattr, 0, sizeof(*fattr)); memset(fattr, 0, sizeof(*fattr));
fattr->cf_cifsattrs = le32_to_cpu(info->Attributes); fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);
...@@ -553,7 +558,7 @@ int cifs_get_file_info(struct file *filp) ...@@ -553,7 +558,7 @@ int cifs_get_file_info(struct file *filp)
struct inode *inode = filp->f_path.dentry->d_inode; struct inode *inode = filp->f_path.dentry->d_inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct cifsFileInfo *cfile = filp->private_data; struct cifsFileInfo *cfile = filp->private_data;
struct cifsTconInfo *tcon = tlink_tcon(cfile->tlink); struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
xid = GetXid(); xid = GetXid();
rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data); rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data);
...@@ -590,7 +595,7 @@ int cifs_get_inode_info(struct inode **pinode, ...@@ -590,7 +595,7 @@ int cifs_get_inode_info(struct inode **pinode,
struct super_block *sb, int xid, const __u16 *pfid) struct super_block *sb, int xid, const __u16 *pfid)
{ {
int rc = 0, tmprc; int rc = 0, tmprc;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
char *buf = NULL; char *buf = NULL;
...@@ -735,10 +740,10 @@ static const struct inode_operations cifs_ipc_inode_ops = { ...@@ -735,10 +740,10 @@ static const struct inode_operations cifs_ipc_inode_ops = {
.lookup = cifs_lookup, .lookup = cifs_lookup,
}; };
char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb, char *cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
struct cifsTconInfo *tcon) struct cifs_tcon *tcon)
{ {
int pplen = cifs_sb->prepathlen; int pplen = vol->prepath ? strlen(vol->prepath) : 0;
int dfsplen; int dfsplen;
char *full_path = NULL; char *full_path = NULL;
...@@ -772,7 +777,7 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb, ...@@ -772,7 +777,7 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
} }
} }
} }
strncpy(full_path + dfsplen, cifs_sb->prepath, pplen); strncpy(full_path + dfsplen, vol->prepath, pplen);
full_path[dfsplen + pplen] = 0; /* add trailing null */ full_path[dfsplen + pplen] = 0; /* add trailing null */
return full_path; return full_path;
} }
...@@ -884,19 +889,13 @@ struct inode *cifs_root_iget(struct super_block *sb) ...@@ -884,19 +889,13 @@ struct inode *cifs_root_iget(struct super_block *sb)
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct inode *inode = NULL; struct inode *inode = NULL;
long rc; long rc;
char *full_path; struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
full_path = cifs_build_path_to_root(cifs_sb, tcon);
if (full_path == NULL)
return ERR_PTR(-ENOMEM);
xid = GetXid(); xid = GetXid();
if (tcon->unix_ext) if (tcon->unix_ext)
rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid); rc = cifs_get_inode_info_unix(&inode, "", sb, xid);
else else
rc = cifs_get_inode_info(&inode, full_path, NULL, sb, rc = cifs_get_inode_info(&inode, "", NULL, sb, xid, NULL);
xid, NULL);
if (!inode) { if (!inode) {
inode = ERR_PTR(rc); inode = ERR_PTR(rc);
...@@ -922,7 +921,6 @@ struct inode *cifs_root_iget(struct super_block *sb) ...@@ -922,7 +921,6 @@ struct inode *cifs_root_iget(struct super_block *sb)
} }
out: out:
kfree(full_path);
/* can not call macro FreeXid here since in a void func /* can not call macro FreeXid here since in a void func
* TODO: This is no longer true * TODO: This is no longer true
*/ */
...@@ -943,7 +941,7 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid, ...@@ -943,7 +941,7 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
struct cifsInodeInfo *cifsInode = CIFS_I(inode); struct cifsInodeInfo *cifsInode = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink = NULL; struct tcon_link *tlink = NULL;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
FILE_BASIC_INFO info_buf; FILE_BASIC_INFO info_buf;
if (attrs == NULL) if (attrs == NULL)
...@@ -1061,7 +1059,7 @@ cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid) ...@@ -1061,7 +1059,7 @@ cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
struct cifsInodeInfo *cifsInode = CIFS_I(inode); struct cifsInodeInfo *cifsInode = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
__u32 dosattr, origattr; __u32 dosattr, origattr;
FILE_BASIC_INFO *info_buf = NULL; FILE_BASIC_INFO *info_buf = NULL;
...@@ -1179,7 +1177,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry) ...@@ -1179,7 +1177,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
struct super_block *sb = dir->i_sb; struct super_block *sb = dir->i_sb;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
struct iattr *attrs = NULL; struct iattr *attrs = NULL;
__u32 dosattr = 0, origattr = 0; __u32 dosattr = 0, origattr = 0;
...@@ -1277,7 +1275,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) ...@@ -1277,7 +1275,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
int xid; int xid;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
char *full_path = NULL; char *full_path = NULL;
struct inode *newinode = NULL; struct inode *newinode = NULL;
struct cifs_fattr fattr; struct cifs_fattr fattr;
...@@ -1455,7 +1453,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) ...@@ -1455,7 +1453,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
int xid; int xid;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
char *full_path = NULL; char *full_path = NULL;
struct cifsInodeInfo *cifsInode; struct cifsInodeInfo *cifsInode;
...@@ -1512,7 +1510,7 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath, ...@@ -1512,7 +1510,7 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
{ {
struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb);
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
__u16 srcfid; __u16 srcfid;
int oplock, rc; int oplock, rc;
...@@ -1564,7 +1562,7 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry, ...@@ -1564,7 +1562,7 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
char *toName = NULL; char *toName = NULL;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
FILE_UNIX_BASIC_INFO *info_buf_source = NULL; FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
FILE_UNIX_BASIC_INFO *info_buf_target; FILE_UNIX_BASIC_INFO *info_buf_target;
int xid, rc, tmprc; int xid, rc, tmprc;
...@@ -1794,7 +1792,7 @@ int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, ...@@ -1794,7 +1792,7 @@ int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat) struct kstat *stat)
{ {
struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
int rc; int rc;
...@@ -1872,7 +1870,8 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, ...@@ -1872,7 +1870,8 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
struct cifsInodeInfo *cifsInode = CIFS_I(inode); struct cifsInodeInfo *cifsInode = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink = NULL; struct tcon_link *tlink = NULL;
struct cifsTconInfo *pTcon = NULL; struct cifs_tcon *pTcon = NULL;
struct cifs_io_parms io_parms;
/* /*
* To avoid spurious oplock breaks from server, in the case of * To avoid spurious oplock breaks from server, in the case of
...@@ -1894,8 +1893,14 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, ...@@ -1894,8 +1893,14 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
cFYI(1, "SetFSize for attrs rc = %d", rc); cFYI(1, "SetFSize for attrs rc = %d", rc);
if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
unsigned int bytes_written; unsigned int bytes_written;
rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size,
&bytes_written, NULL, NULL, 1); io_parms.netfid = nfid;
io_parms.pid = npid;
io_parms.tcon = pTcon;
io_parms.offset = 0;
io_parms.length = attrs->ia_size;
rc = CIFSSMBWrite(xid, &io_parms, &bytes_written,
NULL, NULL, 1);
cFYI(1, "Wrt seteof rc %d", rc); cFYI(1, "Wrt seteof rc %d", rc);
} }
} else } else
...@@ -1930,10 +1935,15 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, ...@@ -1930,10 +1935,15 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
CIFS_MOUNT_MAP_SPECIAL_CHR); CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc == 0) { if (rc == 0) {
unsigned int bytes_written; unsigned int bytes_written;
rc = CIFSSMBWrite(xid, pTcon, netfid, 0,
attrs->ia_size, io_parms.netfid = netfid;
&bytes_written, NULL, io_parms.pid = current->tgid;
NULL, 1); io_parms.tcon = pTcon;
io_parms.offset = 0;
io_parms.length = attrs->ia_size;
rc = CIFSSMBWrite(xid, &io_parms,
&bytes_written,
NULL, NULL, 1);
cFYI(1, "wrt seteof rc %d", rc); cFYI(1, "wrt seteof rc %d", rc);
CIFSSMBClose(xid, pTcon, netfid); CIFSSMBClose(xid, pTcon, netfid);
} }
...@@ -1961,7 +1971,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) ...@@ -1961,7 +1971,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
struct cifsInodeInfo *cifsInode = CIFS_I(inode); struct cifsInodeInfo *cifsInode = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
struct cifs_unix_set_info_args *args = NULL; struct cifs_unix_set_info_args *args = NULL;
struct cifsFileInfo *open_file; struct cifsFileInfo *open_file;
...@@ -2247,7 +2257,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs) ...@@ -2247,7 +2257,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
{ {
struct inode *inode = direntry->d_inode; struct inode *inode = direntry->d_inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct cifsTconInfo *pTcon = cifs_sb_master_tcon(cifs_sb); struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb);
if (pTcon->unix_ext) if (pTcon->unix_ext)
return cifs_setattr_unix(direntry, attrs); return cifs_setattr_unix(direntry, attrs);
......
...@@ -38,7 +38,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) ...@@ -38,7 +38,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
#ifdef CONFIG_CIFS_POSIX #ifdef CONFIG_CIFS_POSIX
struct cifsFileInfo *pSMBFile = filep->private_data; struct cifsFileInfo *pSMBFile = filep->private_data;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
__u64 ExtAttrBits = 0; __u64 ExtAttrBits = 0;
__u64 ExtAttrMask = 0; __u64 ExtAttrMask = 0;
__u64 caps; __u64 caps;
......
...@@ -175,7 +175,7 @@ CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str) ...@@ -175,7 +175,7 @@ CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
} }
static int static int
CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon, CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
{ {
...@@ -184,6 +184,7 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon, ...@@ -184,6 +184,7 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
__u16 netfid = 0; __u16 netfid = 0;
u8 *buf; u8 *buf;
unsigned int bytes_written = 0; unsigned int bytes_written = 0;
struct cifs_io_parms io_parms;
buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
if (!buf) if (!buf)
...@@ -203,10 +204,13 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon, ...@@ -203,10 +204,13 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
return rc; return rc;
} }
rc = CIFSSMBWrite(xid, tcon, netfid, io_parms.netfid = netfid;
CIFS_MF_SYMLINK_FILE_SIZE /* length */, io_parms.pid = current->tgid;
0 /* offset */, io_parms.tcon = tcon;
&bytes_written, buf, NULL, 0); io_parms.offset = 0;
io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, buf, NULL, 0);
CIFSSMBClose(xid, tcon, netfid); CIFSSMBClose(xid, tcon, netfid);
kfree(buf); kfree(buf);
if (rc != 0) if (rc != 0)
...@@ -219,7 +223,7 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon, ...@@ -219,7 +223,7 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
} }
static int static int
CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon, CIFSQueryMFSymLink(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, char **symlinkinfo, const unsigned char *searchName, char **symlinkinfo,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
{ {
...@@ -231,6 +235,7 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon, ...@@ -231,6 +235,7 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
unsigned int bytes_read = 0; unsigned int bytes_read = 0;
int buf_type = CIFS_NO_BUFFER; int buf_type = CIFS_NO_BUFFER;
unsigned int link_len = 0; unsigned int link_len = 0;
struct cifs_io_parms io_parms;
FILE_ALL_INFO file_info; FILE_ALL_INFO file_info;
rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ, rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ,
...@@ -249,11 +254,13 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon, ...@@ -249,11 +254,13 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
if (!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
pbuf = buf; pbuf = buf;
io_parms.netfid = netfid;
io_parms.pid = current->tgid;
io_parms.tcon = tcon;
io_parms.offset = 0;
io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
rc = CIFSSMBRead(xid, tcon, netfid, rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type);
CIFS_MF_SYMLINK_FILE_SIZE /* length */,
0 /* offset */,
&bytes_read, &pbuf, &buf_type);
CIFSSMBClose(xid, tcon, netfid); CIFSSMBClose(xid, tcon, netfid);
if (rc != 0) { if (rc != 0) {
kfree(buf); kfree(buf);
...@@ -291,7 +298,8 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr, ...@@ -291,7 +298,8 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
int oplock = 0; int oplock = 0;
__u16 netfid = 0; __u16 netfid = 0;
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
struct cifs_io_parms io_parms;
u8 *buf; u8 *buf;
char *pbuf; char *pbuf;
unsigned int bytes_read = 0; unsigned int bytes_read = 0;
...@@ -328,11 +336,13 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr, ...@@ -328,11 +336,13 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
goto out; goto out;
} }
pbuf = buf; pbuf = buf;
io_parms.netfid = netfid;
io_parms.pid = current->tgid;
io_parms.tcon = pTcon;
io_parms.offset = 0;
io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
rc = CIFSSMBRead(xid, pTcon, netfid, rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type);
CIFS_MF_SYMLINK_FILE_SIZE /* length */,
0 /* offset */,
&bytes_read, &pbuf, &buf_type);
CIFSSMBClose(xid, pTcon, netfid); CIFSSMBClose(xid, pTcon, netfid);
if (rc != 0) { if (rc != 0) {
kfree(buf); kfree(buf);
...@@ -370,7 +380,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, ...@@ -370,7 +380,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
char *toName = NULL; char *toName = NULL;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
struct cifsInodeInfo *cifsInode; struct cifsInodeInfo *cifsInode;
tlink = cifs_sb_tlink(cifs_sb); tlink = cifs_sb_tlink(cifs_sb);
...@@ -445,7 +455,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd) ...@@ -445,7 +455,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
char *target_path = NULL; char *target_path = NULL;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink = NULL; struct tcon_link *tlink = NULL;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
xid = GetXid(); xid = GetXid();
...@@ -518,7 +528,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) ...@@ -518,7 +528,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
int xid; int xid;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
char *full_path = NULL; char *full_path = NULL;
struct inode *newinode = NULL; struct inode *newinode = NULL;
......
...@@ -67,12 +67,12 @@ _FreeXid(unsigned int xid) ...@@ -67,12 +67,12 @@ _FreeXid(unsigned int xid)
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
} }
struct cifsSesInfo * struct cifs_ses *
sesInfoAlloc(void) sesInfoAlloc(void)
{ {
struct cifsSesInfo *ret_buf; struct cifs_ses *ret_buf;
ret_buf = kzalloc(sizeof(struct cifsSesInfo), GFP_KERNEL); ret_buf = kzalloc(sizeof(struct cifs_ses), GFP_KERNEL);
if (ret_buf) { if (ret_buf) {
atomic_inc(&sesInfoAllocCount); atomic_inc(&sesInfoAllocCount);
ret_buf->status = CifsNew; ret_buf->status = CifsNew;
...@@ -85,7 +85,7 @@ sesInfoAlloc(void) ...@@ -85,7 +85,7 @@ sesInfoAlloc(void)
} }
void void
sesInfoFree(struct cifsSesInfo *buf_to_free) sesInfoFree(struct cifs_ses *buf_to_free)
{ {
if (buf_to_free == NULL) { if (buf_to_free == NULL) {
cFYI(1, "Null buffer passed to sesInfoFree"); cFYI(1, "Null buffer passed to sesInfoFree");
...@@ -105,11 +105,11 @@ sesInfoFree(struct cifsSesInfo *buf_to_free) ...@@ -105,11 +105,11 @@ sesInfoFree(struct cifsSesInfo *buf_to_free)
kfree(buf_to_free); kfree(buf_to_free);
} }
struct cifsTconInfo * struct cifs_tcon *
tconInfoAlloc(void) tconInfoAlloc(void)
{ {
struct cifsTconInfo *ret_buf; struct cifs_tcon *ret_buf;
ret_buf = kzalloc(sizeof(struct cifsTconInfo), GFP_KERNEL); ret_buf = kzalloc(sizeof(struct cifs_tcon), GFP_KERNEL);
if (ret_buf) { if (ret_buf) {
atomic_inc(&tconInfoAllocCount); atomic_inc(&tconInfoAllocCount);
ret_buf->tidStatus = CifsNew; ret_buf->tidStatus = CifsNew;
...@@ -124,7 +124,7 @@ tconInfoAlloc(void) ...@@ -124,7 +124,7 @@ tconInfoAlloc(void)
} }
void void
tconInfoFree(struct cifsTconInfo *buf_to_free) tconInfoFree(struct cifs_tcon *buf_to_free)
{ {
if (buf_to_free == NULL) { if (buf_to_free == NULL) {
cFYI(1, "Null buffer passed to tconInfoFree"); cFYI(1, "Null buffer passed to tconInfoFree");
...@@ -295,11 +295,11 @@ __u16 GetNextMid(struct TCP_Server_Info *server) ...@@ -295,11 +295,11 @@ __u16 GetNextMid(struct TCP_Server_Info *server)
case it is responsbility of caller to set the mid */ case it is responsbility of caller to set the mid */
void void
header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
const struct cifsTconInfo *treeCon, int word_count const struct cifs_tcon *treeCon, int word_count
/* length of fixed section (word count) in two byte units */) /* length of fixed section (word count) in two byte units */)
{ {
struct list_head *temp_item; struct list_head *temp_item;
struct cifsSesInfo *ses; struct cifs_ses *ses;
char *temp = (char *) buffer; char *temp = (char *) buffer;
memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */ memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */
...@@ -359,7 +359,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , ...@@ -359,7 +359,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
"did not match tcon uid"); "did not match tcon uid");
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) { list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) {
ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list); ses = list_entry(temp_item, struct cifs_ses, smb_ses_list);
if (ses->linux_uid == current_fsuid()) { if (ses->linux_uid == current_fsuid()) {
if (ses->server == treeCon->ses->server) { if (ses->server == treeCon->ses->server) {
cFYI(1, "found matching uid substitute right smb_uid"); cFYI(1, "found matching uid substitute right smb_uid");
...@@ -380,7 +380,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , ...@@ -380,7 +380,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
if (treeCon->nocase) if (treeCon->nocase)
buffer->Flags |= SMBFLG_CASELESS; buffer->Flags |= SMBFLG_CASELESS;
if ((treeCon->ses) && (treeCon->ses->server)) if ((treeCon->ses) && (treeCon->ses->server))
if (treeCon->ses->server->secMode & if (treeCon->ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
} }
...@@ -507,8 +507,8 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) ...@@ -507,8 +507,8 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
{ {
struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf; struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;
struct list_head *tmp, *tmp1, *tmp2; struct list_head *tmp, *tmp1, *tmp2;
struct cifsSesInfo *ses; struct cifs_ses *ses;
struct cifsTconInfo *tcon; struct cifs_tcon *tcon;
struct cifsInodeInfo *pCifsInode; struct cifsInodeInfo *pCifsInode;
struct cifsFileInfo *netfile; struct cifsFileInfo *netfile;
...@@ -566,9 +566,9 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) ...@@ -566,9 +566,9 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
/* look up tcon based on tid & uid */ /* look up tcon based on tid & uid */
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
list_for_each(tmp, &srv->smb_ses_list) { list_for_each(tmp, &srv->smb_ses_list) {
ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list); ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
list_for_each(tmp1, &ses->tcon_list) { list_for_each(tmp1, &ses->tcon_list) {
tcon = list_entry(tmp1, struct cifsTconInfo, tcon_list); tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
if (tcon->tid != buf->Tid) if (tcon->tid != buf->Tid)
continue; continue;
......
...@@ -836,7 +836,7 @@ ntstatus_to_dos(__u32 ntstatus, __u8 *eclass, __u16 *ecode) ...@@ -836,7 +836,7 @@ ntstatus_to_dos(__u32 ntstatus, __u8 *eclass, __u16 *ecode)
} }
int int
map_smb_to_linux_error(struct smb_hdr *smb, int logErr) map_smb_to_linux_error(struct smb_hdr *smb, bool logErr)
{ {
unsigned int i; unsigned int i;
int rc = -EIO; /* if transport error smb error may not be set */ int rc = -EIO; /* if transport error smb error may not be set */
......
...@@ -195,7 +195,7 @@ int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb, ...@@ -195,7 +195,7 @@ int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb,
int len; int len;
int oplock = 0; int oplock = 0;
int rc; int rc;
struct cifsTconInfo *ptcon = cifs_sb_tcon(cifs_sb); struct cifs_tcon *ptcon = cifs_sb_tcon(cifs_sb);
char *tmpbuffer; char *tmpbuffer;
rc = CIFSSMBOpen(xid, ptcon, full_path, FILE_OPEN, GENERIC_READ, rc = CIFSSMBOpen(xid, ptcon, full_path, FILE_OPEN, GENERIC_READ,
...@@ -223,7 +223,7 @@ static int initiate_cifs_search(const int xid, struct file *file) ...@@ -223,7 +223,7 @@ static int initiate_cifs_search(const int xid, struct file *file)
struct cifsFileInfo *cifsFile; struct cifsFileInfo *cifsFile;
struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
struct tcon_link *tlink = NULL; struct tcon_link *tlink = NULL;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
if (file->private_data == NULL) { if (file->private_data == NULL) {
tlink = cifs_sb_tlink(cifs_sb); tlink = cifs_sb_tlink(cifs_sb);
...@@ -496,7 +496,7 @@ static int cifs_save_resume_key(const char *current_entry, ...@@ -496,7 +496,7 @@ static int cifs_save_resume_key(const char *current_entry,
assume that they are located in the findfirst return buffer.*/ assume that they are located in the findfirst return buffer.*/
/* We start counting in the buffer with entry 2 and increment for every /* We start counting in the buffer with entry 2 and increment for every
entry (do not increment for . or .. entry) */ entry (do not increment for . or .. entry) */
static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon,
struct file *file, char **ppCurrentEntry, int *num_to_ret) struct file *file, char **ppCurrentEntry, int *num_to_ret)
{ {
int rc = 0; int rc = 0;
...@@ -764,7 +764,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) ...@@ -764,7 +764,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
{ {
int rc = 0; int rc = 0;
int xid, i; int xid, i;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
struct cifsFileInfo *cifsFile = NULL; struct cifsFileInfo *cifsFile = NULL;
char *current_entry; char *current_entry;
int num_to_fill = 0; int num_to_fill = 0;
......
...@@ -37,13 +37,13 @@ ...@@ -37,13 +37,13 @@
* the socket has been reestablished (so we know whether to use vc 0). * the socket has been reestablished (so we know whether to use vc 0).
* Called while holding the cifs_tcp_ses_lock, so do not block * Called while holding the cifs_tcp_ses_lock, so do not block
*/ */
static bool is_first_ses_reconnect(struct cifsSesInfo *ses) static bool is_first_ses_reconnect(struct cifs_ses *ses)
{ {
struct list_head *tmp; struct list_head *tmp;
struct cifsSesInfo *tmp_ses; struct cifs_ses *tmp_ses;
list_for_each(tmp, &ses->server->smb_ses_list) { list_for_each(tmp, &ses->server->smb_ses_list) {
tmp_ses = list_entry(tmp, struct cifsSesInfo, tmp_ses = list_entry(tmp, struct cifs_ses,
smb_ses_list); smb_ses_list);
if (tmp_ses->need_reconnect == false) if (tmp_ses->need_reconnect == false)
return false; return false;
...@@ -61,11 +61,11 @@ static bool is_first_ses_reconnect(struct cifsSesInfo *ses) ...@@ -61,11 +61,11 @@ static bool is_first_ses_reconnect(struct cifsSesInfo *ses)
* any vc but zero (some servers reset the connection on vcnum zero) * any vc but zero (some servers reset the connection on vcnum zero)
* *
*/ */
static __le16 get_next_vcnum(struct cifsSesInfo *ses) static __le16 get_next_vcnum(struct cifs_ses *ses)
{ {
__u16 vcnum = 0; __u16 vcnum = 0;
struct list_head *tmp; struct list_head *tmp;
struct cifsSesInfo *tmp_ses; struct cifs_ses *tmp_ses;
__u16 max_vcs = ses->server->max_vcs; __u16 max_vcs = ses->server->max_vcs;
__u16 i; __u16 i;
int free_vc_found = 0; int free_vc_found = 0;
...@@ -87,7 +87,7 @@ static __le16 get_next_vcnum(struct cifsSesInfo *ses) ...@@ -87,7 +87,7 @@ static __le16 get_next_vcnum(struct cifsSesInfo *ses)
free_vc_found = 1; free_vc_found = 1;
list_for_each(tmp, &ses->server->smb_ses_list) { list_for_each(tmp, &ses->server->smb_ses_list) {
tmp_ses = list_entry(tmp, struct cifsSesInfo, tmp_ses = list_entry(tmp, struct cifs_ses,
smb_ses_list); smb_ses_list);
if (tmp_ses->vcnum == i) { if (tmp_ses->vcnum == i) {
free_vc_found = 0; free_vc_found = 0;
...@@ -114,7 +114,7 @@ static __le16 get_next_vcnum(struct cifsSesInfo *ses) ...@@ -114,7 +114,7 @@ static __le16 get_next_vcnum(struct cifsSesInfo *ses)
return cpu_to_le16(vcnum); return cpu_to_le16(vcnum);
} }
static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB)
{ {
__u32 capabilities = 0; __u32 capabilities = 0;
...@@ -136,7 +136,7 @@ static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) ...@@ -136,7 +136,7 @@ static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
CAP_LARGE_WRITE_X | CAP_LARGE_READ_X; CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
if (ses->server->secMode & if (ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
...@@ -181,7 +181,7 @@ unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp) ...@@ -181,7 +181,7 @@ unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
*pbcc_area = bcc_ptr; *pbcc_area = bcc_ptr;
} }
static void unicode_domain_string(char **pbcc_area, struct cifsSesInfo *ses, static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
const struct nls_table *nls_cp) const struct nls_table *nls_cp)
{ {
char *bcc_ptr = *pbcc_area; char *bcc_ptr = *pbcc_area;
...@@ -204,7 +204,7 @@ static void unicode_domain_string(char **pbcc_area, struct cifsSesInfo *ses, ...@@ -204,7 +204,7 @@ static void unicode_domain_string(char **pbcc_area, struct cifsSesInfo *ses,
} }
static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses, static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
const struct nls_table *nls_cp) const struct nls_table *nls_cp)
{ {
char *bcc_ptr = *pbcc_area; char *bcc_ptr = *pbcc_area;
...@@ -236,7 +236,7 @@ static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses, ...@@ -236,7 +236,7 @@ static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
*pbcc_area = bcc_ptr; *pbcc_area = bcc_ptr;
} }
static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses, static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
const struct nls_table *nls_cp) const struct nls_table *nls_cp)
{ {
char *bcc_ptr = *pbcc_area; char *bcc_ptr = *pbcc_area;
...@@ -276,7 +276,7 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses, ...@@ -276,7 +276,7 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
} }
static void static void
decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses, decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifs_ses *ses,
const struct nls_table *nls_cp) const struct nls_table *nls_cp)
{ {
int len; int len;
...@@ -310,7 +310,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses, ...@@ -310,7 +310,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
} }
static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft, static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
struct cifsSesInfo *ses, struct cifs_ses *ses,
const struct nls_table *nls_cp) const struct nls_table *nls_cp)
{ {
int rc = 0; int rc = 0;
...@@ -364,7 +364,7 @@ static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft, ...@@ -364,7 +364,7 @@ static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
} }
static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
struct cifsSesInfo *ses) struct cifs_ses *ses)
{ {
unsigned int tioffset; /* challenge message target info area */ unsigned int tioffset; /* challenge message target info area */
unsigned int tilen; /* challenge message target info area length */ unsigned int tilen; /* challenge message target info area length */
...@@ -411,7 +411,7 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, ...@@ -411,7 +411,7 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
/* We do not malloc the blob, it is passed in pbuffer, because /* We do not malloc the blob, it is passed in pbuffer, because
it is fixed size, and small, making this approach cleaner */ it is fixed size, and small, making this approach cleaner */
static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
struct cifsSesInfo *ses) struct cifs_ses *ses)
{ {
NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer; NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
__u32 flags; __u32 flags;
...@@ -424,7 +424,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, ...@@ -424,7 +424,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET | flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC; NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
if (ses->server->secMode & if (ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
flags |= NTLMSSP_NEGOTIATE_SIGN; flags |= NTLMSSP_NEGOTIATE_SIGN;
if (!ses->server->session_estab) if (!ses->server->session_estab)
...@@ -449,7 +449,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, ...@@ -449,7 +449,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
This function returns the length of the data in the blob */ This function returns the length of the data in the blob */
static int build_ntlmssp_auth_blob(unsigned char *pbuffer, static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
u16 *buflen, u16 *buflen,
struct cifsSesInfo *ses, struct cifs_ses *ses,
const struct nls_table *nls_cp) const struct nls_table *nls_cp)
{ {
int rc; int rc;
...@@ -464,10 +464,10 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, ...@@ -464,10 +464,10 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC; NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
if (ses->server->secMode & if (ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
flags |= NTLMSSP_NEGOTIATE_SIGN; flags |= NTLMSSP_NEGOTIATE_SIGN;
if (ses->server->secMode & SECMODE_SIGN_REQUIRED) if (ses->server->sec_mode & SECMODE_SIGN_REQUIRED)
flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE); tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
...@@ -551,7 +551,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, ...@@ -551,7 +551,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
} }
int int
CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, CIFS_SessSetup(unsigned int xid, struct cifs_ses *ses,
const struct nls_table *nls_cp) const struct nls_table *nls_cp)
{ {
int rc = 0; int rc = 0;
...@@ -657,7 +657,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -657,7 +657,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
*/ */
rc = calc_lanman_hash(ses->password, ses->server->cryptkey, rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
ses->server->secMode & SECMODE_PW_ENCRYPT ? ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
true : false, lnm_session_key); true : false, lnm_session_key);
ses->flags |= CIFS_SES_LANMAN; ses->flags |= CIFS_SES_LANMAN;
......
...@@ -295,7 +295,7 @@ static int wait_for_free_request(struct TCP_Server_Info *server, ...@@ -295,7 +295,7 @@ static int wait_for_free_request(struct TCP_Server_Info *server,
return 0; return 0;
} }
static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf, static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
struct mid_q_entry **ppmidQ) struct mid_q_entry **ppmidQ)
{ {
if (ses->server->tcpStatus == CifsExiting) { if (ses->server->tcpStatus == CifsExiting) {
...@@ -342,22 +342,24 @@ wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ) ...@@ -342,22 +342,24 @@ wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
* the result. Caller is responsible for dealing with timeouts. * the result. Caller is responsible for dealing with timeouts.
*/ */
int int
cifs_call_async(struct TCP_Server_Info *server, struct smb_hdr *in_buf, cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov,
mid_callback_t *callback, void *cbdata) unsigned int nvec, mid_callback_t *callback, void *cbdata,
bool ignore_pend)
{ {
int rc; int rc;
struct mid_q_entry *mid; struct mid_q_entry *mid;
struct smb_hdr *hdr = (struct smb_hdr *)iov[0].iov_base;
rc = wait_for_free_request(server, CIFS_ASYNC_OP); rc = wait_for_free_request(server, ignore_pend ? CIFS_ASYNC_OP : 0);
if (rc) if (rc)
return rc; return rc;
/* enable signing if server requires it */ /* enable signing if server requires it */
if (server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
in_buf->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
mutex_lock(&server->srv_mutex); mutex_lock(&server->srv_mutex);
mid = AllocMidQEntry(in_buf, server); mid = AllocMidQEntry(hdr, server);
if (mid == NULL) { if (mid == NULL) {
mutex_unlock(&server->srv_mutex); mutex_unlock(&server->srv_mutex);
return -ENOMEM; return -ENOMEM;
...@@ -368,7 +370,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_hdr *in_buf, ...@@ -368,7 +370,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
list_add_tail(&mid->qhead, &server->pending_mid_q); list_add_tail(&mid->qhead, &server->pending_mid_q);
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
rc = cifs_sign_smb(in_buf, server, &mid->sequence_number); rc = cifs_sign_smb2(iov, nvec, server, &mid->sequence_number);
if (rc) { if (rc) {
mutex_unlock(&server->srv_mutex); mutex_unlock(&server->srv_mutex);
goto out_err; goto out_err;
...@@ -380,7 +382,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_hdr *in_buf, ...@@ -380,7 +382,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
#ifdef CONFIG_CIFS_STATS2 #ifdef CONFIG_CIFS_STATS2
atomic_inc(&server->inSend); atomic_inc(&server->inSend);
#endif #endif
rc = smb_send(server, in_buf, be32_to_cpu(in_buf->smb_buf_length)); rc = smb_sendv(server, iov, nvec);
#ifdef CONFIG_CIFS_STATS2 #ifdef CONFIG_CIFS_STATS2
atomic_dec(&server->inSend); atomic_dec(&server->inSend);
mid->when_sent = jiffies; mid->when_sent = jiffies;
...@@ -407,7 +409,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_hdr *in_buf, ...@@ -407,7 +409,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
* *
*/ */
int int
SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses, SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
struct smb_hdr *in_buf, int flags) struct smb_hdr *in_buf, int flags)
{ {
int rc; int rc;
...@@ -424,7 +426,7 @@ SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -424,7 +426,7 @@ SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
} }
static int static int
sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
{ {
int rc = 0; int rc = 0;
...@@ -432,28 +434,21 @@ sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) ...@@ -432,28 +434,21 @@ sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
mid->mid, mid->midState); mid->mid, mid->midState);
spin_lock(&GlobalMid_Lock); spin_lock(&GlobalMid_Lock);
/* ensure that it's no longer on the pending_mid_q */
list_del_init(&mid->qhead);
switch (mid->midState) { switch (mid->midState) {
case MID_RESPONSE_RECEIVED: case MID_RESPONSE_RECEIVED:
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
return rc; return rc;
case MID_REQUEST_SUBMITTED:
/* socket is going down, reject all calls */
if (server->tcpStatus == CifsExiting) {
cERROR(1, "%s: canceling mid=%d cmd=0x%x state=%d",
__func__, mid->mid, mid->command, mid->midState);
rc = -EHOSTDOWN;
break;
}
case MID_RETRY_NEEDED: case MID_RETRY_NEEDED:
rc = -EAGAIN; rc = -EAGAIN;
break; break;
case MID_RESPONSE_MALFORMED: case MID_RESPONSE_MALFORMED:
rc = -EIO; rc = -EIO;
break; break;
case MID_SHUTDOWN:
rc = -EHOSTDOWN;
break;
default: default:
list_del_init(&mid->qhead);
cERROR(1, "%s: invalid mid state mid=%d state=%d", __func__, cERROR(1, "%s: invalid mid state mid=%d state=%d", __func__,
mid->mid, mid->midState); mid->mid, mid->midState);
rc = -EIO; rc = -EIO;
...@@ -502,13 +497,31 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_hdr *in_buf, ...@@ -502,13 +497,31 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
} }
int int
SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
bool log_error)
{
dump_smb(mid->resp_buf,
min_t(u32, 92, be32_to_cpu(mid->resp_buf->smb_buf_length)));
/* convert the length into a more usable form */
if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
/* FIXME: add code to kill session */
if (cifs_verify_signature(mid->resp_buf, server,
mid->sequence_number + 1) != 0)
cERROR(1, "Unexpected SMB signature");
}
/* BB special case reconnect tid and uid here? */
return map_smb_to_linux_error(mid->resp_buf, log_error);
}
int
SendReceive2(const unsigned int xid, struct cifs_ses *ses,
struct kvec *iov, int n_vec, int *pRespBufType /* ret */, struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
const int flags) const int flags)
{ {
int rc = 0; int rc = 0;
int long_op; int long_op;
unsigned int receive_len;
struct mid_q_entry *midQ; struct mid_q_entry *midQ;
struct smb_hdr *in_buf = iov[0].iov_base; struct smb_hdr *in_buf = iov[0].iov_base;
...@@ -598,61 +611,31 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -598,61 +611,31 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
cifs_small_buf_release(in_buf); cifs_small_buf_release(in_buf);
rc = sync_mid_result(midQ, ses->server); rc = cifs_sync_mid_result(midQ, ses->server);
if (rc != 0) { if (rc != 0) {
atomic_dec(&ses->server->inFlight); atomic_dec(&ses->server->inFlight);
wake_up(&ses->server->request_q); wake_up(&ses->server->request_q);
return rc; return rc;
} }
receive_len = be32_to_cpu(midQ->resp_buf->smb_buf_length); if (!midQ->resp_buf || midQ->midState != MID_RESPONSE_RECEIVED) {
if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
cERROR(1, "Frame too large received. Length: %d Xid: %d",
receive_len, xid);
rc = -EIO; rc = -EIO;
cFYI(1, "Bad MID state?");
goto out; goto out;
} }
/* rcvd frame is ok */ iov[0].iov_base = (char *)midQ->resp_buf;
iov[0].iov_len = be32_to_cpu(midQ->resp_buf->smb_buf_length) + 4;
if (midQ->resp_buf && if (midQ->largeBuf)
(midQ->midState == MID_RESPONSE_RECEIVED)) { *pRespBufType = CIFS_LARGE_BUFFER;
else
iov[0].iov_base = (char *)midQ->resp_buf; *pRespBufType = CIFS_SMALL_BUFFER;
if (midQ->largeBuf)
*pRespBufType = CIFS_LARGE_BUFFER;
else
*pRespBufType = CIFS_SMALL_BUFFER;
iov[0].iov_len = receive_len + 4;
dump_smb(midQ->resp_buf, 80);
/* convert the length into a more usable form */
if ((receive_len > 24) &&
(ses->server->secMode & (SECMODE_SIGN_REQUIRED |
SECMODE_SIGN_ENABLED))) {
rc = cifs_verify_signature(midQ->resp_buf,
ses->server,
midQ->sequence_number+1);
if (rc) {
cERROR(1, "Unexpected SMB signature");
/* BB FIXME add code to kill session */
}
}
/* BB special case reconnect tid and uid here? */
rc = map_smb_to_linux_error(midQ->resp_buf,
flags & CIFS_LOG_ERROR);
if ((flags & CIFS_NO_RESP) == 0) rc = cifs_check_receive(midQ, ses->server, flags & CIFS_LOG_ERROR);
midQ->resp_buf = NULL; /* mark it so buf will
not be freed by
delete_mid */
} else {
rc = -EIO;
cFYI(1, "Bad MID state?");
}
/* mark it so buf will not be freed by delete_mid */
if ((flags & CIFS_NO_RESP) == 0)
midQ->resp_buf = NULL;
out: out:
delete_mid(midQ); delete_mid(midQ);
atomic_dec(&ses->server->inFlight); atomic_dec(&ses->server->inFlight);
...@@ -662,12 +645,11 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -662,12 +645,11 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
} }
int int
SendReceive(const unsigned int xid, struct cifsSesInfo *ses, SendReceive(const unsigned int xid, struct cifs_ses *ses,
struct smb_hdr *in_buf, struct smb_hdr *out_buf, struct smb_hdr *in_buf, struct smb_hdr *out_buf,
int *pbytes_returned, const int long_op) int *pbytes_returned, const int long_op)
{ {
int rc = 0; int rc = 0;
unsigned int receive_len;
struct mid_q_entry *midQ; struct mid_q_entry *midQ;
if (ses == NULL) { if (ses == NULL) {
...@@ -750,54 +732,23 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -750,54 +732,23 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
} }
rc = sync_mid_result(midQ, ses->server); rc = cifs_sync_mid_result(midQ, ses->server);
if (rc != 0) { if (rc != 0) {
atomic_dec(&ses->server->inFlight); atomic_dec(&ses->server->inFlight);
wake_up(&ses->server->request_q); wake_up(&ses->server->request_q);
return rc; return rc;
} }
receive_len = be32_to_cpu(midQ->resp_buf->smb_buf_length); if (!midQ->resp_buf || !out_buf ||
midQ->midState != MID_RESPONSE_RECEIVED) {
if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
cERROR(1, "Frame too large received. Length: %d Xid: %d",
receive_len, xid);
rc = -EIO;
goto out;
}
/* rcvd frame is ok */
if (midQ->resp_buf && out_buf
&& (midQ->midState == MID_RESPONSE_RECEIVED)) {
out_buf->smb_buf_length = cpu_to_be32(receive_len);
memcpy((char *)out_buf + 4,
(char *)midQ->resp_buf + 4,
receive_len);
dump_smb(out_buf, 92);
/* convert the length into a more usable form */
if ((receive_len > 24) &&
(ses->server->secMode & (SECMODE_SIGN_REQUIRED |
SECMODE_SIGN_ENABLED))) {
rc = cifs_verify_signature(out_buf,
ses->server,
midQ->sequence_number+1);
if (rc) {
cERROR(1, "Unexpected SMB signature");
/* BB FIXME add code to kill session */
}
}
*pbytes_returned = be32_to_cpu(out_buf->smb_buf_length);
/* BB special case reconnect tid and uid here? */
rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
} else {
rc = -EIO; rc = -EIO;
cERROR(1, "Bad MID state?"); cERROR(1, "Bad MID state?");
goto out;
} }
*pbytes_returned = be32_to_cpu(midQ->resp_buf->smb_buf_length);
memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
rc = cifs_check_receive(midQ, ses->server, 0);
out: out:
delete_mid(midQ); delete_mid(midQ);
atomic_dec(&ses->server->inFlight); atomic_dec(&ses->server->inFlight);
...@@ -810,12 +761,12 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -810,12 +761,12 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
blocking lock to return. */ blocking lock to return. */
static int static int
send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon, send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
struct smb_hdr *in_buf, struct smb_hdr *in_buf,
struct smb_hdr *out_buf) struct smb_hdr *out_buf)
{ {
int bytes_returned; int bytes_returned;
struct cifsSesInfo *ses = tcon->ses; struct cifs_ses *ses = tcon->ses;
LOCK_REQ *pSMB = (LOCK_REQ *)in_buf; LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
/* We just modify the current in_buf to change /* We just modify the current in_buf to change
...@@ -832,15 +783,14 @@ send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon, ...@@ -832,15 +783,14 @@ send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon,
} }
int int
SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
struct smb_hdr *in_buf, struct smb_hdr *out_buf, struct smb_hdr *in_buf, struct smb_hdr *out_buf,
int *pbytes_returned) int *pbytes_returned)
{ {
int rc = 0; int rc = 0;
int rstart = 0; int rstart = 0;
unsigned int receive_len;
struct mid_q_entry *midQ; struct mid_q_entry *midQ;
struct cifsSesInfo *ses; struct cifs_ses *ses;
if (tcon == NULL || tcon->ses == NULL) { if (tcon == NULL || tcon->ses == NULL) {
cERROR(1, "Null smb session"); cERROR(1, "Null smb session");
...@@ -957,50 +907,20 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, ...@@ -957,50 +907,20 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
rstart = 1; rstart = 1;
} }
rc = sync_mid_result(midQ, ses->server); rc = cifs_sync_mid_result(midQ, ses->server);
if (rc != 0) if (rc != 0)
return rc; return rc;
receive_len = be32_to_cpu(midQ->resp_buf->smb_buf_length);
if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
cERROR(1, "Frame too large received. Length: %d Xid: %d",
receive_len, xid);
rc = -EIO;
goto out;
}
/* rcvd frame is ok */ /* rcvd frame is ok */
if (out_buf == NULL || midQ->midState != MID_RESPONSE_RECEIVED) {
if ((out_buf == NULL) || (midQ->midState != MID_RESPONSE_RECEIVED)) {
rc = -EIO; rc = -EIO;
cERROR(1, "Bad MID state?"); cERROR(1, "Bad MID state?");
goto out; goto out;
} }
out_buf->smb_buf_length = cpu_to_be32(receive_len); *pbytes_returned = be32_to_cpu(midQ->resp_buf->smb_buf_length);
memcpy((char *)out_buf + 4, memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
(char *)midQ->resp_buf + 4, rc = cifs_check_receive(midQ, ses->server, 0);
receive_len);
dump_smb(out_buf, 92);
/* convert the length into a more usable form */
if ((receive_len > 24) &&
(ses->server->secMode & (SECMODE_SIGN_REQUIRED |
SECMODE_SIGN_ENABLED))) {
rc = cifs_verify_signature(out_buf,
ses->server,
midQ->sequence_number+1);
if (rc) {
cERROR(1, "Unexpected SMB signature");
/* BB FIXME add code to kill session */
}
}
*pbytes_returned = be32_to_cpu(out_buf->smb_buf_length);
/* BB special case reconnect tid and uid here? */
rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
out: out:
delete_mid(midQ); delete_mid(midQ);
if (rstart && rc == -EACCES) if (rstart && rc == -EACCES)
......
...@@ -49,7 +49,7 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name) ...@@ -49,7 +49,7 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
int xid; int xid;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
struct super_block *sb; struct super_block *sb;
char *full_path = NULL; char *full_path = NULL;
...@@ -109,7 +109,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, ...@@ -109,7 +109,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
int xid; int xid;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
struct super_block *sb; struct super_block *sb;
char *full_path; char *full_path;
struct cifs_ntsd *pacl; struct cifs_ntsd *pacl;
...@@ -240,7 +240,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, ...@@ -240,7 +240,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
int xid; int xid;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
struct super_block *sb; struct super_block *sb;
char *full_path; char *full_path;
...@@ -372,7 +372,7 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size) ...@@ -372,7 +372,7 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
int xid; int xid;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink; struct tcon_link *tlink;
struct cifsTconInfo *pTcon; struct cifs_tcon *pTcon;
struct super_block *sb; struct super_block *sb;
char *full_path; char *full_path;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment