提交 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,7 +549,7 @@ 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,
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,11 +576,13 @@ 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;
union {
struct {
atomic_t num_writes;
atomic_t num_reads;
atomic_t num_flushes;
......@@ -513,6 +604,14 @@ struct cifs_tcon {
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,8 +1149,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
goto unlink_out;
}
if ((tcon->ses->capabilities & CAP_UNIX) &&
(CIFS_UNIX_POSIX_PATH_OPS_CAP &
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,
......@@ -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;
size_t buf_size = sizeof(struct smb_hdr);
/* 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 */
#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_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);
......@@ -193,7 +193,7 @@ cifs_std_info_to_fattr(struct cifs_fattr *fattr, FIND_FILE_STANDARD_INFO *info,
we try to do FindFirst on (NTFS) directory symlinks */
/*
int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb,
int xid)
unsigned int xid)
{
__u16 fid;
int len;
......@@ -220,7 +220,7 @@ int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb,
}
*/
static int initiate_cifs_search(const int xid, struct file *file)
static int initiate_cifs_search(const unsigned int xid, struct file *file)
{
__u16 search_flags;
int rc = 0;
......@@ -228,7 +228,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 cifs_tcon *pTcon;
struct cifs_tcon *tcon;
if (file->private_data == NULL) {
tlink = cifs_sb_tlink(cifs_sb);
......@@ -242,10 +242,10 @@ static int initiate_cifs_search(const int xid, struct file *file)
}
file->private_data = cifsFile;
cifsFile->tlink = cifs_get_tlink(tlink);
pTcon = tlink_tcon(tlink);
tcon = tlink_tcon(tlink);
} else {
cifsFile = file->private_data;
pTcon = tlink_tcon(cifsFile->tlink);
tcon = tlink_tcon(cifsFile->tlink);
}
cifsFile->invalidHandle = true;
......@@ -262,11 +262,11 @@ static int initiate_cifs_search(const int xid, struct file *file)
ffirst_retry:
/* test for Unix extensions */
/* but now check for them on the share/mount not on the SMB session */
/* if (pTcon->ses->capabilities & CAP_UNIX) { */
if (pTcon->unix_ext)
/* if (cap_unix(tcon->ses) { */
if (tcon->unix_ext)
cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX;
else if ((pTcon->ses->capabilities &
(CAP_NT_SMBS | CAP_NT_FIND)) == 0) {
else if ((tcon->ses->capabilities &
tcon->ses->server->vals->cap_nt_find) == 0) {
cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD;
} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
cifsFile->srch_inf.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO;
......@@ -278,7 +278,7 @@ static int initiate_cifs_search(const int xid, struct file *file)
if (backup_cred(cifs_sb))
search_flags |= CIFS_SEARCH_BACKUP_SEARCH;
rc = CIFSFindFirst(xid, pTcon, full_path, cifs_sb->local_nls,
rc = CIFSFindFirst(xid, tcon, full_path, cifs_sb->local_nls,
&cifsFile->netfid, search_flags, &cifsFile->srch_inf,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
......@@ -507,7 +507,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 cifs_tcon *pTcon,
static int find_cifs_entry(const unsigned int xid, struct cifs_tcon *pTcon,
struct file *file, char **ppCurrentEntry, int *num_to_ret)
{
__u16 search_flags;
......@@ -721,7 +721,8 @@ static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
{
int rc = 0;
int xid, i;
unsigned int xid;
int i;
struct cifs_tcon *pTcon;
struct cifsFileInfo *cifsFile = NULL;
char *current_entry;
......@@ -730,7 +731,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
char *end_of_smb;
unsigned int max_len;
xid = GetXid();
xid = get_xid();
/*
* Ensure FindFirst doesn't fail before doing filldir() for '.' and
......@@ -768,7 +769,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
if (file->private_data == NULL) {
rc = -EINVAL;
FreeXid(xid);
free_xid(xid);
return rc;
}
cifsFile = file->private_data;
......@@ -840,6 +841,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
} /* end switch */
rddir2_exit:
FreeXid(xid);
free_xid(xid);
return rc;
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册