提交 98077a72 编写于 作者: L Linus Torvalds

Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6

Pull CIFS fixes from Steve French.

* 'for-next' of git://git.samba.org/sfrench/cifs-2.6: (40 commits)
  cifs: ensure that we always do cifsFileInfo_get under the spinlock
  CIFS: Make CAP_* checks protocol independent
  CIFS: Allow SMB2 statistics to be tracked
  CIFS: Move clear/print_stats code to ops struct
  CIFS: Add echo request support for SMB2
  CIFS: Move echo code to osp struct
  CIFS: Add SMB2 support for async requests
  CIFS: Setup async request in ops struct
  CIFS: Add SMB2 support for build_path_to_root
  CIFS: Move building path to root to ops struct
  CIFS: Query SMB2 inode info
  CIFS: Move query inode info code to ops struct
  CIFS: Add SMB2 support for is_path_accessible
  CIFS: Move is_path_accessible to ops struct
  CIFS: Move informational tcon calls to ops struct
  CIFS: Move getting dfs referalls to ops struct
  CIFS: Process reconnects for SMB2 shares
  CIFS: Add tree connect/disconnect capability for SMB2
  CIFS: Add session setup/logoff capability for SMB2
  CIFS: Add capability to send SMB2 negotiate message
  ...
......@@ -16,4 +16,5 @@ cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o
cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o
cifs-$(CONFIG_CIFS_SMB2) += smb2ops.o
cifs-$(CONFIG_CIFS_SMB2) += smb2ops.o smb2maperror.o smb2transport.o \
smb2misc.o smb2pdu.o smb2inode.o
......@@ -152,7 +152,7 @@ static uint16_t cifs_super_get_key(const void *cookie_netfs_data, void *buffer,
sharename = extract_sharename(tcon->treeName);
if (IS_ERR(sharename)) {
cFYI(1, "%s: couldn't extract sharename\n", __func__);
cFYI(1, "%s: couldn't extract sharename", __func__);
sharename = NULL;
return 0;
}
......
......@@ -65,7 +65,7 @@ void cifs_dump_detail(void *buf)
cERROR(1, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d",
smb->Command, smb->Status.CifsError,
smb->Flags, smb->Flags2, smb->Mid, smb->Pid);
cERROR(1, "smb buf %p len %d", smb, smbCalcSize(smb));
cERROR(1, "smb buf %p len %u", smb, smbCalcSize(smb));
#endif /* CONFIG_CIFS_DEBUG2 */
}
......@@ -282,24 +282,8 @@ static ssize_t cifs_stats_proc_write(struct file *file,
struct cifs_tcon,
tcon_list);
atomic_set(&tcon->num_smbs_sent, 0);
atomic_set(&tcon->num_writes, 0);
atomic_set(&tcon->num_reads, 0);
atomic_set(&tcon->num_oplock_brks, 0);
atomic_set(&tcon->num_opens, 0);
atomic_set(&tcon->num_posixopens, 0);
atomic_set(&tcon->num_posixmkdirs, 0);
atomic_set(&tcon->num_closes, 0);
atomic_set(&tcon->num_deletes, 0);
atomic_set(&tcon->num_mkdirs, 0);
atomic_set(&tcon->num_rmdirs, 0);
atomic_set(&tcon->num_renames, 0);
atomic_set(&tcon->num_t2renames, 0);
atomic_set(&tcon->num_ffirst, 0);
atomic_set(&tcon->num_fnext, 0);
atomic_set(&tcon->num_fclose, 0);
atomic_set(&tcon->num_hardlinks, 0);
atomic_set(&tcon->num_symlinks, 0);
atomic_set(&tcon->num_locks, 0);
if (server->ops->clear_stats)
server->ops->clear_stats(tcon);
}
}
}
......@@ -358,42 +342,10 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
seq_printf(m, "\n%d) %s", i, tcon->treeName);
if (tcon->need_reconnect)
seq_puts(m, "\tDISCONNECTED ");
seq_printf(m, "\nSMBs: %d Oplock Breaks: %d",
atomic_read(&tcon->num_smbs_sent),
atomic_read(&tcon->num_oplock_brks));
seq_printf(m, "\nReads: %d Bytes: %lld",
atomic_read(&tcon->num_reads),
(long long)(tcon->bytes_read));
seq_printf(m, "\nWrites: %d Bytes: %lld",
atomic_read(&tcon->num_writes),
(long long)(tcon->bytes_written));
seq_printf(m, "\nFlushes: %d",
atomic_read(&tcon->num_flushes));
seq_printf(m, "\nLocks: %d HardLinks: %d "
"Symlinks: %d",
atomic_read(&tcon->num_locks),
atomic_read(&tcon->num_hardlinks),
atomic_read(&tcon->num_symlinks));
seq_printf(m, "\nOpens: %d Closes: %d "
"Deletes: %d",
atomic_read(&tcon->num_opens),
atomic_read(&tcon->num_closes),
atomic_read(&tcon->num_deletes));
seq_printf(m, "\nPosix Opens: %d "
"Posix Mkdirs: %d",
atomic_read(&tcon->num_posixopens),
atomic_read(&tcon->num_posixmkdirs));
seq_printf(m, "\nMkdirs: %d Rmdirs: %d",
atomic_read(&tcon->num_mkdirs),
atomic_read(&tcon->num_rmdirs));
seq_printf(m, "\nRenames: %d T2 Renames %d",
atomic_read(&tcon->num_renames),
atomic_read(&tcon->num_t2renames));
seq_printf(m, "\nFindFirst: %d FNext %d "
"FClose %d",
atomic_read(&tcon->num_ffirst),
atomic_read(&tcon->num_fnext),
atomic_read(&tcon->num_fclose));
seq_printf(m, "\nSMBs: %d",
atomic_read(&tcon->num_smbs_sent));
if (server->ops->print_stats)
server->ops->print_stats(m, tcon);
}
}
}
......
......@@ -275,7 +275,8 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
struct cifs_sb_info *cifs_sb;
struct cifs_ses *ses;
char *full_path;
int xid, i;
unsigned int xid;
int i;
int rc;
struct vfsmount *mnt;
struct tcon_link *tlink;
......@@ -302,11 +303,11 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
}
ses = tlink_tcon(tlink)->ses;
xid = GetXid();
xid = get_xid();
rc = get_dfs_path(xid, ses, full_path + 1, cifs_sb->local_nls,
&num_referrals, &referrals,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
FreeXid(xid);
free_xid(xid);
cifs_put_tlink(tlink);
......
......@@ -331,3 +331,63 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
return i;
}
#ifdef CONFIG_CIFS_SMB2
/*
* cifs_local_to_utf16_bytes - how long will a string be after conversion?
* @from - pointer to input string
* @maxbytes - don't go past this many bytes of input string
* @codepage - source codepage
*
* Walk a string and return the number of bytes that the string will
* be after being converted to the given charset, not including any null
* termination required. Don't walk past maxbytes in the source buffer.
*/
static int
cifs_local_to_utf16_bytes(const char *from, int len,
const struct nls_table *codepage)
{
int charlen;
int i;
wchar_t wchar_to;
for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
charlen = codepage->char2uni(from, len, &wchar_to);
/* Failed conversion defaults to a question mark */
if (charlen < 1)
charlen = 1;
}
return 2 * i; /* UTF16 characters are two bytes */
}
/*
* cifs_strndup_to_utf16 - copy a string to wire format from the local codepage
* @src - source string
* @maxlen - don't walk past this many bytes in the source string
* @utf16_len - the length of the allocated string in bytes (including null)
* @cp - source codepage
* @remap - map special chars
*
* Take a string convert it from the local codepage to UTF16 and
* put it in a new buffer. Returns a pointer to the new string or NULL on
* error.
*/
__le16 *
cifs_strndup_to_utf16(const char *src, const int maxlen, int *utf16_len,
const struct nls_table *cp, int remap)
{
int len;
__le16 *dst;
len = cifs_local_to_utf16_bytes(src, maxlen, cp);
len += 2; /* NULL */
dst = kmalloc(len, GFP_KERNEL);
if (!dst) {
*utf16_len = 0;
return NULL;
}
cifsConvertToUTF16(dst, src, strlen(src), cp, remap);
*utf16_len = len;
return dst;
}
#endif /* CONFIG_CIFS_SMB2 */
......@@ -84,7 +84,11 @@ char *cifs_strndup_from_utf16(const char *src, const int maxlen,
const struct nls_table *codepage);
extern int cifsConvertToUTF16(__le16 *target, const char *source, int maxlen,
const struct nls_table *cp, int mapChars);
#ifdef CONFIG_CIFS_SMB2
extern __le16 *cifs_strndup_to_utf16(const char *src, const int maxlen,
int *utf16_len, const struct nls_table *cp,
int remap);
#endif /* CONFIG_CIFS_SMB2 */
#endif
/*
......
......@@ -525,7 +525,7 @@ init_cifs_idmap(void)
struct key *keyring;
int ret;
cFYI(1, "Registering the %s key type\n", cifs_idmap_key_type.name);
cFYI(1, "Registering the %s key type", cifs_idmap_key_type.name);
/* create an override credential set with a special thread keyring in
* which requests are cached
......@@ -572,7 +572,7 @@ init_cifs_idmap(void)
sidgidtree = RB_ROOT;
register_shrinker(&cifs_shrinker);
cFYI(1, "cifs idmap keyring: %d\n", key_serial(keyring));
cFYI(1, "cifs idmap keyring: %d", key_serial(keyring));
return 0;
failed_put_key:
......@@ -589,7 +589,7 @@ exit_cifs_idmap(void)
unregister_key_type(&cifs_idmap_key_type);
put_cred(root_cred);
unregister_shrinker(&cifs_shrinker);
cFYI(1, "Unregistered %s key type\n", cifs_idmap_key_type.name);
cFYI(1, "Unregistered %s key type", cifs_idmap_key_type.name);
}
void
......@@ -1153,15 +1153,16 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
__u16 fid, u32 *pacllen)
{
struct cifs_ntsd *pntsd = NULL;
int xid, rc;
unsigned int xid;
int rc;
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
return ERR_CAST(tlink);
xid = GetXid();
xid = get_xid();
rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen);
FreeXid(xid);
free_xid(xid);
cifs_put_tlink(tlink);
......@@ -1176,7 +1177,8 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
{
struct cifs_ntsd *pntsd = NULL;
int oplock = 0;
int xid, rc, create_options = 0;
unsigned int xid;
int rc, create_options = 0;
__u16 fid;
struct cifs_tcon *tcon;
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
......@@ -1185,7 +1187,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
return ERR_CAST(tlink);
tcon = tlink_tcon(tlink);
xid = GetXid();
xid = get_xid();
if (backup_cred(cifs_sb))
create_options |= CREATE_OPEN_BACKUP_INTENT;
......@@ -1199,7 +1201,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
}
cifs_put_tlink(tlink);
FreeXid(xid);
free_xid(xid);
cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
if (rc)
......@@ -1230,7 +1232,8 @@ int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
struct inode *inode, const char *path, int aclflag)
{
int oplock = 0;
int xid, rc, access_flags, create_options = 0;
unsigned int xid;
int rc, access_flags, create_options = 0;
__u16 fid;
struct cifs_tcon *tcon;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
......@@ -1240,7 +1243,7 @@ int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
return PTR_ERR(tlink);
tcon = tlink_tcon(tlink);
xid = GetXid();
xid = get_xid();
if (backup_cred(cifs_sb))
create_options |= CREATE_OPEN_BACKUP_INTENT;
......@@ -1263,7 +1266,7 @@ int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
CIFSSMBClose(xid, tcon, fid);
out:
FreeXid(xid);
free_xid(xid);
cifs_put_tlink(tlink);
return rc;
}
......
......@@ -47,20 +47,20 @@ static int cifs_calc_signature(const struct kvec *iov, int n_vec,
return -EINVAL;
if (!server->secmech.sdescmd5) {
cERROR(1, "%s: Can't generate signature\n", __func__);
cERROR(1, "%s: Can't generate signature", __func__);
return -1;
}
rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
if (rc) {
cERROR(1, "%s: Could not init md5\n", __func__);
cERROR(1, "%s: Could not init md5", __func__);
return rc;
}
rc = crypto_shash_update(&server->secmech.sdescmd5->shash,
server->session_key.response, server->session_key.len);
if (rc) {
cERROR(1, "%s: Could not update with response\n", __func__);
cERROR(1, "%s: Could not update with response", __func__);
return rc;
}
......@@ -85,7 +85,7 @@ static int cifs_calc_signature(const struct kvec *iov, int n_vec,
iov[i].iov_base, iov[i].iov_len);
}
if (rc) {
cERROR(1, "%s: Could not update with payload\n",
cERROR(1, "%s: Could not update with payload",
__func__);
return rc;
}
......@@ -93,13 +93,13 @@ static int cifs_calc_signature(const struct kvec *iov, int n_vec,
rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature);
if (rc)
cERROR(1, "%s: Could not generate md5 hash\n", __func__);
cERROR(1, "%s: Could not generate md5 hash", __func__);
return rc;
}
/* must be called with server->srv_mutex held */
int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
__u32 *pexpected_response_sequence_number)
{
int rc = 0;
......@@ -143,7 +143,7 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
iov.iov_base = cifs_pdu;
iov.iov_len = be32_to_cpu(cifs_pdu->smb_buf_length) + 4;
return cifs_sign_smb2(&iov, 1, server,
return cifs_sign_smbv(&iov, 1, server,
pexpected_response_sequence_number);
}
......@@ -399,7 +399,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
wchar_t *server;
if (!ses->server->secmech.sdeschmacmd5) {
cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash");
return -1;
}
......@@ -415,7 +415,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
if (rc) {
cERROR(1, "calc_ntlmv2_hash: could not init hmacmd5\n");
cERROR(1, "calc_ntlmv2_hash: could not init hmacmd5");
return rc;
}
......@@ -423,7 +423,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
len = ses->user_name ? strlen(ses->user_name) : 0;
user = kmalloc(2 + (len * 2), GFP_KERNEL);
if (user == NULL) {
cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n");
cERROR(1, "calc_ntlmv2_hash: user mem alloc failure");
rc = -ENOMEM;
return rc;
}
......@@ -439,7 +439,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
(char *)user, 2 * len);
kfree(user);
if (rc) {
cERROR(1, "%s: Could not update with user\n", __func__);
cERROR(1, "%s: Could not update with user", __func__);
return rc;
}
......@@ -460,7 +460,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
(char *)domain, 2 * len);
kfree(domain);
if (rc) {
cERROR(1, "%s: Could not update with domain\n",
cERROR(1, "%s: Could not update with domain",
__func__);
return rc;
}
......@@ -480,7 +480,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
(char *)server, 2 * len);
kfree(server);
if (rc) {
cERROR(1, "%s: Could not update with server\n",
cERROR(1, "%s: Could not update with server",
__func__);
return rc;
}
......@@ -489,7 +489,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
ntlmv2_hash);
if (rc)
cERROR(1, "%s: Could not generate md5 hash\n", __func__);
cERROR(1, "%s: Could not generate md5 hash", __func__);
return rc;
}
......@@ -501,7 +501,7 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
unsigned int offset = CIFS_SESS_KEY_SIZE + 8;
if (!ses->server->secmech.sdeschmacmd5) {
cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash");
return -1;
}
......@@ -527,14 +527,14 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
ses->auth_key.response + offset, ses->auth_key.len - offset);
if (rc) {
cERROR(1, "%s: Could not update with response\n", __func__);
cERROR(1, "%s: Could not update with response", __func__);
return rc;
}
rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
ses->auth_key.response + CIFS_SESS_KEY_SIZE);
if (rc)
cERROR(1, "%s: Could not generate md5 hash\n", __func__);
cERROR(1, "%s: Could not generate md5 hash", __func__);
return rc;
}
......@@ -613,7 +613,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
if (rc) {
cERROR(1, "%s: Could not init hmacmd5\n", __func__);
cERROR(1, "%s: Could not init hmacmd5", __func__);
goto setup_ntlmv2_rsp_ret;
}
......@@ -621,14 +621,14 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
ses->auth_key.response + CIFS_SESS_KEY_SIZE,
CIFS_HMAC_MD5_HASH_SIZE);
if (rc) {
cERROR(1, "%s: Could not update with response\n", __func__);
cERROR(1, "%s: Could not update with response", __func__);
goto setup_ntlmv2_rsp_ret;
}
rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
ses->auth_key.response);
if (rc)
cERROR(1, "%s: Could not generate md5 hash\n", __func__);
cERROR(1, "%s: Could not generate md5 hash", __func__);
setup_ntlmv2_rsp_ret:
kfree(tiblob);
......@@ -650,7 +650,7 @@ calc_seckey(struct cifs_ses *ses)
tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm_arc4)) {
rc = PTR_ERR(tfm_arc4);
cERROR(1, "could not allocate crypto API arc4\n");
cERROR(1, "could not allocate crypto API arc4");
return rc;
}
......@@ -668,7 +668,7 @@ calc_seckey(struct cifs_ses *ses)
rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, CIFS_CPHTXT_SIZE);
if (rc) {
cERROR(1, "could not encrypt session key rc: %d\n", rc);
cERROR(1, "could not encrypt session key rc: %d", rc);
crypto_free_blkcipher(tfm_arc4);
return rc;
}
......@@ -705,13 +705,13 @@ cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
if (IS_ERR(server->secmech.hmacmd5)) {
cERROR(1, "could not allocate crypto hmacmd5\n");
cERROR(1, "could not allocate crypto hmacmd5");
return PTR_ERR(server->secmech.hmacmd5);
}
server->secmech.md5 = crypto_alloc_shash("md5", 0, 0);
if (IS_ERR(server->secmech.md5)) {
cERROR(1, "could not allocate crypto md5\n");
cERROR(1, "could not allocate crypto md5");
rc = PTR_ERR(server->secmech.md5);
goto crypto_allocate_md5_fail;
}
......@@ -720,7 +720,7 @@ cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
crypto_shash_descsize(server->secmech.hmacmd5);
server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
if (!server->secmech.sdeschmacmd5) {
cERROR(1, "cifs_crypto_shash_allocate: can't alloc hmacmd5\n");
cERROR(1, "cifs_crypto_shash_allocate: can't alloc hmacmd5");
rc = -ENOMEM;
goto crypto_allocate_hmacmd5_sdesc_fail;
}
......@@ -732,7 +732,7 @@ cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
crypto_shash_descsize(server->secmech.md5);
server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL);
if (!server->secmech.sdescmd5) {
cERROR(1, "cifs_crypto_shash_allocate: can't alloc md5\n");
cERROR(1, "cifs_crypto_shash_allocate: can't alloc md5");
rc = -ENOMEM;
goto crypto_allocate_md5_sdesc_fail;
}
......
......@@ -48,6 +48,9 @@
#include <linux/key-type.h>
#include "cifs_spnego.h"
#include "fscache.h"
#ifdef CONFIG_CIFS_SMB2
#include "smb2pdu.h"
#endif
#define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */
int cifsFYI = 0;
......@@ -158,9 +161,9 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
int rc = -EOPNOTSUPP;
int xid;
unsigned int xid;
xid = GetXid();
xid = get_xid();
buf->f_type = CIFS_MAGIC_NUMBER;
......@@ -197,7 +200,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
if (rc)
rc = SMBOldQFSInfo(xid, tcon, buf);
FreeXid(xid);
free_xid(xid);
return 0;
}
......@@ -546,8 +549,8 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
char *s, *p;
char sep;
full_path = cifs_build_path_to_root(vol, cifs_sb,
cifs_sb_master_tcon(cifs_sb));
full_path = build_path_to_root(vol, cifs_sb,
cifs_sb_master_tcon(cifs_sb));
if (full_path == NULL)
return ERR_PTR(-ENOMEM);
......@@ -980,6 +983,14 @@ cifs_destroy_inodecache(void)
static int
cifs_init_request_bufs(void)
{
size_t max_hdr_size = MAX_CIFS_HDR_SIZE;
#ifdef CONFIG_CIFS_SMB2
/*
* SMB2 maximum header size is bigger than CIFS one - no problems to
* allocate some more bytes for CIFS.
*/
max_hdr_size = MAX_SMB2_HDR_SIZE;
#endif
if (CIFSMaxBufSize < 8192) {
/* Buffer size can not be smaller than 2 * PATH_MAX since maximum
Unicode path name has to fit in any SMB/CIFS path based frames */
......@@ -991,8 +1002,7 @@ cifs_init_request_bufs(void)
}
/* cERROR(1, "CIFSMaxBufSize %d 0x%x",CIFSMaxBufSize,CIFSMaxBufSize); */
cifs_req_cachep = kmem_cache_create("cifs_request",
CIFSMaxBufSize +
MAX_CIFS_HDR_SIZE, 0,
CIFSMaxBufSize + max_hdr_size, 0,
SLAB_HWCACHE_ALIGN, NULL);
if (cifs_req_cachep == NULL)
return -ENOMEM;
......
......@@ -22,11 +22,15 @@
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/slab.h>
#include <linux/mempool.h>
#include <linux/workqueue.h>
#include "cifs_fs_sb.h"
#include "cifsacl.h"
#include <crypto/internal/hash.h>
#include <linux/scatterlist.h>
#ifdef CONFIG_CIFS_SMB2
#include "smb2pdu.h"
#endif
/*
* The sizes of various internal tables and strings
......@@ -72,6 +76,9 @@
/* (max path length + 1 for null) * 2 for unicode */
#define MAX_NAME 514
/* SMB echo "timeout" -- FIXME: tunable? */
#define SMB_ECHO_INTERVAL (60 * HZ)
#include "cifspdu.h"
#ifndef XATTR_DOS_ATTRIB
......@@ -160,6 +167,10 @@ struct mid_q_entry;
struct TCP_Server_Info;
struct cifsFileInfo;
struct cifs_ses;
struct cifs_tcon;
struct dfs_info3_param;
struct cifs_fattr;
struct smb_vol;
struct smb_version_operations {
int (*send_cancel)(struct TCP_Server_Info *, void *,
......@@ -168,12 +179,17 @@ struct smb_version_operations {
/* setup request: allocate mid, sign message */
int (*setup_request)(struct cifs_ses *, struct kvec *, unsigned int,
struct mid_q_entry **);
/* setup async request: allocate mid, sign message */
int (*setup_async_request)(struct TCP_Server_Info *, struct kvec *,
unsigned int, struct mid_q_entry **);
/* check response: verify signature, map error */
int (*check_receive)(struct mid_q_entry *, struct TCP_Server_Info *,
bool);
void (*add_credits)(struct TCP_Server_Info *, const unsigned int);
void (*add_credits)(struct TCP_Server_Info *, const unsigned int,
const int);
void (*set_credits)(struct TCP_Server_Info *, const int);
int * (*get_credits_field)(struct TCP_Server_Info *);
int * (*get_credits_field)(struct TCP_Server_Info *, const int);
unsigned int (*get_credits)(struct mid_q_entry *);
__u64 (*get_next_mid)(struct TCP_Server_Info *);
/* data offset from read response message */
unsigned int (*read_data_offset)(char *);
......@@ -184,9 +200,52 @@ struct smb_version_operations {
/* find mid corresponding to the response message */
struct mid_q_entry * (*find_mid)(struct TCP_Server_Info *, char *);
void (*dump_detail)(void *);
void (*clear_stats)(struct cifs_tcon *);
void (*print_stats)(struct seq_file *m, struct cifs_tcon *);
/* verify the message */
int (*check_message)(char *, unsigned int);
bool (*is_oplock_break)(char *, struct TCP_Server_Info *);
/* process transaction2 response */
bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *,
char *, int);
/* check if we need to negotiate */
bool (*need_neg)(struct TCP_Server_Info *);
/* negotiate to the server */
int (*negotiate)(const unsigned int, struct cifs_ses *);
/* setup smb sessionn */
int (*sess_setup)(const unsigned int, struct cifs_ses *,
const struct nls_table *);
/* close smb session */
int (*logoff)(const unsigned int, struct cifs_ses *);
/* connect to a server share */
int (*tree_connect)(const unsigned int, struct cifs_ses *, const char *,
struct cifs_tcon *, const struct nls_table *);
/* close tree connecion */
int (*tree_disconnect)(const unsigned int, struct cifs_tcon *);
/* get DFS referrals */
int (*get_dfs_refer)(const unsigned int, struct cifs_ses *,
const char *, struct dfs_info3_param **,
unsigned int *, const struct nls_table *, int);
/* informational QFS call */
void (*qfs_tcon)(const unsigned int, struct cifs_tcon *);
/* check if a path is accessible or not */
int (*is_path_accessible)(const unsigned int, struct cifs_tcon *,
struct cifs_sb_info *, const char *);
/* query path data from the server */
int (*query_path_info)(const unsigned int, struct cifs_tcon *,
struct cifs_sb_info *, const char *,
FILE_ALL_INFO *, bool *);
/* get server index number */
int (*get_srv_inum)(const unsigned int, struct cifs_tcon *,
struct cifs_sb_info *, const char *,
u64 *uniqueid, FILE_ALL_INFO *);
/* build a full path to the root of the mount */
char * (*build_path_to_root)(struct smb_vol *, struct cifs_sb_info *,
struct cifs_tcon *);
/* check if we can send an echo or nor */
bool (*can_echo)(struct TCP_Server_Info *);
/* send echo request */
int (*echo)(struct TCP_Server_Info *);
};
struct smb_version_values {
......@@ -198,6 +257,10 @@ struct smb_version_values {
size_t header_size;
size_t max_header_size;
size_t read_rsp_size;
__le16 lock_cmd;
unsigned int cap_unix;
unsigned int cap_nt_find;
unsigned int cap_large_files;
};
#define HEADER_SIZE(server) (server->vals->header_size)
......@@ -291,6 +354,12 @@ get_rfc1002_length(void *buf)
return be32_to_cpu(*((__be32 *)buf));
}
static inline void
inc_rfc1001_len(void *buf, int count)
{
be32_add_cpu((__be32 *)buf, count);
}
struct TCP_Server_Info {
struct list_head tcp_ses_list;
struct list_head smb_ses_list;
......@@ -319,8 +388,13 @@ struct TCP_Server_Info {
struct mutex srv_mutex;
struct task_struct *tsk;
char server_GUID[16];
char sec_mode;
__u16 sec_mode;
bool session_estab; /* mark when very first sess is established */
#ifdef CONFIG_CIFS_SMB2
int echo_credits; /* echo reserved slots */
int oplock_credits; /* oplock break reserved slots */
bool echoes:1; /* enable echoes */
#endif
u16 dialect; /* dialect index that server chose */
enum securityEnum secType;
bool oplocks:1; /* enable oplocks */
......@@ -337,7 +411,7 @@ struct TCP_Server_Info {
unsigned int max_vcs; /* maximum number of smb sessions, at least
those that can be specified uniquely with
vcnumbers */
int capabilities; /* allow selective disabling of caps by smb sess */
unsigned int capabilities; /* selective disabling of caps by smb sess */
int timeAdj; /* Adjust for difference in server time zone in sec */
__u64 CurrentMid; /* multiplex id - rotating counter */
char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlm, ntlmv2 etc */
......@@ -366,6 +440,10 @@ struct TCP_Server_Info {
atomic_t in_send; /* requests trying to send */
atomic_t num_waiters; /* blocked waiting to get in sendrecv */
#endif
#ifdef CONFIG_CIFS_SMB2
unsigned int max_read;
unsigned int max_write;
#endif /* CONFIG_CIFS_SMB2 */
};
static inline unsigned int
......@@ -389,9 +467,10 @@ has_credits(struct TCP_Server_Info *server, int *credits)
}
static inline void
add_credits(struct TCP_Server_Info *server, const unsigned int add)
add_credits(struct TCP_Server_Info *server, const unsigned int add,
const int optype)
{
server->ops->add_credits(server, add);
server->ops->add_credits(server, add, optype);
}
static inline void
......@@ -453,10 +532,10 @@ struct cifs_ses {
char *serverOS; /* name of operating system underlying server */
char *serverNOS; /* name of network operating system of server */
char *serverDomain; /* security realm of server */
int Suid; /* remote smb uid */
__u64 Suid; /* remote smb uid */
uid_t linux_uid; /* overriding owner of files on the mount */
uid_t cred_uid; /* owner of credentials */
int capabilities;
unsigned int capabilities;
char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for
TCP names - will ipv6 and sctp addresses fit? */
char *user_name; /* must not be null except during init of sess
......@@ -466,6 +545,9 @@ struct cifs_ses {
struct session_key auth_key;
struct ntlmssp_auth *ntlmssp; /* ciphertext, flags, server challenge */
bool need_reconnect:1; /* connection reset, uid now invalid */
#ifdef CONFIG_CIFS_SMB2
__u16 session_flags;
#endif /* CONFIG_CIFS_SMB2 */
};
/* no more than one of the following three session flags may be set */
#define CIFS_SES_NT4 1
......@@ -475,6 +557,13 @@ struct cifs_ses {
which do not negotiate NTLM or POSIX dialects, but instead
negotiate one of the older LANMAN dialects */
#define CIFS_SES_LANMAN 8
static inline bool
cap_unix(struct cifs_ses *ses)
{
return ses->server->vals->cap_unix & ses->capabilities;
}
/*
* there is one of these for each connection to a resource on a particular
* session
......@@ -487,32 +576,42 @@ struct cifs_tcon {
char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */
char *nativeFileSystem;
char *password; /* for share-level security */
__u16 tid; /* The 2 byte tree id */
__u32 tid; /* The 4 byte tree id */
__u16 Flags; /* optional support bits */
enum statusEnum tidStatus;
#ifdef CONFIG_CIFS_STATS
atomic_t num_smbs_sent;
atomic_t num_writes;
atomic_t num_reads;
atomic_t num_flushes;
atomic_t num_oplock_brks;
atomic_t num_opens;
atomic_t num_closes;
atomic_t num_deletes;
atomic_t num_mkdirs;
atomic_t num_posixopens;
atomic_t num_posixmkdirs;
atomic_t num_rmdirs;
atomic_t num_renames;
atomic_t num_t2renames;
atomic_t num_ffirst;
atomic_t num_fnext;
atomic_t num_fclose;
atomic_t num_hardlinks;
atomic_t num_symlinks;
atomic_t num_locks;
atomic_t num_acl_get;
atomic_t num_acl_set;
union {
struct {
atomic_t num_writes;
atomic_t num_reads;
atomic_t num_flushes;
atomic_t num_oplock_brks;
atomic_t num_opens;
atomic_t num_closes;
atomic_t num_deletes;
atomic_t num_mkdirs;
atomic_t num_posixopens;
atomic_t num_posixmkdirs;
atomic_t num_rmdirs;
atomic_t num_renames;
atomic_t num_t2renames;
atomic_t num_ffirst;
atomic_t num_fnext;
atomic_t num_fclose;
atomic_t num_hardlinks;
atomic_t num_symlinks;
atomic_t num_locks;
atomic_t num_acl_get;
atomic_t num_acl_set;
} cifs_stats;
#ifdef CONFIG_CIFS_SMB2
struct {
atomic_t smb2_com_sent[NUMBER_OF_SMB2_COMMANDS];
atomic_t smb2_com_failed[NUMBER_OF_SMB2_COMMANDS];
} smb2_stats;
#endif /* CONFIG_CIFS_SMB2 */
} stats;
#ifdef CONFIG_CIFS_STATS2
unsigned long long time_writes;
unsigned long long time_reads;
......@@ -543,6 +642,15 @@ struct cifs_tcon {
bool local_lease:1; /* check leases (only) on local system not remote */
bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */
bool need_reconnect:1; /* connection reset, tid now invalid */
#ifdef CONFIG_CIFS_SMB2
bool print:1; /* set if connection to printer share */
bool bad_network_name:1; /* set if ret status STATUS_BAD_NETWORK_NAME */
__u32 capabilities;
__u32 share_flags;
__u32 maximal_access;
__u32 vol_serial_number;
__le64 vol_create_time;
#endif /* CONFIG_CIFS_SMB2 */
#ifdef CONFIG_CIFS_FSCACHE
u64 resource_id; /* server resource id */
struct fscache_cookie *fscache; /* cookie for share */
......@@ -657,13 +765,13 @@ struct cifs_io_parms {
* Take a reference on the file private data. Must be called with
* cifs_file_list_lock held.
*/
static inline
struct cifsFileInfo *cifsFileInfo_get(struct cifsFileInfo *cifs_file)
static inline void
cifsFileInfo_get_locked(struct cifsFileInfo *cifs_file)
{
++cifs_file->count;
return cifs_file;
}
struct cifsFileInfo *cifsFileInfo_get(struct cifsFileInfo *cifs_file);
void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
/*
......@@ -734,6 +842,15 @@ convert_delimiter(char *path, char delim)
}
}
static inline char *
build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
struct cifs_tcon *tcon)
{
if (!vol->ops->build_path_to_root)
return NULL;
return vol->ops->build_path_to_root(vol, cifs_sb, tcon);
}
#ifdef CONFIG_CIFS_STATS
#define cifs_stats_inc atomic_inc
......@@ -791,6 +908,7 @@ typedef void (mid_callback_t)(struct mid_q_entry *mid);
/* one of these for every pending CIFS request to the server */
struct mid_q_entry {
struct list_head qhead; /* mids waiting on reply from this server */
struct TCP_Server_Info *server; /* server corresponding to this mid */
__u64 mid; /* multiplex id */
__u32 pid; /* process id */
__u32 sequence_number; /* for CIFS signing */
......@@ -954,6 +1072,12 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
#define CIFS_LARGE_BUF_OP 0x020 /* large request buffer */
#define CIFS_NO_RESP 0x040 /* no response buffer required */
/* Type of request operation */
#define CIFS_ECHO_OP 0x080 /* echo request */
#define CIFS_OBREAK_OP 0x0100 /* oplock break request */
#define CIFS_NEG_OP 0x0200 /* negotiate request */
#define CIFS_OP_MASK 0x0380 /* mask request type */
/* Security Flags: indicate type of session setup needed */
#define CIFSSEC_MAY_SIGN 0x00001
#define CIFSSEC_MAY_NTLM 0x00002
......@@ -1127,6 +1251,8 @@ void cifs_oplock_break(struct work_struct *work);
extern const struct slow_work_ops cifs_oplock_break_ops;
extern struct workqueue_struct *cifsiod_wq;
extern mempool_t *cifs_mid_poolp;
/* Operations for different SMB versions */
#define SMB1_VERSION_STRING "1.0"
extern struct smb_version_operations smb1_operations;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -157,10 +157,10 @@ check_name(struct dentry *direntry)
/* Inode operations in similar order to how they appear in Linux file fs.h */
static int cifs_do_create(struct inode *inode, struct dentry *direntry,
int xid, struct tcon_link *tlink, unsigned oflags,
umode_t mode, __u32 *oplock, __u16 *fileHandle,
int *created)
static int
cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
struct tcon_link *tlink, unsigned oflags, umode_t mode,
__u32 *oplock, __u16 *fileHandle, int *created)
{
int rc = -ENOENT;
int create_options = CREATE_NOT_DIR;
......@@ -182,8 +182,7 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry,
goto out;
}
if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
!tcon->broken_posix_open &&
if (tcon->unix_ext && cap_unix(tcon->ses) && !tcon->broken_posix_open &&
(CIFS_UNIX_POSIX_PATH_OPS_CAP &
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
rc = cifs_posix_open(full_path, &newinode,
......@@ -382,12 +381,11 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
int *opened)
{
int rc;
int xid;
unsigned int xid;
struct tcon_link *tlink;
struct cifs_tcon *tcon;
__u16 fileHandle;
__u32 oplock;
struct file *filp;
struct cifsFileInfo *pfile_info;
/* Posix open is only called (at lookup time) for file create now. For
......@@ -412,15 +410,14 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
if (rc)
return rc;
xid = GetXid();
xid = get_xid();
cFYI(1, "parent inode = 0x%p name is: %s and dentry = 0x%p",
inode, direntry->d_name.name, direntry);
tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb));
filp = ERR_CAST(tlink);
if (IS_ERR(tlink))
goto free_xid;
goto out_free_xid;
tcon = tlink_tcon(tlink);
......@@ -436,17 +433,16 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
goto out;
}
pfile_info = cifs_new_fileinfo(fileHandle, filp, tlink, oplock);
pfile_info = cifs_new_fileinfo(fileHandle, file, tlink, oplock);
if (pfile_info == NULL) {
CIFSSMBClose(xid, tcon, fileHandle);
fput(filp);
rc = -ENOMEM;
}
out:
cifs_put_tlink(tlink);
free_xid:
FreeXid(xid);
out_free_xid:
free_xid(xid);
return rc;
}
......@@ -454,7 +450,7 @@ int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
bool excl)
{
int rc;
int xid = GetXid();
unsigned int xid = get_xid();
/*
* BB below access is probably too much for mknod to request
* but we have to do query and setpathinfo so requesting
......@@ -474,7 +470,7 @@ int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb));
rc = PTR_ERR(tlink);
if (IS_ERR(tlink))
goto free_xid;
goto out_free_xid;
rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
&oplock, &fileHandle, &created);
......@@ -482,9 +478,8 @@ int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
CIFSSMBClose(xid, tlink_tcon(tlink), fileHandle);
cifs_put_tlink(tlink);
free_xid:
FreeXid(xid);
out_free_xid:
free_xid(xid);
return rc;
}
......@@ -492,7 +487,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
dev_t device_number)
{
int rc = -EPERM;
int xid;
unsigned int xid;
int create_options = CREATE_NOT_DIR | CREATE_OPTION_SPECIAL;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
......@@ -516,7 +511,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
pTcon = tlink_tcon(tlink);
xid = GetXid();
xid = get_xid();
full_path = build_path_from_dentry(direntry);
if (full_path == NULL) {
......@@ -564,7 +559,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
if (buf == NULL) {
kfree(full_path);
rc = -ENOMEM;
FreeXid(xid);
free_xid(xid);
return rc;
}
......@@ -614,7 +609,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
mknod_out:
kfree(full_path);
kfree(buf);
FreeXid(xid);
free_xid(xid);
cifs_put_tlink(tlink);
return rc;
}
......@@ -623,7 +618,7 @@ struct dentry *
cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
unsigned int flags)
{
int xid;
unsigned int xid;
int rc = 0; /* to get around spurious gcc warning, set to zero here */
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
......@@ -631,7 +626,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
struct inode *newInode = NULL;
char *full_path = NULL;
xid = GetXid();
xid = get_xid();
cFYI(1, "parent inode = 0x%p name is: %s and dentry = 0x%p",
parent_dir_inode, direntry->d_name.name, direntry);
......@@ -641,7 +636,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink)) {
FreeXid(xid);
free_xid(xid);
return (struct dentry *)tlink;
}
pTcon = tlink_tcon(tlink);
......@@ -695,7 +690,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
lookup_out:
kfree(full_path);
cifs_put_tlink(tlink);
FreeXid(xid);
free_xid(xid);
return ERR_PTR(rc);
}
......
此差异已折叠。
......@@ -289,7 +289,7 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
int cifs_get_file_info_unix(struct file *filp)
{
int rc;
int xid;
unsigned int xid;
FILE_UNIX_BASIC_INFO find_data;
struct cifs_fattr fattr;
struct inode *inode = filp->f_path.dentry->d_inode;
......@@ -297,7 +297,7 @@ int cifs_get_file_info_unix(struct file *filp)
struct cifsFileInfo *cfile = filp->private_data;
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
xid = GetXid();
xid = get_xid();
rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data);
if (!rc) {
cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
......@@ -307,13 +307,13 @@ int cifs_get_file_info_unix(struct file *filp)
}
cifs_fattr_to_inode(inode, &fattr);
FreeXid(xid);
free_xid(xid);
return rc;
}
int cifs_get_inode_info_unix(struct inode **pinode,
const unsigned char *full_path,
struct super_block *sb, int xid)
struct super_block *sb, unsigned int xid)
{
int rc;
FILE_UNIX_BASIC_INFO find_data;
......@@ -367,7 +367,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
static int
cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
struct cifs_sb_info *cifs_sb, int xid)
struct cifs_sb_info *cifs_sb, unsigned int xid)
{
int rc;
int oplock = 0;
......@@ -466,7 +466,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
* FIXME: Doesn't this clobber the type bit we got from cifs_sfu_type ?
*/
static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
struct cifs_sb_info *cifs_sb, int xid)
struct cifs_sb_info *cifs_sb, unsigned int xid)
{
#ifdef CONFIG_CIFS_XATTR
ssize_t rc;
......@@ -557,7 +557,7 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
int cifs_get_file_info(struct file *filp)
{
int rc;
int xid;
unsigned int xid;
FILE_ALL_INFO find_data;
struct cifs_fattr fattr;
struct inode *inode = filp->f_path.dentry->d_inode;
......@@ -565,7 +565,7 @@ int cifs_get_file_info(struct file *filp)
struct cifsFileInfo *cfile = filp->private_data;
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
xid = GetXid();
xid = get_xid();
rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data);
switch (rc) {
case 0:
......@@ -596,65 +596,58 @@ int cifs_get_file_info(struct file *filp)
fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
cifs_fattr_to_inode(inode, &fattr);
cgfi_exit:
FreeXid(xid);
free_xid(xid);
return rc;
}
int cifs_get_inode_info(struct inode **pinode,
const unsigned char *full_path, FILE_ALL_INFO *pfindData,
struct super_block *sb, int xid, const __u16 *pfid)
int
cifs_get_inode_info(struct inode **inode, const char *full_path,
FILE_ALL_INFO *data, struct super_block *sb, int xid,
const __u16 *fid)
{
int rc = 0, tmprc;
struct cifs_tcon *pTcon;
struct cifs_tcon *tcon;
struct TCP_Server_Info *server;
struct tcon_link *tlink;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
char *buf = NULL;
bool adjustTZ = false;
bool adjust_tz = false;
struct cifs_fattr fattr;
tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
return PTR_ERR(tlink);
pTcon = tlink_tcon(tlink);
tcon = tlink_tcon(tlink);
server = tcon->ses->server;
cFYI(1, "Getting info on %s", full_path);
if ((pfindData == NULL) && (*pinode != NULL)) {
if (CIFS_I(*pinode)->clientCanCacheRead) {
if ((data == NULL) && (*inode != NULL)) {
if (CIFS_I(*inode)->clientCanCacheRead) {
cFYI(1, "No need to revalidate cached inode sizes");
goto cgii_exit;
}
}
/* if file info not passed in then get it from server */
if (pfindData == NULL) {
/* if inode info is not passed, get it from server */
if (data == NULL) {
if (!server->ops->query_path_info) {
rc = -ENOSYS;
goto cgii_exit;
}
buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
if (buf == NULL) {
rc = -ENOMEM;
goto cgii_exit;
}
pfindData = (FILE_ALL_INFO *)buf;
/* could do find first instead but this returns more info */
rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData,
0 /* not legacy */,
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
/* BB optimize code so we do not make the above call
when server claims no NT SMB support and the above call
failed at least once - set flag in tcon or mount */
if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
rc = SMBQueryInformation(xid, pTcon, full_path,
pfindData, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
adjustTZ = true;
}
data = (FILE_ALL_INFO *)buf;
rc = server->ops->query_path_info(xid, tcon, cifs_sb, full_path,
data, &adjust_tz);
}
if (!rc) {
cifs_all_info_to_fattr(&fattr, (FILE_ALL_INFO *) pfindData,
cifs_sb, adjustTZ);
cifs_all_info_to_fattr(&fattr, (FILE_ALL_INFO *)data, cifs_sb,
adjust_tz);
} else if (rc == -EREMOTE) {
cifs_create_dfs_fattr(&fattr, sb);
rc = 0;
......@@ -668,28 +661,17 @@ int cifs_get_inode_info(struct inode **pinode,
* Is an i_ino of zero legal? Can we use that to check if the server
* supports returning inode numbers? Are there other sanity checks we
* can use to ensure that the server is really filling in that field?
*
* We can not use the IndexNumber field by default from Windows or
* Samba (in ALL_INFO buf) but we can request it explicitly. The SNIA
* CIFS spec claims that this value is unique within the scope of a
* share, and the windows docs hint that it's actually unique
* per-machine.
*
* There may be higher info levels that work but are there Windows
* server or network appliances for which IndexNumber field is not
* guaranteed unique?
*/
if (*pinode == NULL) {
if (*inode == NULL) {
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
int rc1 = 0;
rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
full_path, &fattr.cf_uniqueid,
cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc1 || !fattr.cf_uniqueid) {
cFYI(1, "GetSrvInodeNum rc %d", rc1);
if (server->ops->get_srv_inum)
tmprc = server->ops->get_srv_inum(xid, tcon,
cifs_sb, full_path, &fattr.cf_uniqueid,
data);
else
tmprc = -ENOSYS;
if (tmprc || !fattr.cf_uniqueid) {
cFYI(1, "GetSrvInodeNum rc %d", tmprc);
fattr.cf_uniqueid = iunique(sb, ROOT_I);
cifs_autodisable_serverino(cifs_sb);
}
......@@ -697,7 +679,7 @@ int cifs_get_inode_info(struct inode **pinode,
fattr.cf_uniqueid = iunique(sb, ROOT_I);
}
} else {
fattr.cf_uniqueid = CIFS_I(*pinode)->uniqueid;
fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid;
}
/* query for SFU type info if supported and needed */
......@@ -711,8 +693,7 @@ int cifs_get_inode_info(struct inode **pinode,
#ifdef CONFIG_CIFS_ACL
/* fill in 0777 bits from ACL */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path,
pfid);
rc = cifs_acl_to_fattr(cifs_sb, &fattr, *inode, full_path, fid);
if (rc) {
cFYI(1, "%s: Getting ACL failed with error: %d",
__func__, rc);
......@@ -732,12 +713,12 @@ int cifs_get_inode_info(struct inode **pinode,
cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
}
if (!*pinode) {
*pinode = cifs_iget(sb, &fattr);
if (!*pinode)
if (!*inode) {
*inode = cifs_iget(sb, &fattr);
if (!*inode)
rc = -ENOMEM;
} else {
cifs_fattr_to_inode(*pinode, &fattr);
cifs_fattr_to_inode(*inode, &fattr);
}
cgii_exit:
......@@ -750,38 +731,6 @@ static const struct inode_operations cifs_ipc_inode_ops = {
.lookup = cifs_lookup,
};
char *cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
struct cifs_tcon *tcon)
{
int pplen = vol->prepath ? strlen(vol->prepath) : 0;
int dfsplen;
char *full_path = NULL;
/* if no prefix path, simply set path to the root of share to "" */
if (pplen == 0) {
full_path = kmalloc(1, GFP_KERNEL);
if (full_path)
full_path[0] = 0;
return full_path;
}
if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
else
dfsplen = 0;
full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL);
if (full_path == NULL)
return full_path;
if (dfsplen)
strncpy(full_path, tcon->treeName, dfsplen);
strncpy(full_path + dfsplen, vol->prepath, pplen);
convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
full_path[dfsplen + pplen] = 0; /* add trailing null */
return full_path;
}
static int
cifs_find_inode(struct inode *inode, void *opaque)
{
......@@ -886,13 +835,13 @@ cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
/* gets root inode */
struct inode *cifs_root_iget(struct super_block *sb)
{
int xid;
unsigned int xid;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct inode *inode = NULL;
long rc;
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
xid = GetXid();
xid = get_xid();
if (tcon->unix_ext)
rc = cifs_get_inode_info_unix(&inode, "", sb, xid);
else
......@@ -922,15 +871,15 @@ struct inode *cifs_root_iget(struct super_block *sb)
}
out:
/* can not call macro FreeXid here since in a void func
/* can not call macro free_xid here since in a void func
* TODO: This is no longer true
*/
_FreeXid(xid);
_free_xid(xid);
return inode;
}
static int
cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
cifs_set_file_info(struct inode *inode, struct iattr *attrs, unsigned int xid,
char *full_path, __u32 dosattr)
{
int rc;
......@@ -1051,7 +1000,8 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
* anything else.
*/
static int
cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
cifs_rename_pending_delete(char *full_path, struct dentry *dentry,
unsigned int xid)
{
int oplock = 0;
int rc;
......@@ -1171,7 +1121,7 @@ cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
int cifs_unlink(struct inode *dir, struct dentry *dentry)
{
int rc = 0;
int xid;
unsigned int xid;
char *full_path = NULL;
struct inode *inode = dentry->d_inode;
struct cifsInodeInfo *cifs_inode;
......@@ -1189,7 +1139,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
return PTR_ERR(tlink);
tcon = tlink_tcon(tlink);
xid = GetXid();
xid = get_xid();
/* Unlink can be called from rename so we can not take the
* sb->s_vfs_rename_mutex here */
......@@ -1199,9 +1149,8 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
goto unlink_out;
}
if ((tcon->ses->capabilities & CAP_UNIX) &&
(CIFS_UNIX_POSIX_PATH_OPS_CAP &
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
rc = CIFSPOSIXDelFile(xid, tcon, full_path,
SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
......@@ -1265,7 +1214,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
unlink_out:
kfree(full_path);
kfree(attrs);
FreeXid(xid);
free_xid(xid);
cifs_put_tlink(tlink);
return rc;
}
......@@ -1273,10 +1222,10 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
{
int rc = 0, tmprc;
int xid;
unsigned int xid;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
struct cifs_tcon *pTcon;
struct cifs_tcon *tcon;
char *full_path = NULL;
struct inode *newinode = NULL;
struct cifs_fattr fattr;
......@@ -1287,9 +1236,9 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
return PTR_ERR(tlink);
pTcon = tlink_tcon(tlink);
tcon = tlink_tcon(tlink);
xid = GetXid();
xid = get_xid();
full_path = build_path_from_dentry(direntry);
if (full_path == NULL) {
......@@ -1297,9 +1246,8 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
goto mkdir_out;
}
if ((pTcon->ses->capabilities & CAP_UNIX) &&
(CIFS_UNIX_POSIX_PATH_OPS_CAP &
le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
u32 oplock = 0;
FILE_UNIX_BASIC_INFO *pInfo =
kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
......@@ -1309,7 +1257,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
}
mode &= ~current_umask();
rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
rc = CIFSPOSIXCreate(xid, tcon, SMB_O_DIRECTORY | SMB_O_CREAT,
mode, NULL /* netfid */, pInfo, &oplock,
full_path, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
......@@ -1353,14 +1301,14 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
}
mkdir_retry_old:
/* BB add setting the equivalent of mode via CreateX w/ACLs */
rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
rc = CIFSSMBMkDir(xid, tcon, full_path, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc) {
cFYI(1, "cifs_mkdir returned 0x%x", rc);
d_drop(direntry);
} else {
mkdir_get_info:
if (pTcon->unix_ext)
if (tcon->unix_ext)
rc = cifs_get_inode_info_unix(&newinode, full_path,
inode->i_sb, xid);
else
......@@ -1378,7 +1326,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
if (inode->i_mode & S_ISGID)
mode |= S_ISGID;
if (pTcon->unix_ext) {
if (tcon->unix_ext) {
struct cifs_unix_set_info_args args = {
.mode = mode,
.ctime = NO_CHANGE_64,
......@@ -1396,7 +1344,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
args.uid = NO_CHANGE_64;
args.gid = NO_CHANGE_64;
}
CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args,
cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
......@@ -1411,7 +1359,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
cifsInode = CIFS_I(newinode);
dosattrs = cifsInode->cifsAttrs|ATTR_READONLY;
pInfo.Attributes = cpu_to_le32(dosattrs);
tmprc = CIFSSMBSetPathInfo(xid, pTcon,
tmprc = CIFSSMBSetPathInfo(xid, tcon,
full_path, &pInfo,
cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
......@@ -1446,7 +1394,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
*/
CIFS_I(inode)->time = 0;
kfree(full_path);
FreeXid(xid);
free_xid(xid);
cifs_put_tlink(tlink);
return rc;
}
......@@ -1454,7 +1402,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
int cifs_rmdir(struct inode *inode, struct dentry *direntry)
{
int rc = 0;
int xid;
unsigned int xid;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
struct cifs_tcon *pTcon;
......@@ -1463,7 +1411,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
cFYI(1, "cifs_rmdir, inode = 0x%p", inode);
xid = GetXid();
xid = get_xid();
full_path = build_path_from_dentry(direntry);
if (full_path == NULL) {
......@@ -1506,13 +1454,14 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
rmdir_exit:
kfree(full_path);
FreeXid(xid);
free_xid(xid);
return rc;
}
static int
cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
struct dentry *to_dentry, const char *toPath)
cifs_do_rename(unsigned int xid, struct dentry *from_dentry,
const char *fromPath, struct dentry *to_dentry,
const char *toPath)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb);
struct tcon_link *tlink;
......@@ -1571,7 +1520,8 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
struct cifs_tcon *tcon;
FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
FILE_UNIX_BASIC_INFO *info_buf_target;
int xid, rc, tmprc;
unsigned int xid;
int rc, tmprc;
cifs_sb = CIFS_SB(source_dir->i_sb);
tlink = cifs_sb_tlink(cifs_sb);
......@@ -1579,7 +1529,7 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
return PTR_ERR(tlink);
tcon = tlink_tcon(tlink);
xid = GetXid();
xid = get_xid();
/*
* we already have the rename sem so we do not need to
......@@ -1652,7 +1602,7 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
kfree(info_buf_source);
kfree(fromName);
kfree(toName);
FreeXid(xid);
free_xid(xid);
cifs_put_tlink(tlink);
return rc;
}
......@@ -1727,7 +1677,7 @@ int cifs_revalidate_file_attr(struct file *filp)
int cifs_revalidate_dentry_attr(struct dentry *dentry)
{
int xid;
unsigned int xid;
int rc = 0;
struct inode *inode = dentry->d_inode;
struct super_block *sb = dentry->d_sb;
......@@ -1739,7 +1689,7 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
if (!cifs_inode_needs_reval(inode))
return rc;
xid = GetXid();
xid = get_xid();
/* can not safely grab the rename sem here if rename calls revalidate
since that would deadlock */
......@@ -1761,7 +1711,7 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
out:
kfree(full_path);
FreeXid(xid);
free_xid(xid);
return rc;
}
......@@ -1869,7 +1819,7 @@ static void cifs_setsize(struct inode *inode, loff_t offset)
static int
cifs_set_file_size(struct inode *inode, struct iattr *attrs,
int xid, char *full_path)
unsigned int xid, char *full_path)
{
int rc;
struct cifsFileInfo *open_file;
......@@ -1971,7 +1921,7 @@ static int
cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
{
int rc;
int xid;
unsigned int xid;
char *full_path = NULL;
struct inode *inode = direntry->d_inode;
struct cifsInodeInfo *cifsInode = CIFS_I(inode);
......@@ -1984,7 +1934,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
cFYI(1, "setattr_unix on file %s attrs->ia_valid=0x%x",
direntry->d_name.name, attrs->ia_valid);
xid = GetXid();
xid = get_xid();
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
attrs->ia_valid |= ATTR_FORCE;
......@@ -2104,14 +2054,14 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
out:
kfree(args);
kfree(full_path);
FreeXid(xid);
free_xid(xid);
return rc;
}
static int
cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
{
int xid;
unsigned int xid;
uid_t uid = NO_CHANGE_32;
gid_t gid = NO_CHANGE_32;
struct inode *inode = direntry->d_inode;
......@@ -2122,7 +2072,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
__u32 dosattr = 0;
__u64 mode = NO_CHANGE_64;
xid = GetXid();
xid = get_xid();
cFYI(1, "setattr on file %s attrs->iavalid 0x%x",
direntry->d_name.name, attrs->ia_valid);
......@@ -2132,14 +2082,14 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
rc = inode_change_ok(inode, attrs);
if (rc < 0) {
FreeXid(xid);
free_xid(xid);
return rc;
}
full_path = build_path_from_dentry(direntry);
if (full_path == NULL) {
rc = -ENOMEM;
FreeXid(xid);
free_xid(xid);
return rc;
}
......@@ -2265,7 +2215,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
cifs_setattr_exit:
kfree(full_path);
FreeXid(xid);
free_xid(xid);
return rc;
}
......
......@@ -34,7 +34,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
{
struct inode *inode = filep->f_dentry->d_inode;
int rc = -ENOTTY; /* strange error - but the precedent */
int xid;
unsigned int xid;
struct cifs_sb_info *cifs_sb;
#ifdef CONFIG_CIFS_POSIX
struct cifsFileInfo *pSMBFile = filep->private_data;
......@@ -44,7 +44,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
__u64 caps;
#endif /* CONFIG_CIFS_POSIX */
xid = GetXid();
xid = get_xid();
cFYI(1, "ioctl file %p cmd %u arg %lu", filep, command, arg);
......@@ -105,6 +105,6 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
break;
}
FreeXid(xid);
free_xid(xid);
return rc;
}
......@@ -56,14 +56,14 @@ symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash)
md5 = crypto_alloc_shash("md5", 0, 0);
if (IS_ERR(md5)) {
rc = PTR_ERR(md5);
cERROR(1, "%s: Crypto md5 allocation error %d\n", __func__, rc);
cERROR(1, "%s: Crypto md5 allocation error %d", __func__, rc);
return rc;
}
size = sizeof(struct shash_desc) + crypto_shash_descsize(md5);
sdescmd5 = kmalloc(size, GFP_KERNEL);
if (!sdescmd5) {
rc = -ENOMEM;
cERROR(1, "%s: Memory allocation failure\n", __func__);
cERROR(1, "%s: Memory allocation failure", __func__);
goto symlink_hash_err;
}
sdescmd5->shash.tfm = md5;
......@@ -71,17 +71,17 @@ symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash)
rc = crypto_shash_init(&sdescmd5->shash);
if (rc) {
cERROR(1, "%s: Could not init md5 shash\n", __func__);
cERROR(1, "%s: Could not init md5 shash", __func__);
goto symlink_hash_err;
}
rc = crypto_shash_update(&sdescmd5->shash, link_str, link_len);
if (rc) {
cERROR(1, "%s: Could not update iwth link_str\n", __func__);
cERROR(1, "%s: Could not update iwth link_str", __func__);
goto symlink_hash_err;
}
rc = crypto_shash_final(&sdescmd5->shash, md5_hash);
if (rc)
cERROR(1, "%s: Could not generate md5 hash\n", __func__);
cERROR(1, "%s: Could not generate md5 hash", __func__);
symlink_hash_err:
crypto_free_shash(md5);
......@@ -115,7 +115,7 @@ CIFSParseMFSymlink(const u8 *buf,
rc = symlink_hash(link_len, link_str, md5_hash);
if (rc) {
cFYI(1, "%s: MD5 hash failure: %d\n", __func__, rc);
cFYI(1, "%s: MD5 hash failure: %d", __func__, rc);
return rc;
}
......@@ -154,7 +154,7 @@ CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
rc = symlink_hash(link_len, link_str, md5_hash);
if (rc) {
cFYI(1, "%s: MD5 hash failure: %d\n", __func__, rc);
cFYI(1, "%s: MD5 hash failure: %d", __func__, rc);
return rc;
}
......@@ -181,7 +181,7 @@ CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
}
static int
CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
CIFSCreateMFSymLink(const unsigned int xid, struct cifs_tcon *tcon,
const char *fromName, const char *toName,
struct cifs_sb_info *cifs_sb)
{
......@@ -238,7 +238,7 @@ CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
}
static int
CIFSQueryMFSymLink(const int xid, struct cifs_tcon *tcon,
CIFSQueryMFSymLink(const unsigned int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, char **symlinkinfo,
const struct nls_table *nls_codepage, int remap)
{
......@@ -307,7 +307,7 @@ CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr)
int
CIFSCheckMFSymlink(struct cifs_fattr *fattr,
const unsigned char *path,
struct cifs_sb_info *cifs_sb, int xid)
struct cifs_sb_info *cifs_sb, unsigned int xid)
{
int rc;
int oplock = 0;
......@@ -390,7 +390,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
struct dentry *direntry)
{
int rc = -EACCES;
int xid;
unsigned int xid;
char *fromName = NULL;
char *toName = NULL;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
......@@ -403,7 +403,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
return PTR_ERR(tlink);
pTcon = tlink_tcon(tlink);
xid = GetXid();
xid = get_xid();
fromName = build_path_from_dentry(old_file);
toName = build_path_from_dentry(direntry);
......@@ -455,7 +455,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
cifs_hl_exit:
kfree(fromName);
kfree(toName);
FreeXid(xid);
free_xid(xid);
cifs_put_tlink(tlink);
return rc;
}
......@@ -465,14 +465,14 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
{
struct inode *inode = direntry->d_inode;
int rc = -ENOMEM;
int xid;
unsigned int xid;
char *full_path = NULL;
char *target_path = NULL;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink = NULL;
struct cifs_tcon *tcon;
xid = GetXid();
xid = get_xid();
tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink)) {
......@@ -495,8 +495,8 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
* but there doesn't seem to be any harm in allowing the client to
* read them.
*/
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
&& !(tcon->ses->capabilities & CAP_UNIX)) {
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) &&
!cap_unix(tcon->ses)) {
rc = -EACCES;
goto out;
}
......@@ -518,7 +518,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
if ((rc != 0) && (tcon->ses->capabilities & CAP_UNIX))
if ((rc != 0) && cap_unix(tcon->ses))
rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
cifs_sb->local_nls);
......@@ -529,7 +529,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
target_path = ERR_PTR(rc);
}
FreeXid(xid);
free_xid(xid);
if (tlink)
cifs_put_tlink(tlink);
nd_set_link(nd, target_path);
......@@ -540,14 +540,14 @@ int
cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
{
int rc = -EOPNOTSUPP;
int xid;
unsigned int xid;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink;
struct cifs_tcon *pTcon;
char *full_path = NULL;
struct inode *newinode = NULL;
xid = GetXid();
xid = get_xid();
tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink)) {
......@@ -594,7 +594,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
symlink_exit:
kfree(full_path);
cifs_put_tlink(tlink);
FreeXid(xid);
free_xid(xid);
return rc;
}
......
......@@ -29,6 +29,9 @@
#include "smberr.h"
#include "nterr.h"
#include "cifs_unicode.h"
#ifdef CONFIG_CIFS_SMB2
#include "smb2pdu.h"
#endif
extern mempool_t *cifs_sm_req_poolp;
extern mempool_t *cifs_req_poolp;
......@@ -40,7 +43,7 @@ extern mempool_t *cifs_req_poolp;
since the cifs fs was mounted */
unsigned int
_GetXid(void)
_get_xid(void)
{
unsigned int xid;
......@@ -58,7 +61,7 @@ _GetXid(void)
}
void
_FreeXid(unsigned int xid)
_free_xid(unsigned int xid)
{
spin_lock(&GlobalMid_Lock);
/* if (GlobalTotalActiveXid == 0)
......@@ -143,17 +146,27 @@ struct smb_hdr *
cifs_buf_get(void)
{
struct smb_hdr *ret_buf = NULL;
/* We could use negotiated size instead of max_msgsize -
but it may be more efficient to always alloc same size
albeit slightly larger than necessary and maxbuffersize
defaults to this and can not be bigger */
size_t buf_size = sizeof(struct smb_hdr);
#ifdef CONFIG_CIFS_SMB2
/*
* SMB2 header is bigger than CIFS one - no problems to clean some
* more bytes for CIFS.
*/
buf_size = sizeof(struct smb2_hdr);
#endif
/*
* We could use negotiated size instead of max_msgsize -
* but it may be more efficient to always alloc same size
* albeit slightly larger than necessary and maxbuffersize
* defaults to this and can not be bigger.
*/
ret_buf = mempool_alloc(cifs_req_poolp, GFP_NOFS);
/* clear the first few header bytes */
/* for most paths, more is cleared in header_assemble */
if (ret_buf) {
memset(ret_buf, 0, sizeof(struct smb_hdr) + 3);
memset(ret_buf, 0, buf_size + 3);
atomic_inc(&bufAllocCount);
#ifdef CONFIG_CIFS_STATS2
atomic_inc(&totBufAllocCount);
......@@ -448,7 +461,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
if (tcon->tid != buf->Tid)
continue;
cifs_stats_inc(&tcon->num_oplock_brks);
cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks);
spin_lock(&cifs_file_list_lock);
list_for_each(tmp2, &tcon->openFileList) {
netfile = list_entry(tmp2, struct cifsFileInfo,
......
......@@ -31,7 +31,7 @@ const struct nt_err_code_struct nt_errs[] = {
{"NT_STATUS_INVALID_INFO_CLASS", NT_STATUS_INVALID_INFO_CLASS},
{"NT_STATUS_INFO_LENGTH_MISMATCH", NT_STATUS_INFO_LENGTH_MISMATCH},
{"NT_STATUS_ACCESS_VIOLATION", NT_STATUS_ACCESS_VIOLATION},
{"STATUS_BUFFER_OVERFLOW", STATUS_BUFFER_OVERFLOW},
{"NT_STATUS_BUFFER_OVERFLOW", NT_STATUS_BUFFER_OVERFLOW},
{"NT_STATUS_IN_PAGE_ERROR", NT_STATUS_IN_PAGE_ERROR},
{"NT_STATUS_PAGEFILE_QUOTA", NT_STATUS_PAGEFILE_QUOTA},
{"NT_STATUS_INVALID_HANDLE", NT_STATUS_INVALID_HANDLE},
......@@ -681,7 +681,7 @@ const struct nt_err_code_struct nt_errs[] = {
NT_STATUS_QUOTA_LIST_INCONSISTENT},
{"NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE},
{"NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES},
{"STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES},
{"STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED},
{"NT_STATUS_MORE_ENTRIES", NT_STATUS_MORE_ENTRIES},
{"NT_STATUS_SOME_UNMAPPED", NT_STATUS_SOME_UNMAPPED},
{NULL, 0}
};
......@@ -35,18 +35,20 @@ struct nt_err_code_struct {
extern const struct nt_err_code_struct nt_errs[];
/* Win32 Status codes. */
#define STATUS_MORE_ENTRIES 0x0105
#define ERROR_INVALID_PARAMETER 0x0057
#define ERROR_INSUFFICIENT_BUFFER 0x007a
#define STATUS_1804 0x070c
#define STATUS_NOTIFY_ENUM_DIR 0x010c
#define NT_STATUS_MORE_ENTRIES 0x0105
#define NT_ERROR_INVALID_PARAMETER 0x0057
#define NT_ERROR_INSUFFICIENT_BUFFER 0x007a
#define NT_STATUS_1804 0x070c
#define NT_STATUS_NOTIFY_ENUM_DIR 0x010c
/* Win32 Error codes extracted using a loop in smbclient then printing a
netmon sniff to a file. */
/*
* Win32 Error codes extracted using a loop in smbclient then printing a netmon
* sniff to a file.
*/
#define NT_STATUS_OK 0x0000
#define STATUS_SOME_UNMAPPED 0x0107
#define STATUS_BUFFER_OVERFLOW 0x80000005
#define NT_STATUS_OK 0x0000
#define NT_STATUS_SOME_UNMAPPED 0x0107
#define NT_STATUS_BUFFER_OVERFLOW 0x80000005
#define NT_STATUS_NO_MORE_ENTRIES 0x8000001a
#define NT_STATUS_MEDIA_CHANGED 0x8000001c
#define NT_STATUS_END_OF_MEDIA 0x8000001e
......
......@@ -126,3 +126,13 @@ typedef struct _AUTHENTICATE_MESSAGE {
do not set the version is present flag */
char UserString[0];
} __attribute__((packed)) AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE;
/*
* Size of the session key (crypto key encrypted with the password
*/
int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, struct cifs_ses *ses);
void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, struct cifs_ses *ses);
int build_ntlmssp_auth_blob(unsigned char *pbuffer, u16 *buflen,
struct cifs_ses *ses,
const struct nls_table *nls_cp);
此差异已折叠。
......@@ -364,7 +364,7 @@ static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
return rc;
}
static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
struct cifs_ses *ses)
{
unsigned int tioffset; /* challenge message target info area */
......@@ -415,7 +415,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,
void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
struct cifs_ses *ses)
{
NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
......@@ -451,7 +451,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
/* We do not malloc the blob, it is passed in pbuffer, because its
maximum possible size is fixed and small, making this approach cleaner.
This function returns the length of the data in the blob */
static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
int build_ntlmssp_auth_blob(unsigned char *pbuffer,
u16 *buflen,
struct cifs_ses *ses,
const struct nls_table *nls_cp)
......@@ -556,7 +556,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
}
int
CIFS_SessSetup(unsigned int xid, struct cifs_ses *ses,
CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
const struct nls_table *nls_cp)
{
int rc = 0;
......@@ -898,7 +898,7 @@ CIFS_SessSetup(unsigned int xid, struct cifs_ses *ses,
if (action & GUEST_LOGIN)
cFYI(1, "Guest login"); /* BB mark SesInfo struct? */
ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */
cFYI(1, "UID = %d ", ses->Suid);
cFYI(1, "UID = %llu ", ses->Suid);
/* response can have either 3 or 4 word count - Samba sends 3 */
/* and lanman response is 3 */
bytes_remaining = get_bcc(smb_buf);
......@@ -938,7 +938,7 @@ CIFS_SessSetup(unsigned int xid, struct cifs_ses *ses,
ssetup_exit:
if (spnego_key) {
key_revoke(spnego_key);
key_invalidate(spnego_key);
key_put(spnego_key);
}
kfree(str_area);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册