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
This commit is contained in:
commit
40efeb4d0b
|
@ -153,26 +153,6 @@ config CIFS_ACL
|
|||
Allows to fetch CIFS/NTFS ACL from the server. The DACL blob
|
||||
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
|
||||
bool "Allow nfsd to export CIFS file system (EXPERIMENTAL)"
|
||||
depends on CIFS && EXPERIMENTAL
|
||||
|
|
|
@ -457,6 +457,9 @@ A partial list of the supported mount options follows:
|
|||
otherwise - read from the server. All written data are stored
|
||||
in the cache, but if the client doesn't have Exclusive Oplock,
|
||||
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
|
||||
supports them. (default)
|
||||
noacl Do not allow setfacl and getfacl calls on this mount
|
||||
|
|
|
@ -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,
|
||||
uint16_t maxbuf)
|
||||
{
|
||||
const struct cifsTconInfo *tcon = cookie_netfs_data;
|
||||
const struct cifs_tcon *tcon = cookie_netfs_data;
|
||||
char *sharename;
|
||||
uint16_t len;
|
||||
|
||||
|
@ -173,7 +173,7 @@ cifs_fscache_super_get_aux(const void *cookie_netfs_data, void *buffer,
|
|||
uint16_t maxbuf)
|
||||
{
|
||||
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));
|
||||
auxdata.resource_id = tcon->resource_id;
|
||||
|
@ -192,7 +192,7 @@ fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data,
|
|||
uint16_t datalen)
|
||||
{
|
||||
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))
|
||||
return FSCACHE_CHECKAUX_OBSOLETE;
|
||||
|
|
|
@ -110,8 +110,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
|
|||
struct list_head *tmp1, *tmp2, *tmp3;
|
||||
struct mid_q_entry *mid_entry;
|
||||
struct TCP_Server_Info *server;
|
||||
struct cifsSesInfo *ses;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_ses *ses;
|
||||
struct cifs_tcon *tcon;
|
||||
int i, j;
|
||||
__u32 dev_type;
|
||||
|
||||
|
@ -152,7 +152,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
|
|||
tcp_ses_list);
|
||||
i++;
|
||||
list_for_each(tmp2, &server->smb_ses_list) {
|
||||
ses = list_entry(tmp2, struct cifsSesInfo,
|
||||
ses = list_entry(tmp2, struct cifs_ses,
|
||||
smb_ses_list);
|
||||
if ((ses->serverDomain == NULL) ||
|
||||
(ses->serverOS == NULL) ||
|
||||
|
@ -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 "
|
||||
"Server: %d SecMode: 0x%x Req On Wire: %d",
|
||||
server->tcpStatus, server->srv_count,
|
||||
server->secMode,
|
||||
server->sec_mode,
|
||||
atomic_read(&server->inFlight));
|
||||
|
||||
#ifdef CONFIG_CIFS_STATS2
|
||||
|
@ -183,7 +183,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
|
|||
seq_puts(m, "\n\tShares:");
|
||||
j = 0;
|
||||
list_for_each(tmp3, &ses->tcon_list) {
|
||||
tcon = list_entry(tmp3, struct cifsTconInfo,
|
||||
tcon = list_entry(tmp3, struct cifs_tcon,
|
||||
tcon_list);
|
||||
++j;
|
||||
dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
|
||||
|
@ -256,8 +256,8 @@ static ssize_t cifs_stats_proc_write(struct file *file,
|
|||
int rc;
|
||||
struct list_head *tmp1, *tmp2, *tmp3;
|
||||
struct TCP_Server_Info *server;
|
||||
struct cifsSesInfo *ses;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_ses *ses;
|
||||
struct cifs_tcon *tcon;
|
||||
|
||||
rc = get_user(c, buffer);
|
||||
if (rc)
|
||||
|
@ -273,11 +273,11 @@ static ssize_t cifs_stats_proc_write(struct file *file,
|
|||
server = list_entry(tmp1, struct TCP_Server_Info,
|
||||
tcp_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);
|
||||
list_for_each(tmp3, &ses->tcon_list) {
|
||||
tcon = list_entry(tmp3,
|
||||
struct cifsTconInfo,
|
||||
struct cifs_tcon,
|
||||
tcon_list);
|
||||
atomic_set(&tcon->num_smbs_sent, 0);
|
||||
atomic_set(&tcon->num_writes, 0);
|
||||
|
@ -312,8 +312,8 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
|
|||
int i;
|
||||
struct list_head *tmp1, *tmp2, *tmp3;
|
||||
struct TCP_Server_Info *server;
|
||||
struct cifsSesInfo *ses;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_ses *ses;
|
||||
struct cifs_tcon *tcon;
|
||||
|
||||
seq_printf(m,
|
||||
"Resources in use\nCIFS Session: %d\n",
|
||||
|
@ -346,11 +346,11 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
|
|||
server = list_entry(tmp1, struct TCP_Server_Info,
|
||||
tcp_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);
|
||||
list_for_each(tmp3, &ses->tcon_list) {
|
||||
tcon = list_entry(tmp3,
|
||||
struct cifsTconInfo,
|
||||
struct cifs_tcon,
|
||||
tcon_list);
|
||||
i++;
|
||||
seq_printf(m, "\n%d) %s", i, tcon->treeName);
|
||||
|
|
|
@ -272,7 +272,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
|
|||
struct dfs_info3_param *referrals = NULL;
|
||||
unsigned int num_referrals = 0;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct cifsSesInfo *ses;
|
||||
struct cifs_ses *ses;
|
||||
char *full_path;
|
||||
int xid, i;
|
||||
int rc;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#define CIFS_MOUNT_MF_SYMLINKS 0x10000 /* Minshall+French Symlinks enabled */
|
||||
#define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */
|
||||
#define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */
|
||||
#define CIFS_MOUNT_RWPIDFORWARD 0x80000 /* use pid forwarding for rw */
|
||||
|
||||
struct cifs_sb_info {
|
||||
struct rb_root tlink_tree;
|
||||
|
@ -56,8 +57,6 @@ struct cifs_sb_info {
|
|||
mode_t mnt_file_mode;
|
||||
mode_t mnt_dir_mode;
|
||||
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 */
|
||||
struct backing_dev_info bdi;
|
||||
struct delayed_work prune_tlinks;
|
||||
|
|
|
@ -95,7 +95,7 @@ struct key_type cifs_spnego_key_type = {
|
|||
|
||||
/* get a key struct with a SPNEGO security blob, suitable for session setup */
|
||||
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 sockaddr_in *sa = (struct sockaddr_in *) &server->dstaddr;
|
||||
|
|
|
@ -41,7 +41,7 @@ struct cifs_spnego_msg {
|
|||
|
||||
#ifdef __KERNEL__
|
||||
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 /* _CIFS_SPNEGO_H */
|
||||
|
|
|
@ -38,7 +38,7 @@ static const struct cifs_sid sid_everyone = {
|
|||
1, 1, {0, 0, 0, 0, 0, 1}, {0} };
|
||||
/* security id for Authenticated Users system group */
|
||||
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 */
|
||||
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)
|
|||
if (num_subauth) {
|
||||
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 (le32_to_cpu(ctsid->sub_auth[i]) >
|
||||
le32_to_cpu(cwsid->sub_auth[i]))
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
|
@ -945,7 +946,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
|
|||
int oplock = 0;
|
||||
int xid, rc;
|
||||
__u16 fid;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_tcon *tcon;
|
||||
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
|
||||
|
||||
if (IS_ERR(tlink))
|
||||
|
@ -1013,7 +1014,7 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
|
|||
int oplock = 0;
|
||||
int xid, rc;
|
||||
__u16 fid;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_tcon *tcon;
|
||||
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
|
||||
|
||||
if (IS_ERR(tlink))
|
||||
|
|
|
@ -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 */
|
||||
int setup_ntlm_response(struct cifsSesInfo *ses)
|
||||
int setup_ntlm_response(struct cifs_ses *ses)
|
||||
{
|
||||
int rc = 0;
|
||||
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,
|
|||
* Allocate domain name which gets freed when session struct is deallocated.
|
||||
*/
|
||||
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 wlen;
|
||||
|
@ -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.
|
||||
*/
|
||||
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 type;
|
||||
|
@ -445,7 +445,7 @@ find_domain_name(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
|
|||
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)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -527,7 +527,7 @@ calc_exit_2:
|
|||
}
|
||||
|
||||
static int
|
||||
CalcNTLMv2_response(const struct cifsSesInfo *ses, char *ntlmv2_hash)
|
||||
CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
|
||||
{
|
||||
int rc;
|
||||
unsigned int offset = CIFS_SESS_KEY_SIZE + 8;
|
||||
|
@ -563,7 +563,7 @@ CalcNTLMv2_response(const struct cifsSesInfo *ses, char *ntlmv2_hash)
|
|||
|
||||
|
||||
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 baselen;
|
||||
|
@ -649,7 +649,7 @@ setup_ntlmv2_rsp_ret:
|
|||
}
|
||||
|
||||
int
|
||||
calc_seckey(struct cifsSesInfo *ses)
|
||||
calc_seckey(struct cifs_ses *ses)
|
||||
{
|
||||
int rc;
|
||||
struct crypto_blkcipher *tfm_arc4;
|
||||
|
|
233
fs/cifs/cifsfs.c
233
fs/cifs/cifsfs.c
|
@ -104,46 +104,25 @@ cifs_sb_deactive(struct super_block *sb)
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct inode *inode;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
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);
|
||||
if (cifs_sb == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&cifs_sb->tlink_tree_lock);
|
||||
cifs_sb->tlink_tree = RB_ROOT;
|
||||
|
||||
rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY);
|
||||
if (rc) {
|
||||
kfree(cifs_sb);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
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 (!silent)
|
||||
|
@ -194,15 +173,7 @@ out_no_root:
|
|||
cifs_umount(sb, cifs_sb);
|
||||
|
||||
out_mount_failed:
|
||||
if (cifs_sb) {
|
||||
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);
|
||||
}
|
||||
bdi_destroy(&cifs_sb->bdi);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -237,7 +208,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
|||
{
|
||||
struct super_block *sb = dentry->d_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 xid;
|
||||
|
||||
|
@ -390,7 +361,7 @@ static int
|
|||
cifs_show_options(struct seq_file *s, struct vfsmount *m)
|
||||
{
|
||||
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;
|
||||
srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr;
|
||||
|
||||
|
@ -444,14 +415,20 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
|
|||
seq_printf(s, ",nocase");
|
||||
if (tcon->retry)
|
||||
seq_printf(s, ",hard");
|
||||
if (cifs_sb->prepath)
|
||||
seq_printf(s, ",prepath=%s", cifs_sb->prepath);
|
||||
if (tcon->unix_ext)
|
||||
seq_printf(s, ",unix");
|
||||
else
|
||||
seq_printf(s, ",nounix");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
|
||||
seq_printf(s, ",posixpaths");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
|
||||
seq_printf(s, ",setuids");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
|
||||
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)
|
||||
seq_printf(s, ",directio");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
|
||||
|
@ -484,7 +461,7 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
|
|||
static void cifs_umount_begin(struct super_block *sb)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_tcon *tcon;
|
||||
|
||||
if (cifs_sb == NULL)
|
||||
return;
|
||||
|
@ -559,29 +536,189 @@ static const struct super_operations cifs_super_ops = {
|
|||
#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 *
|
||||
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;
|
||||
struct super_block *sb;
|
||||
|
||||
sb = sget(fs_type, NULL, set_anon_super, NULL);
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct smb_vol *volume_info;
|
||||
struct cifs_mnt_data mnt_data;
|
||||
struct dentry *root;
|
||||
|
||||
cFYI(1, "Devname: %s flags: %d ", dev_name, flags);
|
||||
|
||||
if (IS_ERR(sb))
|
||||
return ERR_CAST(sb);
|
||||
rc = cifs_setup_volume_info(&volume_info, (char *)data, dev_name);
|
||||
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;
|
||||
/* 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) {
|
||||
deactivate_locked_super(sb);
|
||||
return ERR_PTR(rc);
|
||||
root = ERR_PTR(rc);
|
||||
goto out_super;
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
|
@ -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 list_head tcp_ses_list;
|
||||
struct list_head smb_ses_list;
|
||||
|
@ -179,7 +254,7 @@ struct TCP_Server_Info {
|
|||
struct mutex srv_mutex;
|
||||
struct task_struct *tsk;
|
||||
char server_GUID[16];
|
||||
char secMode;
|
||||
char sec_mode;
|
||||
bool session_estab; /* mark when very first sess is established */
|
||||
u16 dialect; /* dialect index that server chose */
|
||||
enum securityEnum secType;
|
||||
|
@ -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
|
||||
*/
|
||||
struct cifsSesInfo {
|
||||
struct cifs_ses {
|
||||
struct list_head smb_ses_list;
|
||||
struct list_head tcon_list;
|
||||
struct mutex session_mutex;
|
||||
|
@ -294,11 +369,11 @@ struct cifsSesInfo {
|
|||
* there is one of these for each connection to a resource on a particular
|
||||
* session
|
||||
*/
|
||||
struct cifsTconInfo {
|
||||
struct cifs_tcon {
|
||||
struct list_head tcon_list;
|
||||
int tc_count;
|
||||
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 *nativeFileSystem;
|
||||
char *password; /* for share-level security */
|
||||
|
@ -380,12 +455,12 @@ struct tcon_link {
|
|||
#define TCON_LINK_IN_TREE 2
|
||||
unsigned long tl_time;
|
||||
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);
|
||||
|
||||
static inline struct cifsTconInfo *
|
||||
static inline struct cifs_tcon *
|
||||
tlink_tcon(struct tcon_link *tlink)
|
||||
{
|
||||
return tlink->tl_tcon;
|
||||
|
@ -402,7 +477,7 @@ cifs_get_tlink(struct tcon_link *tlink)
|
|||
}
|
||||
|
||||
/* 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.
|
||||
|
@ -455,6 +530,14 @@ struct cifsFileInfo {
|
|||
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
|
||||
* cifs_file_list_lock held.
|
||||
|
@ -509,10 +592,30 @@ static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb)
|
|||
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
|
||||
#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)
|
||||
{
|
||||
if (bytes) {
|
||||
|
@ -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)
|
||||
{
|
||||
spin_lock(&tcon->stat_lock);
|
||||
|
@ -543,9 +646,8 @@ struct mid_q_entry;
|
|||
* This is the prototype for the mid callback function. When creating one,
|
||||
* take special care to avoid deadlocks. Things to bear in mind:
|
||||
*
|
||||
* - it will be called by cifsd
|
||||
* - the GlobalMid_Lock will be held
|
||||
* - the mid will be removed from the pending_mid_q list
|
||||
* - it will be called by cifsd, with no locks held
|
||||
* - the mid will be removed from any lists
|
||||
*/
|
||||
typedef void (mid_callback_t)(struct mid_q_entry *mid);
|
||||
|
||||
|
@ -573,7 +675,7 @@ struct mid_q_entry {
|
|||
struct oplock_q_entry {
|
||||
struct list_head qhead;
|
||||
struct inode *pinode;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_tcon *tcon;
|
||||
__u16 netfid;
|
||||
};
|
||||
|
||||
|
@ -656,6 +758,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
|
|||
#define MID_RESPONSE_RECEIVED 4
|
||||
#define MID_RETRY_NEEDED 8 /* session closed while this request out */
|
||||
#define MID_RESPONSE_MALFORMED 0x10
|
||||
#define MID_SHUTDOWN 0x20
|
||||
|
||||
/* Types of response buffer returned from SendReceive2 */
|
||||
#define CIFS_NO_BUFFER 0 /* Response buffer not returned */
|
||||
|
|
|
@ -57,8 +57,9 @@ extern int init_cifs_idmap(void);
|
|||
extern void exit_cifs_idmap(void);
|
||||
extern void cifs_destroy_idmaptrees(void);
|
||||
extern char *build_path_from_dentry(struct dentry *);
|
||||
extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
|
||||
struct cifsTconInfo *tcon);
|
||||
extern char *cifs_build_path_to_root(struct smb_vol *vol,
|
||||
struct cifs_sb_info *cifs_sb,
|
||||
struct cifs_tcon *tcon);
|
||||
extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
|
||||
extern char *cifs_compose_mount_options(const char *sb_mountdata,
|
||||
const char *fullpath, const struct dfs_info3_param *ref,
|
||||
|
@ -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,
|
||||
struct TCP_Server_Info *server);
|
||||
extern void DeleteMidQEntry(struct mid_q_entry *midEntry);
|
||||
extern int cifs_call_async(struct TCP_Server_Info *server,
|
||||
struct smb_hdr *in_buf, mid_callback_t *callback,
|
||||
void *cbdata);
|
||||
extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
|
||||
extern int cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov,
|
||||
unsigned int nvec, mid_callback_t *callback,
|
||||
void *cbdata, bool ignore_pend);
|
||||
extern int SendReceive(const unsigned int /* xid */ , struct cifs_ses *,
|
||||
struct smb_hdr * /* input */ ,
|
||||
struct smb_hdr * /* out */ ,
|
||||
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);
|
||||
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 */,
|
||||
int * /* type of buf returned */ , const int flags);
|
||||
extern int SendReceiveBlockingLock(const unsigned int xid,
|
||||
struct cifsTconInfo *ptcon,
|
||||
struct cifs_tcon *ptcon,
|
||||
struct smb_hdr *in_buf ,
|
||||
struct smb_hdr *out_buf,
|
||||
int *bytes_returned);
|
||||
|
@ -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_fill_sockaddr(struct sockaddr *dst, const char *src, int len,
|
||||
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 */ ,
|
||||
const struct cifsTconInfo *, int /* length of
|
||||
const struct cifs_tcon *, int /* length of
|
||||
fixed section (word count) in two byte units */);
|
||||
extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
|
||||
struct cifsSesInfo *ses,
|
||||
struct cifs_ses *ses,
|
||||
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);
|
||||
extern __u16 GetNextMid(struct TCP_Server_Info *server);
|
||||
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 *,
|
|||
extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *,
|
||||
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 *,
|
||||
const char *);
|
||||
struct smb_vol *, const char *);
|
||||
extern int cifs_umount(struct super_block *, struct cifs_sb_info *);
|
||||
extern void cifs_dfs_release_automount_timer(void);
|
||||
void cifs_proc_init(void);
|
||||
void cifs_proc_clean(void);
|
||||
|
||||
extern int cifs_negotiate_protocol(unsigned int xid,
|
||||
struct cifsSesInfo *ses);
|
||||
extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
|
||||
struct cifs_ses *ses);
|
||||
extern int cifs_setup_session(unsigned int xid, struct cifs_ses *ses,
|
||||
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,
|
||||
const char *tree, struct cifsTconInfo *tcon,
|
||||
extern int CIFSTCon(unsigned int xid, struct cifs_ses *ses,
|
||||
const char *tree, struct cifs_tcon *tcon,
|
||||
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,
|
||||
__u16 *searchHandle, struct cifs_search_info *psrch_inf,
|
||||
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);
|
||||
|
||||
extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
|
||||
extern int CIFSFindClose(const int, struct cifs_tcon *tcon,
|
||||
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);
|
||||
extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
|
||||
extern int CIFSSMBQPathInfo(const int xid, struct cifs_tcon *tcon,
|
||||
const unsigned char *searchName,
|
||||
FILE_ALL_INFO *findData,
|
||||
int legacy /* whether to use old info level */,
|
||||
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,
|
||||
FILE_ALL_INFO *findData,
|
||||
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);
|
||||
extern int CIFSSMBUnixQPathInfo(const int xid,
|
||||
struct cifsTconInfo *tcon,
|
||||
struct cifs_tcon *tcon,
|
||||
const unsigned char *searchName,
|
||||
FILE_UNIX_BASIC_INFO *pFindData,
|
||||
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,
|
||||
struct dfs_info3_param **target_nodes,
|
||||
unsigned int *number_of_nodes_in_array,
|
||||
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 struct nls_table *nls_codepage,
|
||||
unsigned int *pnum_referrals,
|
||||
struct dfs_info3_param **preferrals,
|
||||
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);
|
||||
extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
|
||||
extern int CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon,
|
||||
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);
|
||||
extern int CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon,
|
||||
extern int CIFSSMBSetFSUnixInfo(const int xid, struct cifs_tcon *tcon,
|
||||
__u64 cap);
|
||||
|
||||
extern int CIFSSMBQFSAttributeInfo(const int xid,
|
||||
struct cifsTconInfo *tcon);
|
||||
extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon);
|
||||
extern int CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon);
|
||||
extern int CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
|
||||
struct cifs_tcon *tcon);
|
||||
extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon);
|
||||
extern int CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon);
|
||||
extern int CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
|
||||
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 struct nls_table *nls_codepage,
|
||||
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,
|
||||
__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);
|
||||
#if 0
|
||||
extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon,
|
||||
extern int CIFSSMBSetAttrLegacy(int xid, struct cifs_tcon *tcon,
|
||||
char *fileName, __u16 dos_attributes,
|
||||
const struct nls_table *nls_codepage);
|
||||
#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,
|
||||
bool setAllocationSizeFlag,
|
||||
const struct nls_table *nls_codepage,
|
||||
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,
|
||||
bool AllocSizeFlag);
|
||||
|
||||
|
@ -257,120 +266,116 @@ struct cifs_unix_set_info_args {
|
|||
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,
|
||||
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,
|
||||
const struct cifs_unix_set_info_args *args,
|
||||
const struct nls_table *nls_codepage,
|
||||
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 struct nls_table *nls_codepage,
|
||||
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,
|
||||
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 struct nls_table *nls_codepage,
|
||||
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 struct nls_table *nls_codepage,
|
||||
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 struct nls_table *nls_codepage,
|
||||
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,
|
||||
const struct nls_table *nls_codepage,
|
||||
int remap_special_chars);
|
||||
extern int CIFSCreateHardLink(const int xid,
|
||||
struct cifsTconInfo *tcon,
|
||||
struct cifs_tcon *tcon,
|
||||
const char *fromName, const char *toName,
|
||||
const struct nls_table *nls_codepage,
|
||||
int remap_special_chars);
|
||||
extern int CIFSUnixCreateHardLink(const int xid,
|
||||
struct cifsTconInfo *tcon,
|
||||
struct cifs_tcon *tcon,
|
||||
const char *fromName, const char *toName,
|
||||
const struct nls_table *nls_codepage,
|
||||
int remap_special_chars);
|
||||
extern int CIFSUnixCreateSymLink(const int xid,
|
||||
struct cifsTconInfo *tcon,
|
||||
struct cifs_tcon *tcon,
|
||||
const char *fromName, const char *toName,
|
||||
const struct nls_table *nls_codepage);
|
||||
extern int CIFSSMBUnixQuerySymLink(const int xid,
|
||||
struct cifsTconInfo *tcon,
|
||||
struct cifs_tcon *tcon,
|
||||
const unsigned char *searchName, char **syminfo,
|
||||
const struct nls_table *nls_codepage);
|
||||
#ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
|
||||
extern int CIFSSMBQueryReparseLinkInfo(const int xid,
|
||||
struct cifsTconInfo *tcon,
|
||||
struct cifs_tcon *tcon,
|
||||
const unsigned char *searchName,
|
||||
char *symlinkinfo, const int buflen, __u16 fid,
|
||||
const struct nls_table *nls_codepage);
|
||||
#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 int access_flags, const int omode,
|
||||
__u16 *netfid, int *pOplock, FILE_ALL_INFO *,
|
||||
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 int access_flags, const int omode,
|
||||
__u16 *netfid, int *pOplock, FILE_ALL_INFO *,
|
||||
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,
|
||||
FILE_UNIX_BASIC_INFO *pRetData,
|
||||
__u32 *pOplock, const char *name,
|
||||
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);
|
||||
|
||||
extern int CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon,
|
||||
extern int CIFSSMBFlush(const int xid, struct cifs_tcon *tcon,
|
||||
const int smb_file_id);
|
||||
|
||||
extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
|
||||
const int netfid, unsigned int count,
|
||||
const __u64 lseek, unsigned int *nbytes, char **buf,
|
||||
extern int CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms,
|
||||
unsigned int *nbytes, char **buf,
|
||||
int *return_buf_type);
|
||||
extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
|
||||
const int netfid, const unsigned int count,
|
||||
const __u64 lseek, unsigned int *nbytes,
|
||||
const char *buf, const char __user *ubuf,
|
||||
extern int CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
|
||||
unsigned int *nbytes, const char *buf,
|
||||
const char __user *ubuf, const int long_op);
|
||||
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);
|
||||
extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *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,
|
||||
extern int CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
|
||||
const unsigned char *searchName, __u64 *inode_number,
|
||||
const struct nls_table *nls_codepage,
|
||||
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 __u64 offset, const __u32 numUnlock,
|
||||
const __u32 numLock, const __u8 lockType,
|
||||
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 __u64 len, struct file_lock *,
|
||||
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 CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses);
|
||||
extern int CIFSSMBLogoff(const int xid, struct cifs_ses *ses);
|
||||
|
||||
extern struct cifsSesInfo *sesInfoAlloc(void);
|
||||
extern void sesInfoFree(struct cifsSesInfo *);
|
||||
extern struct cifsTconInfo *tconInfoAlloc(void);
|
||||
extern void tconInfoFree(struct cifsTconInfo *);
|
||||
extern struct cifs_ses *sesInfoAlloc(void);
|
||||
extern void sesInfoFree(struct cifs_ses *);
|
||||
extern struct cifs_tcon *tconInfoAlloc(void);
|
||||
extern void tconInfoFree(struct cifs_tcon *);
|
||||
|
||||
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 *,
|
||||
|
@ -379,51 +384,51 @@ extern int cifs_verify_signature(struct smb_hdr *,
|
|||
struct TCP_Server_Info *server,
|
||||
__u32 expected_sequence_number);
|
||||
extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *);
|
||||
extern int setup_ntlm_response(struct cifsSesInfo *);
|
||||
extern int setup_ntlmv2_rsp(struct cifsSesInfo *, const struct nls_table *);
|
||||
extern int setup_ntlm_response(struct cifs_ses *);
|
||||
extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *);
|
||||
extern int cifs_crypto_shash_allocate(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
|
||||
extern int calc_lanman_hash(const char *password, const char *cryptkey,
|
||||
bool encrypt, char *lnm_session_key);
|
||||
#endif /* CIFS_WEAK_PW_HASH */
|
||||
#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,
|
||||
__u32 filter, struct file *file, int multishot,
|
||||
const struct nls_table *nls_codepage);
|
||||
#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */
|
||||
extern int CIFSSMBCopy(int xid,
|
||||
struct cifsTconInfo *source_tcon,
|
||||
struct cifs_tcon *source_tcon,
|
||||
const char *fromName,
|
||||
const __u16 target_tid,
|
||||
const char *toName, const int flags,
|
||||
const struct nls_table *nls_codepage,
|
||||
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 *ea_name, char *EAData,
|
||||
size_t bufsize, const struct nls_table *nls_codepage,
|
||||
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 void *ea_value, const __u16 ea_value_len,
|
||||
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);
|
||||
extern int CIFSSMBSetCIFSACL(const int, struct cifsTconInfo *, __u16,
|
||||
extern int CIFSSMBSetCIFSACL(const int, struct cifs_tcon *, __u16,
|
||||
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,
|
||||
char *acl_inf, const int buflen, const int acl_type,
|
||||
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 char *local_acl, const int buflen, const int acl_type,
|
||||
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);
|
||||
extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
|
||||
extern bool CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr);
|
||||
|
@ -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 SMBencrypt(unsigned char *passwd, const unsigned char *c8,
|
||||
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 */
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <linux/vfs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/posix_acl_xattr.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include "cifspdu.h"
|
||||
#include "cifsglob.h"
|
||||
|
@ -84,7 +85,7 @@ static struct {
|
|||
|
||||
/* Mark as invalid, all open files on tree connections since they
|
||||
were closed when session to server was lost */
|
||||
static void mark_open_files_invalid(struct cifsTconInfo *pTcon)
|
||||
static void mark_open_files_invalid(struct cifs_tcon *pTcon)
|
||||
{
|
||||
struct cifsFileInfo *open_file = NULL;
|
||||
struct list_head *tmp;
|
||||
|
@ -104,10 +105,10 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon)
|
|||
|
||||
/* reconnect the socket, tcon, and smb session if needed */
|
||||
static int
|
||||
cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command)
|
||||
cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cifsSesInfo *ses;
|
||||
struct cifs_ses *ses;
|
||||
struct TCP_Server_Info *server;
|
||||
struct nls_table *nls_codepage;
|
||||
|
||||
|
@ -226,7 +227,7 @@ out:
|
|||
SMB information in the SMB header. If the return code is zero, this
|
||||
function must have filled in request_buf pointer */
|
||||
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)
|
||||
{
|
||||
int rc;
|
||||
|
@ -252,7 +253,7 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
|
|||
|
||||
int
|
||||
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;
|
||||
struct smb_hdr *buffer;
|
||||
|
@ -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 */
|
||||
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)
|
||||
{
|
||||
*request_buf = cifs_buf_get();
|
||||
|
@ -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 */
|
||||
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)
|
||||
{
|
||||
int rc;
|
||||
|
@ -317,7 +318,7 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (tcon->ses->need_reconnect || tcon->need_reconnect)
|
||||
|
@ -366,7 +367,7 @@ static inline void inc_rfc1001_len(void *pSMB, int count)
|
|||
}
|
||||
|
||||
int
|
||||
CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
|
||||
CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
|
||||
{
|
||||
NEGOTIATE_REQ *pSMB;
|
||||
NEGOTIATE_RSP *pSMBr;
|
||||
|
@ -450,7 +451,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
|
|||
rc = -EOPNOTSUPP;
|
||||
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->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize),
|
||||
(__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);
|
||||
|
@ -504,7 +505,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
|
|||
cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
|
||||
memcpy(ses->server->cryptkey, rsp->EncryptionKey,
|
||||
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 */
|
||||
goto neg_err_exit;
|
||||
}
|
||||
|
@ -526,11 +527,11 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
|
|||
goto neg_err_exit;
|
||||
}
|
||||
/* else wct == 17 NTLM */
|
||||
server->secMode = pSMBr->SecurityMode;
|
||||
if ((server->secMode & SECMODE_USER) == 0)
|
||||
server->sec_mode = pSMBr->SecurityMode;
|
||||
if ((server->sec_mode & SECMODE_USER) == 0)
|
||||
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
|
||||
if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
|
||||
#endif /* CIFS_WEAK_PW_HASH */
|
||||
|
@ -570,18 +571,10 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
|
|||
if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
|
||||
memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
|
||||
CIFS_CRYPTO_KEY_SIZE);
|
||||
} else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC)
|
||||
&& (pSMBr->EncryptionKeyLength == 0)) {
|
||||
} else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
|
||||
server->capabilities & CAP_EXTENDED_SECURITY) &&
|
||||
(pSMBr->EncryptionKeyLength == 0)) {
|
||||
/* 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);
|
||||
if (count < 16) {
|
||||
rc = -EIO;
|
||||
|
@ -624,6 +617,9 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
|
|||
} else
|
||||
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
|
||||
server->capabilities &= ~CAP_EXTENDED_SECURITY;
|
||||
|
||||
|
@ -634,27 +630,27 @@ signing_check:
|
|||
/* MUST_SIGN already includes the MAY_SIGN FLAG
|
||||
so if this is zero it means that signing is disabled */
|
||||
cFYI(1, "Signing disabled");
|
||||
if (server->secMode & SECMODE_SIGN_REQUIRED) {
|
||||
if (server->sec_mode & SECMODE_SIGN_REQUIRED) {
|
||||
cERROR(1, "Server requires "
|
||||
"packet signing to be enabled in "
|
||||
"/proc/fs/cifs/SecurityFlags.");
|
||||
rc = -EOPNOTSUPP;
|
||||
}
|
||||
server->secMode &=
|
||||
server->sec_mode &=
|
||||
~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
|
||||
} else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
|
||||
/* signing required */
|
||||
cFYI(1, "Must sign - secFlags 0x%x", secFlags);
|
||||
if ((server->secMode &
|
||||
if ((server->sec_mode &
|
||||
(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
|
||||
cERROR(1, "signing required but server lacks support");
|
||||
rc = -EOPNOTSUPP;
|
||||
} else
|
||||
server->secMode |= SECMODE_SIGN_REQUIRED;
|
||||
server->sec_mode |= SECMODE_SIGN_REQUIRED;
|
||||
} else {
|
||||
/* signing optional ie CIFSSEC_MAY_SIGN */
|
||||
if ((server->secMode & SECMODE_SIGN_REQUIRED) == 0)
|
||||
server->secMode &=
|
||||
if ((server->sec_mode & SECMODE_SIGN_REQUIRED) == 0)
|
||||
server->sec_mode &=
|
||||
~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
|
||||
}
|
||||
|
||||
|
@ -666,7 +662,7 @@ neg_err_exit:
|
|||
}
|
||||
|
||||
int
|
||||
CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
|
||||
CIFSSMBTDis(const int xid, struct cifs_tcon *tcon)
|
||||
{
|
||||
struct smb_hdr *smb_buffer;
|
||||
int rc = 0;
|
||||
|
@ -725,6 +721,7 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
|
|||
{
|
||||
ECHO_REQ *smb;
|
||||
int rc = 0;
|
||||
struct kvec iov;
|
||||
|
||||
cFYI(1, "In echo request");
|
||||
|
||||
|
@ -739,9 +736,10 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
|
|||
put_bcc(1, &smb->hdr);
|
||||
smb->Data[0] = 'a';
|
||||
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,
|
||||
cifs_echo_callback, server);
|
||||
rc = cifs_call_async(server, &iov, 1, cifs_echo_callback, server, true);
|
||||
if (rc)
|
||||
cFYI(1, "Echo request failed: %d", rc);
|
||||
|
||||
|
@ -751,7 +749,7 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
|
|||
}
|
||||
|
||||
int
|
||||
CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
|
||||
CIFSSMBLogoff(const int xid, struct cifs_ses *ses)
|
||||
{
|
||||
LOGOFF_ANDX_REQ *pSMB;
|
||||
int rc = 0;
|
||||
|
@ -778,7 +776,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
|
|||
|
||||
pSMB->hdr.Mid = GetNextMid(ses->server);
|
||||
|
||||
if (ses->server->secMode &
|
||||
if (ses->server->sec_mode &
|
||||
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
|
||||
pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
|
||||
|
||||
|
@ -798,7 +796,7 @@ session_already_dead:
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
TRANSACTION2_SPI_REQ *pSMB = NULL;
|
||||
|
@ -873,7 +871,7 @@ PsxDelete:
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
DELETE_FILE_REQ *pSMB = NULL;
|
||||
|
@ -918,7 +916,7 @@ DelFileRetry:
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
DELETE_DIRECTORY_REQ *pSMB = NULL;
|
||||
|
@ -961,7 +959,7 @@ RmDirRetry:
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -1004,7 +1002,7 @@ MkDirRetry:
|
|||
}
|
||||
|
||||
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,
|
||||
__u32 *pOplock, const char *name,
|
||||
const struct nls_table *nls_codepage, int remap)
|
||||
|
@ -1170,7 +1168,7 @@ access_flags_to_smbopen_mode(const int access_flags)
|
|||
}
|
||||
|
||||
int
|
||||
SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
|
||||
SMBLegacyOpen(const int xid, struct cifs_tcon *tcon,
|
||||
const char *fileName, const int openDisposition,
|
||||
const int access_flags, const int create_options, __u16 *netfid,
|
||||
int *pOplock, FILE_ALL_INFO *pfile_info,
|
||||
|
@ -1277,7 +1275,7 @@ OldOpenRetry:
|
|||
}
|
||||
|
||||
int
|
||||
CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSSMBOpen(const int xid, struct cifs_tcon *tcon,
|
||||
const char *fileName, const int openDisposition,
|
||||
const int access_flags, const int create_options, __u16 *netfid,
|
||||
int *pOplock, FILE_ALL_INFO *pfile_info,
|
||||
|
@ -1379,8 +1377,7 @@ openRetry:
|
|||
}
|
||||
|
||||
int
|
||||
CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
|
||||
const unsigned int count, const __u64 lseek, unsigned int *nbytes,
|
||||
CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms, unsigned int *nbytes,
|
||||
char **buf, int *pbuf_type)
|
||||
{
|
||||
int rc = -EACCES;
|
||||
|
@ -1390,13 +1387,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
|
|||
int wct;
|
||||
int resp_buf_type = 0;
|
||||
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);
|
||||
if (tcon->ses->capabilities & CAP_LARGE_FILES)
|
||||
wct = 12;
|
||||
else {
|
||||
wct = 10; /* old style read */
|
||||
if ((lseek >> 32) > 0) {
|
||||
if ((offset >> 32) > 0) {
|
||||
/* can not handle this big offset for old */
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -1407,15 +1409,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
|
|||
if (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 */
|
||||
if (tcon->ses->server == NULL)
|
||||
return -ECONNABORTED;
|
||||
|
||||
pSMB->AndXCommand = 0xFF; /* none */
|
||||
pSMB->Fid = netfid;
|
||||
pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF);
|
||||
pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
|
||||
if (wct == 12)
|
||||
pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
|
||||
pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
|
||||
|
||||
pSMB->Remaining = 0;
|
||||
pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
|
||||
|
@ -1484,9 +1489,8 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
|
|||
|
||||
|
||||
int
|
||||
CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
|
||||
const int netfid, const unsigned int count,
|
||||
const __u64 offset, unsigned int *nbytes, const char *buf,
|
||||
CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
|
||||
unsigned int *nbytes, const char *buf,
|
||||
const char __user *ubuf, const int long_op)
|
||||
{
|
||||
int rc = -EACCES;
|
||||
|
@ -1495,6 +1499,11 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
|
|||
int bytes_returned, wct;
|
||||
__u32 bytes_sent;
|
||||
__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;
|
||||
|
||||
|
@ -1516,6 +1525,10 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
|
|||
(void **) &pSMBr);
|
||||
if (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 */
|
||||
if (tcon->ses->server == NULL)
|
||||
return -ECONNABORTED;
|
||||
|
@ -1602,17 +1615,259 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
|
|||
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
|
||||
CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
|
||||
const int netfid, const unsigned int count,
|
||||
const __u64 offset, unsigned int *nbytes, struct kvec *iov,
|
||||
int n_vec, const int long_op)
|
||||
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
|
||||
CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
|
||||
unsigned int *nbytes, struct kvec *iov, int n_vec,
|
||||
const int long_op)
|
||||
{
|
||||
int rc = -EACCES;
|
||||
WRITE_REQ *pSMB = NULL;
|
||||
int wct;
|
||||
int smb_hdr_len;
|
||||
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;
|
||||
|
||||
|
@ -1630,6 +1885,10 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
|
|||
rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
|
||||
if (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 */
|
||||
if (tcon->ses->server == NULL)
|
||||
return -ECONNABORTED;
|
||||
|
@ -1705,7 +1964,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
|
|||
|
||||
|
||||
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 __u64 offset, const __u32 numUnlock,
|
||||
const __u32 numLock, const __u8 lockType,
|
||||
|
@ -1775,7 +2034,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
|
|||
}
|
||||
|
||||
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,
|
||||
struct file_lock *pLockData, const __u16 lock_type,
|
||||
const bool waitFlag)
|
||||
|
@ -1913,7 +2172,7 @@ plk_err_exit:
|
|||
|
||||
|
||||
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;
|
||||
CLOSE_REQ *pSMB = NULL;
|
||||
|
@ -1946,7 +2205,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
|
|||
}
|
||||
|
||||
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;
|
||||
FLUSH_REQ *pSMB = NULL;
|
||||
|
@ -1967,7 +2226,7 @@ CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
|
|||
}
|
||||
|
||||
int
|
||||
CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSSMBRename(const int xid, struct cifs_tcon *tcon,
|
||||
const char *fromName, const char *toName,
|
||||
const struct nls_table *nls_codepage, int remap)
|
||||
{
|
||||
|
@ -2034,7 +2293,7 @@ renameRetry:
|
|||
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,
|
||||
const struct nls_table *nls_codepage, int remap)
|
||||
{
|
||||
|
@ -2114,7 +2373,7 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
|
|||
}
|
||||
|
||||
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 struct nls_table *nls_codepage, int remap)
|
||||
{
|
||||
|
@ -2182,7 +2441,7 @@ copyRetry:
|
|||
}
|
||||
|
||||
int
|
||||
CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSUnixCreateSymLink(const int xid, struct cifs_tcon *tcon,
|
||||
const char *fromName, const char *toName,
|
||||
const struct nls_table *nls_codepage)
|
||||
{
|
||||
|
@ -2271,7 +2530,7 @@ createSymLinkRetry:
|
|||
}
|
||||
|
||||
int
|
||||
CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSUnixCreateHardLink(const int xid, struct cifs_tcon *tcon,
|
||||
const char *fromName, const char *toName,
|
||||
const struct nls_table *nls_codepage, int remap)
|
||||
{
|
||||
|
@ -2356,7 +2615,7 @@ createHardLinkRetry:
|
|||
}
|
||||
|
||||
int
|
||||
CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSCreateHardLink(const int xid, struct cifs_tcon *tcon,
|
||||
const char *fromName, const char *toName,
|
||||
const struct nls_table *nls_codepage, int remap)
|
||||
{
|
||||
|
@ -2428,7 +2687,7 @@ winCreateHardLinkRetry:
|
|||
}
|
||||
|
||||
int
|
||||
CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSSMBUnixQuerySymLink(const int xid, struct cifs_tcon *tcon,
|
||||
const unsigned char *searchName, char **symlinkinfo,
|
||||
const struct nls_table *nls_codepage)
|
||||
{
|
||||
|
@ -2533,7 +2792,7 @@ querySymLinkRetry:
|
|||
* it is not compiled in by default until callers fixed up and more tested.
|
||||
*/
|
||||
int
|
||||
CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSSMBQueryReparseLinkInfo(const int xid, struct cifs_tcon *tcon,
|
||||
const unsigned char *searchName,
|
||||
char *symlinkinfo, const int buflen, __u16 fid,
|
||||
const struct nls_table *nls_codepage)
|
||||
|
@ -2771,7 +3030,7 @@ static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
|
|||
}
|
||||
|
||||
int
|
||||
CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSSMBGetPosixACL(const int xid, struct cifs_tcon *tcon,
|
||||
const unsigned char *searchName,
|
||||
char *acl_inf, const int buflen, const int acl_type,
|
||||
const struct nls_table *nls_codepage, int remap)
|
||||
|
@ -2859,7 +3118,7 @@ queryAclRetry:
|
|||
}
|
||||
|
||||
int
|
||||
CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSSMBSetPosixACL(const int xid, struct cifs_tcon *tcon,
|
||||
const unsigned char *fileName,
|
||||
const char *local_acl, const int buflen,
|
||||
const int acl_type,
|
||||
|
@ -2939,7 +3198,7 @@ setACLerrorExit:
|
|||
|
||||
/* BB fix tabs in this function FIXME BB */
|
||||
int
|
||||
CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSGetExtAttr(const int xid, struct cifs_tcon *tcon,
|
||||
const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -3032,7 +3291,7 @@ GetExtAttrOut:
|
|||
*/
|
||||
static int
|
||||
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)
|
||||
{
|
||||
int rc;
|
||||
|
@ -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 */
|
||||
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)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -3207,7 +3466,7 @@ qsec_out:
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
__u16 byte_count, param_count, data_count, param_offset, data_offset;
|
||||
|
@ -3273,7 +3532,7 @@ setCifsAclRetry:
|
|||
|
||||
/* Legacy Query Path Information call for lookup to old servers such
|
||||
as Win9x/WinME */
|
||||
int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
|
||||
int SMBQueryInformation(const int xid, struct cifs_tcon *tcon,
|
||||
const unsigned char *searchName,
|
||||
FILE_ALL_INFO *pFinfo,
|
||||
const struct nls_table *nls_codepage, int remap)
|
||||
|
@ -3341,7 +3600,7 @@ QInfRetry:
|
|||
}
|
||||
|
||||
int
|
||||
CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSSMBQFileInfo(const int xid, struct cifs_tcon *tcon,
|
||||
u16 netfid, FILE_ALL_INFO *pFindData)
|
||||
{
|
||||
struct smb_t2_qfi_req *pSMB = NULL;
|
||||
|
@ -3408,7 +3667,7 @@ QFileInfoRetry:
|
|||
}
|
||||
|
||||
int
|
||||
CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSSMBQPathInfo(const int xid, struct cifs_tcon *tcon,
|
||||
const unsigned char *searchName,
|
||||
FILE_ALL_INFO *pFindData,
|
||||
int legacy /* old style infolevel */,
|
||||
|
@ -3509,7 +3768,7 @@ QPathInfoRetry:
|
|||
}
|
||||
|
||||
int
|
||||
CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSSMBUnixQFileInfo(const int xid, struct cifs_tcon *tcon,
|
||||
u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
|
||||
{
|
||||
struct smb_t2_qfi_req *pSMB = NULL;
|
||||
|
@ -3578,7 +3837,7 @@ UnixQFileInfoRetry:
|
|||
}
|
||||
|
||||
int
|
||||
CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSSMBUnixQPathInfo(const int xid, struct cifs_tcon *tcon,
|
||||
const unsigned char *searchName,
|
||||
FILE_UNIX_BASIC_INFO *pFindData,
|
||||
const struct nls_table *nls_codepage, int remap)
|
||||
|
@ -3664,7 +3923,7 @@ UnixQPathInfoRetry:
|
|||
|
||||
/* xid, tcon, searchName and codepage are input parms, rest are returned */
|
||||
int
|
||||
CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
|
||||
const char *searchName,
|
||||
const struct nls_table *nls_codepage,
|
||||
__u16 *pnetfid,
|
||||
|
@ -3812,7 +4071,7 @@ findFirstRetry:
|
|||
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)
|
||||
{
|
||||
TRANSACTION2_FNEXT_REQ *pSMB = NULL;
|
||||
|
@ -3950,7 +4209,7 @@ FNext2_err_exit:
|
|||
}
|
||||
|
||||
int
|
||||
CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSFindClose(const int xid, struct cifs_tcon *tcon,
|
||||
const __u16 searchHandle)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -3982,7 +4241,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
|
|||
}
|
||||
|
||||
int
|
||||
CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
|
||||
const unsigned char *searchName,
|
||||
__u64 *inode_number,
|
||||
const struct nls_table *nls_codepage, int remap)
|
||||
|
@ -4184,7 +4443,7 @@ parse_DFS_referrals_exit:
|
|||
}
|
||||
|
||||
int
|
||||
CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
|
||||
CIFSGetDFSRefer(const int xid, struct cifs_ses *ses,
|
||||
const unsigned char *searchName,
|
||||
struct dfs_info3_param **target_nodes,
|
||||
unsigned int *num_of_nodes,
|
||||
|
@ -4233,7 +4492,7 @@ getDFSRetry:
|
|||
}
|
||||
|
||||
if (ses->server) {
|
||||
if (ses->server->secMode &
|
||||
if (ses->server->sec_mode &
|
||||
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
|
||||
pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
|
||||
}
|
||||
|
@ -4298,7 +4557,7 @@ GetDFSRefExit:
|
|||
|
||||
/* Query File System Info such as free space to old servers such as Win 9x */
|
||||
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 */
|
||||
TRANSACTION2_QFSI_REQ *pSMB = NULL;
|
||||
|
@ -4377,7 +4636,7 @@ oldQFSInfoRetry:
|
|||
}
|
||||
|
||||
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 */
|
||||
TRANSACTION2_QFSI_REQ *pSMB = NULL;
|
||||
|
@ -4456,7 +4715,7 @@ QFSInfoRetry:
|
|||
}
|
||||
|
||||
int
|
||||
CIFSSMBQFSAttributeInfo(const int xid, struct cifsTconInfo *tcon)
|
||||
CIFSSMBQFSAttributeInfo(const int xid, struct cifs_tcon *tcon)
|
||||
{
|
||||
/* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
|
||||
TRANSACTION2_QFSI_REQ *pSMB = NULL;
|
||||
|
@ -4526,7 +4785,7 @@ QFSAttributeRetry:
|
|||
}
|
||||
|
||||
int
|
||||
CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon)
|
||||
CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon)
|
||||
{
|
||||
/* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
|
||||
TRANSACTION2_QFSI_REQ *pSMB = NULL;
|
||||
|
@ -4597,7 +4856,7 @@ QFSDeviceRetry:
|
|||
}
|
||||
|
||||
int
|
||||
CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon)
|
||||
CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon)
|
||||
{
|
||||
/* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
|
||||
TRANSACTION2_QFSI_REQ *pSMB = NULL;
|
||||
|
@ -4667,7 +4926,7 @@ QFSUnixRetry:
|
|||
}
|
||||
|
||||
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 */
|
||||
TRANSACTION2_SETFSI_REQ *pSMB = NULL;
|
||||
|
@ -4741,7 +5000,7 @@ SETFSUnixRetry:
|
|||
|
||||
|
||||
int
|
||||
CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
|
||||
struct kstatfs *FSData)
|
||||
{
|
||||
/* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
|
||||
|
@ -4834,7 +5093,7 @@ QFSPosixRetry:
|
|||
in Samba which this routine can run into */
|
||||
|
||||
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,
|
||||
const struct nls_table *nls_codepage, int remap)
|
||||
{
|
||||
|
@ -4923,7 +5182,7 @@ SetEOFRetry:
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct smb_com_transaction2_sfi_req *pSMB = NULL;
|
||||
|
@ -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
|
||||
DOS time format with 2 second granularity */
|
||||
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)
|
||||
{
|
||||
struct smb_com_transaction2_sfi_req *pSMB = NULL;
|
||||
|
@ -5067,7 +5326,7 @@ CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct smb_com_transaction2_sfi_req *pSMB = NULL;
|
||||
|
@ -5123,7 +5382,7 @@ CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
|
|||
}
|
||||
|
||||
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 struct nls_table *nls_codepage, int remap)
|
||||
{
|
||||
|
@ -5207,7 +5466,7 @@ SetTimesRetry:
|
|||
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 */
|
||||
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)
|
||||
{
|
||||
SETATTR_REQ *pSMB = NULL;
|
||||
|
@ -5295,7 +5554,7 @@ cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
|
|||
}
|
||||
|
||||
int
|
||||
CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
|
||||
const struct cifs_unix_set_info_args *args,
|
||||
u16 fid, u32 pid_of_opener)
|
||||
{
|
||||
|
@ -5358,7 +5617,7 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
|
|||
}
|
||||
|
||||
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 nls_table *nls_codepage, int remap)
|
||||
{
|
||||
|
@ -5445,7 +5704,7 @@ setPermsRetry:
|
|||
* the data isn't copied to it, but the length is returned.
|
||||
*/
|
||||
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,
|
||||
char *EAData, size_t buf_size,
|
||||
const struct nls_table *nls_codepage, int remap)
|
||||
|
@ -5626,7 +5885,7 @@ QAllEAsOut:
|
|||
}
|
||||
|
||||
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 __u16 ea_value_len, const struct nls_table *nls_codepage,
|
||||
int remap)
|
||||
|
@ -5753,7 +6012,7 @@ SetEARetry:
|
|||
* incompatible for network fs clients, we could instead simply
|
||||
* 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,
|
||||
__u32 filter, struct file *pfile, int multishot,
|
||||
const struct nls_table *nls_codepage)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -50,12 +50,11 @@ build_path_from_dentry(struct dentry *direntry)
|
|||
{
|
||||
struct dentry *temp;
|
||||
int namelen;
|
||||
int pplen;
|
||||
int dfsplen;
|
||||
char *full_path;
|
||||
char dirsep;
|
||||
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)
|
||||
return NULL; /* not much we can do if dentry is freed and
|
||||
|
@ -63,13 +62,12 @@ build_path_from_dentry(struct dentry *direntry)
|
|||
when the server crashed */
|
||||
|
||||
dirsep = CIFS_DIR_SEP(cifs_sb);
|
||||
pplen = cifs_sb->prepathlen;
|
||||
if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
|
||||
dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
|
||||
else
|
||||
dfsplen = 0;
|
||||
cifs_bp_rename_retry:
|
||||
namelen = pplen + dfsplen;
|
||||
namelen = dfsplen;
|
||||
for (temp = direntry; !IS_ROOT(temp);) {
|
||||
namelen += (1 + temp->d_name.len);
|
||||
temp = temp->d_parent;
|
||||
|
@ -100,7 +98,7 @@ cifs_bp_rename_retry:
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
if (namelen != pplen + dfsplen) {
|
||||
if (namelen != dfsplen) {
|
||||
cERROR(1, "did not end path lookup where expected namelen is %d",
|
||||
namelen);
|
||||
/* presumably this is only possible if racing with a rename
|
||||
|
@ -126,7 +124,6 @@ cifs_bp_rename_retry:
|
|||
}
|
||||
}
|
||||
}
|
||||
strncpy(full_path + dfsplen, CIFS_SB(direntry->d_sb)->prepath, pplen);
|
||||
return full_path;
|
||||
}
|
||||
|
||||
|
@ -152,7 +149,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
|||
__u16 fileHandle;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct tcon_link *tlink;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_tcon *tcon;
|
||||
char *full_path = NULL;
|
||||
FILE_ALL_INFO *buf = NULL;
|
||||
struct inode *newinode = NULL;
|
||||
|
@ -356,7 +353,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
|
|||
int xid;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct tcon_link *tlink;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
struct cifs_io_parms io_parms;
|
||||
char *full_path = NULL;
|
||||
struct inode *newinode = NULL;
|
||||
int oplock = 0;
|
||||
|
@ -439,16 +437,19 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
|
|||
* timestamps in, but we can reuse it safely */
|
||||
|
||||
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)) {
|
||||
memcpy(pdev->type, "IntxCHR", 8);
|
||||
pdev->major =
|
||||
cpu_to_le64(MAJOR(device_number));
|
||||
pdev->minor =
|
||||
cpu_to_le64(MINOR(device_number));
|
||||
rc = CIFSSMBWrite(xid, pTcon,
|
||||
fileHandle,
|
||||
sizeof(struct win_dev),
|
||||
0, &bytes_written, (char *)pdev,
|
||||
rc = CIFSSMBWrite(xid, &io_parms,
|
||||
&bytes_written, (char *)pdev,
|
||||
NULL, 0);
|
||||
} else if (S_ISBLK(mode)) {
|
||||
memcpy(pdev->type, "IntxBLK", 8);
|
||||
|
@ -456,10 +457,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
|
|||
cpu_to_le64(MAJOR(device_number));
|
||||
pdev->minor =
|
||||
cpu_to_le64(MINOR(device_number));
|
||||
rc = CIFSSMBWrite(xid, pTcon,
|
||||
fileHandle,
|
||||
sizeof(struct win_dev),
|
||||
0, &bytes_written, (char *)pdev,
|
||||
rc = CIFSSMBWrite(xid, &io_parms,
|
||||
&bytes_written, (char *)pdev,
|
||||
NULL, 0);
|
||||
} /* else if (S_ISFIFO) */
|
||||
CIFSSMBClose(xid, pTcon, fileHandle);
|
||||
|
@ -486,7 +485,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
|
|||
bool posix_open = false;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct tcon_link *tlink;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
struct cifsFileInfo *cfile;
|
||||
struct inode *newInode = NULL;
|
||||
char *full_path = NULL;
|
||||
|
|
376
fs/cifs/file.c
376
fs/cifs/file.c
|
@ -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_fattr fattr;
|
||||
struct tcon_link *tlink;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_tcon *tcon;
|
||||
|
||||
cFYI(1, "posix open %s", full_path);
|
||||
|
||||
|
@ -168,7 +168,7 @@ posix_open_ret:
|
|||
|
||||
static int
|
||||
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)
|
||||
{
|
||||
int rc;
|
||||
|
@ -285,7 +285,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
|
|||
void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
|
||||
{
|
||||
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 cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifsLockInfo *li, *tmp;
|
||||
|
@ -343,7 +343,7 @@ int cifs_open(struct inode *inode, struct file *file)
|
|||
int xid;
|
||||
__u32 oplock;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_tcon *tcon;
|
||||
struct tcon_link *tlink;
|
||||
struct cifsFileInfo *pCifsFile = NULL;
|
||||
char *full_path = NULL;
|
||||
|
@ -457,7 +457,7 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
|
|||
int xid;
|
||||
__u32 oplock;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_tcon *tcon;
|
||||
struct cifsInodeInfo *pCifsInode;
|
||||
struct inode *inode;
|
||||
char *full_path = NULL;
|
||||
|
@ -596,7 +596,7 @@ int cifs_closedir(struct inode *inode, struct file *file)
|
|||
xid = GetXid();
|
||||
|
||||
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");
|
||||
spin_lock(&cifs_file_list_lock);
|
||||
|
@ -653,7 +653,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
|
|||
__u64 length;
|
||||
bool wait_flag = false;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_tcon *tcon;
|
||||
__u16 netfid;
|
||||
__u8 lockType = LOCKING_ANDX_LARGE_FILES;
|
||||
bool posix_locking = 0;
|
||||
|
@ -725,8 +725,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
|
|||
else
|
||||
posix_lock_type = CIFS_WRLCK;
|
||||
rc = CIFSSMBPosixLock(xid, tcon, netfid, 1 /* get */,
|
||||
length, pfLock,
|
||||
posix_lock_type, wait_flag);
|
||||
length, pfLock, posix_lock_type,
|
||||
wait_flag);
|
||||
FreeXid(xid);
|
||||
return rc;
|
||||
}
|
||||
|
@ -797,8 +797,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
|
|||
posix_lock_type = CIFS_UNLCK;
|
||||
|
||||
rc = CIFSSMBPosixLock(xid, tcon, netfid, 0 /* set */,
|
||||
length, pfLock,
|
||||
posix_lock_type, wait_flag);
|
||||
length, pfLock, posix_lock_type,
|
||||
wait_flag);
|
||||
} else {
|
||||
struct cifsFileInfo *fid = file->private_data;
|
||||
|
||||
|
@ -857,7 +857,7 @@ cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
|
|||
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,
|
||||
loff_t *poffset)
|
||||
{
|
||||
|
@ -865,10 +865,11 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
|
|||
unsigned int bytes_written = 0;
|
||||
unsigned int total_written;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
int xid;
|
||||
struct dentry *dentry = open_file->dentry;
|
||||
struct cifsInodeInfo *cifsi = CIFS_I(dentry->d_inode);
|
||||
struct cifs_io_parms io_parms;
|
||||
|
||||
cifs_sb = CIFS_SB(dentry->d_sb);
|
||||
|
||||
|
@ -901,8 +902,13 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
|
|||
/* iov[0] is reserved for smb header */
|
||||
iov[1].iov_base = (char *)write_data + total_written;
|
||||
iov[1].iov_len = len;
|
||||
rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid, len,
|
||||
*poffset, &bytes_written, iov, 1, 0);
|
||||
io_parms.netfid = open_file->netfid;
|
||||
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 (total_written)
|
||||
|
@ -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);
|
||||
if (open_file) {
|
||||
bytes_written = cifs_write(open_file, write_data,
|
||||
to - from, &offset);
|
||||
bytes_written = cifs_write(open_file, open_file->pid,
|
||||
write_data, to - from, &offset);
|
||||
cifsFileInfo_put(open_file);
|
||||
/* Does mm or vfs already set times? */
|
||||
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)
|
|||
static int cifs_writepages(struct address_space *mapping,
|
||||
struct writeback_control *wbc)
|
||||
{
|
||||
unsigned int bytes_to_write;
|
||||
unsigned int bytes_written;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
int done = 0;
|
||||
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 cifs_sb_info *cifs_sb = CIFS_SB(mapping->host->i_sb);
|
||||
bool done = false, scanned = false, range_whole = false;
|
||||
pgoff_t end, index;
|
||||
struct cifs_writedata *wdata;
|
||||
struct page *page;
|
||||
struct pagevec pvec;
|
||||
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
|
||||
*/
|
||||
if (cifs_sb->wsize < PAGE_CACHE_SIZE)
|
||||
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) {
|
||||
index = mapping->writeback_index; /* Start from prev offset */
|
||||
end = -1;
|
||||
|
@ -1151,24 +1119,49 @@ static int cifs_writepages(struct address_space *mapping,
|
|||
index = wbc->range_start >> PAGE_CACHE_SHIFT;
|
||||
end = wbc->range_end >> PAGE_CACHE_SHIFT;
|
||||
if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
|
||||
range_whole = 1;
|
||||
scanned = 1;
|
||||
range_whole = true;
|
||||
scanned = true;
|
||||
}
|
||||
retry:
|
||||
while (!done && (index <= end) &&
|
||||
(nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
|
||||
PAGECACHE_TAG_DIRTY,
|
||||
min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1))) {
|
||||
int first;
|
||||
unsigned int i;
|
||||
while (!done && index <= end) {
|
||||
unsigned int i, nr_pages, found_pages;
|
||||
pgoff_t next = 0, tofind;
|
||||
struct page **pages;
|
||||
|
||||
first = -1;
|
||||
next = 0;
|
||||
n_iov = 0;
|
||||
bytes_to_write = 0;
|
||||
tofind = min((cifs_sb->wsize / PAGE_CACHE_SIZE) - 1,
|
||||
end - index) + 1;
|
||||
|
||||
for (i = 0; i < nr_pages; i++) {
|
||||
page = pvec.pages[i];
|
||||
wdata = cifs_writedata_alloc((unsigned int)tofind);
|
||||
if (!wdata) {
|
||||
rc = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
* lock on the page itself: the page may be truncated or
|
||||
|
@ -1177,7 +1170,7 @@ retry:
|
|||
* mapping
|
||||
*/
|
||||
|
||||
if (first < 0)
|
||||
if (nr_pages == 0)
|
||||
lock_page(page);
|
||||
else if (!trylock_page(page))
|
||||
break;
|
||||
|
@ -1188,7 +1181,7 @@ retry:
|
|||
}
|
||||
|
||||
if (!wbc->range_cyclic && page->index > end) {
|
||||
done = 1;
|
||||
done = true;
|
||||
unlock_page(page);
|
||||
break;
|
||||
}
|
||||
|
@ -1215,119 +1208,89 @@ retry:
|
|||
set_page_writeback(page);
|
||||
|
||||
if (page_offset(page) >= mapping->host->i_size) {
|
||||
done = 1;
|
||||
done = true;
|
||||
unlock_page(page);
|
||||
end_page_writeback(page);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* BB can we get rid of this? pages are held by pvec
|
||||
*/
|
||||
page_cache_get(page);
|
||||
|
||||
len = min(mapping->host->i_size - page_offset(page),
|
||||
(loff_t)PAGE_CACHE_SIZE);
|
||||
|
||||
/* reserve iov[0] for the smb header */
|
||||
n_iov++;
|
||||
iov[n_iov].iov_base = kmap(page);
|
||||
iov[n_iov].iov_len = len;
|
||||
bytes_to_write += len;
|
||||
|
||||
if (first < 0) {
|
||||
first = i;
|
||||
offset = page_offset(page);
|
||||
}
|
||||
wdata->pages[i] = page;
|
||||
next = page->index + 1;
|
||||
if (bytes_to_write + PAGE_CACHE_SIZE > cifs_sb->wsize)
|
||||
break;
|
||||
++nr_pages;
|
||||
}
|
||||
if (n_iov) {
|
||||
retry_write:
|
||||
open_file = find_writable_file(CIFS_I(mapping->host),
|
||||
false);
|
||||
if (!open_file) {
|
||||
|
||||
/* reset index to refind any pages skipped */
|
||||
if (nr_pages == 0)
|
||||
index = wdata->pages[0]->index + 1;
|
||||
|
||||
/* put any pages we aren't going to use */
|
||||
for (i = nr_pages; i < found_pages; i++) {
|
||||
page_cache_release(wdata->pages[i]);
|
||||
wdata->pages[i] = NULL;
|
||||
}
|
||||
|
||||
/* nothing to write? */
|
||||
if (nr_pages == 0) {
|
||||
kref_put(&wdata->refcount, cifs_writedata_release);
|
||||
continue;
|
||||
}
|
||||
|
||||
wdata->sync_mode = wbc->sync_mode;
|
||||
wdata->nr_pages = nr_pages;
|
||||
wdata->offset = page_offset(wdata->pages[0]);
|
||||
|
||||
do {
|
||||
if (wdata->cfile != NULL)
|
||||
cifsFileInfo_put(wdata->cfile);
|
||||
wdata->cfile = find_writable_file(CIFS_I(mapping->host),
|
||||
false);
|
||||
if (!wdata->cfile) {
|
||||
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);
|
||||
break;
|
||||
}
|
||||
rc = cifs_async_writev(wdata);
|
||||
} while (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN);
|
||||
|
||||
cFYI(1, "Write2 rc=%d, wrote=%u", rc, bytes_written);
|
||||
for (i = 0; i < nr_pages; ++i)
|
||||
unlock_page(wdata->pages[i]);
|
||||
|
||||
/*
|
||||
* For now, treat a short write as if nothing got
|
||||
* written. A zero length write however indicates
|
||||
* ENOSPC or EFBIG. We have no way to know which
|
||||
* though, so call it ENOSPC for now. EFBIG would
|
||||
* get translated to AS_EIO anyway.
|
||||
*
|
||||
* FIXME: make it take into account the data that did
|
||||
* get written
|
||||
*/
|
||||
if (rc == 0) {
|
||||
if (bytes_written == 0)
|
||||
rc = -ENOSPC;
|
||||
else if (bytes_written < bytes_to_write)
|
||||
rc = -EAGAIN;
|
||||
}
|
||||
|
||||
/* retry on data-integrity flush */
|
||||
if (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN)
|
||||
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++) {
|
||||
page = pvec.pages[first + i];
|
||||
/* on retryable write error, redirty page */
|
||||
/* send failure -- clean up the mess */
|
||||
if (rc != 0) {
|
||||
for (i = 0; i < nr_pages; ++i) {
|
||||
if (rc == -EAGAIN)
|
||||
redirty_page_for_writepage(wbc, page);
|
||||
else if (rc != 0)
|
||||
SetPageError(page);
|
||||
kunmap(page);
|
||||
unlock_page(page);
|
||||
end_page_writeback(page);
|
||||
page_cache_release(page);
|
||||
redirty_page_for_writepage(wbc,
|
||||
wdata->pages[i]);
|
||||
else
|
||||
SetPageError(wdata->pages[i]);
|
||||
end_page_writeback(wdata->pages[i]);
|
||||
page_cache_release(wdata->pages[i]);
|
||||
}
|
||||
|
||||
if (rc != -EAGAIN)
|
||||
mapping_set_error(mapping, rc);
|
||||
else
|
||||
rc = 0;
|
||||
}
|
||||
kref_put(&wdata->refcount, cifs_writedata_release);
|
||||
|
||||
if ((wbc->nr_to_write -= n_iov) <= 0)
|
||||
done = 1;
|
||||
index = next;
|
||||
} else
|
||||
/* Need to re-find the pages we skipped */
|
||||
index = pvec.pages[0]->index + 1;
|
||||
wbc->nr_to_write -= nr_pages;
|
||||
if (wbc->nr_to_write <= 0)
|
||||
done = true;
|
||||
|
||||
pagevec_release(&pvec);
|
||||
index = next;
|
||||
}
|
||||
|
||||
if (!scanned && !done) {
|
||||
/*
|
||||
* We hit the last page and there is more work to be done: wrap
|
||||
* back to the start of the file
|
||||
*/
|
||||
scanned = 1;
|
||||
scanned = true;
|
||||
index = 0;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
|
||||
mapping->writeback_index = index;
|
||||
|
||||
FreeXid(xid);
|
||||
kfree(iov);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -1383,6 +1346,14 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
|
|||
{
|
||||
int rc;
|
||||
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",
|
||||
page, pos, copied);
|
||||
|
@ -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
|
||||
such as updating last write time */
|
||||
page_data = kmap(page);
|
||||
rc = cifs_write(file->private_data, page_data + offset,
|
||||
copied, &pos);
|
||||
rc = cifs_write(cfile, pid, page_data + offset, copied, &pos);
|
||||
/* if (rc < 0) should we set writebehind rc? */
|
||||
kunmap(page);
|
||||
|
||||
|
@ -1435,7 +1405,7 @@ int cifs_strict_fsync(struct file *file, int datasync)
|
|||
{
|
||||
int xid;
|
||||
int rc = 0;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_tcon *tcon;
|
||||
struct cifsFileInfo *smbfile = file->private_data;
|
||||
struct inode *inode = file->f_path.dentry->d_inode;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
|
@ -1465,7 +1435,7 @@ int cifs_fsync(struct file *file, int datasync)
|
|||
{
|
||||
int xid;
|
||||
int rc = 0;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_tcon *tcon;
|
||||
struct cifsFileInfo *smbfile = file->private_data;
|
||||
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,
|
|||
struct iov_iter it;
|
||||
struct inode *inode;
|
||||
struct cifsFileInfo *open_file;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct cifs_io_parms io_parms;
|
||||
int xid, rc;
|
||||
__u32 pid;
|
||||
|
||||
len = iov_length(iov, nr_segs);
|
||||
if (!len)
|
||||
|
@ -1590,6 +1562,12 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
|
|||
|
||||
xid = GetXid();
|
||||
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);
|
||||
inode = file->f_path.dentry->d_inode;
|
||||
|
||||
|
@ -1616,9 +1594,13 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
|
|||
if (rc != 0)
|
||||
break;
|
||||
}
|
||||
rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid,
|
||||
cur_len, *poffset, &written,
|
||||
to_send, npages, 0);
|
||||
io_parms.netfid = open_file->netfid;
|
||||
io_parms.pid = pid;
|
||||
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);
|
||||
|
||||
for (i = 0; i < npages; i++)
|
||||
|
@ -1711,10 +1693,12 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
|
|||
size_t len, cur_len;
|
||||
int iov_offset = 0;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
struct cifsFileInfo *open_file;
|
||||
struct smb_com_read_rsp *pSMBr;
|
||||
struct cifs_io_parms io_parms;
|
||||
char *read_data;
|
||||
__u32 pid;
|
||||
|
||||
if (!nr_segs)
|
||||
return 0;
|
||||
|
@ -1729,6 +1713,11 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
|
|||
open_file = file->private_data;
|
||||
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)
|
||||
cFYI(1, "attempting read on write only file instance");
|
||||
|
||||
|
@ -1744,8 +1733,12 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
|
|||
if (rc != 0)
|
||||
break;
|
||||
}
|
||||
rc = CIFSSMBRead(xid, pTcon, open_file->netfid,
|
||||
cur_len, *poffset, &bytes_read,
|
||||
io_parms.netfid = open_file->netfid;
|
||||
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);
|
||||
pSMBr = (struct smb_com_read_rsp *)read_data;
|
||||
if (read_data) {
|
||||
|
@ -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 current_read_size;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
int xid;
|
||||
char *current_offset;
|
||||
struct cifsFileInfo *open_file;
|
||||
struct cifs_io_parms io_parms;
|
||||
int buf_type = CIFS_NO_BUFFER;
|
||||
__u32 pid;
|
||||
|
||||
xid = GetXid();
|
||||
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,
|
|||
open_file = file->private_data;
|
||||
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)
|
||||
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,
|
|||
if (rc != 0)
|
||||
break;
|
||||
}
|
||||
rc = CIFSSMBRead(xid, pTcon,
|
||||
open_file->netfid,
|
||||
current_read_size, *poffset,
|
||||
&bytes_read, ¤t_offset,
|
||||
&buf_type);
|
||||
io_parms.netfid = open_file->netfid;
|
||||
io_parms.pid = pid;
|
||||
io_parms.tcon = pTcon;
|
||||
io_parms.offset = *poffset;
|
||||
io_parms.length = current_read_size;
|
||||
rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
|
||||
¤t_offset, &buf_type);
|
||||
}
|
||||
if (rc || (bytes_read == 0)) {
|
||||
if (total_read) {
|
||||
|
@ -1996,13 +1998,15 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
|
|||
loff_t offset;
|
||||
struct page *page;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
unsigned int bytes_read = 0;
|
||||
unsigned int read_size, i;
|
||||
char *smb_read_data = NULL;
|
||||
struct smb_com_read_rsp *pSMBr;
|
||||
struct cifsFileInfo *open_file;
|
||||
struct cifs_io_parms io_parms;
|
||||
int buf_type = CIFS_NO_BUFFER;
|
||||
__u32 pid;
|
||||
|
||||
xid = GetXid();
|
||||
if (file->private_data == NULL) {
|
||||
|
@ -2024,6 +2028,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
|
|||
goto read_complete;
|
||||
|
||||
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; ) {
|
||||
unsigned contig_pages;
|
||||
struct page *tmp_page;
|
||||
|
@ -2065,12 +2074,13 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
|
|||
if (rc != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
rc = CIFSSMBRead(xid, pTcon,
|
||||
open_file->netfid,
|
||||
read_size, offset,
|
||||
&bytes_read, &smb_read_data,
|
||||
&buf_type);
|
||||
io_parms.netfid = open_file->netfid;
|
||||
io_parms.pid = pid;
|
||||
io_parms.tcon = pTcon;
|
||||
io_parms.offset = offset;
|
||||
io_parms.length = read_size;
|
||||
rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
|
||||
&smb_read_data, &buf_type);
|
||||
/* BB more RC checks ? */
|
||||
if (rc == -EAGAIN) {
|
||||
if (smb_read_data) {
|
||||
|
|
|
@ -40,7 +40,7 @@ void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server)
|
|||
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;
|
||||
|
||||
|
@ -51,7 +51,7 @@ void cifs_fscache_get_super_cookie(struct cifsTconInfo *tcon)
|
|||
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);
|
||||
fscache_relinquish_cookie(tcon->fscache, 0);
|
||||
|
@ -62,7 +62,7 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode)
|
|||
{
|
||||
struct cifsInodeInfo *cifsi = CIFS_I(inode);
|
||||
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)
|
||||
return;
|
||||
|
|
|
@ -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_release_client_cookie(struct TCP_Server_Info *);
|
||||
extern void cifs_fscache_get_super_cookie(struct cifsTconInfo *);
|
||||
extern void cifs_fscache_release_super_cookie(struct cifsTconInfo *);
|
||||
extern void cifs_fscache_get_super_cookie(struct cifs_tcon *);
|
||||
extern void cifs_fscache_release_super_cookie(struct cifs_tcon *);
|
||||
|
||||
extern void cifs_fscache_release_inode_cookie(struct inode *);
|
||||
extern void cifs_fscache_set_inode_cookie(struct inode *, struct file *);
|
||||
|
@ -99,9 +99,9 @@ static inline void
|
|||
cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) {}
|
||||
static inline void
|
||||
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
|
||||
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_set_inode_cookie(struct inode *inode,
|
||||
|
|
|
@ -295,7 +295,7 @@ int cifs_get_file_info_unix(struct file *filp)
|
|||
struct inode *inode = filp->f_path.dentry->d_inode;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifsFileInfo *cfile = filp->private_data;
|
||||
struct cifsTconInfo *tcon = tlink_tcon(cfile->tlink);
|
||||
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
|
||||
|
||||
xid = GetXid();
|
||||
rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data);
|
||||
|
@ -318,7 +318,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
|
|||
int rc;
|
||||
FILE_UNIX_BASIC_INFO find_data;
|
||||
struct cifs_fattr fattr;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_tcon *tcon;
|
||||
struct tcon_link *tlink;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
|
||||
|
||||
|
@ -373,7 +373,8 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
|
|||
int oplock = 0;
|
||||
__u16 netfid;
|
||||
struct tcon_link *tlink;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_tcon *tcon;
|
||||
struct cifs_io_parms io_parms;
|
||||
char buf[24];
|
||||
unsigned int bytes_read;
|
||||
char *pbuf;
|
||||
|
@ -405,9 +406,13 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
|
|||
if (rc == 0) {
|
||||
int buf_type = CIFS_NO_BUFFER;
|
||||
/* Read header */
|
||||
rc = CIFSSMBRead(xid, tcon, netfid,
|
||||
24 /* length */, 0 /* offset */,
|
||||
&bytes_read, &pbuf, &buf_type);
|
||||
io_parms.netfid = netfid;
|
||||
io_parms.pid = current->tgid;
|
||||
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 (memcmp("IntxBLK", pbuf, 8) == 0) {
|
||||
cFYI(1, "Block device");
|
||||
|
@ -468,7 +473,7 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
|
|||
char ea_value[4];
|
||||
__u32 mode;
|
||||
struct tcon_link *tlink;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_tcon *tcon;
|
||||
|
||||
tlink = cifs_sb_tlink(cifs_sb);
|
||||
if (IS_ERR(tlink))
|
||||
|
@ -502,7 +507,7 @@ static void
|
|||
cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
|
||||
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));
|
||||
fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);
|
||||
|
@ -553,7 +558,7 @@ int cifs_get_file_info(struct file *filp)
|
|||
struct inode *inode = filp->f_path.dentry->d_inode;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifsFileInfo *cfile = filp->private_data;
|
||||
struct cifsTconInfo *tcon = tlink_tcon(cfile->tlink);
|
||||
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
|
||||
|
||||
xid = GetXid();
|
||||
rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data);
|
||||
|
@ -590,7 +595,7 @@ int cifs_get_inode_info(struct inode **pinode,
|
|||
struct super_block *sb, int xid, const __u16 *pfid)
|
||||
{
|
||||
int rc = 0, tmprc;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
struct tcon_link *tlink;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
|
||||
char *buf = NULL;
|
||||
|
@ -735,10 +740,10 @@ static const struct inode_operations cifs_ipc_inode_ops = {
|
|||
.lookup = cifs_lookup,
|
||||
};
|
||||
|
||||
char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
|
||||
struct cifsTconInfo *tcon)
|
||||
char *cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
|
||||
struct cifs_tcon *tcon)
|
||||
{
|
||||
int pplen = cifs_sb->prepathlen;
|
||||
int pplen = vol->prepath ? strlen(vol->prepath) : 0;
|
||||
int dfsplen;
|
||||
char *full_path = NULL;
|
||||
|
||||
|
@ -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 */
|
||||
return full_path;
|
||||
}
|
||||
|
@ -884,19 +889,13 @@ struct inode *cifs_root_iget(struct super_block *sb)
|
|||
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
|
||||
struct inode *inode = NULL;
|
||||
long rc;
|
||||
char *full_path;
|
||||
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);
|
||||
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
|
||||
|
||||
xid = GetXid();
|
||||
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
|
||||
rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
|
||||
xid, NULL);
|
||||
rc = cifs_get_inode_info(&inode, "", NULL, sb, xid, NULL);
|
||||
|
||||
if (!inode) {
|
||||
inode = ERR_PTR(rc);
|
||||
|
@ -922,7 +921,6 @@ struct inode *cifs_root_iget(struct super_block *sb)
|
|||
}
|
||||
|
||||
out:
|
||||
kfree(full_path);
|
||||
/* can not call macro FreeXid here since in a void func
|
||||
* TODO: This is no longer true
|
||||
*/
|
||||
|
@ -943,7 +941,7 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
|
|||
struct cifsInodeInfo *cifsInode = CIFS_I(inode);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct tcon_link *tlink = NULL;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
FILE_BASIC_INFO info_buf;
|
||||
|
||||
if (attrs == NULL)
|
||||
|
@ -1061,7 +1059,7 @@ cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
|
|||
struct cifsInodeInfo *cifsInode = CIFS_I(inode);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct tcon_link *tlink;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_tcon *tcon;
|
||||
__u32 dosattr, origattr;
|
||||
FILE_BASIC_INFO *info_buf = NULL;
|
||||
|
||||
|
@ -1179,7 +1177,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
|
|||
struct super_block *sb = dir->i_sb;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
|
||||
struct tcon_link *tlink;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_tcon *tcon;
|
||||
struct iattr *attrs = NULL;
|
||||
__u32 dosattr = 0, origattr = 0;
|
||||
|
||||
|
@ -1277,7 +1275,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
|
|||
int xid;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct tcon_link *tlink;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
char *full_path = NULL;
|
||||
struct inode *newinode = NULL;
|
||||
struct cifs_fattr fattr;
|
||||
|
@ -1455,7 +1453,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
|
|||
int xid;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct tcon_link *tlink;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
char *full_path = NULL;
|
||||
struct cifsInodeInfo *cifsInode;
|
||||
|
||||
|
@ -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 tcon_link *tlink;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
__u16 srcfid;
|
||||
int oplock, rc;
|
||||
|
||||
|
@ -1564,7 +1562,7 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
|
|||
char *toName = NULL;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
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_target;
|
||||
int xid, rc, tmprc;
|
||||
|
@ -1794,7 +1792,7 @@ int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
|||
struct kstat *stat)
|
||||
{
|
||||
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;
|
||||
int rc;
|
||||
|
||||
|
@ -1872,7 +1870,8 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
|
|||
struct cifsInodeInfo *cifsInode = CIFS_I(inode);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
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
|
||||
|
@ -1894,8 +1893,14 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
|
|||
cFYI(1, "SetFSize for attrs rc = %d", rc);
|
||||
if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
|
||||
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);
|
||||
}
|
||||
} else
|
||||
|
@ -1930,10 +1935,15 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
|
|||
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||
if (rc == 0) {
|
||||
unsigned int bytes_written;
|
||||
rc = CIFSSMBWrite(xid, pTcon, netfid, 0,
|
||||
attrs->ia_size,
|
||||
&bytes_written, NULL,
|
||||
NULL, 1);
|
||||
|
||||
io_parms.netfid = netfid;
|
||||
io_parms.pid = current->tgid;
|
||||
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);
|
||||
CIFSSMBClose(xid, pTcon, netfid);
|
||||
}
|
||||
|
@ -1961,7 +1971,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
|
|||
struct cifsInodeInfo *cifsInode = CIFS_I(inode);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct tcon_link *tlink;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
struct cifs_unix_set_info_args *args = NULL;
|
||||
struct cifsFileInfo *open_file;
|
||||
|
||||
|
@ -2247,7 +2257,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
|
|||
{
|
||||
struct inode *inode = direntry->d_inode;
|
||||
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)
|
||||
return cifs_setattr_unix(direntry, attrs);
|
||||
|
|
|
@ -38,7 +38,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
|
|||
struct cifs_sb_info *cifs_sb;
|
||||
#ifdef CONFIG_CIFS_POSIX
|
||||
struct cifsFileInfo *pSMBFile = filep->private_data;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_tcon *tcon;
|
||||
__u64 ExtAttrBits = 0;
|
||||
__u64 ExtAttrMask = 0;
|
||||
__u64 caps;
|
||||
|
|
|
@ -175,7 +175,7 @@ CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
|
|||
}
|
||||
|
||||
static int
|
||||
CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
|
||||
const char *fromName, const char *toName,
|
||||
const struct nls_table *nls_codepage, int remap)
|
||||
{
|
||||
|
@ -184,6 +184,7 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
|
|||
__u16 netfid = 0;
|
||||
u8 *buf;
|
||||
unsigned int bytes_written = 0;
|
||||
struct cifs_io_parms io_parms;
|
||||
|
||||
buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
|
||||
if (!buf)
|
||||
|
@ -203,10 +204,13 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
|
|||
return rc;
|
||||
}
|
||||
|
||||
rc = CIFSSMBWrite(xid, tcon, netfid,
|
||||
CIFS_MF_SYMLINK_FILE_SIZE /* length */,
|
||||
0 /* offset */,
|
||||
&bytes_written, buf, NULL, 0);
|
||||
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 = CIFSSMBWrite(xid, &io_parms, &bytes_written, buf, NULL, 0);
|
||||
CIFSSMBClose(xid, tcon, netfid);
|
||||
kfree(buf);
|
||||
if (rc != 0)
|
||||
|
@ -219,7 +223,7 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
|
|||
}
|
||||
|
||||
static int
|
||||
CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
|
||||
CIFSQueryMFSymLink(const int xid, struct cifs_tcon *tcon,
|
||||
const unsigned char *searchName, char **symlinkinfo,
|
||||
const struct nls_table *nls_codepage, int remap)
|
||||
{
|
||||
|
@ -231,6 +235,7 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
|
|||
unsigned int bytes_read = 0;
|
||||
int buf_type = CIFS_NO_BUFFER;
|
||||
unsigned int link_len = 0;
|
||||
struct cifs_io_parms io_parms;
|
||||
FILE_ALL_INFO file_info;
|
||||
|
||||
rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ,
|
||||
|
@ -249,11 +254,13 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
|
|||
if (!buf)
|
||||
return -ENOMEM;
|
||||
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,
|
||||
CIFS_MF_SYMLINK_FILE_SIZE /* length */,
|
||||
0 /* offset */,
|
||||
&bytes_read, &pbuf, &buf_type);
|
||||
rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type);
|
||||
CIFSSMBClose(xid, tcon, netfid);
|
||||
if (rc != 0) {
|
||||
kfree(buf);
|
||||
|
@ -291,7 +298,8 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
|
|||
int oplock = 0;
|
||||
__u16 netfid = 0;
|
||||
struct tcon_link *tlink;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
struct cifs_io_parms io_parms;
|
||||
u8 *buf;
|
||||
char *pbuf;
|
||||
unsigned int bytes_read = 0;
|
||||
|
@ -328,11 +336,13 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
|
|||
goto out;
|
||||
}
|
||||
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,
|
||||
CIFS_MF_SYMLINK_FILE_SIZE /* length */,
|
||||
0 /* offset */,
|
||||
&bytes_read, &pbuf, &buf_type);
|
||||
rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type);
|
||||
CIFSSMBClose(xid, pTcon, netfid);
|
||||
if (rc != 0) {
|
||||
kfree(buf);
|
||||
|
@ -370,7 +380,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
|
|||
char *toName = NULL;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct tcon_link *tlink;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
struct cifsInodeInfo *cifsInode;
|
||||
|
||||
tlink = cifs_sb_tlink(cifs_sb);
|
||||
|
@ -445,7 +455,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
|
|||
char *target_path = NULL;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct tcon_link *tlink = NULL;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_tcon *tcon;
|
||||
|
||||
xid = GetXid();
|
||||
|
||||
|
@ -518,7 +528,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
|
|||
int xid;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct tcon_link *tlink;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
char *full_path = NULL;
|
||||
struct inode *newinode = NULL;
|
||||
|
||||
|
|
|
@ -67,12 +67,12 @@ _FreeXid(unsigned int xid)
|
|||
spin_unlock(&GlobalMid_Lock);
|
||||
}
|
||||
|
||||
struct cifsSesInfo *
|
||||
struct cifs_ses *
|
||||
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) {
|
||||
atomic_inc(&sesInfoAllocCount);
|
||||
ret_buf->status = CifsNew;
|
||||
|
@ -85,7 +85,7 @@ sesInfoAlloc(void)
|
|||
}
|
||||
|
||||
void
|
||||
sesInfoFree(struct cifsSesInfo *buf_to_free)
|
||||
sesInfoFree(struct cifs_ses *buf_to_free)
|
||||
{
|
||||
if (buf_to_free == NULL) {
|
||||
cFYI(1, "Null buffer passed to sesInfoFree");
|
||||
|
@ -105,11 +105,11 @@ sesInfoFree(struct cifsSesInfo *buf_to_free)
|
|||
kfree(buf_to_free);
|
||||
}
|
||||
|
||||
struct cifsTconInfo *
|
||||
struct cifs_tcon *
|
||||
tconInfoAlloc(void)
|
||||
{
|
||||
struct cifsTconInfo *ret_buf;
|
||||
ret_buf = kzalloc(sizeof(struct cifsTconInfo), GFP_KERNEL);
|
||||
struct cifs_tcon *ret_buf;
|
||||
ret_buf = kzalloc(sizeof(struct cifs_tcon), GFP_KERNEL);
|
||||
if (ret_buf) {
|
||||
atomic_inc(&tconInfoAllocCount);
|
||||
ret_buf->tidStatus = CifsNew;
|
||||
|
@ -124,7 +124,7 @@ tconInfoAlloc(void)
|
|||
}
|
||||
|
||||
void
|
||||
tconInfoFree(struct cifsTconInfo *buf_to_free)
|
||||
tconInfoFree(struct cifs_tcon *buf_to_free)
|
||||
{
|
||||
if (buf_to_free == NULL) {
|
||||
cFYI(1, "Null buffer passed to tconInfoFree");
|
||||
|
@ -295,11 +295,11 @@ __u16 GetNextMid(struct TCP_Server_Info *server)
|
|||
case it is responsbility of caller to set the mid */
|
||||
void
|
||||
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 */)
|
||||
{
|
||||
struct list_head *temp_item;
|
||||
struct cifsSesInfo *ses;
|
||||
struct cifs_ses *ses;
|
||||
char *temp = (char *) buffer;
|
||||
|
||||
memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */
|
||||
|
@ -359,7 +359,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
|
|||
"did not match tcon uid");
|
||||
spin_lock(&cifs_tcp_ses_lock);
|
||||
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->server == treeCon->ses->server) {
|
||||
cFYI(1, "found matching uid substitute right smb_uid");
|
||||
|
@ -380,7 +380,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
|
|||
if (treeCon->nocase)
|
||||
buffer->Flags |= SMBFLG_CASELESS;
|
||||
if ((treeCon->ses) && (treeCon->ses->server))
|
||||
if (treeCon->ses->server->secMode &
|
||||
if (treeCon->ses->server->sec_mode &
|
||||
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
|
||||
buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
|
||||
}
|
||||
|
@ -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 list_head *tmp, *tmp1, *tmp2;
|
||||
struct cifsSesInfo *ses;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct cifs_ses *ses;
|
||||
struct cifs_tcon *tcon;
|
||||
struct cifsInodeInfo *pCifsInode;
|
||||
struct cifsFileInfo *netfile;
|
||||
|
||||
|
@ -566,9 +566,9 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
|
|||
/* look up tcon based on tid & uid */
|
||||
spin_lock(&cifs_tcp_ses_lock);
|
||||
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) {
|
||||
tcon = list_entry(tmp1, struct cifsTconInfo, tcon_list);
|
||||
tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
|
||||
if (tcon->tid != buf->Tid)
|
||||
continue;
|
||||
|
||||
|
|
|
@ -836,7 +836,7 @@ ntstatus_to_dos(__u32 ntstatus, __u8 *eclass, __u16 *ecode)
|
|||
}
|
||||
|
||||
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;
|
||||
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,
|
|||
int len;
|
||||
int oplock = 0;
|
||||
int rc;
|
||||
struct cifsTconInfo *ptcon = cifs_sb_tcon(cifs_sb);
|
||||
struct cifs_tcon *ptcon = cifs_sb_tcon(cifs_sb);
|
||||
char *tmpbuffer;
|
||||
|
||||
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)
|
|||
struct cifsFileInfo *cifsFile;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
|
||||
struct tcon_link *tlink = NULL;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
|
||||
if (file->private_data == NULL) {
|
||||
tlink = cifs_sb_tlink(cifs_sb);
|
||||
|
@ -496,7 +496,7 @@ static int cifs_save_resume_key(const char *current_entry,
|
|||
assume that they are located in the findfirst return buffer.*/
|
||||
/* We start counting in the buffer with entry 2 and increment for every
|
||||
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)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -764,7 +764,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
|
|||
{
|
||||
int rc = 0;
|
||||
int xid, i;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
struct cifsFileInfo *cifsFile = NULL;
|
||||
char *current_entry;
|
||||
int num_to_fill = 0;
|
||||
|
|
|
@ -37,13 +37,13 @@
|
|||
* 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
|
||||
*/
|
||||
static bool is_first_ses_reconnect(struct cifsSesInfo *ses)
|
||||
static bool is_first_ses_reconnect(struct cifs_ses *ses)
|
||||
{
|
||||
struct list_head *tmp;
|
||||
struct cifsSesInfo *tmp_ses;
|
||||
struct cifs_ses *tmp_ses;
|
||||
|
||||
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);
|
||||
if (tmp_ses->need_reconnect == false)
|
||||
return false;
|
||||
|
@ -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)
|
||||
*
|
||||
*/
|
||||
static __le16 get_next_vcnum(struct cifsSesInfo *ses)
|
||||
static __le16 get_next_vcnum(struct cifs_ses *ses)
|
||||
{
|
||||
__u16 vcnum = 0;
|
||||
struct list_head *tmp;
|
||||
struct cifsSesInfo *tmp_ses;
|
||||
struct cifs_ses *tmp_ses;
|
||||
__u16 max_vcs = ses->server->max_vcs;
|
||||
__u16 i;
|
||||
int free_vc_found = 0;
|
||||
|
@ -87,7 +87,7 @@ static __le16 get_next_vcnum(struct cifsSesInfo *ses)
|
|||
free_vc_found = 1;
|
||||
|
||||
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);
|
||||
if (tmp_ses->vcnum == i) {
|
||||
free_vc_found = 0;
|
||||
|
@ -114,7 +114,7 @@ get_vc_num_exit:
|
|||
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;
|
||||
|
||||
|
@ -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 |
|
||||
CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
|
||||
|
||||
if (ses->server->secMode &
|
||||
if (ses->server->sec_mode &
|
||||
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
|
||||
pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
|
||||
|
||||
|
@ -181,7 +181,7 @@ unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
|
|||
*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)
|
||||
{
|
||||
char *bcc_ptr = *pbcc_area;
|
||||
|
@ -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)
|
||||
{
|
||||
char *bcc_ptr = *pbcc_area;
|
||||
|
@ -236,7 +236,7 @@ static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
|
|||
*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)
|
||||
{
|
||||
char *bcc_ptr = *pbcc_area;
|
||||
|
@ -276,7 +276,7 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int len;
|
||||
|
@ -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,
|
||||
struct cifsSesInfo *ses,
|
||||
struct cifs_ses *ses,
|
||||
const struct nls_table *nls_cp)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -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,
|
||||
struct cifsSesInfo *ses)
|
||||
struct cifs_ses *ses)
|
||||
{
|
||||
unsigned int tioffset; /* challenge message target info area */
|
||||
unsigned int tilen; /* challenge message target info area length */
|
||||
|
@ -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
|
||||
it is fixed size, and small, making this approach cleaner */
|
||||
static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
|
||||
struct cifsSesInfo *ses)
|
||||
struct cifs_ses *ses)
|
||||
{
|
||||
NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
|
||||
__u32 flags;
|
||||
|
@ -424,7 +424,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
|
|||
flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
|
||||
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
|
||||
NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
|
||||
if (ses->server->secMode &
|
||||
if (ses->server->sec_mode &
|
||||
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
|
||||
flags |= NTLMSSP_NEGOTIATE_SIGN;
|
||||
if (!ses->server->session_estab)
|
||||
|
@ -449,7 +449,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
|
|||
This function returns the length of the data in the blob */
|
||||
static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
|
||||
u16 *buflen,
|
||||
struct cifsSesInfo *ses,
|
||||
struct cifs_ses *ses,
|
||||
const struct nls_table *nls_cp)
|
||||
{
|
||||
int rc;
|
||||
|
@ -464,10 +464,10 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
|
|||
NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
|
||||
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
|
||||
NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
|
||||
if (ses->server->secMode &
|
||||
if (ses->server->sec_mode &
|
||||
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
|
||||
flags |= NTLMSSP_NEGOTIATE_SIGN;
|
||||
if (ses->server->secMode & SECMODE_SIGN_REQUIRED)
|
||||
if (ses->server->sec_mode & SECMODE_SIGN_REQUIRED)
|
||||
flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
|
||||
|
||||
tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
|
||||
|
@ -551,7 +551,7 @@ setup_ntlmv2_ret:
|
|||
}
|
||||
|
||||
int
|
||||
CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
|
||||
CIFS_SessSetup(unsigned int xid, struct cifs_ses *ses,
|
||||
const struct nls_table *nls_cp)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -657,7 +657,7 @@ ssetup_ntlmssp_authenticate:
|
|||
*/
|
||||
|
||||
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);
|
||||
|
||||
ses->flags |= CIFS_SES_LANMAN;
|
||||
|
|
|
@ -295,7 +295,7 @@ static int wait_for_free_request(struct TCP_Server_Info *server,
|
|||
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)
|
||||
{
|
||||
if (ses->server->tcpStatus == CifsExiting) {
|
||||
|
@ -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.
|
||||
*/
|
||||
int
|
||||
cifs_call_async(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
|
||||
mid_callback_t *callback, void *cbdata)
|
||||
cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov,
|
||||
unsigned int nvec, mid_callback_t *callback, void *cbdata,
|
||||
bool ignore_pend)
|
||||
{
|
||||
int rc;
|
||||
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)
|
||||
return rc;
|
||||
|
||||
/* enable signing if server requires it */
|
||||
if (server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
|
||||
in_buf->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
|
||||
if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
|
||||
hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
|
||||
|
||||
mutex_lock(&server->srv_mutex);
|
||||
mid = AllocMidQEntry(in_buf, server);
|
||||
mid = AllocMidQEntry(hdr, server);
|
||||
if (mid == NULL) {
|
||||
mutex_unlock(&server->srv_mutex);
|
||||
return -ENOMEM;
|
||||
|
@ -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);
|
||||
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) {
|
||||
mutex_unlock(&server->srv_mutex);
|
||||
goto out_err;
|
||||
|
@ -380,7 +382,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
|
|||
#ifdef CONFIG_CIFS_STATS2
|
||||
atomic_inc(&server->inSend);
|
||||
#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
|
||||
atomic_dec(&server->inSend);
|
||||
mid->when_sent = jiffies;
|
||||
|
@ -407,7 +409,7 @@ out_err:
|
|||
*
|
||||
*/
|
||||
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)
|
||||
{
|
||||
int rc;
|
||||
|
@ -424,7 +426,7 @@ SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
|
@ -432,28 +434,21 @@ sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
|
|||
mid->mid, mid->midState);
|
||||
|
||||
spin_lock(&GlobalMid_Lock);
|
||||
/* ensure that it's no longer on the pending_mid_q */
|
||||
list_del_init(&mid->qhead);
|
||||
|
||||
switch (mid->midState) {
|
||||
case MID_RESPONSE_RECEIVED:
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
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:
|
||||
rc = -EAGAIN;
|
||||
break;
|
||||
case MID_RESPONSE_MALFORMED:
|
||||
rc = -EIO;
|
||||
break;
|
||||
case MID_SHUTDOWN:
|
||||
rc = -EHOSTDOWN;
|
||||
break;
|
||||
default:
|
||||
list_del_init(&mid->qhead);
|
||||
cERROR(1, "%s: invalid mid state mid=%d state=%d", __func__,
|
||||
mid->mid, mid->midState);
|
||||
rc = -EIO;
|
||||
|
@ -502,13 +497,31 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
|
|||
}
|
||||
|
||||
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 */,
|
||||
const int flags)
|
||||
{
|
||||
int rc = 0;
|
||||
int long_op;
|
||||
unsigned int receive_len;
|
||||
struct mid_q_entry *midQ;
|
||||
struct smb_hdr *in_buf = iov[0].iov_base;
|
||||
|
||||
|
@ -598,61 +611,31 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
|
|||
|
||||
cifs_small_buf_release(in_buf);
|
||||
|
||||
rc = sync_mid_result(midQ, ses->server);
|
||||
rc = cifs_sync_mid_result(midQ, ses->server);
|
||||
if (rc != 0) {
|
||||
atomic_dec(&ses->server->inFlight);
|
||||
wake_up(&ses->server->request_q);
|
||||
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);
|
||||
if (!midQ->resp_buf || midQ->midState != MID_RESPONSE_RECEIVED) {
|
||||
rc = -EIO;
|
||||
cFYI(1, "Bad MID state?");
|
||||
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->largeBuf)
|
||||
*pRespBufType = CIFS_LARGE_BUFFER;
|
||||
else
|
||||
*pRespBufType = CIFS_SMALL_BUFFER;
|
||||
|
||||
if (midQ->resp_buf &&
|
||||
(midQ->midState == MID_RESPONSE_RECEIVED)) {
|
||||
|
||||
iov[0].iov_base = (char *)midQ->resp_buf;
|
||||
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)
|
||||
midQ->resp_buf = NULL; /* mark it so buf will
|
||||
not be freed by
|
||||
delete_mid */
|
||||
} else {
|
||||
rc = -EIO;
|
||||
cFYI(1, "Bad MID state?");
|
||||
}
|
||||
rc = cifs_check_receive(midQ, ses->server, flags & CIFS_LOG_ERROR);
|
||||
|
||||
/* mark it so buf will not be freed by delete_mid */
|
||||
if ((flags & CIFS_NO_RESP) == 0)
|
||||
midQ->resp_buf = NULL;
|
||||
out:
|
||||
delete_mid(midQ);
|
||||
atomic_dec(&ses->server->inFlight);
|
||||
|
@ -662,12 +645,11 @@ out:
|
|||
}
|
||||
|
||||
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,
|
||||
int *pbytes_returned, const int long_op)
|
||||
{
|
||||
int rc = 0;
|
||||
unsigned int receive_len;
|
||||
struct mid_q_entry *midQ;
|
||||
|
||||
if (ses == NULL) {
|
||||
|
@ -750,54 +732,23 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
|
|||
spin_unlock(&GlobalMid_Lock);
|
||||
}
|
||||
|
||||
rc = sync_mid_result(midQ, ses->server);
|
||||
rc = cifs_sync_mid_result(midQ, ses->server);
|
||||
if (rc != 0) {
|
||||
atomic_dec(&ses->server->inFlight);
|
||||
wake_up(&ses->server->request_q);
|
||||
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);
|
||||
if (!midQ->resp_buf || !out_buf ||
|
||||
midQ->midState != MID_RESPONSE_RECEIVED) {
|
||||
rc = -EIO;
|
||||
cERROR(1, "Bad MID state?");
|
||||
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;
|
||||
cERROR(1, "Bad MID state?");
|
||||
}
|
||||
|
||||
*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:
|
||||
delete_mid(midQ);
|
||||
atomic_dec(&ses->server->inFlight);
|
||||
|
@ -810,12 +761,12 @@ out:
|
|||
blocking lock to return. */
|
||||
|
||||
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 *out_buf)
|
||||
{
|
||||
int bytes_returned;
|
||||
struct cifsSesInfo *ses = tcon->ses;
|
||||
struct cifs_ses *ses = tcon->ses;
|
||||
LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
|
||||
|
||||
/* We just modify the current in_buf to change
|
||||
|
@ -832,15 +783,14 @@ send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon,
|
|||
}
|
||||
|
||||
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,
|
||||
int *pbytes_returned)
|
||||
{
|
||||
int rc = 0;
|
||||
int rstart = 0;
|
||||
unsigned int receive_len;
|
||||
struct mid_q_entry *midQ;
|
||||
struct cifsSesInfo *ses;
|
||||
struct cifs_ses *ses;
|
||||
|
||||
if (tcon == NULL || tcon->ses == NULL) {
|
||||
cERROR(1, "Null smb session");
|
||||
|
@ -957,50 +907,20 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
|
|||
rstart = 1;
|
||||
}
|
||||
|
||||
rc = sync_mid_result(midQ, ses->server);
|
||||
rc = cifs_sync_mid_result(midQ, ses->server);
|
||||
if (rc != 0)
|
||||
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 */
|
||||
|
||||
if ((out_buf == NULL) || (midQ->midState != MID_RESPONSE_RECEIVED)) {
|
||||
if (out_buf == NULL || midQ->midState != MID_RESPONSE_RECEIVED) {
|
||||
rc = -EIO;
|
||||
cERROR(1, "Bad MID state?");
|
||||
goto out;
|
||||
}
|
||||
|
||||
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 */ );
|
||||
|
||||
*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:
|
||||
delete_mid(midQ);
|
||||
if (rstart && rc == -EACCES)
|
||||
|
|
|
@ -49,7 +49,7 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
|
|||
int xid;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct tcon_link *tlink;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
struct super_block *sb;
|
||||
char *full_path = NULL;
|
||||
|
||||
|
@ -109,7 +109,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
|
|||
int xid;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct tcon_link *tlink;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
struct super_block *sb;
|
||||
char *full_path;
|
||||
struct cifs_ntsd *pacl;
|
||||
|
@ -240,7 +240,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
|
|||
int xid;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct tcon_link *tlink;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
struct super_block *sb;
|
||||
char *full_path;
|
||||
|
||||
|
@ -372,7 +372,7 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
|
|||
int xid;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct tcon_link *tlink;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifs_tcon *pTcon;
|
||||
struct super_block *sb;
|
||||
char *full_path;
|
||||
|
||||
|
|
Loading…
Reference in New Issue