提交 c7ce227a 编写于 作者: N Namjae Jeon 提交者: Zhong Jinghua

cifsd: Alignment should match open parenthesis

mainline inclusion
from mainline-5.15-rc1
commit 070fb21e
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I60T7G
CVE: NA

Reference: https://git.kernel.org/torvalds/linux/c/070fb21e5912

-------------------------------

Fix warnings "Alignment should match open parenthesis" from
checkpatch.pl --strict.
Signed-off-by: NNamjae Jeon <namjae.jeon@samsung.com>
Signed-off-by: NSteve French <stfrench@microsoft.com>
Signed-off-by: NJason Yan <yanaijie@huawei.com>
Signed-off-by: NZhong Jinghua <zhongjinghua@huawei.com>
上级 c80d7e9f
...@@ -37,7 +37,7 @@ static char NTLMSSP_OID_STR[NTLMSSP_OID_LEN] = { 0x2b, 0x06, 0x01, 0x04, 0x01, ...@@ -37,7 +37,7 @@ static char NTLMSSP_OID_STR[NTLMSSP_OID_LEN] = { 0x2b, 0x06, 0x01, 0x04, 0x01,
static bool static bool
asn1_subid_decode(const unsigned char **begin, const unsigned char *end, asn1_subid_decode(const unsigned char **begin, const unsigned char *end,
unsigned long *subid) unsigned long *subid)
{ {
const unsigned char *ptr = *begin; const unsigned char *ptr = *begin;
unsigned char ch; unsigned char ch;
...@@ -58,7 +58,7 @@ asn1_subid_decode(const unsigned char **begin, const unsigned char *end, ...@@ -58,7 +58,7 @@ asn1_subid_decode(const unsigned char **begin, const unsigned char *end,
} }
static bool asn1_oid_decode(const unsigned char *value, size_t vlen, static bool asn1_oid_decode(const unsigned char *value, size_t vlen,
unsigned long **oid, size_t *oidlen) unsigned long **oid, size_t *oidlen)
{ {
const unsigned char *iptr = value, *end = value + vlen; const unsigned char *iptr = value, *end = value + vlen;
unsigned long *optr; unsigned long *optr;
...@@ -106,9 +106,8 @@ static bool asn1_oid_decode(const unsigned char *value, size_t vlen, ...@@ -106,9 +106,8 @@ static bool asn1_oid_decode(const unsigned char *value, size_t vlen,
return false; return false;
} }
static bool static bool oid_eq(unsigned long *oid1, unsigned int oid1len,
oid_eq(unsigned long *oid1, unsigned int oid1len, unsigned long *oid2, unsigned int oid2len)
unsigned long *oid2, unsigned int oid2len)
{ {
if (oid1len != oid2len) if (oid1len != oid2len)
return false; return false;
...@@ -118,7 +117,7 @@ oid_eq(unsigned long *oid1, unsigned int oid1len, ...@@ -118,7 +117,7 @@ oid_eq(unsigned long *oid1, unsigned int oid1len,
int int
ksmbd_decode_negTokenInit(unsigned char *security_blob, int length, ksmbd_decode_negTokenInit(unsigned char *security_blob, int length,
struct ksmbd_conn *conn) struct ksmbd_conn *conn)
{ {
return asn1_ber_decoder(&spnego_negtokeninit_decoder, conn, return asn1_ber_decoder(&spnego_negtokeninit_decoder, conn,
security_blob, length); security_blob, length);
...@@ -126,7 +125,7 @@ ksmbd_decode_negTokenInit(unsigned char *security_blob, int length, ...@@ -126,7 +125,7 @@ ksmbd_decode_negTokenInit(unsigned char *security_blob, int length,
int int
ksmbd_decode_negTokenTarg(unsigned char *security_blob, int length, ksmbd_decode_negTokenTarg(unsigned char *security_blob, int length,
struct ksmbd_conn *conn) struct ksmbd_conn *conn)
{ {
return asn1_ber_decoder(&spnego_negtokentarg_decoder, conn, return asn1_ber_decoder(&spnego_negtokentarg_decoder, conn,
security_blob, length); security_blob, length);
...@@ -146,10 +145,7 @@ static int compute_asn_hdr_len_bytes(int len) ...@@ -146,10 +145,7 @@ static int compute_asn_hdr_len_bytes(int len)
return 0; return 0;
} }
static void encode_asn_tag(char *buf, static void encode_asn_tag(char *buf, unsigned int *ofs, char tag, char seq,
unsigned int *ofs,
char tag,
char seq,
int length) int length)
{ {
int i; int i;
...@@ -184,7 +180,7 @@ static void encode_asn_tag(char *buf, ...@@ -184,7 +180,7 @@ static void encode_asn_tag(char *buf,
} }
int build_spnego_ntlmssp_neg_blob(unsigned char **pbuffer, u16 *buflen, int build_spnego_ntlmssp_neg_blob(unsigned char **pbuffer, u16 *buflen,
char *ntlm_blob, int ntlm_blob_len) char *ntlm_blob, int ntlm_blob_len)
{ {
char *buf; char *buf;
unsigned int ofs = 0; unsigned int ofs = 0;
...@@ -225,7 +221,7 @@ int build_spnego_ntlmssp_neg_blob(unsigned char **pbuffer, u16 *buflen, ...@@ -225,7 +221,7 @@ int build_spnego_ntlmssp_neg_blob(unsigned char **pbuffer, u16 *buflen,
} }
int build_spnego_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen, int build_spnego_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen,
int neg_result) int neg_result)
{ {
char *buf; char *buf;
unsigned int ofs = 0; unsigned int ofs = 0;
...@@ -252,8 +248,8 @@ int build_spnego_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen, ...@@ -252,8 +248,8 @@ int build_spnego_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen,
return 0; return 0;
} }
int gssapi_this_mech(void *context, size_t hdrlen, int gssapi_this_mech(void *context, size_t hdrlen, unsigned char tag,
unsigned char tag, const void *value, size_t vlen) const void *value, size_t vlen)
{ {
unsigned long *oid; unsigned long *oid;
size_t oidlen; size_t oidlen;
...@@ -277,8 +273,8 @@ int gssapi_this_mech(void *context, size_t hdrlen, ...@@ -277,8 +273,8 @@ int gssapi_this_mech(void *context, size_t hdrlen,
return err; return err;
} }
int neg_token_init_mech_type(void *context, size_t hdrlen, int neg_token_init_mech_type(void *context, size_t hdrlen, unsigned char tag,
unsigned char tag, const void *value, size_t vlen) const void *value, size_t vlen)
{ {
struct ksmbd_conn *conn = context; struct ksmbd_conn *conn = context;
unsigned long *oid; unsigned long *oid;
...@@ -314,8 +310,8 @@ int neg_token_init_mech_type(void *context, size_t hdrlen, ...@@ -314,8 +310,8 @@ int neg_token_init_mech_type(void *context, size_t hdrlen,
return -EBADMSG; return -EBADMSG;
} }
int neg_token_init_mech_token(void *context, size_t hdrlen, int neg_token_init_mech_token(void *context, size_t hdrlen, unsigned char tag,
unsigned char tag, const void *value, size_t vlen) const void *value, size_t vlen)
{ {
struct ksmbd_conn *conn = context; struct ksmbd_conn *conn = context;
...@@ -328,8 +324,8 @@ int neg_token_init_mech_token(void *context, size_t hdrlen, ...@@ -328,8 +324,8 @@ int neg_token_init_mech_token(void *context, size_t hdrlen,
return 0; return 0;
} }
int neg_token_targ_resp_token(void *context, size_t hdrlen, int neg_token_targ_resp_token(void *context, size_t hdrlen, unsigned char tag,
unsigned char tag, const void *value, size_t vlen) const void *value, size_t vlen)
{ {
struct ksmbd_conn *conn = context; struct ksmbd_conn *conn = context;
......
...@@ -10,20 +10,12 @@ ...@@ -10,20 +10,12 @@
#ifndef __ASN1_H__ #ifndef __ASN1_H__
#define __ASN1_H__ #define __ASN1_H__
int ksmbd_decode_negTokenInit(unsigned char *security_blob, int ksmbd_decode_negTokenInit(unsigned char *security_blob, int length,
int length,
struct ksmbd_conn *conn); struct ksmbd_conn *conn);
int ksmbd_decode_negTokenTarg(unsigned char *security_blob, int length,
int ksmbd_decode_negTokenTarg(unsigned char *security_blob,
int length,
struct ksmbd_conn *conn); struct ksmbd_conn *conn);
int build_spnego_ntlmssp_neg_blob(unsigned char **pbuffer, u16 *buflen,
int build_spnego_ntlmssp_neg_blob(unsigned char **pbuffer, char *ntlm_blob, int ntlm_blob_len);
u16 *buflen, int build_spnego_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen,
char *ntlm_blob,
int ntlm_blob_len);
int build_spnego_ntlmssp_auth_blob(unsigned char **pbuffer,
u16 *buflen,
int neg_result); int neg_result);
#endif /* __ASN1_H__ */ #endif /* __ASN1_H__ */
...@@ -93,8 +93,7 @@ smbhash(unsigned char *out, const unsigned char *in, unsigned char *key) ...@@ -93,8 +93,7 @@ smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
struct des_ctx ctx; struct des_ctx ctx;
if (fips_enabled) { if (fips_enabled) {
ksmbd_debug(AUTH, ksmbd_debug(AUTH, "FIPS compliance enabled: DES not permitted\n");
"FIPS compliance enabled: DES not permitted\n");
return -ENOENT; return -ENOENT;
} }
...@@ -120,7 +119,7 @@ static int ksmbd_enc_p24(unsigned char *p21, const unsigned char *c8, unsigned c ...@@ -120,7 +119,7 @@ static int ksmbd_enc_p24(unsigned char *p21, const unsigned char *c8, unsigned c
/* produce a md4 message digest from data of length n bytes */ /* produce a md4 message digest from data of length n bytes */
static int ksmbd_enc_md4(unsigned char *md4_hash, unsigned char *link_str, static int ksmbd_enc_md4(unsigned char *md4_hash, unsigned char *link_str,
int link_len) int link_len)
{ {
int rc; int rc;
struct ksmbd_crypto_ctx *ctx; struct ksmbd_crypto_ctx *ctx;
...@@ -152,7 +151,7 @@ static int ksmbd_enc_md4(unsigned char *md4_hash, unsigned char *link_str, ...@@ -152,7 +151,7 @@ static int ksmbd_enc_md4(unsigned char *md4_hash, unsigned char *link_str,
} }
static int ksmbd_enc_update_sess_key(unsigned char *md5_hash, char *nonce, static int ksmbd_enc_update_sess_key(unsigned char *md5_hash, char *nonce,
char *server_challenge, int len) char *server_challenge, int len)
{ {
int rc; int rc;
struct ksmbd_crypto_ctx *ctx; struct ksmbd_crypto_ctx *ctx;
...@@ -197,7 +196,7 @@ static int ksmbd_enc_update_sess_key(unsigned char *md5_hash, char *nonce, ...@@ -197,7 +196,7 @@ static int ksmbd_enc_update_sess_key(unsigned char *md5_hash, char *nonce,
* *
*/ */
static int ksmbd_gen_sess_key(struct ksmbd_session *sess, char *hash, static int ksmbd_gen_sess_key(struct ksmbd_session *sess, char *hash,
char *hmac) char *hmac)
{ {
struct ksmbd_crypto_ctx *ctx; struct ksmbd_crypto_ctx *ctx;
int rc; int rc;
...@@ -226,15 +225,13 @@ static int ksmbd_gen_sess_key(struct ksmbd_session *sess, char *hash, ...@@ -226,15 +225,13 @@ static int ksmbd_gen_sess_key(struct ksmbd_session *sess, char *hash,
hmac, hmac,
SMB2_NTLMV2_SESSKEY_SIZE); SMB2_NTLMV2_SESSKEY_SIZE);
if (rc) { if (rc) {
ksmbd_debug(AUTH, "Could not update with response error %d\n", ksmbd_debug(AUTH, "Could not update with response error %d\n", rc);
rc);
goto out; goto out;
} }
rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), sess->sess_key); rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), sess->sess_key);
if (rc) { if (rc) {
ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n", ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n", rc);
rc);
goto out; goto out;
} }
...@@ -244,7 +241,7 @@ static int ksmbd_gen_sess_key(struct ksmbd_session *sess, char *hash, ...@@ -244,7 +241,7 @@ static int ksmbd_gen_sess_key(struct ksmbd_session *sess, char *hash,
} }
static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash, static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
char *dname) char *dname)
{ {
int ret, len, conv_len; int ret, len, conv_len;
wchar_t *domain = NULL; wchar_t *domain = NULL;
...@@ -280,7 +277,7 @@ static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash, ...@@ -280,7 +277,7 @@ static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
} }
conv_len = smb_strtoUTF16(uniname, user_name(sess->user), len, conv_len = smb_strtoUTF16(uniname, user_name(sess->user), len,
sess->conn->local_nls); sess->conn->local_nls);
if (conv_len < 0 || conv_len > len) { if (conv_len < 0 || conv_len > len) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
...@@ -304,7 +301,7 @@ static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash, ...@@ -304,7 +301,7 @@ static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
} }
conv_len = smb_strtoUTF16((__le16 *)domain, dname, len, conv_len = smb_strtoUTF16((__le16 *)domain, dname, len,
sess->conn->local_nls); sess->conn->local_nls);
if (conv_len < 0 || conv_len > len) { if (conv_len < 0 || conv_len > len) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
...@@ -350,11 +347,10 @@ int ksmbd_auth_ntlm(struct ksmbd_session *sess, char *pw_buf) ...@@ -350,11 +347,10 @@ int ksmbd_auth_ntlm(struct ksmbd_session *sess, char *pw_buf)
return rc; return rc;
} }
ksmbd_enc_md4(sess->sess_key, ksmbd_enc_md4(sess->sess_key, user_passkey(sess->user),
user_passkey(sess->user), CIFS_SMB1_SESSKEY_SIZE);
CIFS_SMB1_SESSKEY_SIZE);
memcpy(sess->sess_key + CIFS_SMB1_SESSKEY_SIZE, key, memcpy(sess->sess_key + CIFS_SMB1_SESSKEY_SIZE, key,
CIFS_AUTH_RESP_SIZE); CIFS_AUTH_RESP_SIZE);
sess->sequence_number = 1; sess->sequence_number = 1;
if (strncmp(pw_buf, key, CIFS_AUTH_RESP_SIZE) != 0) { if (strncmp(pw_buf, key, CIFS_AUTH_RESP_SIZE) != 0) {
...@@ -376,7 +372,7 @@ int ksmbd_auth_ntlm(struct ksmbd_session *sess, char *pw_buf) ...@@ -376,7 +372,7 @@ int ksmbd_auth_ntlm(struct ksmbd_session *sess, char *pw_buf)
* Return: 0 on success, error number on error * Return: 0 on success, error number on error
*/ */
int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2, int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
int blen, char *domain_name) int blen, char *domain_name)
{ {
char ntlmv2_hash[CIFS_ENCPWD_SIZE]; char ntlmv2_hash[CIFS_ENCPWD_SIZE];
char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE]; char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
...@@ -455,7 +451,7 @@ int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2, ...@@ -455,7 +451,7 @@ int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
* Return: 0 on success, error number on error * Return: 0 on success, error number on error
*/ */
static int __ksmbd_auth_ntlmv2(struct ksmbd_session *sess, char *client_nonce, static int __ksmbd_auth_ntlmv2(struct ksmbd_session *sess, char *client_nonce,
char *ntlm_resp) char *ntlm_resp)
{ {
char sess_key[CIFS_SMB1_SESSKEY_SIZE] = {0}; char sess_key[CIFS_SMB1_SESSKEY_SIZE] = {0};
int rc; int rc;
...@@ -494,7 +490,7 @@ static int __ksmbd_auth_ntlmv2(struct ksmbd_session *sess, char *client_nonce, ...@@ -494,7 +490,7 @@ static int __ksmbd_auth_ntlmv2(struct ksmbd_session *sess, char *client_nonce,
* Return: 0 on success, error number on error * Return: 0 on success, error number on error
*/ */
int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob, int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
int blob_len, struct ksmbd_session *sess) int blob_len, struct ksmbd_session *sess)
{ {
char *domain_name; char *domain_name;
unsigned int lm_off, nt_off; unsigned int lm_off, nt_off;
...@@ -503,13 +499,13 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob, ...@@ -503,13 +499,13 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
if (blob_len < sizeof(struct authenticate_message)) { if (blob_len < sizeof(struct authenticate_message)) {
ksmbd_debug(AUTH, "negotiate blob len %d too small\n", ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
blob_len); blob_len);
return -EINVAL; return -EINVAL;
} }
if (memcmp(authblob->Signature, "NTLMSSP", 8)) { if (memcmp(authblob->Signature, "NTLMSSP", 8)) {
ksmbd_debug(AUTH, "blob signature incorrect %s\n", ksmbd_debug(AUTH, "blob signature incorrect %s\n",
authblob->Signature); authblob->Signature);
return -EINVAL; return -EINVAL;
} }
...@@ -538,11 +534,10 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob, ...@@ -538,11 +534,10 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
/* process NTLMv2 authentication */ /* process NTLMv2 authentication */
ksmbd_debug(AUTH, "decode_ntlmssp_authenticate_blob dname%s\n", ksmbd_debug(AUTH, "decode_ntlmssp_authenticate_blob dname%s\n",
domain_name); domain_name);
ret = ksmbd_auth_ntlmv2(sess, ret = ksmbd_auth_ntlmv2(sess, (struct ntlmv2_resp *)((char *)authblob + nt_off),
(struct ntlmv2_resp *)((char *)authblob + nt_off), nt_len - CIFS_ENCPWD_SIZE,
nt_len - CIFS_ENCPWD_SIZE, domain_name);
domain_name);
kfree(domain_name); kfree(domain_name);
return ret; return ret;
} }
...@@ -556,17 +551,17 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob, ...@@ -556,17 +551,17 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
* *
*/ */
int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob, int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
int blob_len, struct ksmbd_session *sess) int blob_len, struct ksmbd_session *sess)
{ {
if (blob_len < sizeof(struct negotiate_message)) { if (blob_len < sizeof(struct negotiate_message)) {
ksmbd_debug(AUTH, "negotiate blob len %d too small\n", ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
blob_len); blob_len);
return -EINVAL; return -EINVAL;
} }
if (memcmp(negblob->Signature, "NTLMSSP", 8)) { if (memcmp(negblob->Signature, "NTLMSSP", 8)) {
ksmbd_debug(AUTH, "blob signature incorrect %s\n", ksmbd_debug(AUTH, "blob signature incorrect %s\n",
negblob->Signature); negblob->Signature);
return -EINVAL; return -EINVAL;
} }
...@@ -584,7 +579,7 @@ int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob, ...@@ -584,7 +579,7 @@ int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
*/ */
unsigned int unsigned int
ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob, ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
struct ksmbd_session *sess) struct ksmbd_session *sess)
{ {
struct target_info *tinfo; struct target_info *tinfo;
wchar_t *name; wchar_t *name;
...@@ -623,7 +618,7 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob, ...@@ -623,7 +618,7 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
return -ENOMEM; return -ENOMEM;
conv_len = smb_strtoUTF16((__le16 *)name, ksmbd_netbios_name(), len, conv_len = smb_strtoUTF16((__le16 *)name, ksmbd_netbios_name(), len,
sess->conn->local_nls); sess->conn->local_nls);
if (conv_len < 0 || conv_len > len) { if (conv_len < 0 || conv_len > len) {
kfree(name); kfree(name);
return -EINVAL; return -EINVAL;
...@@ -641,7 +636,7 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob, ...@@ -641,7 +636,7 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
/* Initialize random conn challenge */ /* Initialize random conn challenge */
get_random_bytes(sess->ntlmssp.cryptkey, sizeof(__u64)); get_random_bytes(sess->ntlmssp.cryptkey, sizeof(__u64));
memcpy(chgblob->Challenge, sess->ntlmssp.cryptkey, memcpy(chgblob->Challenge, sess->ntlmssp.cryptkey,
CIFS_CRYPTO_KEY_SIZE); CIFS_CRYPTO_KEY_SIZE);
/* Add Target Information to security buffer */ /* Add Target Information to security buffer */
chgblob->TargetInfoArray.BufferOffset = cpu_to_le32(blob_len); chgblob->TargetInfoArray.BufferOffset = cpu_to_le32(blob_len);
...@@ -676,7 +671,7 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob, ...@@ -676,7 +671,7 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
#ifdef CONFIG_SMB_SERVER_KERBEROS5 #ifdef CONFIG_SMB_SERVER_KERBEROS5
int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob, int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
int in_len, char *out_blob, int *out_len) int in_len, char *out_blob, int *out_len)
{ {
struct ksmbd_spnego_authen_response *resp; struct ksmbd_spnego_authen_response *resp;
struct ksmbd_user *user = NULL; struct ksmbd_user *user = NULL;
...@@ -696,7 +691,7 @@ int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob, ...@@ -696,7 +691,7 @@ int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
if (*out_len <= resp->spnego_blob_len) { if (*out_len <= resp->spnego_blob_len) {
ksmbd_debug(AUTH, "buf len %d, but blob len %d\n", ksmbd_debug(AUTH, "buf len %d, but blob len %d\n",
*out_len, resp->spnego_blob_len); *out_len, resp->spnego_blob_len);
retval = -EINVAL; retval = -EINVAL;
goto out; goto out;
} }
...@@ -717,7 +712,7 @@ int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob, ...@@ -717,7 +712,7 @@ int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
memcpy(sess->sess_key, resp->payload, resp->session_key_len); memcpy(sess->sess_key, resp->payload, resp->session_key_len);
memcpy(out_blob, resp->payload + resp->session_key_len, memcpy(out_blob, resp->payload + resp->session_key_len,
resp->spnego_blob_len); resp->spnego_blob_len);
*out_len = resp->spnego_blob_len; *out_len = resp->spnego_blob_len;
retval = 0; retval = 0;
out: out:
...@@ -726,7 +721,7 @@ int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob, ...@@ -726,7 +721,7 @@ int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
} }
#else #else
int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob, int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
int in_len, char *out_blob, int *out_len) int in_len, char *out_blob, int *out_len)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -742,7 +737,7 @@ int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob, ...@@ -742,7 +737,7 @@ int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
* *
*/ */
int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov, int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
int n_vec, char *sig) int n_vec, char *sig)
{ {
struct ksmbd_crypto_ctx *ctx; struct ksmbd_crypto_ctx *ctx;
int rc, i; int rc, i;
...@@ -793,7 +788,7 @@ int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov, ...@@ -793,7 +788,7 @@ int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
* *
*/ */
int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov, int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
int n_vec, char *sig) int n_vec, char *sig)
{ {
struct ksmbd_crypto_ctx *ctx; struct ksmbd_crypto_ctx *ctx;
int rc, i; int rc, i;
...@@ -841,7 +836,7 @@ struct derivation { ...@@ -841,7 +836,7 @@ struct derivation {
}; };
static int generate_key(struct ksmbd_session *sess, struct kvec label, static int generate_key(struct ksmbd_session *sess, struct kvec label,
struct kvec context, __u8 *key, unsigned int key_size) struct kvec context, __u8 *key, unsigned int key_size)
{ {
unsigned char zero = 0x0; unsigned char zero = 0x0;
__u8 i[4] = {0, 0, 0, 1}; __u8 i[4] = {0, 0, 0, 1};
...@@ -914,7 +909,7 @@ static int generate_key(struct ksmbd_session *sess, struct kvec label, ...@@ -914,7 +909,7 @@ static int generate_key(struct ksmbd_session *sess, struct kvec label,
rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), hashptr); rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), hashptr);
if (rc) { if (rc) {
ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n", ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n",
rc); rc);
goto smb3signkey_ret; goto smb3signkey_ret;
} }
...@@ -926,7 +921,7 @@ static int generate_key(struct ksmbd_session *sess, struct kvec label, ...@@ -926,7 +921,7 @@ static int generate_key(struct ksmbd_session *sess, struct kvec label,
} }
static int generate_smb3signingkey(struct ksmbd_session *sess, static int generate_smb3signingkey(struct ksmbd_session *sess,
const struct derivation *signing) const struct derivation *signing)
{ {
int rc; int rc;
struct channel *chann; struct channel *chann;
...@@ -942,7 +937,7 @@ static int generate_smb3signingkey(struct ksmbd_session *sess, ...@@ -942,7 +937,7 @@ static int generate_smb3signingkey(struct ksmbd_session *sess,
key = sess->smb3signingkey; key = sess->smb3signingkey;
rc = generate_key(sess, signing->label, signing->context, key, rc = generate_key(sess, signing->label, signing->context, key,
SMB3_SIGN_KEY_SIZE); SMB3_SIGN_KEY_SIZE);
if (rc) if (rc)
return rc; return rc;
...@@ -952,9 +947,9 @@ static int generate_smb3signingkey(struct ksmbd_session *sess, ...@@ -952,9 +947,9 @@ static int generate_smb3signingkey(struct ksmbd_session *sess,
ksmbd_debug(AUTH, "dumping generated AES signing keys\n"); ksmbd_debug(AUTH, "dumping generated AES signing keys\n");
ksmbd_debug(AUTH, "Session Id %llu\n", sess->id); ksmbd_debug(AUTH, "Session Id %llu\n", sess->id);
ksmbd_debug(AUTH, "Session Key %*ph\n", ksmbd_debug(AUTH, "Session Key %*ph\n",
SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key); SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
ksmbd_debug(AUTH, "Signing Key %*ph\n", ksmbd_debug(AUTH, "Signing Key %*ph\n",
SMB3_SIGN_KEY_SIZE, key); SMB3_SIGN_KEY_SIZE, key);
return 0; return 0;
} }
...@@ -990,19 +985,19 @@ struct derivation_twin { ...@@ -990,19 +985,19 @@ struct derivation_twin {
}; };
static int generate_smb3encryptionkey(struct ksmbd_session *sess, static int generate_smb3encryptionkey(struct ksmbd_session *sess,
const struct derivation_twin *ptwin) const struct derivation_twin *ptwin)
{ {
int rc; int rc;
rc = generate_key(sess, ptwin->encryption.label, rc = generate_key(sess, ptwin->encryption.label,
ptwin->encryption.context, sess->smb3encryptionkey, ptwin->encryption.context, sess->smb3encryptionkey,
SMB3_ENC_DEC_KEY_SIZE); SMB3_ENC_DEC_KEY_SIZE);
if (rc) if (rc)
return rc; return rc;
rc = generate_key(sess, ptwin->decryption.label, rc = generate_key(sess, ptwin->decryption.label,
ptwin->decryption.context, ptwin->decryption.context,
sess->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE); sess->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE);
if (rc) if (rc)
return rc; return rc;
...@@ -1010,18 +1005,18 @@ static int generate_smb3encryptionkey(struct ksmbd_session *sess, ...@@ -1010,18 +1005,18 @@ static int generate_smb3encryptionkey(struct ksmbd_session *sess,
ksmbd_debug(AUTH, "Cipher type %d\n", sess->conn->cipher_type); ksmbd_debug(AUTH, "Cipher type %d\n", sess->conn->cipher_type);
ksmbd_debug(AUTH, "Session Id %llu\n", sess->id); ksmbd_debug(AUTH, "Session Id %llu\n", sess->id);
ksmbd_debug(AUTH, "Session Key %*ph\n", ksmbd_debug(AUTH, "Session Key %*ph\n",
SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key); SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
if (sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM || if (sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) { sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
ksmbd_debug(AUTH, "ServerIn Key %*ph\n", ksmbd_debug(AUTH, "ServerIn Key %*ph\n",
SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3encryptionkey); SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3encryptionkey);
ksmbd_debug(AUTH, "ServerOut Key %*ph\n", ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3decryptionkey); SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3decryptionkey);
} else { } else {
ksmbd_debug(AUTH, "ServerIn Key %*ph\n", ksmbd_debug(AUTH, "ServerIn Key %*ph\n",
SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3encryptionkey); SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3encryptionkey);
ksmbd_debug(AUTH, "ServerOut Key %*ph\n", ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3decryptionkey); SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3decryptionkey);
} }
return 0; return 0;
} }
...@@ -1067,7 +1062,7 @@ int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess) ...@@ -1067,7 +1062,7 @@ int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess)
} }
int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf, int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
__u8 *pi_hash) __u8 *pi_hash)
{ {
int rc; int rc;
struct smb2_hdr *rcv_hdr = (struct smb2_hdr *)buf; struct smb2_hdr *rcv_hdr = (struct smb2_hdr *)buf;
...@@ -1114,7 +1109,7 @@ int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf, ...@@ -1114,7 +1109,7 @@ int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
} }
int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len, int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
__u8 *pi_hash) __u8 *pi_hash)
{ {
int rc; int rc;
struct ksmbd_crypto_ctx *ctx = NULL; struct ksmbd_crypto_ctx *ctx = NULL;
...@@ -1148,7 +1143,7 @@ int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len, ...@@ -1148,7 +1143,7 @@ int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
} }
static int ksmbd_get_encryption_key(struct ksmbd_conn *conn, __u64 ses_id, static int ksmbd_get_encryption_key(struct ksmbd_conn *conn, __u64 ses_id,
int enc, u8 *key) int enc, u8 *key)
{ {
struct ksmbd_session *sess; struct ksmbd_session *sess;
u8 *ses_enc_key; u8 *ses_enc_key;
...@@ -1165,7 +1160,7 @@ static int ksmbd_get_encryption_key(struct ksmbd_conn *conn, __u64 ses_id, ...@@ -1165,7 +1160,7 @@ static int ksmbd_get_encryption_key(struct ksmbd_conn *conn, __u64 ses_id,
} }
static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf, static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
unsigned int buflen) unsigned int buflen)
{ {
void *addr; void *addr;
...@@ -1177,7 +1172,7 @@ static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf, ...@@ -1177,7 +1172,7 @@ static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
} }
static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec, static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
u8 *sign) u8 *sign)
{ {
struct scatterlist *sg; struct scatterlist *sg;
unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 24; unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 24;
...@@ -1242,7 +1237,7 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec, ...@@ -1242,7 +1237,7 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
} }
int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov, int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
unsigned int nvec, int enc) unsigned int nvec, int enc)
{ {
struct smb2_transform_hdr *tr_hdr = struct smb2_transform_hdr *tr_hdr =
(struct smb2_transform_hdr *)iov[0].iov_base; (struct smb2_transform_hdr *)iov[0].iov_base;
......
...@@ -35,56 +35,31 @@ struct ksmbd_session; ...@@ -35,56 +35,31 @@ struct ksmbd_session;
struct ksmbd_conn; struct ksmbd_conn;
struct kvec; struct kvec;
int ksmbd_crypt_message(struct ksmbd_conn *conn, int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
struct kvec *iov, unsigned int nvec, int enc);
unsigned int nvec,
int enc);
void ksmbd_copy_gss_neg_header(void *buf); void ksmbd_copy_gss_neg_header(void *buf);
int ksmbd_auth_ntlm(struct ksmbd_session *sess, char *pw_buf);
int ksmbd_auth_ntlm(struct ksmbd_session *sess, int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
char *pw_buf); int blen, char *domain_name);
int ksmbd_auth_ntlmv2(struct ksmbd_session *sess,
struct ntlmv2_resp *ntlmv2,
int blen,
char *domain_name);
int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob, int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
int blob_len, int blob_len, struct ksmbd_session *sess);
struct ksmbd_session *sess);
int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob, int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
int blob_len, int blob_len, struct ksmbd_session *sess);
struct ksmbd_session *sess);
unsigned int unsigned int
ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob, ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
struct ksmbd_session *sess); struct ksmbd_session *sess);
int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
int ksmbd_krb5_authenticate(struct ksmbd_session *sess, int in_len, char *out_blob, int *out_len);
char *in_blob, int in_len, int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
char *out_blob, int *out_len); int n_vec, char *sig);
int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, int n_vec, char *sig);
char *key,
struct kvec *iov,
int n_vec,
char *sig);
int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn,
char *key,
struct kvec *iov,
int n_vec,
char *sig);
int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess); int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess);
int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess); int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess);
int ksmbd_gen_smb30_encryptionkey(struct ksmbd_session *sess); int ksmbd_gen_smb30_encryptionkey(struct ksmbd_session *sess);
int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess); int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess);
int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn,
char *buf,
__u8 *pi_hash); __u8 *pi_hash);
int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len, int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
__u8 *pi_hash); __u8 *pi_hash);
#endif #endif
...@@ -251,7 +251,8 @@ int ksmbd_init_buffer_pools(void) ...@@ -251,7 +251,8 @@ int ksmbd_init_buffer_pools(void)
goto out; goto out;
filp_cache = kmem_cache_create("ksmbd_file_cache", filp_cache = kmem_cache_create("ksmbd_file_cache",
sizeof(struct ksmbd_file), 0, SLAB_HWCACHE_ALIGN, NULL); sizeof(struct ksmbd_file), 0,
SLAB_HWCACHE_ALIGN, NULL);
if (!filp_cache) if (!filp_cache)
goto out; goto out;
......
...@@ -8,12 +8,9 @@ ...@@ -8,12 +8,9 @@
void *ksmbd_find_buffer(size_t size); void *ksmbd_find_buffer(size_t size);
void ksmbd_release_buffer(void *buffer); void ksmbd_release_buffer(void *buffer);
void *ksmbd_realloc_response(void *ptr, size_t old_sz, size_t new_sz); void *ksmbd_realloc_response(void *ptr, size_t old_sz, size_t new_sz);
void ksmbd_free_file_struct(void *filp); void ksmbd_free_file_struct(void *filp);
void *ksmbd_alloc_file_struct(void); void *ksmbd_alloc_file_struct(void);
void ksmbd_destroy_buffer_pools(void); void ksmbd_destroy_buffer_pools(void);
int ksmbd_init_buffer_pools(void); int ksmbd_init_buffer_pools(void);
......
...@@ -201,30 +201,30 @@ int ksmbd_conn_write(struct ksmbd_work *work) ...@@ -201,30 +201,30 @@ int ksmbd_conn_write(struct ksmbd_work *work)
} }
int ksmbd_conn_rdma_read(struct ksmbd_conn *conn, void *buf, int ksmbd_conn_rdma_read(struct ksmbd_conn *conn, void *buf,
unsigned int buflen, u32 remote_key, u64 remote_offset, unsigned int buflen, u32 remote_key, u64 remote_offset,
u32 remote_len) u32 remote_len)
{ {
int ret = -EINVAL; int ret = -EINVAL;
if (conn->transport->ops->rdma_read) if (conn->transport->ops->rdma_read)
ret = conn->transport->ops->rdma_read(conn->transport, ret = conn->transport->ops->rdma_read(conn->transport,
buf, buflen, buf, buflen,
remote_key, remote_offset, remote_key, remote_offset,
remote_len); remote_len);
return ret; return ret;
} }
int ksmbd_conn_rdma_write(struct ksmbd_conn *conn, void *buf, int ksmbd_conn_rdma_write(struct ksmbd_conn *conn, void *buf,
unsigned int buflen, u32 remote_key, u64 remote_offset, unsigned int buflen, u32 remote_key,
u32 remote_len) u64 remote_offset, u32 remote_len)
{ {
int ret = -EINVAL; int ret = -EINVAL;
if (conn->transport->ops->rdma_write) if (conn->transport->ops->rdma_write)
ret = conn->transport->ops->rdma_write(conn->transport, ret = conn->transport->ops->rdma_write(conn->transport,
buf, buflen, buf, buflen,
remote_key, remote_offset, remote_key, remote_offset,
remote_len); remote_len);
return ret; return ret;
} }
...@@ -250,7 +250,7 @@ bool ksmbd_conn_alive(struct ksmbd_conn *conn) ...@@ -250,7 +250,7 @@ bool ksmbd_conn_alive(struct ksmbd_conn *conn)
if (server_conf.deadtime > 0 && if (server_conf.deadtime > 0 &&
time_after(jiffies, conn->last_active + server_conf.deadtime)) { time_after(jiffies, conn->last_active + server_conf.deadtime)) {
ksmbd_debug(CONN, "No response from client in %lu minutes\n", ksmbd_debug(CONN, "No response from client in %lu minutes\n",
server_conf.deadtime / SMB_ECHO_INTERVAL); server_conf.deadtime / SMB_ECHO_INTERVAL);
return false; return false;
} }
return true; return true;
...@@ -390,7 +390,7 @@ static void stop_sessions(void) ...@@ -390,7 +390,7 @@ static void stop_sessions(void)
task = conn->transport->handler; task = conn->transport->handler;
if (task) if (task)
ksmbd_debug(CONN, "Stop session handler %s/%d\n", ksmbd_debug(CONN, "Stop session handler %s/%d\n",
task->comm, task_pid_nr(task)); task->comm, task_pid_nr(task));
conn->status = KSMBD_SESS_EXITING; conn->status = KSMBD_SESS_EXITING;
} }
read_unlock(&conn_list_lock); read_unlock(&conn_list_lock);
......
...@@ -118,13 +118,13 @@ struct ksmbd_transport_ops { ...@@ -118,13 +118,13 @@ struct ksmbd_transport_ops {
void (*disconnect)(struct ksmbd_transport *t); void (*disconnect)(struct ksmbd_transport *t);
int (*read)(struct ksmbd_transport *t, char *buf, unsigned int size); int (*read)(struct ksmbd_transport *t, char *buf, unsigned int size);
int (*writev)(struct ksmbd_transport *t, struct kvec *iovs, int niov, int (*writev)(struct ksmbd_transport *t, struct kvec *iovs, int niov,
int size, bool need_invalidate_rkey, int size, bool need_invalidate_rkey,
unsigned int remote_key); unsigned int remote_key);
int (*rdma_read)(struct ksmbd_transport *t, void *buf, unsigned int len, int (*rdma_read)(struct ksmbd_transport *t, void *buf, unsigned int len,
u32 remote_key, u64 remote_offset, u32 remote_len); u32 remote_key, u64 remote_offset, u32 remote_len);
int (*rdma_write)(struct ksmbd_transport *t, void *buf, int (*rdma_write)(struct ksmbd_transport *t, void *buf,
unsigned int len, u32 remote_key, u64 remote_offset, unsigned int len, u32 remote_key, u64 remote_offset,
u32 remote_len); u32 remote_len);
}; };
struct ksmbd_transport { struct ksmbd_transport {
...@@ -139,24 +139,20 @@ struct ksmbd_transport { ...@@ -139,24 +139,20 @@ struct ksmbd_transport {
bool ksmbd_conn_alive(struct ksmbd_conn *conn); bool ksmbd_conn_alive(struct ksmbd_conn *conn);
void ksmbd_conn_wait_idle(struct ksmbd_conn *conn); void ksmbd_conn_wait_idle(struct ksmbd_conn *conn);
struct ksmbd_conn *ksmbd_conn_alloc(void); struct ksmbd_conn *ksmbd_conn_alloc(void);
void ksmbd_conn_free(struct ksmbd_conn *conn); void ksmbd_conn_free(struct ksmbd_conn *conn);
bool ksmbd_conn_lookup_dialect(struct ksmbd_conn *c); bool ksmbd_conn_lookup_dialect(struct ksmbd_conn *c);
int ksmbd_conn_write(struct ksmbd_work *work); int ksmbd_conn_write(struct ksmbd_work *work);
int ksmbd_conn_rdma_read(struct ksmbd_conn *conn, void *buf, int ksmbd_conn_rdma_read(struct ksmbd_conn *conn, void *buf,
unsigned int buflen, u32 remote_key, u64 remote_offset, unsigned int buflen, u32 remote_key, u64 remote_offset,
u32 remote_len); u32 remote_len);
int ksmbd_conn_rdma_write(struct ksmbd_conn *conn, void *buf, int ksmbd_conn_rdma_write(struct ksmbd_conn *conn, void *buf,
unsigned int buflen, u32 remote_key, u64 remote_offset, unsigned int buflen, u32 remote_key, u64 remote_offset,
u32 remote_len); u32 remote_len);
void ksmbd_conn_enqueue_request(struct ksmbd_work *work); void ksmbd_conn_enqueue_request(struct ksmbd_work *work);
int ksmbd_conn_try_dequeue_request(struct ksmbd_work *work); int ksmbd_conn_try_dequeue_request(struct ksmbd_work *work);
void ksmbd_conn_init_server_callbacks(struct ksmbd_conn_ops *ops); void ksmbd_conn_init_server_callbacks(struct ksmbd_conn_ops *ops);
int ksmbd_conn_handler_loop(void *p); int ksmbd_conn_handler_loop(void *p);
int ksmbd_conn_transport_init(void); int ksmbd_conn_transport_init(void);
void ksmbd_conn_transport_destroy(void); void ksmbd_conn_transport_destroy(void);
......
...@@ -123,8 +123,8 @@ static struct ksmbd_crypto_ctx *ksmbd_find_crypto_ctx(void) ...@@ -123,8 +123,8 @@ static struct ksmbd_crypto_ctx *ksmbd_find_crypto_ctx(void)
spin_lock(&ctx_list.ctx_lock); spin_lock(&ctx_list.ctx_lock);
if (!list_empty(&ctx_list.idle_ctx)) { if (!list_empty(&ctx_list.idle_ctx)) {
ctx = list_entry(ctx_list.idle_ctx.next, ctx = list_entry(ctx_list.idle_ctx.next,
struct ksmbd_crypto_ctx, struct ksmbd_crypto_ctx,
list); list);
list_del(&ctx->list); list_del(&ctx->list);
spin_unlock(&ctx_list.ctx_lock); spin_unlock(&ctx_list.ctx_lock);
return ctx; return ctx;
......
...@@ -59,7 +59,6 @@ struct ksmbd_crypto_ctx { ...@@ -59,7 +59,6 @@ struct ksmbd_crypto_ctx {
#define CRYPTO_CCM(c) ((c)->ccmaes[CRYPTO_AEAD_AES_CCM]) #define CRYPTO_CCM(c) ((c)->ccmaes[CRYPTO_AEAD_AES_CCM])
void ksmbd_release_crypto_ctx(struct ksmbd_crypto_ctx *ctx); void ksmbd_release_crypto_ctx(struct ksmbd_crypto_ctx *ctx);
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_hmacmd5(void); struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_hmacmd5(void);
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_hmacsha256(void); struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_hmacsha256(void);
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_cmacaes(void); struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_cmacaes(void);
...@@ -67,10 +66,8 @@ struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_sha512(void); ...@@ -67,10 +66,8 @@ struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_sha512(void);
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_sha256(void); struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_sha256(void);
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_md4(void); struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_md4(void);
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_md5(void); struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_md5(void);
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_gcm(void); struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_gcm(void);
struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_ccm(void); struct ksmbd_crypto_ctx *ksmbd_crypto_ctx_find_ccm(void);
void ksmbd_crypto_destroy(void); void ksmbd_crypto_destroy(void);
int ksmbd_crypto_create(void); int ksmbd_crypto_create(void);
......
...@@ -39,13 +39,13 @@ void ksmbd_free_work_struct(struct ksmbd_work *work) ...@@ -39,13 +39,13 @@ void ksmbd_free_work_struct(struct ksmbd_work *work)
{ {
WARN_ON(work->saved_cred != NULL); WARN_ON(work->saved_cred != NULL);
if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_TBUF && if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_TBUF &&
work->set_trans_buf) work->set_trans_buf)
ksmbd_release_buffer(work->response_buf); ksmbd_release_buffer(work->response_buf);
else else
kvfree(work->response_buf); kvfree(work->response_buf);
if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_RBUF && if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_RBUF &&
work->set_read_buf) work->set_read_buf)
ksmbd_release_buffer(work->aux_payload_buf); ksmbd_release_buffer(work->aux_payload_buf);
else else
kvfree(work->aux_payload_buf); kvfree(work->aux_payload_buf);
...@@ -65,8 +65,8 @@ void ksmbd_work_pool_destroy(void) ...@@ -65,8 +65,8 @@ void ksmbd_work_pool_destroy(void)
int ksmbd_work_pool_init(void) int ksmbd_work_pool_init(void)
{ {
work_cache = kmem_cache_create("ksmbd_work_cache", work_cache = kmem_cache_create("ksmbd_work_cache",
sizeof(struct ksmbd_work), 0, sizeof(struct ksmbd_work), 0,
SLAB_HWCACHE_ALIGN, NULL); SLAB_HWCACHE_ALIGN, NULL);
if (!work_cache) if (!work_cache)
return -ENOMEM; return -ENOMEM;
return 0; return 0;
......
...@@ -135,7 +135,7 @@ int parse_stream_name(char *filename, char **stream_name, int *s_type) ...@@ -135,7 +135,7 @@ int parse_stream_name(char *filename, char **stream_name, int *s_type)
} }
ksmbd_debug(SMB, "stream name : %s, stream type : %s\n", s_name, ksmbd_debug(SMB, "stream name : %s, stream type : %s\n", s_name,
stream_type); stream_type);
if (!strncasecmp("$data", stream_type, 5)) if (!strncasecmp("$data", stream_type, 5))
*s_type = DATA_STREAM; *s_type = DATA_STREAM;
else if (!strncasecmp("$index_allocation", stream_type, 17)) else if (!strncasecmp("$index_allocation", stream_type, 17))
...@@ -267,7 +267,8 @@ char *convert_to_unix_name(struct ksmbd_share_config *share, char *name) ...@@ -267,7 +267,8 @@ char *convert_to_unix_name(struct ksmbd_share_config *share, char *name)
} }
char *ksmbd_convert_dir_info_name(struct ksmbd_dir_info *d_info, char *ksmbd_convert_dir_info_name(struct ksmbd_dir_info *d_info,
const struct nls_table *local_nls, int *conv_len) const struct nls_table *local_nls,
int *conv_len)
{ {
char *conv; char *conv;
int sz = min(4 * d_info->name_len, PATH_MAX); int sz = min(4 * d_info->name_len, PATH_MAX);
...@@ -280,11 +281,8 @@ char *ksmbd_convert_dir_info_name(struct ksmbd_dir_info *d_info, ...@@ -280,11 +281,8 @@ char *ksmbd_convert_dir_info_name(struct ksmbd_dir_info *d_info,
return NULL; return NULL;
/* XXX */ /* XXX */
*conv_len = smbConvertToUTF16((__le16 *)conv, *conv_len = smbConvertToUTF16((__le16 *)conv, d_info->name,
d_info->name, d_info->name_len, local_nls, 0);
d_info->name_len,
local_nls,
0);
*conv_len *= 2; *conv_len *= 2;
/* We allocate buffer twice bigger than needed. */ /* We allocate buffer twice bigger than needed. */
......
...@@ -12,32 +12,23 @@ struct kstat; ...@@ -12,32 +12,23 @@ struct kstat;
struct ksmbd_file; struct ksmbd_file;
int match_pattern(const char *str, size_t len, const char *pattern); int match_pattern(const char *str, size_t len, const char *pattern);
int ksmbd_validate_filename(char *filename); int ksmbd_validate_filename(char *filename);
int parse_stream_name(char *filename, char **stream_name, int *s_type); int parse_stream_name(char *filename, char **stream_name, int *s_type);
char *convert_to_nt_pathname(char *filename, char *sharepath); char *convert_to_nt_pathname(char *filename, char *sharepath);
int get_nlink(struct kstat *st); int get_nlink(struct kstat *st);
void ksmbd_conv_path_to_unix(char *path); void ksmbd_conv_path_to_unix(char *path);
void ksmbd_strip_last_slash(char *path); void ksmbd_strip_last_slash(char *path);
void ksmbd_conv_path_to_windows(char *path); void ksmbd_conv_path_to_windows(char *path);
char *ksmbd_extract_sharename(char *treename); char *ksmbd_extract_sharename(char *treename);
char *convert_to_unix_name(struct ksmbd_share_config *share, char *name); char *convert_to_unix_name(struct ksmbd_share_config *share, char *name);
#define KSMBD_DIR_INFO_ALIGNMENT 8 #define KSMBD_DIR_INFO_ALIGNMENT 8
struct ksmbd_dir_info; struct ksmbd_dir_info;
char *ksmbd_convert_dir_info_name(struct ksmbd_dir_info *d_info, char *ksmbd_convert_dir_info_name(struct ksmbd_dir_info *d_info,
const struct nls_table *local_nls, const struct nls_table *local_nls,
int *conv_len); int *conv_len);
#define NTFS_TIME_OFFSET ((u64)(369 * 365 + 89) * 24 * 3600 * 10000000) #define NTFS_TIME_OFFSET ((u64)(369 * 365 + 89) * 24 * 3600 * 10000000)
struct timespec64 ksmbd_NTtimeToUnix(__le64 ntutc); struct timespec64 ksmbd_NTtimeToUnix(__le64 ntutc);
u64 ksmbd_UnixTimeToNT(struct timespec64 t); u64 ksmbd_UnixTimeToNT(struct timespec64 t);
long long ksmbd_systime(void); long long ksmbd_systime(void);
......
...@@ -185,7 +185,7 @@ int ndr_decode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da) ...@@ -185,7 +185,7 @@ int ndr_decode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da)
version2 = ndr_read_int32(n); version2 = ndr_read_int32(n);
if (da->version != version2) { if (da->version != version2) {
ksmbd_err("ndr version mismatched(version: %d, version2: %d)\n", ksmbd_err("ndr version mismatched(version: %d, version2: %d)\n",
da->version, version2); da->version, version2);
return -EINVAL; return -EINVAL;
} }
...@@ -235,7 +235,8 @@ static int ndr_encode_posix_acl_entry(struct ndr *n, struct xattr_smb_acl *acl) ...@@ -235,7 +235,8 @@ static int ndr_encode_posix_acl_entry(struct ndr *n, struct xattr_smb_acl *acl)
} }
int ndr_encode_posix_acl(struct ndr *n, struct inode *inode, int ndr_encode_posix_acl(struct ndr *n, struct inode *inode,
struct xattr_smb_acl *acl, struct xattr_smb_acl *def_acl) struct xattr_smb_acl *acl,
struct xattr_smb_acl *def_acl)
{ {
int ref_id = 0x00020000; int ref_id = 0x00020000;
...@@ -315,7 +316,7 @@ int ndr_decode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl) ...@@ -315,7 +316,7 @@ int ndr_decode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl)
version2 = ndr_read_int32(n); version2 = ndr_read_int32(n);
if (acl->version != version2) { if (acl->version != version2) {
ksmbd_err("ndr version mismatched(version: %d, version2: %d)\n", ksmbd_err("ndr version mismatched(version: %d, version2: %d)\n",
acl->version, version2); acl->version, version2);
return -EINVAL; return -EINVAL;
} }
......
...@@ -15,7 +15,8 @@ struct ndr { ...@@ -15,7 +15,8 @@ struct ndr {
int ndr_encode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da); int ndr_encode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da);
int ndr_decode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da); int ndr_decode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da);
int ndr_encode_posix_acl(struct ndr *n, struct inode *inode, int ndr_encode_posix_acl(struct ndr *n, struct inode *inode,
struct xattr_smb_acl *acl, struct xattr_smb_acl *def_acl); struct xattr_smb_acl *acl,
struct xattr_smb_acl *def_acl);
int ndr_encode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl); int ndr_encode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl);
int ndr_encode_v3_ntacl(struct ndr *n, struct xattr_ntacl *acl); int ndr_encode_v3_ntacl(struct ndr *n, struct xattr_ntacl *acl);
int ndr_decode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl); int ndr_decode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl);
...@@ -29,7 +29,7 @@ static DEFINE_RWLOCK(lease_list_lock); ...@@ -29,7 +29,7 @@ static DEFINE_RWLOCK(lease_list_lock);
* Return: allocated opinfo object on success, otherwise NULL * Return: allocated opinfo object on success, otherwise NULL
*/ */
static struct oplock_info *alloc_opinfo(struct ksmbd_work *work, static struct oplock_info *alloc_opinfo(struct ksmbd_work *work,
u64 id, __u16 Tid) u64 id, __u16 Tid)
{ {
struct ksmbd_session *sess = work->sess; struct ksmbd_session *sess = work->sess;
struct oplock_info *opinfo; struct oplock_info *opinfo;
...@@ -153,7 +153,7 @@ static struct oplock_info *opinfo_get_list(struct ksmbd_inode *ci) ...@@ -153,7 +153,7 @@ static struct oplock_info *opinfo_get_list(struct ksmbd_inode *ci)
rcu_read_lock(); rcu_read_lock();
opinfo = list_first_or_null_rcu(&ci->m_op_list, struct oplock_info, opinfo = list_first_or_null_rcu(&ci->m_op_list, struct oplock_info,
op_entry); op_entry);
if (opinfo && !atomic_inc_not_zero(&opinfo->refcount)) if (opinfo && !atomic_inc_not_zero(&opinfo->refcount))
opinfo = NULL; opinfo = NULL;
rcu_read_unlock(); rcu_read_unlock();
...@@ -269,8 +269,7 @@ int opinfo_write_to_none(struct oplock_info *opinfo) ...@@ -269,8 +269,7 @@ int opinfo_write_to_none(struct oplock_info *opinfo)
opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)) { opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)) {
ksmbd_err("bad oplock(0x%x)\n", opinfo->level); ksmbd_err("bad oplock(0x%x)\n", opinfo->level);
if (opinfo->is_lease) if (opinfo->is_lease)
ksmbd_err("lease state(0x%x)\n", ksmbd_err("lease state(0x%x)\n", lease->state);
lease->state);
return -EINVAL; return -EINVAL;
} }
opinfo->level = SMB2_OPLOCK_LEVEL_NONE; opinfo->level = SMB2_OPLOCK_LEVEL_NONE;
...@@ -312,8 +311,7 @@ int lease_read_to_write(struct oplock_info *opinfo) ...@@ -312,8 +311,7 @@ int lease_read_to_write(struct oplock_info *opinfo)
struct lease *lease = opinfo->o_lease; struct lease *lease = opinfo->o_lease;
if (!(lease->state & SMB2_LEASE_READ_CACHING_LE)) { if (!(lease->state & SMB2_LEASE_READ_CACHING_LE)) {
ksmbd_debug(OPLOCK, "bad lease state(0x%x)\n", ksmbd_debug(OPLOCK, "bad lease state(0x%x)\n", lease->state);
lease->state);
return -EINVAL; return -EINVAL;
} }
...@@ -338,8 +336,7 @@ static int lease_none_upgrade(struct oplock_info *opinfo, __le32 new_state) ...@@ -338,8 +336,7 @@ static int lease_none_upgrade(struct oplock_info *opinfo, __le32 new_state)
struct lease *lease = opinfo->o_lease; struct lease *lease = opinfo->o_lease;
if (!(lease->state == SMB2_LEASE_NONE_LE)) { if (!(lease->state == SMB2_LEASE_NONE_LE)) {
ksmbd_debug(OPLOCK, "bad lease state(0x%x)\n", ksmbd_debug(OPLOCK, "bad lease state(0x%x)\n", lease->state);
lease->state);
return -EINVAL; return -EINVAL;
} }
...@@ -399,7 +396,7 @@ void close_id_del_oplock(struct ksmbd_file *fp) ...@@ -399,7 +396,7 @@ void close_id_del_oplock(struct ksmbd_file *fp)
* Return: 0 * Return: 0
*/ */
static void grant_write_oplock(struct oplock_info *opinfo_new, int req_oplock, static void grant_write_oplock(struct oplock_info *opinfo_new, int req_oplock,
struct lease_ctx_info *lctx) struct lease_ctx_info *lctx)
{ {
struct lease *lease = opinfo_new->o_lease; struct lease *lease = opinfo_new->o_lease;
...@@ -410,8 +407,7 @@ static void grant_write_oplock(struct oplock_info *opinfo_new, int req_oplock, ...@@ -410,8 +407,7 @@ static void grant_write_oplock(struct oplock_info *opinfo_new, int req_oplock,
if (lctx) { if (lctx) {
lease->state = lctx->req_state; lease->state = lctx->req_state;
memcpy(lease->lease_key, lctx->lease_key, memcpy(lease->lease_key, lctx->lease_key, SMB2_LEASE_KEY_SIZE);
SMB2_LEASE_KEY_SIZE);
} }
} }
...@@ -423,7 +419,7 @@ static void grant_write_oplock(struct oplock_info *opinfo_new, int req_oplock, ...@@ -423,7 +419,7 @@ static void grant_write_oplock(struct oplock_info *opinfo_new, int req_oplock,
* Return: 0 * Return: 0
*/ */
static void grant_read_oplock(struct oplock_info *opinfo_new, static void grant_read_oplock(struct oplock_info *opinfo_new,
struct lease_ctx_info *lctx) struct lease_ctx_info *lctx)
{ {
struct lease *lease = opinfo_new->o_lease; struct lease *lease = opinfo_new->o_lease;
...@@ -433,8 +429,7 @@ static void grant_read_oplock(struct oplock_info *opinfo_new, ...@@ -433,8 +429,7 @@ static void grant_read_oplock(struct oplock_info *opinfo_new,
lease->state = SMB2_LEASE_READ_CACHING_LE; lease->state = SMB2_LEASE_READ_CACHING_LE;
if (lctx->req_state & SMB2_LEASE_HANDLE_CACHING_LE) if (lctx->req_state & SMB2_LEASE_HANDLE_CACHING_LE)
lease->state |= SMB2_LEASE_HANDLE_CACHING_LE; lease->state |= SMB2_LEASE_HANDLE_CACHING_LE;
memcpy(lease->lease_key, lctx->lease_key, memcpy(lease->lease_key, lctx->lease_key, SMB2_LEASE_KEY_SIZE);
SMB2_LEASE_KEY_SIZE);
} }
} }
...@@ -446,7 +441,7 @@ static void grant_read_oplock(struct oplock_info *opinfo_new, ...@@ -446,7 +441,7 @@ static void grant_read_oplock(struct oplock_info *opinfo_new,
* Return: 0 * Return: 0
*/ */
static void grant_none_oplock(struct oplock_info *opinfo_new, static void grant_none_oplock(struct oplock_info *opinfo_new,
struct lease_ctx_info *lctx) struct lease_ctx_info *lctx)
{ {
struct lease *lease = opinfo_new->o_lease; struct lease *lease = opinfo_new->o_lease;
...@@ -454,13 +449,12 @@ static void grant_none_oplock(struct oplock_info *opinfo_new, ...@@ -454,13 +449,12 @@ static void grant_none_oplock(struct oplock_info *opinfo_new,
if (lctx) { if (lctx) {
lease->state = 0; lease->state = 0;
memcpy(lease->lease_key, lctx->lease_key, memcpy(lease->lease_key, lctx->lease_key, SMB2_LEASE_KEY_SIZE);
SMB2_LEASE_KEY_SIZE);
} }
} }
static inline int compare_guid_key(struct oplock_info *opinfo, static inline int compare_guid_key(struct oplock_info *opinfo,
const char *guid1, const char *key1) const char *guid1, const char *key1)
{ {
const char *guid2, *key2; const char *guid2, *key2;
...@@ -483,7 +477,8 @@ static inline int compare_guid_key(struct oplock_info *opinfo, ...@@ -483,7 +477,8 @@ static inline int compare_guid_key(struct oplock_info *opinfo,
* Return: oplock(lease) object on success, otherwise NULL * Return: oplock(lease) object on success, otherwise NULL
*/ */
static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci, static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci,
char *client_guid, struct lease_ctx_info *lctx) char *client_guid,
struct lease_ctx_info *lctx)
{ {
int ret; int ret;
struct lease *lease; struct lease *lease;
...@@ -517,7 +512,7 @@ static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci, ...@@ -517,7 +512,7 @@ static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci,
if ((atomic_read(&ci->op_count) + if ((atomic_read(&ci->op_count) +
atomic_read(&ci->sop_count)) == 1) { atomic_read(&ci->sop_count)) == 1) {
if (lease->state == if (lease->state ==
(lctx->req_state & lease->state)) { (lctx->req_state & lease->state)) {
lease->state |= lctx->req_state; lease->state |= lctx->req_state;
if (lctx->req_state & if (lctx->req_state &
SMB2_LEASE_WRITE_CACHING_LE) SMB2_LEASE_WRITE_CACHING_LE)
...@@ -526,13 +521,13 @@ static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci, ...@@ -526,13 +521,13 @@ static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci,
} else if ((atomic_read(&ci->op_count) + } else if ((atomic_read(&ci->op_count) +
atomic_read(&ci->sop_count)) > 1) { atomic_read(&ci->sop_count)) > 1) {
if (lctx->req_state == if (lctx->req_state ==
(SMB2_LEASE_READ_CACHING_LE | (SMB2_LEASE_READ_CACHING_LE |
SMB2_LEASE_HANDLE_CACHING_LE)) SMB2_LEASE_HANDLE_CACHING_LE))
lease->state = lctx->req_state; lease->state = lctx->req_state;
} }
if (lctx->req_state && lease->state == if (lctx->req_state && lease->state ==
SMB2_LEASE_NONE_LE) SMB2_LEASE_NONE_LE)
lease_none_upgrade(opinfo, lctx->req_state); lease_none_upgrade(opinfo, lctx->req_state);
} }
read_lock(&ci->m_lock); read_lock(&ci->m_lock);
...@@ -547,9 +542,9 @@ static void wait_for_break_ack(struct oplock_info *opinfo) ...@@ -547,9 +542,9 @@ static void wait_for_break_ack(struct oplock_info *opinfo)
int rc = 0; int rc = 0;
rc = wait_event_interruptible_timeout(opinfo->oplock_q, rc = wait_event_interruptible_timeout(opinfo->oplock_q,
opinfo->op_state == OPLOCK_STATE_NONE || opinfo->op_state == OPLOCK_STATE_NONE ||
opinfo->op_state == OPLOCK_CLOSING, opinfo->op_state == OPLOCK_CLOSING,
OPLOCK_WAIT_TIME); OPLOCK_WAIT_TIME);
/* is this a timeout ? */ /* is this a timeout ? */
if (!rc) { if (!rc) {
...@@ -664,8 +659,8 @@ static void __smb2_oplock_break_noti(struct work_struct *wk) ...@@ -664,8 +659,8 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
inc_rfc1001_len(rsp, 24); inc_rfc1001_len(rsp, 24);
ksmbd_debug(OPLOCK, ksmbd_debug(OPLOCK,
"sending oplock break v_id %llu p_id = %llu lock level = %d\n", "sending oplock break v_id %llu p_id = %llu lock level = %d\n",
rsp->VolatileFid, rsp->PersistentFid, rsp->OplockLevel); rsp->VolatileFid, rsp->PersistentFid, rsp->OplockLevel);
ksmbd_fd_put(work, fp); ksmbd_fd_put(work, fp);
ksmbd_conn_write(work); ksmbd_conn_write(work);
...@@ -815,7 +810,7 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo) ...@@ -815,7 +810,7 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo)
struct ksmbd_work *in_work; struct ksmbd_work *in_work;
in_work = list_entry(tmp, struct ksmbd_work, in_work = list_entry(tmp, struct ksmbd_work,
interim_entry); interim_entry);
setup_async_work(in_work, NULL, NULL); setup_async_work(in_work, NULL, NULL);
smb2_send_interim_resp(in_work, STATUS_PENDING); smb2_send_interim_resp(in_work, STATUS_PENDING);
list_del(&in_work->interim_entry); list_del(&in_work->interim_entry);
...@@ -843,7 +838,8 @@ static void wait_lease_breaking(struct oplock_info *opinfo) ...@@ -843,7 +838,8 @@ static void wait_lease_breaking(struct oplock_info *opinfo)
int ret = 0; int ret = 0;
ret = wait_event_interruptible_timeout(opinfo->oplock_brk, ret = wait_event_interruptible_timeout(opinfo->oplock_brk,
atomic_read(&opinfo->breaking_cnt) == 0, HZ); atomic_read(&opinfo->breaking_cnt) == 0,
HZ);
if (!ret) if (!ret)
atomic_set(&opinfo->breaking_cnt, 0); atomic_set(&opinfo->breaking_cnt, 0);
} }
...@@ -855,8 +851,8 @@ static int oplock_break(struct oplock_info *brk_opinfo, int req_op_level) ...@@ -855,8 +851,8 @@ static int oplock_break(struct oplock_info *brk_opinfo, int req_op_level)
/* Need to break exclusive/batch oplock, write lease or overwrite_if */ /* Need to break exclusive/batch oplock, write lease or overwrite_if */
ksmbd_debug(OPLOCK, ksmbd_debug(OPLOCK,
"request to send oplock(level : 0x%x) break notification\n", "request to send oplock(level : 0x%x) break notification\n",
brk_opinfo->level); brk_opinfo->level);
if (brk_opinfo->is_lease) { if (brk_opinfo->is_lease) {
struct lease *lease = brk_opinfo->o_lease; struct lease *lease = brk_opinfo->o_lease;
...@@ -939,7 +935,7 @@ void destroy_lease_table(struct ksmbd_conn *conn) ...@@ -939,7 +935,7 @@ void destroy_lease_table(struct ksmbd_conn *conn)
again: again:
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(opinfo, &lb->lease_list, list_for_each_entry_rcu(opinfo, &lb->lease_list,
lease_entry) { lease_entry) {
rcu_read_unlock(); rcu_read_unlock();
lease_del_list(opinfo); lease_del_list(opinfo);
goto again; goto again;
...@@ -952,7 +948,7 @@ void destroy_lease_table(struct ksmbd_conn *conn) ...@@ -952,7 +948,7 @@ void destroy_lease_table(struct ksmbd_conn *conn)
} }
int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci, int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci,
struct lease_ctx_info *lctx) struct lease_ctx_info *lctx)
{ {
struct oplock_info *opinfo; struct oplock_info *opinfo;
int err = 0; int err = 0;
...@@ -978,20 +974,18 @@ int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci, ...@@ -978,20 +974,18 @@ int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci,
found: found:
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(opinfo, &lb->lease_list, list_for_each_entry_rcu(opinfo, &lb->lease_list, lease_entry) {
lease_entry) {
if (!atomic_inc_not_zero(&opinfo->refcount)) if (!atomic_inc_not_zero(&opinfo->refcount))
continue; continue;
rcu_read_unlock(); rcu_read_unlock();
if (opinfo->o_fp->f_ci == ci) if (opinfo->o_fp->f_ci == ci)
goto op_next; goto op_next;
err = compare_guid_key(opinfo, err = compare_guid_key(opinfo, sess->conn->ClientGUID,
sess->conn->ClientGUID, lctx->lease_key);
lctx->lease_key);
if (err) { if (err) {
err = -EINVAL; err = -EINVAL;
ksmbd_debug(OPLOCK, ksmbd_debug(OPLOCK,
"found same lease key is already used in other files\n"); "found same lease key is already used in other files\n");
opinfo_put(opinfo); opinfo_put(opinfo);
goto out; goto out;
} }
...@@ -1014,7 +1008,7 @@ static void copy_lease(struct oplock_info *op1, struct oplock_info *op2) ...@@ -1014,7 +1008,7 @@ static void copy_lease(struct oplock_info *op1, struct oplock_info *op2)
op2->level = op1->level; op2->level = op1->level;
lease2->state = lease1->state; lease2->state = lease1->state;
memcpy(lease2->lease_key, lease1->lease_key, memcpy(lease2->lease_key, lease1->lease_key,
SMB2_LEASE_KEY_SIZE); SMB2_LEASE_KEY_SIZE);
lease2->duration = lease1->duration; lease2->duration = lease1->duration;
lease2->flags = lease1->flags; lease2->flags = lease1->flags;
} }
...@@ -1040,7 +1034,7 @@ static int add_lease_global_list(struct oplock_info *opinfo) ...@@ -1040,7 +1034,7 @@ static int add_lease_global_list(struct oplock_info *opinfo)
return -ENOMEM; return -ENOMEM;
memcpy(lb->client_guid, opinfo->conn->ClientGUID, memcpy(lb->client_guid, opinfo->conn->ClientGUID,
SMB2_CLIENT_GUID_SIZE); SMB2_CLIENT_GUID_SIZE);
INIT_LIST_HEAD(&lb->lease_list); INIT_LIST_HEAD(&lb->lease_list);
spin_lock_init(&lb->lb_lock); spin_lock_init(&lb->lb_lock);
opinfo->o_lease->l_lb = lb; opinfo->o_lease->l_lb = lb;
...@@ -1050,7 +1044,7 @@ static int add_lease_global_list(struct oplock_info *opinfo) ...@@ -1050,7 +1044,7 @@ static int add_lease_global_list(struct oplock_info *opinfo)
} }
static void set_oplock_level(struct oplock_info *opinfo, int level, static void set_oplock_level(struct oplock_info *opinfo, int level,
struct lease_ctx_info *lctx) struct lease_ctx_info *lctx)
{ {
switch (level) { switch (level) {
case SMB2_OPLOCK_LEVEL_BATCH: case SMB2_OPLOCK_LEVEL_BATCH:
...@@ -1079,8 +1073,8 @@ static void set_oplock_level(struct oplock_info *opinfo, int level, ...@@ -1079,8 +1073,8 @@ static void set_oplock_level(struct oplock_info *opinfo, int level,
* Return: 0 on success, otherwise error * Return: 0 on success, otherwise error
*/ */
int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid, int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid,
struct ksmbd_file *fp, __u16 tid, struct lease_ctx_info *lctx, struct ksmbd_file *fp, __u16 tid,
int share_ret) struct lease_ctx_info *lctx, int share_ret)
{ {
struct ksmbd_session *sess = work->sess; struct ksmbd_session *sess = work->sess;
int err = 0; int err = 0;
...@@ -1122,7 +1116,7 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid, ...@@ -1122,7 +1116,7 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid,
/* is lease already granted ? */ /* is lease already granted ? */
m_opinfo = same_client_has_lease(ci, sess->conn->ClientGUID, m_opinfo = same_client_has_lease(ci, sess->conn->ClientGUID,
lctx); lctx);
if (m_opinfo) { if (m_opinfo) {
copy_lease(m_opinfo, opinfo); copy_lease(m_opinfo, opinfo);
if (atomic_read(&m_opinfo->breaking_cnt)) if (atomic_read(&m_opinfo->breaking_cnt))
...@@ -1208,7 +1202,7 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid, ...@@ -1208,7 +1202,7 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid,
* @is_trunc: truncate on open * @is_trunc: truncate on open
*/ */
static void smb_break_all_write_oplock(struct ksmbd_work *work, static void smb_break_all_write_oplock(struct ksmbd_work *work,
struct ksmbd_file *fp, int is_trunc) struct ksmbd_file *fp, int is_trunc)
{ {
struct oplock_info *brk_opinfo; struct oplock_info *brk_opinfo;
...@@ -1235,7 +1229,7 @@ static void smb_break_all_write_oplock(struct ksmbd_work *work, ...@@ -1235,7 +1229,7 @@ static void smb_break_all_write_oplock(struct ksmbd_work *work,
* @is_trunc: truncate on open * @is_trunc: truncate on open
*/ */
void smb_break_all_levII_oplock(struct ksmbd_work *work, struct ksmbd_file *fp, void smb_break_all_levII_oplock(struct ksmbd_work *work, struct ksmbd_file *fp,
int is_trunc) int is_trunc)
{ {
struct oplock_info *op, *brk_op; struct oplock_info *op, *brk_op;
struct ksmbd_inode *ci; struct ksmbd_inode *ci;
...@@ -1257,18 +1251,18 @@ void smb_break_all_levII_oplock(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -1257,18 +1251,18 @@ void smb_break_all_levII_oplock(struct ksmbd_work *work, struct ksmbd_file *fp,
(~(SMB2_LEASE_READ_CACHING_LE | (~(SMB2_LEASE_READ_CACHING_LE |
SMB2_LEASE_HANDLE_CACHING_LE)))) { SMB2_LEASE_HANDLE_CACHING_LE)))) {
ksmbd_debug(OPLOCK, "unexpected lease state(0x%x)\n", ksmbd_debug(OPLOCK, "unexpected lease state(0x%x)\n",
brk_op->o_lease->state); brk_op->o_lease->state);
goto next; goto next;
} else if (brk_op->level != } else if (brk_op->level !=
SMB2_OPLOCK_LEVEL_II) { SMB2_OPLOCK_LEVEL_II) {
ksmbd_debug(OPLOCK, "unexpected oplock(0x%x)\n", ksmbd_debug(OPLOCK, "unexpected oplock(0x%x)\n",
brk_op->level); brk_op->level);
goto next; goto next;
} }
/* Skip oplock being break to none */ /* Skip oplock being break to none */
if (brk_op->is_lease && (brk_op->o_lease->new_state == if (brk_op->is_lease &&
SMB2_LEASE_NONE_LE) && (brk_op->o_lease->new_state == SMB2_LEASE_NONE_LE) &&
atomic_read(&brk_op->breaking_cnt)) atomic_read(&brk_op->breaking_cnt))
goto next; goto next;
...@@ -1573,9 +1567,9 @@ void create_posix_rsp_buf(char *cc, struct ksmbd_file *fp) ...@@ -1573,9 +1567,9 @@ void create_posix_rsp_buf(char *cc, struct ksmbd_file *fp)
buf->reparse_tag = cpu_to_le32(fp->volatile_id); buf->reparse_tag = cpu_to_le32(fp->volatile_id);
buf->mode = cpu_to_le32(inode->i_mode); buf->mode = cpu_to_le32(inode->i_mode);
id_to_sid(from_kuid(&init_user_ns, inode->i_uid), id_to_sid(from_kuid(&init_user_ns, inode->i_uid),
SIDNFS_USER, (struct smb_sid *)&buf->SidBuffer[0]); SIDNFS_USER, (struct smb_sid *)&buf->SidBuffer[0]);
id_to_sid(from_kgid(&init_user_ns, inode->i_gid), id_to_sid(from_kgid(&init_user_ns, inode->i_gid),
SIDNFS_GROUP, (struct smb_sid *)&buf->SidBuffer[20]); SIDNFS_GROUP, (struct smb_sid *)&buf->SidBuffer[20]);
} }
/* /*
...@@ -1590,7 +1584,7 @@ void create_posix_rsp_buf(char *cc, struct ksmbd_file *fp) ...@@ -1590,7 +1584,7 @@ void create_posix_rsp_buf(char *cc, struct ksmbd_file *fp)
* Return: opinfo if found matching opinfo, otherwise NULL * Return: opinfo if found matching opinfo, otherwise NULL
*/ */
struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn, struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn,
char *lease_key) char *lease_key)
{ {
struct oplock_info *opinfo = NULL, *ret_op = NULL; struct oplock_info *opinfo = NULL, *ret_op = NULL;
struct lease_table *lt; struct lease_table *lt;
...@@ -1619,7 +1613,7 @@ struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn, ...@@ -1619,7 +1613,7 @@ struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn,
SMB2_LEASE_WRITE_CACHING_LE))) SMB2_LEASE_WRITE_CACHING_LE)))
goto op_next; goto op_next;
ret = compare_guid_key(opinfo, conn->ClientGUID, ret = compare_guid_key(opinfo, conn->ClientGUID,
lease_key); lease_key);
if (ret) { if (ret) {
ksmbd_debug(OPLOCK, "found opinfo\n"); ksmbd_debug(OPLOCK, "found opinfo\n");
ret_op = opinfo; ret_op = opinfo;
...@@ -1637,7 +1631,7 @@ struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn, ...@@ -1637,7 +1631,7 @@ struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn,
} }
int smb2_check_durable_oplock(struct ksmbd_file *fp, int smb2_check_durable_oplock(struct ksmbd_file *fp,
struct lease_ctx_info *lctx, char *name) struct lease_ctx_info *lctx, char *name)
{ {
struct oplock_info *opinfo = opinfo_get(fp); struct oplock_info *opinfo = opinfo_get(fp);
int ret = 0; int ret = 0;
......
...@@ -96,11 +96,10 @@ struct oplock_break_info { ...@@ -96,11 +96,10 @@ struct oplock_break_info {
}; };
int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, int smb_grant_oplock(struct ksmbd_work *work, int req_op_level,
u64 pid, struct ksmbd_file *fp, __u16 tid, u64 pid, struct ksmbd_file *fp, __u16 tid,
struct lease_ctx_info *lctx, int share_ret); struct lease_ctx_info *lctx, int share_ret);
void smb_break_all_levII_oplock(struct ksmbd_work *work, void smb_break_all_levII_oplock(struct ksmbd_work *work,
struct ksmbd_file *fp, int is_trunc); struct ksmbd_file *fp, int is_trunc);
int opinfo_write_to_read(struct oplock_info *opinfo); int opinfo_write_to_read(struct oplock_info *opinfo);
int opinfo_read_handle_to_read(struct oplock_info *opinfo); int opinfo_read_handle_to_read(struct oplock_info *opinfo);
int opinfo_write_to_none(struct oplock_info *opinfo); int opinfo_write_to_none(struct oplock_info *opinfo);
...@@ -124,10 +123,10 @@ void create_disk_id_rsp_buf(char *cc, __u64 file_id, __u64 vol_id); ...@@ -124,10 +123,10 @@ void create_disk_id_rsp_buf(char *cc, __u64 file_id, __u64 vol_id);
void create_posix_rsp_buf(char *cc, struct ksmbd_file *fp); void create_posix_rsp_buf(char *cc, struct ksmbd_file *fp);
struct create_context *smb2_find_context_vals(void *open_req, const char *str); struct create_context *smb2_find_context_vals(void *open_req, const char *str);
struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn, struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn,
char *lease_key); char *lease_key);
int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci, int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci,
struct lease_ctx_info *lctx); struct lease_ctx_info *lctx);
void destroy_lease_table(struct ksmbd_conn *conn); void destroy_lease_table(struct ksmbd_conn *conn);
int smb2_check_durable_oplock(struct ksmbd_file *fp, int smb2_check_durable_oplock(struct ksmbd_file *fp,
struct lease_ctx_info *lctx, char *name); struct lease_ctx_info *lctx, char *name);
#endif /* __KSMBD_OPLOCK_H */ #endif /* __KSMBD_OPLOCK_H */
...@@ -106,7 +106,7 @@ static inline int check_conn_state(struct ksmbd_work *work) ...@@ -106,7 +106,7 @@ static inline int check_conn_state(struct ksmbd_work *work)
#define TCP_HANDLER_ABORT 1 #define TCP_HANDLER_ABORT 1
static int __process_request(struct ksmbd_work *work, struct ksmbd_conn *conn, static int __process_request(struct ksmbd_work *work, struct ksmbd_conn *conn,
uint16_t *cmd) uint16_t *cmd)
{ {
struct smb_version_cmds *cmds; struct smb_version_cmds *cmds;
uint16_t command; uint16_t command;
...@@ -159,7 +159,7 @@ static int __process_request(struct ksmbd_work *work, struct ksmbd_conn *conn, ...@@ -159,7 +159,7 @@ static int __process_request(struct ksmbd_work *work, struct ksmbd_conn *conn,
} }
static void __handle_ksmbd_work(struct ksmbd_work *work, static void __handle_ksmbd_work(struct ksmbd_work *work,
struct ksmbd_conn *conn) struct ksmbd_conn *conn)
{ {
u16 command = 0; u16 command = 0;
int rc; int rc;
...@@ -222,8 +222,8 @@ static void __handle_ksmbd_work(struct ksmbd_work *work, ...@@ -222,8 +222,8 @@ static void __handle_ksmbd_work(struct ksmbd_work *work,
} }
} }
if (work->sess && (work->sess->sign || if (work->sess &&
smb3_11_final_sess_setup_resp(work) || (work->sess->sign || smb3_11_final_sess_setup_resp(work) ||
conn->ops->is_sign_req(work, command))) conn->ops->is_sign_req(work, command)))
conn->ops->set_sign_rsp(work); conn->ops->set_sign_rsp(work);
} while (is_chained_smb2_message(work)); } while (is_chained_smb2_message(work));
...@@ -416,7 +416,7 @@ int server_queue_ctrl_reset_work(void) ...@@ -416,7 +416,7 @@ int server_queue_ctrl_reset_work(void)
} }
static ssize_t stats_show(struct class *class, struct class_attribute *attr, static ssize_t stats_show(struct class *class, struct class_attribute *attr,
char *buf) char *buf)
{ {
/* /*
* Inc this each time you change stats output format, * Inc this each time you change stats output format,
...@@ -430,19 +430,15 @@ static ssize_t stats_show(struct class *class, struct class_attribute *attr, ...@@ -430,19 +430,15 @@ static ssize_t stats_show(struct class *class, struct class_attribute *attr,
"shutdown" "shutdown"
}; };
ssize_t sz = scnprintf(buf, ssize_t sz = scnprintf(buf, PAGE_SIZE, "%d %s %d %lu\n", stats_version,
PAGE_SIZE, state[server_conf.state], server_conf.tcp_port,
"%d %s %d %lu\n", server_conf.ipc_last_active / HZ);
stats_version,
state[server_conf.state],
server_conf.tcp_port,
server_conf.ipc_last_active / HZ);
return sz; return sz;
} }
static ssize_t kill_server_store(struct class *class, static ssize_t kill_server_store(struct class *class,
struct class_attribute *attr, const char *buf, struct class_attribute *attr, const char *buf,
size_t len) size_t len)
{ {
if (!sysfs_streq(buf, "hard")) if (!sysfs_streq(buf, "hard"))
return len; return len;
...@@ -458,11 +454,11 @@ static ssize_t kill_server_store(struct class *class, ...@@ -458,11 +454,11 @@ static ssize_t kill_server_store(struct class *class,
} }
static const char * const debug_type_strings[] = {"smb", "auth", "vfs", static const char * const debug_type_strings[] = {"smb", "auth", "vfs",
"oplock", "ipc", "conn", "oplock", "ipc", "conn",
"rdma"}; "rdma"};
static ssize_t debug_show(struct class *class, struct class_attribute *attr, static ssize_t debug_show(struct class *class, struct class_attribute *attr,
char *buf) char *buf)
{ {
ssize_t sz = 0; ssize_t sz = 0;
int i, pos = 0; int i, pos = 0;
...@@ -486,7 +482,7 @@ static ssize_t debug_show(struct class *class, struct class_attribute *attr, ...@@ -486,7 +482,7 @@ static ssize_t debug_show(struct class *class, struct class_attribute *attr,
} }
static ssize_t debug_store(struct class *class, struct class_attribute *attr, static ssize_t debug_store(struct class *class, struct class_attribute *attr,
const char *buf, size_t len) const char *buf, size_t len)
{ {
int i; int i;
......
...@@ -178,19 +178,19 @@ static char *smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr) ...@@ -178,19 +178,19 @@ static char *smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
*/ */
if (*off > 4096) { if (*off > 4096) {
ksmbd_debug(SMB, "offset %d too large, data area ignored\n", ksmbd_debug(SMB, "offset %d too large, data area ignored\n",
*off); *off);
*len = 0; *len = 0;
*off = 0; *off = 0;
} else if (*off < 0) { } else if (*off < 0) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"negative offset %d to data invalid ignore data area\n", "negative offset %d to data invalid ignore data area\n",
*off); *off);
*off = 0; *off = 0;
*len = 0; *len = 0;
} else if (*len < 0) { } else if (*len < 0) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"negative data length %d invalid, data area ignored\n", "negative data length %d invalid, data area ignored\n",
*len); *len);
*len = 0; *len = 0;
} else if (*len > 128 * 1024) { } else if (*len > 128 * 1024) {
ksmbd_debug(SMB, "data area larger than 128K: %d\n", *len); ksmbd_debug(SMB, "data area larger than 128K: %d\n", *len);
...@@ -228,7 +228,7 @@ static unsigned int smb2_calc_size(void *buf) ...@@ -228,7 +228,7 @@ static unsigned int smb2_calc_size(void *buf)
smb2_get_data_area_len(&offset, &data_length, hdr); smb2_get_data_area_len(&offset, &data_length, hdr);
ksmbd_debug(SMB, "SMB2 data length %d offset %d\n", data_length, ksmbd_debug(SMB, "SMB2 data length %d offset %d\n", data_length,
offset); offset);
if (data_length > 0) { if (data_length > 0) {
/* /*
...@@ -239,8 +239,8 @@ static unsigned int smb2_calc_size(void *buf) ...@@ -239,8 +239,8 @@ static unsigned int smb2_calc_size(void *buf)
*/ */
if (offset + 1 < len) if (offset + 1 < len)
ksmbd_debug(SMB, ksmbd_debug(SMB,
"data area offset %d overlaps SMB2 header %d\n", "data area offset %d overlaps SMB2 header %d\n",
offset + 1, len); offset + 1, len);
else else
len = offset + data_length; len = offset + data_length;
} }
...@@ -321,11 +321,11 @@ static int smb2_validate_credit_charge(struct smb2_hdr *hdr) ...@@ -321,11 +321,11 @@ static int smb2_validate_credit_charge(struct smb2_hdr *hdr)
calc_credit_num = DIV_ROUND_UP(max_len, SMB2_MAX_BUFFER_SIZE); calc_credit_num = DIV_ROUND_UP(max_len, SMB2_MAX_BUFFER_SIZE);
if (!credit_charge && max_len > SMB2_MAX_BUFFER_SIZE) { if (!credit_charge && max_len > SMB2_MAX_BUFFER_SIZE) {
ksmbd_err("credit charge is zero and payload size(%d) is bigger than 64K\n", ksmbd_err("credit charge is zero and payload size(%d) is bigger than 64K\n",
max_len); max_len);
return 1; return 1;
} else if (credit_charge < calc_credit_num) { } else if (credit_charge < calc_credit_num) {
ksmbd_err("credit charge : %d, calc_credit_num : %d\n", ksmbd_err("credit charge : %d, calc_credit_num : %d\n",
credit_charge, calc_credit_num); credit_charge, calc_credit_num);
return 1; return 1;
} }
...@@ -357,7 +357,7 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work) ...@@ -357,7 +357,7 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
if (hdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) { if (hdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) {
ksmbd_debug(SMB, "Illegal structure size %u\n", ksmbd_debug(SMB, "Illegal structure size %u\n",
le16_to_cpu(hdr->StructureSize)); le16_to_cpu(hdr->StructureSize));
return 1; return 1;
} }
...@@ -372,8 +372,8 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work) ...@@ -372,8 +372,8 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
(hdr->Status == 0 || pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2_LE)) { (hdr->Status == 0 || pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2_LE)) {
/* error packets have 9 byte structure size */ /* error packets have 9 byte structure size */
ksmbd_debug(SMB, ksmbd_debug(SMB,
"Illegal request size %u for command %d\n", "Illegal request size %u for command %d\n",
le16_to_cpu(pdu->StructureSize2), command); le16_to_cpu(pdu->StructureSize2), command);
return 1; return 1;
} else if (command == SMB2_OPLOCK_BREAK_HE && } else if (command == SMB2_OPLOCK_BREAK_HE &&
hdr->Status == 0 && hdr->Status == 0 &&
...@@ -381,8 +381,8 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work) ...@@ -381,8 +381,8 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
le16_to_cpu(pdu->StructureSize2) != OP_BREAK_STRUCT_SIZE_21) { le16_to_cpu(pdu->StructureSize2) != OP_BREAK_STRUCT_SIZE_21) {
/* special case for SMB2.1 lease break message */ /* special case for SMB2.1 lease break message */
ksmbd_debug(SMB, ksmbd_debug(SMB,
"Illegal request size %d for oplock break\n", "Illegal request size %d for oplock break\n",
le16_to_cpu(pdu->StructureSize2)); le16_to_cpu(pdu->StructureSize2));
return 1; return 1;
} }
} }
...@@ -408,9 +408,9 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work) ...@@ -408,9 +408,9 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
*/ */
if (clc_len < len) { if (clc_len < len) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"cli req padded more than expected. Length %d not %d for cmd:%d mid:%llu\n", "cli req padded more than expected. Length %d not %d for cmd:%d mid:%llu\n",
len, clc_len, command, len, clc_len, command,
le64_to_cpu(hdr->MessageId)); le64_to_cpu(hdr->MessageId));
return 0; return 0;
} }
...@@ -418,9 +418,9 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work) ...@@ -418,9 +418,9 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
return 0; return 0;
ksmbd_debug(SMB, ksmbd_debug(SMB,
"cli req too short, len %d not %d. cmd:%d mid:%llu\n", "cli req too short, len %d not %d. cmd:%d mid:%llu\n",
len, clc_len, command, len, clc_len, command,
le64_to_cpu(hdr->MessageId)); le64_to_cpu(hdr->MessageId));
return 1; return 1;
} }
......
...@@ -296,7 +296,7 @@ int init_smb2_neg_rsp(struct ksmbd_work *work) ...@@ -296,7 +296,7 @@ int init_smb2_neg_rsp(struct ksmbd_work *work)
} }
static int smb2_consume_credit_charge(struct ksmbd_work *work, static int smb2_consume_credit_charge(struct ksmbd_work *work,
unsigned short credit_charge) unsigned short credit_charge)
{ {
struct ksmbd_conn *conn = work->conn; struct ksmbd_conn *conn = work->conn;
unsigned int rsp_credits = 1; unsigned int rsp_credits = 1;
...@@ -336,8 +336,8 @@ int smb2_set_rsp_credits(struct ksmbd_work *work) ...@@ -336,8 +336,8 @@ int smb2_set_rsp_credits(struct ksmbd_work *work)
conn->total_credits = min_credits; conn->total_credits = min_credits;
} }
rsp_credit_charge = smb2_consume_credit_charge(work, rsp_credit_charge =
le16_to_cpu(req_hdr->CreditCharge)); smb2_consume_credit_charge(work, le16_to_cpu(req_hdr->CreditCharge));
if (rsp_credit_charge < 0) if (rsp_credit_charge < 0)
return -EINVAL; return -EINVAL;
...@@ -373,9 +373,9 @@ int smb2_set_rsp_credits(struct ksmbd_work *work) ...@@ -373,9 +373,9 @@ int smb2_set_rsp_credits(struct ksmbd_work *work)
} }
out: out:
ksmbd_debug(SMB, ksmbd_debug(SMB,
"credits: requested[%d] granted[%d] total_granted[%d]\n", "credits: requested[%d] granted[%d] total_granted[%d]\n",
credits_requested, credits_granted, credits_requested, credits_granted,
conn->total_credits); conn->total_credits);
return 0; return 0;
} }
...@@ -420,9 +420,9 @@ static void init_chained_smb2_rsp(struct ksmbd_work *work) ...@@ -420,9 +420,9 @@ static void init_chained_smb2_rsp(struct ksmbd_work *work)
work->next_smb2_rcv_hdr_off += next_hdr_offset; work->next_smb2_rcv_hdr_off += next_hdr_offset;
work->next_smb2_rsp_hdr_off += new_len; work->next_smb2_rsp_hdr_off += new_len;
ksmbd_debug(SMB, ksmbd_debug(SMB,
"Compound req new_len = %d rcv off = %d rsp off = %d\n", "Compound req new_len = %d rcv off = %d rsp off = %d\n",
new_len, work->next_smb2_rcv_hdr_off, new_len, work->next_smb2_rcv_hdr_off,
work->next_smb2_rsp_hdr_off); work->next_smb2_rsp_hdr_off);
rsp_hdr = RESPONSE_BUF_NEXT(work); rsp_hdr = RESPONSE_BUF_NEXT(work);
rcv_hdr = REQUEST_BUF_NEXT(work); rcv_hdr = REQUEST_BUF_NEXT(work);
...@@ -640,7 +640,7 @@ static void destroy_previous_session(struct ksmbd_user *user, u64 id) ...@@ -640,7 +640,7 @@ static void destroy_previous_session(struct ksmbd_user *user, u64 id)
*/ */
static char * static char *
smb2_get_name(struct ksmbd_share_config *share, const char *src, smb2_get_name(struct ksmbd_share_config *share, const char *src,
const int maxlen, struct nls_table *local_nls) const int maxlen, struct nls_table *local_nls)
{ {
char *name, *unixname; char *name, *unixname;
...@@ -684,8 +684,8 @@ int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg) ...@@ -684,8 +684,8 @@ int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg)
rsp_hdr->Id.AsyncId = cpu_to_le64(id); rsp_hdr->Id.AsyncId = cpu_to_le64(id);
ksmbd_debug(SMB, ksmbd_debug(SMB,
"Send interim Response to inform async request id : %d\n", "Send interim Response to inform async request id : %d\n",
work->async_id); work->async_id);
work->cancel_fn = fn; work->cancel_fn = fn;
work->cancel_argv = arg; work->cancel_argv = arg;
...@@ -759,7 +759,7 @@ static int smb2_get_dos_mode(struct kstat *stat, int attribute) ...@@ -759,7 +759,7 @@ static int smb2_get_dos_mode(struct kstat *stat, int attribute)
} }
static void build_preauth_ctxt(struct smb2_preauth_neg_context *pneg_ctxt, static void build_preauth_ctxt(struct smb2_preauth_neg_context *pneg_ctxt,
__le16 hash_id) __le16 hash_id)
{ {
pneg_ctxt->ContextType = SMB2_PREAUTH_INTEGRITY_CAPABILITIES; pneg_ctxt->ContextType = SMB2_PREAUTH_INTEGRITY_CAPABILITIES;
pneg_ctxt->DataLength = cpu_to_le16(38); pneg_ctxt->DataLength = cpu_to_le16(38);
...@@ -771,7 +771,7 @@ static void build_preauth_ctxt(struct smb2_preauth_neg_context *pneg_ctxt, ...@@ -771,7 +771,7 @@ static void build_preauth_ctxt(struct smb2_preauth_neg_context *pneg_ctxt,
} }
static void build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt, static void build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt,
__le16 cipher_type) __le16 cipher_type)
{ {
pneg_ctxt->ContextType = SMB2_ENCRYPTION_CAPABILITIES; pneg_ctxt->ContextType = SMB2_ENCRYPTION_CAPABILITIES;
pneg_ctxt->DataLength = cpu_to_le16(4); pneg_ctxt->DataLength = cpu_to_le16(4);
...@@ -781,7 +781,7 @@ static void build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt, ...@@ -781,7 +781,7 @@ static void build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt,
} }
static void build_compression_ctxt(struct smb2_compression_ctx *pneg_ctxt, static void build_compression_ctxt(struct smb2_compression_ctx *pneg_ctxt,
__le16 comp_algo) __le16 comp_algo)
{ {
pneg_ctxt->ContextType = SMB2_COMPRESSION_CAPABILITIES; pneg_ctxt->ContextType = SMB2_COMPRESSION_CAPABILITIES;
pneg_ctxt->DataLength = pneg_ctxt->DataLength =
...@@ -817,7 +817,7 @@ static void build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt) ...@@ -817,7 +817,7 @@ static void build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
} }
static void assemble_neg_contexts(struct ksmbd_conn *conn, static void assemble_neg_contexts(struct ksmbd_conn *conn,
struct smb2_negotiate_rsp *rsp) struct smb2_negotiate_rsp *rsp)
{ {
/* +4 is to account for the RFC1001 len field */ /* +4 is to account for the RFC1001 len field */
char *pneg_ctxt = (char *)rsp + char *pneg_ctxt = (char *)rsp +
...@@ -826,9 +826,9 @@ static void assemble_neg_contexts(struct ksmbd_conn *conn, ...@@ -826,9 +826,9 @@ static void assemble_neg_contexts(struct ksmbd_conn *conn,
int ctxt_size; int ctxt_size;
ksmbd_debug(SMB, ksmbd_debug(SMB,
"assemble SMB2_PREAUTH_INTEGRITY_CAPABILITIES context\n"); "assemble SMB2_PREAUTH_INTEGRITY_CAPABILITIES context\n");
build_preauth_ctxt((struct smb2_preauth_neg_context *)pneg_ctxt, build_preauth_ctxt((struct smb2_preauth_neg_context *)pneg_ctxt,
conn->preauth_info->Preauth_HashId); conn->preauth_info->Preauth_HashId);
rsp->NegotiateContextCount = cpu_to_le16(neg_ctxt_cnt); rsp->NegotiateContextCount = cpu_to_le16(neg_ctxt_cnt);
inc_rfc1001_len(rsp, AUTH_GSS_PADDING); inc_rfc1001_len(rsp, AUTH_GSS_PADDING);
ctxt_size = sizeof(struct smb2_preauth_neg_context); ctxt_size = sizeof(struct smb2_preauth_neg_context);
...@@ -838,9 +838,9 @@ static void assemble_neg_contexts(struct ksmbd_conn *conn, ...@@ -838,9 +838,9 @@ static void assemble_neg_contexts(struct ksmbd_conn *conn,
if (conn->cipher_type) { if (conn->cipher_type) {
ctxt_size = round_up(ctxt_size, 8); ctxt_size = round_up(ctxt_size, 8);
ksmbd_debug(SMB, ksmbd_debug(SMB,
"assemble SMB2_ENCRYPTION_CAPABILITIES context\n"); "assemble SMB2_ENCRYPTION_CAPABILITIES context\n");
build_encrypt_ctxt((struct smb2_encryption_neg_context *)pneg_ctxt, build_encrypt_ctxt((struct smb2_encryption_neg_context *)pneg_ctxt,
conn->cipher_type); conn->cipher_type);
rsp->NegotiateContextCount = cpu_to_le16(++neg_ctxt_cnt); rsp->NegotiateContextCount = cpu_to_le16(++neg_ctxt_cnt);
ctxt_size += sizeof(struct smb2_encryption_neg_context); ctxt_size += sizeof(struct smb2_encryption_neg_context);
/* Round to 8 byte boundary */ /* Round to 8 byte boundary */
...@@ -852,10 +852,10 @@ static void assemble_neg_contexts(struct ksmbd_conn *conn, ...@@ -852,10 +852,10 @@ static void assemble_neg_contexts(struct ksmbd_conn *conn,
if (conn->compress_algorithm) { if (conn->compress_algorithm) {
ctxt_size = round_up(ctxt_size, 8); ctxt_size = round_up(ctxt_size, 8);
ksmbd_debug(SMB, ksmbd_debug(SMB,
"assemble SMB2_COMPRESSION_CAPABILITIES context\n"); "assemble SMB2_COMPRESSION_CAPABILITIES context\n");
/* Temporarily set to SMB3_COMPRESS_NONE */ /* Temporarily set to SMB3_COMPRESS_NONE */
build_compression_ctxt((struct smb2_compression_ctx *)pneg_ctxt, build_compression_ctxt((struct smb2_compression_ctx *)pneg_ctxt,
conn->compress_algorithm); conn->compress_algorithm);
rsp->NegotiateContextCount = cpu_to_le16(++neg_ctxt_cnt); rsp->NegotiateContextCount = cpu_to_le16(++neg_ctxt_cnt);
ctxt_size += sizeof(struct smb2_compression_ctx); ctxt_size += sizeof(struct smb2_compression_ctx);
/* Round to 8 byte boundary */ /* Round to 8 byte boundary */
...@@ -865,7 +865,7 @@ static void assemble_neg_contexts(struct ksmbd_conn *conn, ...@@ -865,7 +865,7 @@ static void assemble_neg_contexts(struct ksmbd_conn *conn,
if (conn->posix_ext_supported) { if (conn->posix_ext_supported) {
ctxt_size = round_up(ctxt_size, 8); ctxt_size = round_up(ctxt_size, 8);
ksmbd_debug(SMB, ksmbd_debug(SMB,
"assemble SMB2_POSIX_EXTENSIONS_AVAILABLE context\n"); "assemble SMB2_POSIX_EXTENSIONS_AVAILABLE context\n");
build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt); build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt);
rsp->NegotiateContextCount = cpu_to_le16(++neg_ctxt_cnt); rsp->NegotiateContextCount = cpu_to_le16(++neg_ctxt_cnt);
ctxt_size += sizeof(struct smb2_posix_neg_context); ctxt_size += sizeof(struct smb2_posix_neg_context);
...@@ -875,12 +875,11 @@ static void assemble_neg_contexts(struct ksmbd_conn *conn, ...@@ -875,12 +875,11 @@ static void assemble_neg_contexts(struct ksmbd_conn *conn,
} }
static __le32 decode_preauth_ctxt(struct ksmbd_conn *conn, static __le32 decode_preauth_ctxt(struct ksmbd_conn *conn,
struct smb2_preauth_neg_context *pneg_ctxt) struct smb2_preauth_neg_context *pneg_ctxt)
{ {
__le32 err = STATUS_NO_PREAUTH_INTEGRITY_HASH_OVERLAP; __le32 err = STATUS_NO_PREAUTH_INTEGRITY_HASH_OVERLAP;
if (pneg_ctxt->HashAlgorithms == if (pneg_ctxt->HashAlgorithms == SMB2_PREAUTH_INTEGRITY_SHA512) {
SMB2_PREAUTH_INTEGRITY_SHA512) {
conn->preauth_info->Preauth_HashId = conn->preauth_info->Preauth_HashId =
SMB2_PREAUTH_INTEGRITY_SHA512; SMB2_PREAUTH_INTEGRITY_SHA512;
err = STATUS_SUCCESS; err = STATUS_SUCCESS;
...@@ -890,7 +889,7 @@ static __le32 decode_preauth_ctxt(struct ksmbd_conn *conn, ...@@ -890,7 +889,7 @@ static __le32 decode_preauth_ctxt(struct ksmbd_conn *conn,
} }
static int decode_encrypt_ctxt(struct ksmbd_conn *conn, static int decode_encrypt_ctxt(struct ksmbd_conn *conn,
struct smb2_encryption_neg_context *pneg_ctxt) struct smb2_encryption_neg_context *pneg_ctxt)
{ {
int i; int i;
int cph_cnt = le16_to_cpu(pneg_ctxt->CipherCount); int cph_cnt = le16_to_cpu(pneg_ctxt->CipherCount);
...@@ -906,7 +905,7 @@ static int decode_encrypt_ctxt(struct ksmbd_conn *conn, ...@@ -906,7 +905,7 @@ static int decode_encrypt_ctxt(struct ksmbd_conn *conn,
pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES256_CCM || pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES256_CCM ||
pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES256_GCM) { pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES256_GCM) {
ksmbd_debug(SMB, "Cipher ID = 0x%x\n", ksmbd_debug(SMB, "Cipher ID = 0x%x\n",
pneg_ctxt->Ciphers[i]); pneg_ctxt->Ciphers[i]);
conn->cipher_type = pneg_ctxt->Ciphers[i]; conn->cipher_type = pneg_ctxt->Ciphers[i];
break; break;
} }
...@@ -922,7 +921,7 @@ static int decode_encrypt_ctxt(struct ksmbd_conn *conn, ...@@ -922,7 +921,7 @@ static int decode_encrypt_ctxt(struct ksmbd_conn *conn,
} }
static int decode_compress_ctxt(struct ksmbd_conn *conn, static int decode_compress_ctxt(struct ksmbd_conn *conn,
struct smb2_compression_ctx *pneg_ctxt) struct smb2_compression_ctx *pneg_ctxt)
{ {
int algo_cnt = le16_to_cpu(pneg_ctxt->CompressionAlgorithmCount); int algo_cnt = le16_to_cpu(pneg_ctxt->CompressionAlgorithmCount);
...@@ -937,7 +936,7 @@ static int decode_compress_ctxt(struct ksmbd_conn *conn, ...@@ -937,7 +936,7 @@ static int decode_compress_ctxt(struct ksmbd_conn *conn,
} }
static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn, static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
struct smb2_negotiate_req *req) struct smb2_negotiate_req *req)
{ {
int i = 0; int i = 0;
__le32 status = 0; __le32 status = 0;
...@@ -953,16 +952,16 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn, ...@@ -953,16 +952,16 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
while (i++ < neg_ctxt_cnt) { while (i++ < neg_ctxt_cnt) {
if (*ContextType == SMB2_PREAUTH_INTEGRITY_CAPABILITIES) { if (*ContextType == SMB2_PREAUTH_INTEGRITY_CAPABILITIES) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"deassemble SMB2_PREAUTH_INTEGRITY_CAPABILITIES context\n"); "deassemble SMB2_PREAUTH_INTEGRITY_CAPABILITIES context\n");
if (conn->preauth_info->Preauth_HashId) if (conn->preauth_info->Preauth_HashId)
break; break;
status = decode_preauth_ctxt(conn, status = decode_preauth_ctxt(conn,
(struct smb2_preauth_neg_context *)pneg_ctxt); (struct smb2_preauth_neg_context *)pneg_ctxt);
pneg_ctxt += DIV_ROUND_UP(sizeof(struct smb2_preauth_neg_context), 8) * 8; pneg_ctxt += DIV_ROUND_UP(sizeof(struct smb2_preauth_neg_context), 8) * 8;
} else if (*ContextType == SMB2_ENCRYPTION_CAPABILITIES) { } else if (*ContextType == SMB2_ENCRYPTION_CAPABILITIES) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"deassemble SMB2_ENCRYPTION_CAPABILITIES context\n"); "deassemble SMB2_ENCRYPTION_CAPABILITIES context\n");
if (conn->cipher_type) if (conn->cipher_type)
break; break;
...@@ -971,7 +970,7 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn, ...@@ -971,7 +970,7 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
pneg_ctxt += DIV_ROUND_UP(ctxt_size, 8) * 8; pneg_ctxt += DIV_ROUND_UP(ctxt_size, 8) * 8;
} else if (*ContextType == SMB2_COMPRESSION_CAPABILITIES) { } else if (*ContextType == SMB2_COMPRESSION_CAPABILITIES) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"deassemble SMB2_COMPRESSION_CAPABILITIES context\n"); "deassemble SMB2_COMPRESSION_CAPABILITIES context\n");
if (conn->compress_algorithm) if (conn->compress_algorithm)
break; break;
...@@ -980,14 +979,14 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn, ...@@ -980,14 +979,14 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
pneg_ctxt += DIV_ROUND_UP(ctxt_size, 8) * 8; pneg_ctxt += DIV_ROUND_UP(ctxt_size, 8) * 8;
} else if (*ContextType == SMB2_NETNAME_NEGOTIATE_CONTEXT_ID) { } else if (*ContextType == SMB2_NETNAME_NEGOTIATE_CONTEXT_ID) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"deassemble SMB2_NETNAME_NEGOTIATE_CONTEXT_ID context\n"); "deassemble SMB2_NETNAME_NEGOTIATE_CONTEXT_ID context\n");
ctxt_size = sizeof(struct smb2_netname_neg_context); ctxt_size = sizeof(struct smb2_netname_neg_context);
ctxt_size += DIV_ROUND_UP(le16_to_cpu(((struct smb2_netname_neg_context *) ctxt_size += DIV_ROUND_UP(le16_to_cpu(((struct smb2_netname_neg_context *)
pneg_ctxt)->DataLength), 8) * 8; pneg_ctxt)->DataLength), 8) * 8;
pneg_ctxt += ctxt_size; pneg_ctxt += ctxt_size;
} else if (*ContextType == SMB2_POSIX_EXTENSIONS_AVAILABLE) { } else if (*ContextType == SMB2_POSIX_EXTENSIONS_AVAILABLE) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"deassemble SMB2_POSIX_EXTENSIONS_AVAILABLE context\n"); "deassemble SMB2_POSIX_EXTENSIONS_AVAILABLE context\n");
conn->posix_ext_supported = true; conn->posix_ext_supported = true;
pneg_ctxt += DIV_ROUND_UP(sizeof(struct smb2_posix_neg_context), 8) * 8; pneg_ctxt += DIV_ROUND_UP(sizeof(struct smb2_posix_neg_context), 8) * 8;
} }
...@@ -1033,7 +1032,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work) ...@@ -1033,7 +1032,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
case SMB311_PROT_ID: case SMB311_PROT_ID:
conn->preauth_info = conn->preauth_info =
kzalloc(sizeof(struct preauth_integrity_info), kzalloc(sizeof(struct preauth_integrity_info),
GFP_KERNEL); GFP_KERNEL);
if (!conn->preauth_info) { if (!conn->preauth_info) {
rc = -ENOMEM; rc = -ENOMEM;
rsp->hdr.Status = STATUS_INVALID_PARAMETER; rsp->hdr.Status = STATUS_INVALID_PARAMETER;
...@@ -1043,7 +1042,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work) ...@@ -1043,7 +1042,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
status = deassemble_neg_contexts(conn, req); status = deassemble_neg_contexts(conn, req);
if (status != STATUS_SUCCESS) { if (status != STATUS_SUCCESS) {
ksmbd_err("deassemble_neg_contexts error(0x%x)\n", ksmbd_err("deassemble_neg_contexts error(0x%x)\n",
status); status);
rsp->hdr.Status = status; rsp->hdr.Status = status;
rc = -EINVAL; rc = -EINVAL;
goto err_out; goto err_out;
...@@ -1056,8 +1055,8 @@ int smb2_handle_negotiate(struct ksmbd_work *work) ...@@ -1056,8 +1055,8 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
} }
ksmbd_gen_preauth_integrity_hash(conn, ksmbd_gen_preauth_integrity_hash(conn,
work->request_buf, work->request_buf,
conn->preauth_info->Preauth_HashValue); conn->preauth_info->Preauth_HashValue);
rsp->NegotiateContextOffset = rsp->NegotiateContextOffset =
cpu_to_le32(OFFSET_OF_NEG_CONTEXT); cpu_to_le32(OFFSET_OF_NEG_CONTEXT);
assemble_neg_contexts(conn, rsp); assemble_neg_contexts(conn, rsp);
...@@ -1082,7 +1081,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work) ...@@ -1082,7 +1081,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
case BAD_PROT_ID: case BAD_PROT_ID:
default: default:
ksmbd_debug(SMB, "Server dialect :0x%x not supported\n", ksmbd_debug(SMB, "Server dialect :0x%x not supported\n",
conn->dialect); conn->dialect);
rsp->hdr.Status = STATUS_NOT_SUPPORTED; rsp->hdr.Status = STATUS_NOT_SUPPORTED;
rc = -EINVAL; rc = -EINVAL;
goto err_out; goto err_out;
...@@ -1098,7 +1097,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work) ...@@ -1098,7 +1097,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
if (conn->dialect > SMB20_PROT_ID) { if (conn->dialect > SMB20_PROT_ID) {
memcpy(conn->ClientGUID, req->ClientGUID, memcpy(conn->ClientGUID, req->ClientGUID,
SMB2_CLIENT_GUID_SIZE); SMB2_CLIENT_GUID_SIZE);
conn->cli_sec_mode = le16_to_cpu(req->SecurityMode); conn->cli_sec_mode = le16_to_cpu(req->SecurityMode);
} }
...@@ -1112,17 +1111,17 @@ int smb2_handle_negotiate(struct ksmbd_work *work) ...@@ -1112,17 +1111,17 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
rsp->SystemTime = cpu_to_le64(ksmbd_systime()); rsp->SystemTime = cpu_to_le64(ksmbd_systime());
rsp->ServerStartTime = 0; rsp->ServerStartTime = 0;
ksmbd_debug(SMB, "negotiate context offset %d, count %d\n", ksmbd_debug(SMB, "negotiate context offset %d, count %d\n",
le32_to_cpu(rsp->NegotiateContextOffset), le32_to_cpu(rsp->NegotiateContextOffset),
le16_to_cpu(rsp->NegotiateContextCount)); le16_to_cpu(rsp->NegotiateContextCount));
rsp->SecurityBufferOffset = cpu_to_le16(128); rsp->SecurityBufferOffset = cpu_to_le16(128);
rsp->SecurityBufferLength = cpu_to_le16(AUTH_GSS_LENGTH); rsp->SecurityBufferLength = cpu_to_le16(AUTH_GSS_LENGTH);
ksmbd_copy_gss_neg_header(((char *)(&rsp->hdr) + ksmbd_copy_gss_neg_header(((char *)(&rsp->hdr) +
sizeof(rsp->hdr.smb2_buf_length)) + sizeof(rsp->hdr.smb2_buf_length)) +
le16_to_cpu(rsp->SecurityBufferOffset)); le16_to_cpu(rsp->SecurityBufferOffset));
inc_rfc1001_len(rsp, sizeof(struct smb2_negotiate_rsp) - inc_rfc1001_len(rsp, sizeof(struct smb2_negotiate_rsp) -
sizeof(struct smb2_hdr) - sizeof(rsp->Buffer) + sizeof(struct smb2_hdr) - sizeof(rsp->Buffer) +
AUTH_GSS_LENGTH); AUTH_GSS_LENGTH);
rsp->SecurityMode = SMB2_NEGOTIATE_SIGNING_ENABLED_LE; rsp->SecurityMode = SMB2_NEGOTIATE_SIGNING_ENABLED_LE;
conn->use_spnego = true; conn->use_spnego = true;
...@@ -1147,13 +1146,13 @@ int smb2_handle_negotiate(struct ksmbd_work *work) ...@@ -1147,13 +1146,13 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
} }
static int alloc_preauth_hash(struct ksmbd_session *sess, static int alloc_preauth_hash(struct ksmbd_session *sess,
struct ksmbd_conn *conn) struct ksmbd_conn *conn)
{ {
if (sess->Preauth_HashValue) if (sess->Preauth_HashValue)
return 0; return 0;
sess->Preauth_HashValue = kmemdup(conn->preauth_info->Preauth_HashValue, sess->Preauth_HashValue = kmemdup(conn->preauth_info->Preauth_HashValue,
PREAUTH_HASHVALUE_SIZE, GFP_KERNEL); PREAUTH_HASHVALUE_SIZE, GFP_KERNEL);
if (!sess->Preauth_HashValue) if (!sess->Preauth_HashValue)
return -ENOMEM; return -ENOMEM;
...@@ -1180,7 +1179,7 @@ static int generate_preauth_hash(struct ksmbd_work *work) ...@@ -1180,7 +1179,7 @@ static int generate_preauth_hash(struct ksmbd_work *work)
} }
static int decode_negotiation_token(struct ksmbd_work *work, static int decode_negotiation_token(struct ksmbd_work *work,
struct negotiate_message *negblob) struct negotiate_message *negblob)
{ {
struct ksmbd_conn *conn = work->conn; struct ksmbd_conn *conn = work->conn;
struct smb2_sess_setup_req *req; struct smb2_sess_setup_req *req;
...@@ -1203,7 +1202,7 @@ static int decode_negotiation_token(struct ksmbd_work *work, ...@@ -1203,7 +1202,7 @@ static int decode_negotiation_token(struct ksmbd_work *work,
} }
static int ntlm_negotiate(struct ksmbd_work *work, static int ntlm_negotiate(struct ksmbd_work *work,
struct negotiate_message *negblob) struct negotiate_message *negblob)
{ {
struct smb2_sess_setup_req *req = work->request_buf; struct smb2_sess_setup_req *req = work->request_buf;
struct smb2_sess_setup_rsp *rsp = work->response_buf; struct smb2_sess_setup_rsp *rsp = work->response_buf;
...@@ -1247,10 +1246,8 @@ static int ntlm_negotiate(struct ksmbd_work *work, ...@@ -1247,10 +1246,8 @@ static int ntlm_negotiate(struct ksmbd_work *work,
goto out; goto out;
} }
rc = build_spnego_ntlmssp_neg_blob(&spnego_blob, rc = build_spnego_ntlmssp_neg_blob(&spnego_blob, &spnego_blob_len,
&spnego_blob_len, neg_blob, sz);
neg_blob,
sz);
if (rc) { if (rc) {
rc = -ENOMEM; rc = -ENOMEM;
goto out; goto out;
...@@ -1267,7 +1264,7 @@ static int ntlm_negotiate(struct ksmbd_work *work, ...@@ -1267,7 +1264,7 @@ static int ntlm_negotiate(struct ksmbd_work *work,
} }
static struct authenticate_message *user_authblob(struct ksmbd_conn *conn, static struct authenticate_message *user_authblob(struct ksmbd_conn *conn,
struct smb2_sess_setup_req *req) struct smb2_sess_setup_req *req)
{ {
int sz; int sz;
...@@ -1280,7 +1277,7 @@ static struct authenticate_message *user_authblob(struct ksmbd_conn *conn, ...@@ -1280,7 +1277,7 @@ static struct authenticate_message *user_authblob(struct ksmbd_conn *conn,
} }
static struct ksmbd_user *session_user(struct ksmbd_conn *conn, static struct ksmbd_user *session_user(struct ksmbd_conn *conn,
struct smb2_sess_setup_req *req) struct smb2_sess_setup_req *req)
{ {
struct authenticate_message *authblob; struct authenticate_message *authblob;
struct ksmbd_user *user; struct ksmbd_user *user;
...@@ -1396,7 +1393,7 @@ static int ntlm_authenticate(struct ksmbd_work *work) ...@@ -1396,7 +1393,7 @@ static int ntlm_authenticate(struct ksmbd_work *work)
rc = conn->ops->generate_encryptionkey(sess); rc = conn->ops->generate_encryptionkey(sess);
if (rc) { if (rc) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"SMB3 encryption key generation failed\n"); "SMB3 encryption key generation failed\n");
rsp->hdr.Status = STATUS_LOGON_FAILURE; rsp->hdr.Status = STATUS_LOGON_FAILURE;
return rc; return rc;
} }
...@@ -1473,7 +1470,7 @@ static int krb5_authenticate(struct ksmbd_work *work) ...@@ -1473,7 +1470,7 @@ static int krb5_authenticate(struct ksmbd_work *work)
ksmbd_free_user(sess->user); ksmbd_free_user(sess->user);
retval = ksmbd_krb5_authenticate(sess, in_blob, in_len, retval = ksmbd_krb5_authenticate(sess, in_blob, in_len,
out_blob, &out_len); out_blob, &out_len);
if (retval) { if (retval) {
ksmbd_debug(SMB, "krb5 authentication failed\n"); ksmbd_debug(SMB, "krb5 authentication failed\n");
rsp->hdr.Status = STATUS_LOGON_FAILURE; rsp->hdr.Status = STATUS_LOGON_FAILURE;
...@@ -1491,7 +1488,7 @@ static int krb5_authenticate(struct ksmbd_work *work) ...@@ -1491,7 +1488,7 @@ static int krb5_authenticate(struct ksmbd_work *work)
retval = conn->ops->generate_encryptionkey(sess); retval = conn->ops->generate_encryptionkey(sess);
if (retval) { if (retval) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"SMB3 encryption key generation failed\n"); "SMB3 encryption key generation failed\n");
rsp->hdr.Status = STATUS_LOGON_FAILURE; rsp->hdr.Status = STATUS_LOGON_FAILURE;
return retval; return retval;
} }
...@@ -1565,7 +1562,7 @@ int smb2_sess_setup(struct ksmbd_work *work) ...@@ -1565,7 +1562,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
ksmbd_session_register(conn, sess); ksmbd_session_register(conn, sess);
} else { } else {
sess = ksmbd_session_lookup(conn, sess = ksmbd_session_lookup(conn,
le64_to_cpu(req->hdr.SessionId)); le64_to_cpu(req->hdr.SessionId));
if (!sess) { if (!sess) {
rc = -ENOENT; rc = -ENOENT;
rsp->hdr.Status = STATUS_USER_SESSION_DELETED; rsp->hdr.Status = STATUS_USER_SESSION_DELETED;
...@@ -1673,7 +1670,8 @@ int smb2_tree_connect(struct ksmbd_work *work) ...@@ -1673,7 +1670,8 @@ int smb2_tree_connect(struct ksmbd_work *work)
int rc = -EINVAL; int rc = -EINVAL;
treename = smb_strndup_from_utf16(req->Buffer, treename = smb_strndup_from_utf16(req->Buffer,
le16_to_cpu(req->PathLength), true, conn->local_nls); le16_to_cpu(req->PathLength), true,
conn->local_nls);
if (IS_ERR(treename)) { if (IS_ERR(treename)) {
ksmbd_err("treename is NULL\n"); ksmbd_err("treename is NULL\n");
status.ret = KSMBD_TREE_CONN_STATUS_ERROR; status.ret = KSMBD_TREE_CONN_STATUS_ERROR;
...@@ -1687,7 +1685,7 @@ int smb2_tree_connect(struct ksmbd_work *work) ...@@ -1687,7 +1685,7 @@ int smb2_tree_connect(struct ksmbd_work *work)
} }
ksmbd_debug(SMB, "tree connect request for tree %s treename %s\n", ksmbd_debug(SMB, "tree connect request for tree %s treename %s\n",
name, treename); name, treename);
status = ksmbd_tree_conn_connect(sess, name); status = ksmbd_tree_conn_connect(sess, name);
if (status.ret == KSMBD_TREE_CONN_STATUS_OK) if (status.ret == KSMBD_TREE_CONN_STATUS_OK)
...@@ -1772,7 +1770,7 @@ int smb2_tree_connect(struct ksmbd_work *work) ...@@ -1772,7 +1770,7 @@ int smb2_tree_connect(struct ksmbd_work *work)
* Return: file open flags * Return: file open flags
*/ */
static int smb2_create_open_flags(bool file_present, __le32 access, static int smb2_create_open_flags(bool file_present, __le32 access,
__le32 disposition) __le32 disposition)
{ {
int oflags = O_NONBLOCK | O_LARGEFILE; int oflags = O_NONBLOCK | O_LARGEFILE;
...@@ -1910,7 +1908,7 @@ static noinline int create_smb2_pipe(struct ksmbd_work *work) ...@@ -1910,7 +1908,7 @@ static noinline int create_smb2_pipe(struct ksmbd_work *work)
char *name; char *name;
name = smb_strndup_from_utf16(req->Buffer, le16_to_cpu(req->NameLength), name = smb_strndup_from_utf16(req->Buffer, le16_to_cpu(req->NameLength),
1, work->conn->local_nls); 1, work->conn->local_nls);
if (IS_ERR(name)) { if (IS_ERR(name)) {
rsp->hdr.Status = STATUS_NO_MEMORY; rsp->hdr.Status = STATUS_NO_MEMORY;
err = PTR_ERR(name); err = PTR_ERR(name);
...@@ -1987,20 +1985,20 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, struct path *path) ...@@ -1987,20 +1985,20 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, struct path *path)
goto next; goto next;
ksmbd_debug(SMB, ksmbd_debug(SMB,
"name : <%s>, name_len : %u, value_len : %u, next : %u\n", "name : <%s>, name_len : %u, value_len : %u, next : %u\n",
eabuf->name, eabuf->EaNameLength, eabuf->name, eabuf->EaNameLength,
le16_to_cpu(eabuf->EaValueLength), le16_to_cpu(eabuf->EaValueLength),
le32_to_cpu(eabuf->NextEntryOffset)); le32_to_cpu(eabuf->NextEntryOffset));
if (eabuf->EaNameLength > if (eabuf->EaNameLength >
(XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) { (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) {
rc = -EINVAL; rc = -EINVAL;
break; break;
} }
memcpy(attr_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); memcpy(attr_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
memcpy(&attr_name[XATTR_USER_PREFIX_LEN], eabuf->name, memcpy(&attr_name[XATTR_USER_PREFIX_LEN], eabuf->name,
eabuf->EaNameLength); eabuf->EaNameLength);
attr_name[XATTR_USER_PREFIX_LEN + eabuf->EaNameLength] = '\0'; attr_name[XATTR_USER_PREFIX_LEN + eabuf->EaNameLength] = '\0';
value = (char *)&eabuf->name + eabuf->EaNameLength + 1; value = (char *)&eabuf->name + eabuf->EaNameLength + 1;
...@@ -2017,8 +2015,8 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, struct path *path) ...@@ -2017,8 +2015,8 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, struct path *path)
if (rc < 0) { if (rc < 0) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"remove xattr failed(%d)\n", "remove xattr failed(%d)\n",
rc); rc);
break; break;
} }
} }
...@@ -2027,11 +2025,11 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, struct path *path) ...@@ -2027,11 +2025,11 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, struct path *path)
rc = 0; rc = 0;
} else { } else {
rc = ksmbd_vfs_setxattr(path->dentry, attr_name, value, rc = ksmbd_vfs_setxattr(path->dentry, attr_name, value,
le16_to_cpu(eabuf->EaValueLength), 0); le16_to_cpu(eabuf->EaValueLength), 0);
if (rc < 0) { if (rc < 0) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"ksmbd_vfs_setxattr is failed(%d)\n", "ksmbd_vfs_setxattr is failed(%d)\n",
rc); rc);
break; break;
} }
} }
...@@ -2061,7 +2059,8 @@ static inline int check_context_err(void *ctx, char *str) ...@@ -2061,7 +2059,8 @@ static inline int check_context_err(void *ctx, char *str)
} }
static noinline int smb2_set_stream_name_xattr(struct path *path, static noinline int smb2_set_stream_name_xattr(struct path *path,
struct ksmbd_file *fp, char *stream_name, int s_type) struct ksmbd_file *fp,
char *stream_name, int s_type)
{ {
size_t xattr_stream_size; size_t xattr_stream_size;
char *xattr_stream_name; char *xattr_stream_name;
...@@ -2142,13 +2141,13 @@ static int smb2_create_truncate(struct path *path) ...@@ -2142,13 +2141,13 @@ static int smb2_create_truncate(struct path *path)
rc = 0; rc = 0;
if (rc) if (rc)
ksmbd_debug(SMB, ksmbd_debug(SMB,
"ksmbd_truncate_stream_name_xattr failed, rc %d\n", "ksmbd_truncate_stream_name_xattr failed, rc %d\n",
rc); rc);
return rc; return rc;
} }
static void smb2_new_xattrs(struct ksmbd_tree_connect *tcon, struct path *path, static void smb2_new_xattrs(struct ksmbd_tree_connect *tcon, struct path *path,
struct ksmbd_file *fp) struct ksmbd_file *fp)
{ {
struct xattr_dos_attrib da = {0}; struct xattr_dos_attrib da = {0};
int rc; int rc;
...@@ -2169,7 +2168,7 @@ static void smb2_new_xattrs(struct ksmbd_tree_connect *tcon, struct path *path, ...@@ -2169,7 +2168,7 @@ static void smb2_new_xattrs(struct ksmbd_tree_connect *tcon, struct path *path,
} }
static void smb2_update_xattrs(struct ksmbd_tree_connect *tcon, static void smb2_update_xattrs(struct ksmbd_tree_connect *tcon,
struct path *path, struct ksmbd_file *fp) struct path *path, struct ksmbd_file *fp)
{ {
struct xattr_dos_attrib da; struct xattr_dos_attrib da;
int rc; int rc;
...@@ -2190,7 +2189,7 @@ static void smb2_update_xattrs(struct ksmbd_tree_connect *tcon, ...@@ -2190,7 +2189,7 @@ static void smb2_update_xattrs(struct ksmbd_tree_connect *tcon,
} }
static int smb2_creat(struct ksmbd_work *work, struct path *path, char *name, static int smb2_creat(struct ksmbd_work *work, struct path *path, char *name,
int open_flags, umode_t posix_mode, bool is_dir) int open_flags, umode_t posix_mode, bool is_dir)
{ {
struct ksmbd_tree_connect *tcon = work->tcon; struct ksmbd_tree_connect *tcon = work->tcon;
struct ksmbd_share_config *share = tcon->share_conf; struct ksmbd_share_config *share = tcon->share_conf;
...@@ -2220,14 +2219,15 @@ static int smb2_creat(struct ksmbd_work *work, struct path *path, char *name, ...@@ -2220,14 +2219,15 @@ static int smb2_creat(struct ksmbd_work *work, struct path *path, char *name,
rc = ksmbd_vfs_kern_path(name, 0, path, 0); rc = ksmbd_vfs_kern_path(name, 0, path, 0);
if (rc) { if (rc) {
ksmbd_err("cannot get linux path (%s), err = %d\n", ksmbd_err("cannot get linux path (%s), err = %d\n",
name, rc); name, rc);
return rc; return rc;
} }
return 0; return 0;
} }
static int smb2_create_sd_buffer(struct ksmbd_work *work, static int smb2_create_sd_buffer(struct ksmbd_work *work,
struct smb2_create_req *req, struct dentry *dentry) struct smb2_create_req *req,
struct dentry *dentry)
{ {
struct create_context *context; struct create_context *context;
int rc = -ENOENT; int rc = -ENOENT;
...@@ -2241,10 +2241,10 @@ static int smb2_create_sd_buffer(struct ksmbd_work *work, ...@@ -2241,10 +2241,10 @@ static int smb2_create_sd_buffer(struct ksmbd_work *work,
struct create_sd_buf_req *sd_buf; struct create_sd_buf_req *sd_buf;
ksmbd_debug(SMB, ksmbd_debug(SMB,
"Set ACLs using SMB2_CREATE_SD_BUFFER context\n"); "Set ACLs using SMB2_CREATE_SD_BUFFER context\n");
sd_buf = (struct create_sd_buf_req *)context; sd_buf = (struct create_sd_buf_req *)context;
rc = set_info_sec(work->conn, work->tcon, dentry, &sd_buf->ntsd, rc = set_info_sec(work->conn, work->tcon, dentry, &sd_buf->ntsd,
le32_to_cpu(sd_buf->ccontext.DataLength), true); le32_to_cpu(sd_buf->ccontext.DataLength), true);
} }
return rc; return rc;
...@@ -2353,7 +2353,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2353,7 +2353,7 @@ int smb2_open(struct ksmbd_work *work)
if (ksmbd_share_veto_filename(share, name)) { if (ksmbd_share_veto_filename(share, name)) {
rc = -ENOENT; rc = -ENOENT;
ksmbd_debug(SMB, "Reject open(), vetoed file: %s\n", ksmbd_debug(SMB, "Reject open(), vetoed file: %s\n",
name); name);
goto err_out1; goto err_out1;
} }
} else { } else {
...@@ -2376,7 +2376,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2376,7 +2376,7 @@ int smb2_open(struct ksmbd_work *work)
if (le32_to_cpu(req->ImpersonationLevel) > le32_to_cpu(IL_DELEGATE_LE)) { if (le32_to_cpu(req->ImpersonationLevel) > le32_to_cpu(IL_DELEGATE_LE)) {
ksmbd_err("Invalid impersonationlevel : 0x%x\n", ksmbd_err("Invalid impersonationlevel : 0x%x\n",
le32_to_cpu(req->ImpersonationLevel)); le32_to_cpu(req->ImpersonationLevel));
rc = -EIO; rc = -EIO;
rsp->hdr.Status = STATUS_BAD_IMPERSONATION_LEVEL; rsp->hdr.Status = STATUS_BAD_IMPERSONATION_LEVEL;
goto err_out1; goto err_out1;
...@@ -2384,7 +2384,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2384,7 +2384,7 @@ int smb2_open(struct ksmbd_work *work)
if (req->CreateOptions && !(req->CreateOptions & CREATE_OPTIONS_MASK)) { if (req->CreateOptions && !(req->CreateOptions & CREATE_OPTIONS_MASK)) {
ksmbd_err("Invalid create options : 0x%x\n", ksmbd_err("Invalid create options : 0x%x\n",
le32_to_cpu(req->CreateOptions)); le32_to_cpu(req->CreateOptions));
rc = -EINVAL; rc = -EINVAL;
goto err_out1; goto err_out1;
} else { } else {
...@@ -2392,8 +2392,9 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2392,8 +2392,9 @@ int smb2_open(struct ksmbd_work *work)
req->CreateOptions & FILE_RANDOM_ACCESS_LE) req->CreateOptions & FILE_RANDOM_ACCESS_LE)
req->CreateOptions = ~(FILE_SEQUENTIAL_ONLY_LE); req->CreateOptions = ~(FILE_SEQUENTIAL_ONLY_LE);
if (req->CreateOptions & (FILE_OPEN_BY_FILE_ID_LE | if (req->CreateOptions &
CREATE_TREE_CONNECTION | FILE_RESERVE_OPFILTER_LE)) { (FILE_OPEN_BY_FILE_ID_LE | CREATE_TREE_CONNECTION |
FILE_RESERVE_OPFILTER_LE)) {
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
goto err_out1; goto err_out1;
} }
...@@ -2409,23 +2410,23 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2409,23 +2410,23 @@ int smb2_open(struct ksmbd_work *work)
} }
if (le32_to_cpu(req->CreateDisposition) > if (le32_to_cpu(req->CreateDisposition) >
le32_to_cpu(FILE_OVERWRITE_IF_LE)) { le32_to_cpu(FILE_OVERWRITE_IF_LE)) {
ksmbd_err("Invalid create disposition : 0x%x\n", ksmbd_err("Invalid create disposition : 0x%x\n",
le32_to_cpu(req->CreateDisposition)); le32_to_cpu(req->CreateDisposition));
rc = -EINVAL; rc = -EINVAL;
goto err_out1; goto err_out1;
} }
if (!(req->DesiredAccess & DESIRED_ACCESS_MASK)) { if (!(req->DesiredAccess & DESIRED_ACCESS_MASK)) {
ksmbd_err("Invalid desired access : 0x%x\n", ksmbd_err("Invalid desired access : 0x%x\n",
le32_to_cpu(req->DesiredAccess)); le32_to_cpu(req->DesiredAccess));
rc = -EACCES; rc = -EACCES;
goto err_out1; goto err_out1;
} }
if (req->FileAttributes && !(req->FileAttributes & ATTR_MASK_LE)) { if (req->FileAttributes && !(req->FileAttributes & ATTR_MASK_LE)) {
ksmbd_err("Invalid file attribute : 0x%x\n", ksmbd_err("Invalid file attribute : 0x%x\n",
le32_to_cpu(req->FileAttributes)); le32_to_cpu(req->FileAttributes));
rc = -EINVAL; rc = -EINVAL;
goto err_out1; goto err_out1;
} }
...@@ -2447,23 +2448,23 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2447,23 +2448,23 @@ int smb2_open(struct ksmbd_work *work)
} }
context = smb2_find_context_vals(req, context = smb2_find_context_vals(req,
SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST); SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST);
if (IS_ERR(context)) { if (IS_ERR(context)) {
rc = check_context_err(context, rc = check_context_err(context,
SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST); SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST);
if (rc < 0) if (rc < 0)
goto err_out1; goto err_out1;
} else { } else {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"get query maximal access context\n"); "get query maximal access context\n");
maximal_access_ctxt = 1; maximal_access_ctxt = 1;
} }
context = smb2_find_context_vals(req, context = smb2_find_context_vals(req,
SMB2_CREATE_TIMEWARP_REQUEST); SMB2_CREATE_TIMEWARP_REQUEST);
if (IS_ERR(context)) { if (IS_ERR(context)) {
rc = check_context_err(context, rc = check_context_err(context,
SMB2_CREATE_TIMEWARP_REQUEST); SMB2_CREATE_TIMEWARP_REQUEST);
if (rc < 0) if (rc < 0)
goto err_out1; goto err_out1;
} else { } else {
...@@ -2474,10 +2475,10 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2474,10 +2475,10 @@ int smb2_open(struct ksmbd_work *work)
if (tcon->posix_extensions) { if (tcon->posix_extensions) {
context = smb2_find_context_vals(req, context = smb2_find_context_vals(req,
SMB2_CREATE_TAG_POSIX); SMB2_CREATE_TAG_POSIX);
if (IS_ERR(context)) { if (IS_ERR(context)) {
rc = check_context_err(context, rc = check_context_err(context,
SMB2_CREATE_TAG_POSIX); SMB2_CREATE_TAG_POSIX);
if (rc < 0) if (rc < 0)
goto err_out1; goto err_out1;
} else { } else {
...@@ -2516,7 +2517,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2516,7 +2517,7 @@ int smb2_open(struct ksmbd_work *work)
if (!test_tree_conn_flag(tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) { if (!test_tree_conn_flag(tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"User does not have write permission\n"); "User does not have write permission\n");
rc = -EACCES; rc = -EACCES;
path_put(&path); path_put(&path);
goto err_out; goto err_out;
...@@ -2546,11 +2547,11 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2546,11 +2547,11 @@ int smb2_open(struct ksmbd_work *work)
if (rc) { if (rc) {
if (rc == -EACCES) { if (rc == -EACCES) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"User does not have right permission\n"); "User does not have right permission\n");
goto err_out; goto err_out;
} }
ksmbd_debug(SMB, "can not get linux path for %s, rc = %d\n", ksmbd_debug(SMB, "can not get linux path for %s, rc = %d\n",
name, rc); name, rc);
rc = 0; rc = 0;
} else { } else {
file_present = true; file_present = true;
...@@ -2582,7 +2583,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2582,7 +2583,7 @@ int smb2_open(struct ksmbd_work *work)
if (file_present && req->CreateOptions & FILE_NON_DIRECTORY_FILE_LE && if (file_present && req->CreateOptions & FILE_NON_DIRECTORY_FILE_LE &&
S_ISDIR(stat.mode) && !(req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) { S_ISDIR(stat.mode) && !(req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) {
ksmbd_debug(SMB, "open() argument is a directory: %s, %x\n", ksmbd_debug(SMB, "open() argument is a directory: %s, %x\n",
name, req->CreateOptions); name, req->CreateOptions);
rsp->hdr.Status = STATUS_FILE_IS_A_DIRECTORY; rsp->hdr.Status = STATUS_FILE_IS_A_DIRECTORY;
rc = -EIO; rc = -EIO;
goto err_out; goto err_out;
...@@ -2606,7 +2607,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2606,7 +2607,7 @@ int smb2_open(struct ksmbd_work *work)
if (file_present && !(req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) { if (file_present && !(req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) {
rc = smb_check_perm_dacl(conn, path.dentry, &daccess, rc = smb_check_perm_dacl(conn, path.dentry, &daccess,
sess->user->uid); sess->user->uid);
if (rc) if (rc)
goto err_out; goto err_out;
} }
...@@ -2624,13 +2625,13 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2624,13 +2625,13 @@ int smb2_open(struct ksmbd_work *work)
maximal_access = daccess; maximal_access = daccess;
} }
open_flags = smb2_create_open_flags(file_present, open_flags = smb2_create_open_flags(file_present, daccess,
daccess, req->CreateDisposition); req->CreateDisposition);
if (!test_tree_conn_flag(tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) { if (!test_tree_conn_flag(tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
if (open_flags & O_CREAT) { if (open_flags & O_CREAT) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"User does not have write permission\n"); "User does not have write permission\n");
rc = -EACCES; rc = -EACCES;
goto err_out; goto err_out;
} }
...@@ -2639,7 +2640,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2639,7 +2640,7 @@ int smb2_open(struct ksmbd_work *work)
/*create file if not present */ /*create file if not present */
if (!file_present) { if (!file_present) {
rc = smb2_creat(work, &path, name, open_flags, posix_mode, rc = smb2_creat(work, &path, name, open_flags, posix_mode,
req->CreateOptions & FILE_DIRECTORY_FILE_LE); req->CreateOptions & FILE_DIRECTORY_FILE_LE);
if (rc) if (rc)
goto err_out; goto err_out;
...@@ -2663,7 +2664,8 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2663,7 +2664,8 @@ int smb2_open(struct ksmbd_work *work)
*/ */
if (daccess & ~(FILE_READ_ATTRIBUTES_LE | FILE_READ_CONTROL_LE)) { if (daccess & ~(FILE_READ_ATTRIBUTES_LE | FILE_READ_CONTROL_LE)) {
rc = ksmbd_vfs_inode_permission(path.dentry, rc = ksmbd_vfs_inode_permission(path.dentry,
open_flags & O_ACCMODE, may_delete); open_flags & O_ACCMODE,
may_delete);
if (rc) if (rc)
goto err_out; goto err_out;
} }
...@@ -2689,8 +2691,8 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2689,8 +2691,8 @@ int smb2_open(struct ksmbd_work *work)
else else
file_info = FILE_OVERWRITTEN; file_info = FILE_OVERWRITTEN;
if ((req->CreateDisposition & FILE_CREATE_MASK_LE) if ((req->CreateDisposition & FILE_CREATE_MASK_LE) ==
== FILE_SUPERSEDE_LE) FILE_SUPERSEDE_LE)
file_info = FILE_SUPERSEDED; file_info = FILE_SUPERSEDED;
} else if (open_flags & O_CREAT) { } else if (open_flags & O_CREAT) {
file_info = FILE_CREATED; file_info = FILE_CREATED;
...@@ -2732,7 +2734,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2732,7 +2734,7 @@ int smb2_open(struct ksmbd_work *work)
if (test_share_config_flag(work->tcon->share_conf, if (test_share_config_flag(work->tcon->share_conf,
KSMBD_SHARE_FLAG_ACL_XATTR)) { KSMBD_SHARE_FLAG_ACL_XATTR)) {
rc = smb_inherit_dacl(conn, path.dentry, sess->user->uid, rc = smb_inherit_dacl(conn, path.dentry, sess->user->uid,
sess->user->gid); sess->user->gid);
} }
if (rc) { if (rc) {
...@@ -2762,17 +2764,21 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2762,17 +2764,21 @@ int smb2_open(struct ksmbd_work *work)
goto err_out; goto err_out;
rc = build_sec_desc(pntsd, NULL, rc = build_sec_desc(pntsd, NULL,
OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO, OWNER_SECINFO |
&pntsd_size, &fattr); GROUP_SECINFO |
DACL_SECINFO,
&pntsd_size, &fattr);
posix_acl_release(fattr.cf_acls); posix_acl_release(fattr.cf_acls);
posix_acl_release(fattr.cf_dacls); posix_acl_release(fattr.cf_dacls);
rc = ksmbd_vfs_set_sd_xattr(conn, rc = ksmbd_vfs_set_sd_xattr(conn,
path.dentry, pntsd, pntsd_size); path.dentry,
pntsd,
pntsd_size);
kfree(pntsd); kfree(pntsd);
if (rc) if (rc)
ksmbd_err("failed to store ntacl in xattr : %d\n", ksmbd_err("failed to store ntacl in xattr : %d\n",
rc); rc);
} }
} }
} }
...@@ -2829,8 +2835,8 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2829,8 +2835,8 @@ int smb2_open(struct ksmbd_work *work)
if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE) { if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE) {
req_op_level = smb2_map_lease_to_oplock(lc->req_state); req_op_level = smb2_map_lease_to_oplock(lc->req_state);
ksmbd_debug(SMB, ksmbd_debug(SMB,
"lease req for(%s) req oplock state 0x%x, lease state 0x%x\n", "lease req for(%s) req oplock state 0x%x, lease state 0x%x\n",
name, req_op_level, lc->req_state); name, req_op_level, lc->req_state);
rc = find_same_lease_key(sess, fp->f_ci, lc); rc = find_same_lease_key(sess, fp->f_ci, lc);
if (rc) if (rc)
goto err_out; goto err_out;
...@@ -2859,12 +2865,11 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2859,12 +2865,11 @@ int smb2_open(struct ksmbd_work *work)
if (req->CreateContextsOffset) { if (req->CreateContextsOffset) {
struct create_alloc_size_req *az_req; struct create_alloc_size_req *az_req;
az_req = (struct create_alloc_size_req *) az_req = (struct create_alloc_size_req *)smb2_find_context_vals(req,
smb2_find_context_vals(req, SMB2_CREATE_ALLOCATION_SIZE);
SMB2_CREATE_ALLOCATION_SIZE);
if (IS_ERR(az_req)) { if (IS_ERR(az_req)) {
rc = check_context_err(az_req, rc = check_context_err(az_req,
SMB2_CREATE_ALLOCATION_SIZE); SMB2_CREATE_ALLOCATION_SIZE);
if (rc < 0) if (rc < 0)
goto err_out; goto err_out;
} else { } else {
...@@ -2872,13 +2877,13 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2872,13 +2877,13 @@ int smb2_open(struct ksmbd_work *work)
int err; int err;
ksmbd_debug(SMB, ksmbd_debug(SMB,
"request smb2 create allocate size : %llu\n", "request smb2 create allocate size : %llu\n",
alloc_size); alloc_size);
err = ksmbd_vfs_alloc_size(work, fp, alloc_size); err = ksmbd_vfs_alloc_size(work, fp, alloc_size);
if (err < 0) if (err < 0)
ksmbd_debug(SMB, ksmbd_debug(SMB,
"ksmbd_vfs_alloc_size is failed : %d\n", "ksmbd_vfs_alloc_size is failed : %d\n",
err); err);
} }
context = smb2_find_context_vals(req, SMB2_CREATE_QUERY_ON_DISK_ID); context = smb2_find_context_vals(req, SMB2_CREATE_QUERY_ON_DISK_ID);
...@@ -2897,8 +2902,8 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2897,8 +2902,8 @@ int smb2_open(struct ksmbd_work *work)
else else
fp->create_time = ksmbd_UnixTimeToNT(stat.ctime); fp->create_time = ksmbd_UnixTimeToNT(stat.ctime);
if (req->FileAttributes || fp->f_ci->m_fattr == 0) if (req->FileAttributes || fp->f_ci->m_fattr == 0)
fp->f_ci->m_fattr = cpu_to_le32(smb2_get_dos_mode(&stat, fp->f_ci->m_fattr =
le32_to_cpu(req->FileAttributes))); cpu_to_le32(smb2_get_dos_mode(&stat, le32_to_cpu(req->FileAttributes)));
if (!created) if (!created)
smb2_update_xattrs(tcon, &path, fp); smb2_update_xattrs(tcon, &path, fp);
...@@ -2942,7 +2947,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2942,7 +2947,7 @@ int smb2_open(struct ksmbd_work *work)
struct create_context *lease_ccontext; struct create_context *lease_ccontext;
ksmbd_debug(SMB, "lease granted on(%s) lease state 0x%x\n", ksmbd_debug(SMB, "lease granted on(%s) lease state 0x%x\n",
name, opinfo->o_lease->state); name, opinfo->o_lease->state);
rsp->OplockLevel = SMB2_OPLOCK_LEVEL_LEASE; rsp->OplockLevel = SMB2_OPLOCK_LEVEL_LEASE;
lease_ccontext = (struct create_context *)rsp->Buffer; lease_ccontext = (struct create_context *)rsp->Buffer;
...@@ -3170,7 +3175,8 @@ static int dentry_name(struct ksmbd_dir_info *d_info, int info_level) ...@@ -3170,7 +3175,8 @@ static int dentry_name(struct ksmbd_dir_info *d_info, int info_level)
* Return: 0 on success, otherwise error * Return: 0 on success, otherwise error
*/ */
static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level, static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
struct ksmbd_dir_info *d_info, struct ksmbd_kstat *ksmbd_kstat) struct ksmbd_dir_info *d_info,
struct ksmbd_kstat *ksmbd_kstat)
{ {
int next_entry_offset = 0; int next_entry_offset = 0;
char *conv_name; char *conv_name;
...@@ -3323,9 +3329,9 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level, ...@@ -3323,9 +3329,9 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
if (d_info->hide_dot_file && d_info->name[0] == '.') if (d_info->hide_dot_file && d_info->name[0] == '.')
posix_info->DosAttributes |= ATTR_HIDDEN_LE; posix_info->DosAttributes |= ATTR_HIDDEN_LE;
id_to_sid(from_kuid(&init_user_ns, ksmbd_kstat->kstat->uid), id_to_sid(from_kuid(&init_user_ns, ksmbd_kstat->kstat->uid),
SIDNFS_USER, (struct smb_sid *)&posix_info->SidBuffer[0]); SIDNFS_USER, (struct smb_sid *)&posix_info->SidBuffer[0]);
id_to_sid(from_kgid(&init_user_ns, ksmbd_kstat->kstat->gid), id_to_sid(from_kgid(&init_user_ns, ksmbd_kstat->kstat->gid),
SIDNFS_GROUP, (struct smb_sid *)&posix_info->SidBuffer[20]); SIDNFS_GROUP, (struct smb_sid *)&posix_info->SidBuffer[20]);
memcpy(posix_info->name, conv_name, conv_len); memcpy(posix_info->name, conv_name, conv_len);
posix_info->name_len = cpu_to_le32(conv_len); posix_info->name_len = cpu_to_le32(conv_len);
posix_info->NextEntryOffset = cpu_to_le32(next_entry_offset); posix_info->NextEntryOffset = cpu_to_le32(next_entry_offset);
...@@ -3341,9 +3347,9 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level, ...@@ -3341,9 +3347,9 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
kfree(conv_name); kfree(conv_name);
ksmbd_debug(SMB, ksmbd_debug(SMB,
"info_level : %d, buf_len :%d, next_offset : %d, data_count : %d\n", "info_level : %d, buf_len :%d, next_offset : %d, data_count : %d\n",
info_level, d_info->out_buf_len, info_level, d_info->out_buf_len,
next_entry_offset, d_info->data_count); next_entry_offset, d_info->data_count);
return 0; return 0;
} }
...@@ -3392,8 +3398,8 @@ static int process_query_dir_entries(struct smb2_query_dir_private *priv) ...@@ -3392,8 +3398,8 @@ static int process_query_dir_entries(struct smb2_query_dir_private *priv)
if (IS_ERR(dent)) { if (IS_ERR(dent)) {
ksmbd_debug(SMB, "Cannot lookup `%s' [%ld]\n", ksmbd_debug(SMB, "Cannot lookup `%s' [%ld]\n",
priv->d_info->name, priv->d_info->name,
PTR_ERR(dent)); PTR_ERR(dent));
continue; continue;
} }
if (unlikely(d_is_negative(dent))) { if (unlikely(d_is_negative(dent))) {
...@@ -3421,7 +3427,7 @@ static int process_query_dir_entries(struct smb2_query_dir_private *priv) ...@@ -3421,7 +3427,7 @@ static int process_query_dir_entries(struct smb2_query_dir_private *priv)
} }
static int reserve_populate_dentry(struct ksmbd_dir_info *d_info, static int reserve_populate_dentry(struct ksmbd_dir_info *d_info,
int info_level) int info_level)
{ {
int struct_sz; int struct_sz;
int conv_len; int conv_len;
...@@ -3528,7 +3534,7 @@ static int reserve_populate_dentry(struct ksmbd_dir_info *d_info, ...@@ -3528,7 +3534,7 @@ static int reserve_populate_dentry(struct ksmbd_dir_info *d_info,
} }
static int __query_dir(struct dir_context *ctx, const char *name, int namlen, static int __query_dir(struct dir_context *ctx, const char *name, int namlen,
loff_t offset, u64 ino, unsigned int d_type) loff_t offset, u64 ino, unsigned int d_type)
{ {
struct ksmbd_readdir_data *buf; struct ksmbd_readdir_data *buf;
struct smb2_query_dir_private *priv; struct smb2_query_dir_private *priv;
...@@ -3612,17 +3618,18 @@ int smb2_query_dir(struct ksmbd_work *work) ...@@ -3612,17 +3618,18 @@ int smb2_query_dir(struct ksmbd_work *work)
} }
dir_fp = ksmbd_lookup_fd_slow(work, dir_fp = ksmbd_lookup_fd_slow(work,
le64_to_cpu(req->VolatileFileId), le64_to_cpu(req->VolatileFileId),
le64_to_cpu(req->PersistentFileId)); le64_to_cpu(req->PersistentFileId));
if (!dir_fp) { if (!dir_fp) {
rc = -EBADF; rc = -EBADF;
goto err_out2; goto err_out2;
} }
if (!(dir_fp->daccess & FILE_LIST_DIRECTORY_LE) || if (!(dir_fp->daccess & FILE_LIST_DIRECTORY_LE) ||
inode_permission(&init_user_ns, file_inode(dir_fp->filp), MAY_READ | MAY_EXEC)) { inode_permission(&init_user_ns, file_inode(dir_fp->filp),
MAY_READ | MAY_EXEC)) {
ksmbd_err("no right to enumerate directory (%s)\n", ksmbd_err("no right to enumerate directory (%s)\n",
FP_FILENAME(dir_fp)); FP_FILENAME(dir_fp));
rc = -EACCES; rc = -EACCES;
goto err_out2; goto err_out2;
} }
...@@ -3635,8 +3642,8 @@ int smb2_query_dir(struct ksmbd_work *work) ...@@ -3635,8 +3642,8 @@ int smb2_query_dir(struct ksmbd_work *work)
srch_flag = req->Flags; srch_flag = req->Flags;
srch_ptr = smb_strndup_from_utf16(req->Buffer, srch_ptr = smb_strndup_from_utf16(req->Buffer,
le16_to_cpu(req->FileNameLength), 1, le16_to_cpu(req->FileNameLength), 1,
conn->local_nls); conn->local_nls);
if (IS_ERR(srch_ptr)) { if (IS_ERR(srch_ptr)) {
ksmbd_debug(SMB, "Search Pattern not found\n"); ksmbd_debug(SMB, "Search Pattern not found\n");
rc = -EINVAL; rc = -EINVAL;
...@@ -3657,8 +3664,8 @@ int smb2_query_dir(struct ksmbd_work *work) ...@@ -3657,8 +3664,8 @@ int smb2_query_dir(struct ksmbd_work *work)
d_info.wptr = (char *)rsp->Buffer; d_info.wptr = (char *)rsp->Buffer;
d_info.rptr = (char *)rsp->Buffer; d_info.rptr = (char *)rsp->Buffer;
d_info.out_buf_len = (work->response_sz - (get_rfc1002_len(rsp_org) + 4)); d_info.out_buf_len = (work->response_sz - (get_rfc1002_len(rsp_org) + 4));
d_info.out_buf_len = min_t(int, d_info.out_buf_len, d_info.out_buf_len = min_t(int, d_info.out_buf_len, le32_to_cpu(req->OutputBufferLength)) -
le32_to_cpu(req->OutputBufferLength)) - sizeof(struct smb2_query_directory_rsp); sizeof(struct smb2_query_directory_rsp);
d_info.flags = srch_flag; d_info.flags = srch_flag;
/* /*
...@@ -3666,7 +3673,8 @@ int smb2_query_dir(struct ksmbd_work *work) ...@@ -3666,7 +3673,8 @@ int smb2_query_dir(struct ksmbd_work *work)
* in first response * in first response
*/ */
rc = ksmbd_populate_dot_dotdot_entries(work, req->FileInformationClass, rc = ksmbd_populate_dot_dotdot_entries(work, req->FileInformationClass,
dir_fp, &d_info, srch_ptr, smb2_populate_readdir_entry); dir_fp, &d_info, srch_ptr,
smb2_populate_readdir_entry);
if (rc == -ENOSPC) if (rc == -ENOSPC)
rc = 0; rc = 0;
else if (rc) else if (rc)
...@@ -3762,7 +3770,7 @@ int smb2_query_dir(struct ksmbd_work *work) ...@@ -3762,7 +3770,7 @@ int smb2_query_dir(struct ksmbd_work *work)
* Return: 0 on success, otherwise error * Return: 0 on success, otherwise error
*/ */
static int buffer_check_err(int reqOutputBufferLength, static int buffer_check_err(int reqOutputBufferLength,
struct smb2_query_info_rsp *rsp, int infoclass_size) struct smb2_query_info_rsp *rsp, int infoclass_size)
{ {
if (reqOutputBufferLength < le32_to_cpu(rsp->OutputBufferLength)) { if (reqOutputBufferLength < le32_to_cpu(rsp->OutputBufferLength)) {
if (reqOutputBufferLength < infoclass_size) { if (reqOutputBufferLength < infoclass_size) {
...@@ -3797,8 +3805,7 @@ static void get_standard_info_pipe(struct smb2_query_info_rsp *rsp) ...@@ -3797,8 +3805,7 @@ static void get_standard_info_pipe(struct smb2_query_info_rsp *rsp)
inc_rfc1001_len(rsp, sizeof(struct smb2_file_standard_info)); inc_rfc1001_len(rsp, sizeof(struct smb2_file_standard_info));
} }
static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp, static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp, u64 num)
u64 num)
{ {
struct smb2_file_internal_info *file_info; struct smb2_file_internal_info *file_info;
...@@ -3812,8 +3819,8 @@ static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp, ...@@ -3812,8 +3819,8 @@ static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp,
} }
static int smb2_get_info_file_pipe(struct ksmbd_session *sess, static int smb2_get_info_file_pipe(struct ksmbd_session *sess,
struct smb2_query_info_req *req, struct smb2_query_info_req *req,
struct smb2_query_info_rsp *rsp) struct smb2_query_info_rsp *rsp)
{ {
u64 id; u64 id;
int rc; int rc;
...@@ -3827,22 +3834,22 @@ static int smb2_get_info_file_pipe(struct ksmbd_session *sess, ...@@ -3827,22 +3834,22 @@ static int smb2_get_info_file_pipe(struct ksmbd_session *sess,
return -ENOENT; return -ENOENT;
ksmbd_debug(SMB, "FileInfoClass %u, FileId 0x%llx\n", ksmbd_debug(SMB, "FileInfoClass %u, FileId 0x%llx\n",
req->FileInfoClass, le64_to_cpu(req->VolatileFileId)); req->FileInfoClass, le64_to_cpu(req->VolatileFileId));
switch (req->FileInfoClass) { switch (req->FileInfoClass) {
case FILE_STANDARD_INFORMATION: case FILE_STANDARD_INFORMATION:
get_standard_info_pipe(rsp); get_standard_info_pipe(rsp);
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength), rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
rsp, FILE_STANDARD_INFORMATION_SIZE); rsp, FILE_STANDARD_INFORMATION_SIZE);
break; break;
case FILE_INTERNAL_INFORMATION: case FILE_INTERNAL_INFORMATION:
get_internal_info_pipe(rsp, id); get_internal_info_pipe(rsp, id);
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength), rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
rsp, FILE_INTERNAL_INFORMATION_SIZE); rsp, FILE_INTERNAL_INFORMATION_SIZE);
break; break;
default: default:
ksmbd_debug(SMB, "smb2_info_file_pipe for %u not supported\n", ksmbd_debug(SMB, "smb2_info_file_pipe for %u not supported\n",
req->FileInfoClass); req->FileInfoClass);
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
} }
return rc; return rc;
...@@ -3859,8 +3866,8 @@ static int smb2_get_info_file_pipe(struct ksmbd_session *sess, ...@@ -3859,8 +3866,8 @@ static int smb2_get_info_file_pipe(struct ksmbd_session *sess,
* Return: 0 on success, otherwise error * Return: 0 on success, otherwise error
*/ */
static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp, static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp,
struct smb2_query_info_req *req, struct smb2_query_info_req *req,
struct smb2_query_info_rsp *rsp, void *rsp_org) struct smb2_query_info_rsp *rsp, void *rsp_org)
{ {
struct smb2_ea_info *eainfo, *prev_eainfo; struct smb2_ea_info *eainfo, *prev_eainfo;
char *name, *ptr, *xattr_list = NULL, *buf; char *name, *ptr, *xattr_list = NULL, *buf;
...@@ -3883,8 +3890,8 @@ static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -3883,8 +3890,8 @@ static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp,
/* need to send all EAs, if no specific EA is requested*/ /* need to send all EAs, if no specific EA is requested*/
if (le32_to_cpu(req->Flags) & SL_RETURN_SINGLE_ENTRY) if (le32_to_cpu(req->Flags) & SL_RETURN_SINGLE_ENTRY)
ksmbd_debug(SMB, ksmbd_debug(SMB,
"All EAs are requested but need to send single EA entry in rsp flags 0x%x\n", "All EAs are requested but need to send single EA entry in rsp flags 0x%x\n",
le32_to_cpu(req->Flags)); le32_to_cpu(req->Flags));
} }
buf_free_len = work->response_sz - buf_free_len = work->response_sz -
...@@ -3966,7 +3973,7 @@ static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -3966,7 +3973,7 @@ static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp,
if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
memcpy(eainfo->name, &name[XATTR_USER_PREFIX_LEN], memcpy(eainfo->name, &name[XATTR_USER_PREFIX_LEN],
name_len); name_len);
else else
memcpy(eainfo->name, name, name_len); memcpy(eainfo->name, name, name_len);
...@@ -4008,7 +4015,7 @@ static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -4008,7 +4015,7 @@ static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp,
} }
static void get_file_access_info(struct smb2_query_info_rsp *rsp, static void get_file_access_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, void *rsp_org) struct ksmbd_file *fp, void *rsp_org)
{ {
struct smb2_file_access_info *file_info; struct smb2_file_access_info *file_info;
...@@ -4020,7 +4027,7 @@ static void get_file_access_info(struct smb2_query_info_rsp *rsp, ...@@ -4020,7 +4027,7 @@ static void get_file_access_info(struct smb2_query_info_rsp *rsp,
} }
static int get_file_basic_info(struct smb2_query_info_rsp *rsp, static int get_file_basic_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, void *rsp_org) struct ksmbd_file *fp, void *rsp_org)
{ {
struct smb2_file_all_info *basic_info; struct smb2_file_all_info *basic_info;
struct kstat stat; struct kstat stat;
...@@ -4028,7 +4035,7 @@ static int get_file_basic_info(struct smb2_query_info_rsp *rsp, ...@@ -4028,7 +4035,7 @@ static int get_file_basic_info(struct smb2_query_info_rsp *rsp,
if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) { if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) {
ksmbd_err("no right to read the attributes : 0x%x\n", ksmbd_err("no right to read the attributes : 0x%x\n",
fp->daccess); fp->daccess);
return -EACCES; return -EACCES;
} }
...@@ -4051,7 +4058,7 @@ static int get_file_basic_info(struct smb2_query_info_rsp *rsp, ...@@ -4051,7 +4058,7 @@ static int get_file_basic_info(struct smb2_query_info_rsp *rsp,
} }
static unsigned long long get_allocation_size(struct inode *inode, static unsigned long long get_allocation_size(struct inode *inode,
struct kstat *stat) struct kstat *stat)
{ {
unsigned long long alloc_size = 0; unsigned long long alloc_size = 0;
...@@ -4066,7 +4073,7 @@ static unsigned long long get_allocation_size(struct inode *inode, ...@@ -4066,7 +4073,7 @@ static unsigned long long get_allocation_size(struct inode *inode,
} }
static void get_file_standard_info(struct smb2_query_info_rsp *rsp, static void get_file_standard_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, void *rsp_org) struct ksmbd_file *fp, void *rsp_org)
{ {
struct smb2_file_standard_info *sinfo; struct smb2_file_standard_info *sinfo;
unsigned int delete_pending; unsigned int delete_pending;
...@@ -4091,7 +4098,7 @@ static void get_file_standard_info(struct smb2_query_info_rsp *rsp, ...@@ -4091,7 +4098,7 @@ static void get_file_standard_info(struct smb2_query_info_rsp *rsp,
} }
static void get_file_alignment_info(struct smb2_query_info_rsp *rsp, static void get_file_alignment_info(struct smb2_query_info_rsp *rsp,
void *rsp_org) void *rsp_org)
{ {
struct smb2_file_alignment_info *file_info; struct smb2_file_alignment_info *file_info;
...@@ -4104,8 +4111,9 @@ static void get_file_alignment_info(struct smb2_query_info_rsp *rsp, ...@@ -4104,8 +4111,9 @@ static void get_file_alignment_info(struct smb2_query_info_rsp *rsp,
} }
static int get_file_all_info(struct ksmbd_work *work, static int get_file_all_info(struct ksmbd_work *work,
struct smb2_query_info_rsp *rsp, struct ksmbd_file *fp, struct smb2_query_info_rsp *rsp,
void *rsp_org) struct ksmbd_file *fp,
void *rsp_org)
{ {
struct ksmbd_conn *conn = work->conn; struct ksmbd_conn *conn = work->conn;
struct smb2_file_all_info *file_info; struct smb2_file_all_info *file_info;
...@@ -4118,7 +4126,7 @@ static int get_file_all_info(struct ksmbd_work *work, ...@@ -4118,7 +4126,7 @@ static int get_file_all_info(struct ksmbd_work *work,
if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) { if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) {
ksmbd_debug(SMB, "no right to read the attributes : 0x%x\n", ksmbd_debug(SMB, "no right to read the attributes : 0x%x\n",
fp->daccess); fp->daccess);
return -EACCES; return -EACCES;
} }
...@@ -4157,11 +4165,8 @@ static int get_file_all_info(struct ksmbd_work *work, ...@@ -4157,11 +4165,8 @@ static int get_file_all_info(struct ksmbd_work *work,
file_info->CurrentByteOffset = cpu_to_le64(fp->filp->f_pos); file_info->CurrentByteOffset = cpu_to_le64(fp->filp->f_pos);
file_info->Mode = fp->coption; file_info->Mode = fp->coption;
file_info->AlignmentRequirement = 0; file_info->AlignmentRequirement = 0;
conv_len = smbConvertToUTF16((__le16 *)file_info->FileName, conv_len = smbConvertToUTF16((__le16 *)file_info->FileName, filename,
filename, PATH_MAX, conn->local_nls, 0);
PATH_MAX,
conn->local_nls,
0);
conv_len *= 2; conv_len *= 2;
file_info->FileNameLength = cpu_to_le32(conv_len); file_info->FileNameLength = cpu_to_le32(conv_len);
rsp->OutputBufferLength = rsp->OutputBufferLength =
...@@ -4172,8 +4177,9 @@ static int get_file_all_info(struct ksmbd_work *work, ...@@ -4172,8 +4177,9 @@ static int get_file_all_info(struct ksmbd_work *work,
} }
static void get_file_alternate_info(struct ksmbd_work *work, static void get_file_alternate_info(struct ksmbd_work *work,
struct smb2_query_info_rsp *rsp, struct ksmbd_file *fp, struct smb2_query_info_rsp *rsp,
void *rsp_org) struct ksmbd_file *fp,
void *rsp_org)
{ {
struct ksmbd_conn *conn = work->conn; struct ksmbd_conn *conn = work->conn;
struct smb2_file_alt_name_info *file_info; struct smb2_file_alt_name_info *file_info;
...@@ -4192,8 +4198,9 @@ static void get_file_alternate_info(struct ksmbd_work *work, ...@@ -4192,8 +4198,9 @@ static void get_file_alternate_info(struct ksmbd_work *work,
} }
static void get_file_stream_info(struct ksmbd_work *work, static void get_file_stream_info(struct ksmbd_work *work,
struct smb2_query_info_rsp *rsp, struct ksmbd_file *fp, struct smb2_query_info_rsp *rsp,
void *rsp_org) struct ksmbd_file *fp,
void *rsp_org)
{ {
struct ksmbd_conn *conn = work->conn; struct ksmbd_conn *conn = work->conn;
struct smb2_file_stream_info *file_info; struct smb2_file_stream_info *file_info;
...@@ -4236,15 +4243,12 @@ static void get_file_stream_info(struct ksmbd_work *work, ...@@ -4236,15 +4243,12 @@ static void get_file_stream_info(struct ksmbd_work *work,
break; break;
streamlen = snprintf(stream_buf, streamlen + 1, streamlen = snprintf(stream_buf, streamlen + 1,
":%s", &stream_name[XATTR_NAME_STREAM_LEN]); ":%s", &stream_name[XATTR_NAME_STREAM_LEN]);
file_info = (struct smb2_file_stream_info *) file_info = (struct smb2_file_stream_info *)&rsp->Buffer[nbytes];
&rsp->Buffer[nbytes];
streamlen = smbConvertToUTF16((__le16 *)file_info->StreamName, streamlen = smbConvertToUTF16((__le16 *)file_info->StreamName,
stream_buf, stream_buf, streamlen,
streamlen, conn->local_nls, 0);
conn->local_nls,
0);
streamlen *= 2; streamlen *= 2;
kfree(stream_buf); kfree(stream_buf);
file_info->StreamNameLength = cpu_to_le32(streamlen); file_info->StreamNameLength = cpu_to_le32(streamlen);
...@@ -4260,7 +4264,7 @@ static void get_file_stream_info(struct ksmbd_work *work, ...@@ -4260,7 +4264,7 @@ static void get_file_stream_info(struct ksmbd_work *work,
file_info = (struct smb2_file_stream_info *) file_info = (struct smb2_file_stream_info *)
&rsp->Buffer[nbytes]; &rsp->Buffer[nbytes];
streamlen = smbConvertToUTF16((__le16 *)file_info->StreamName, streamlen = smbConvertToUTF16((__le16 *)file_info->StreamName,
"::$DATA", 7, conn->local_nls, 0); "::$DATA", 7, conn->local_nls, 0);
streamlen *= 2; streamlen *= 2;
file_info->StreamNameLength = cpu_to_le32(streamlen); file_info->StreamNameLength = cpu_to_le32(streamlen);
file_info->StreamSize = S_ISDIR(stat.mode) ? 0 : file_info->StreamSize = S_ISDIR(stat.mode) ? 0 :
...@@ -4280,7 +4284,7 @@ static void get_file_stream_info(struct ksmbd_work *work, ...@@ -4280,7 +4284,7 @@ static void get_file_stream_info(struct ksmbd_work *work,
} }
static void get_file_internal_info(struct smb2_query_info_rsp *rsp, static void get_file_internal_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, void *rsp_org) struct ksmbd_file *fp, void *rsp_org)
{ {
struct smb2_file_internal_info *file_info; struct smb2_file_internal_info *file_info;
struct kstat stat; struct kstat stat;
...@@ -4294,7 +4298,7 @@ static void get_file_internal_info(struct smb2_query_info_rsp *rsp, ...@@ -4294,7 +4298,7 @@ static void get_file_internal_info(struct smb2_query_info_rsp *rsp,
} }
static int get_file_network_open_info(struct smb2_query_info_rsp *rsp, static int get_file_network_open_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, void *rsp_org) struct ksmbd_file *fp, void *rsp_org)
{ {
struct smb2_file_ntwrk_info *file_info; struct smb2_file_ntwrk_info *file_info;
struct inode *inode; struct inode *inode;
...@@ -4342,7 +4346,7 @@ static void get_file_ea_info(struct smb2_query_info_rsp *rsp, void *rsp_org) ...@@ -4342,7 +4346,7 @@ static void get_file_ea_info(struct smb2_query_info_rsp *rsp, void *rsp_org)
} }
static void get_file_position_info(struct smb2_query_info_rsp *rsp, static void get_file_position_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, void *rsp_org) struct ksmbd_file *fp, void *rsp_org)
{ {
struct smb2_file_pos_info *file_info; struct smb2_file_pos_info *file_info;
...@@ -4354,7 +4358,7 @@ static void get_file_position_info(struct smb2_query_info_rsp *rsp, ...@@ -4354,7 +4358,7 @@ static void get_file_position_info(struct smb2_query_info_rsp *rsp,
} }
static void get_file_mode_info(struct smb2_query_info_rsp *rsp, static void get_file_mode_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, void *rsp_org) struct ksmbd_file *fp, void *rsp_org)
{ {
struct smb2_file_mode_info *file_info; struct smb2_file_mode_info *file_info;
...@@ -4366,7 +4370,7 @@ static void get_file_mode_info(struct smb2_query_info_rsp *rsp, ...@@ -4366,7 +4370,7 @@ static void get_file_mode_info(struct smb2_query_info_rsp *rsp,
} }
static void get_file_compression_info(struct smb2_query_info_rsp *rsp, static void get_file_compression_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, void *rsp_org) struct ksmbd_file *fp, void *rsp_org)
{ {
struct smb2_file_comp_info *file_info; struct smb2_file_comp_info *file_info;
struct kstat stat; struct kstat stat;
...@@ -4387,7 +4391,7 @@ static void get_file_compression_info(struct smb2_query_info_rsp *rsp, ...@@ -4387,7 +4391,7 @@ static void get_file_compression_info(struct smb2_query_info_rsp *rsp,
} }
static int get_file_attribute_tag_info(struct smb2_query_info_rsp *rsp, static int get_file_attribute_tag_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, void *rsp_org) struct ksmbd_file *fp, void *rsp_org)
{ {
struct smb2_file_attr_tag_info *file_info; struct smb2_file_attr_tag_info *file_info;
...@@ -4402,13 +4406,12 @@ static int get_file_attribute_tag_info(struct smb2_query_info_rsp *rsp, ...@@ -4402,13 +4406,12 @@ static int get_file_attribute_tag_info(struct smb2_query_info_rsp *rsp,
file_info->ReparseTag = 0; file_info->ReparseTag = 0;
rsp->OutputBufferLength = rsp->OutputBufferLength =
cpu_to_le32(sizeof(struct smb2_file_attr_tag_info)); cpu_to_le32(sizeof(struct smb2_file_attr_tag_info));
inc_rfc1001_len(rsp_org, inc_rfc1001_len(rsp_org, sizeof(struct smb2_file_attr_tag_info));
sizeof(struct smb2_file_attr_tag_info));
return 0; return 0;
} }
static int find_file_posix_info(struct smb2_query_info_rsp *rsp, static int find_file_posix_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, void *rsp_org) struct ksmbd_file *fp, void *rsp_org)
{ {
struct smb311_posix_qinfo *file_info; struct smb311_posix_qinfo *file_info;
struct inode *inode = FP_INODE(fp); struct inode *inode = FP_INODE(fp);
...@@ -4436,8 +4439,8 @@ static int find_file_posix_info(struct smb2_query_info_rsp *rsp, ...@@ -4436,8 +4439,8 @@ static int find_file_posix_info(struct smb2_query_info_rsp *rsp,
} }
static int smb2_get_info_file(struct ksmbd_work *work, static int smb2_get_info_file(struct ksmbd_work *work,
struct smb2_query_info_req *req, struct smb2_query_info_req *req,
struct smb2_query_info_rsp *rsp, void *rsp_org) struct smb2_query_info_rsp *rsp, void *rsp_org)
{ {
struct ksmbd_file *fp; struct ksmbd_file *fp;
int fileinfoclass = 0; int fileinfoclass = 0;
...@@ -4454,7 +4457,7 @@ static int smb2_get_info_file(struct ksmbd_work *work, ...@@ -4454,7 +4457,7 @@ static int smb2_get_info_file(struct ksmbd_work *work,
if (work->next_smb2_rcv_hdr_off) { if (work->next_smb2_rcv_hdr_off) {
if (!HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) { if (!HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) {
ksmbd_debug(SMB, "Compound request set FID = %u\n", ksmbd_debug(SMB, "Compound request set FID = %u\n",
work->compound_fid); work->compound_fid);
id = work->compound_fid; id = work->compound_fid;
pid = work->compound_pfid; pid = work->compound_pfid;
} }
...@@ -4569,8 +4572,8 @@ static int smb2_get_info_file(struct ksmbd_work *work, ...@@ -4569,8 +4572,8 @@ static int smb2_get_info_file(struct ksmbd_work *work,
} }
static int smb2_get_info_filesystem(struct ksmbd_work *work, static int smb2_get_info_filesystem(struct ksmbd_work *work,
struct smb2_query_info_req *req, struct smb2_query_info_req *req,
struct smb2_query_info_rsp *rsp, void *rsp_org) struct smb2_query_info_rsp *rsp, void *rsp_org)
{ {
struct ksmbd_session *sess = work->sess; struct ksmbd_session *sess = work->sess;
struct ksmbd_conn *conn = sess->conn; struct ksmbd_conn *conn = sess->conn;
...@@ -4801,8 +4804,8 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, ...@@ -4801,8 +4804,8 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
} }
static int smb2_get_info_sec(struct ksmbd_work *work, static int smb2_get_info_sec(struct ksmbd_work *work,
struct smb2_query_info_req *req, struct smb2_query_info_req *req,
struct smb2_query_info_rsp *rsp, void *rsp_org) struct smb2_query_info_rsp *rsp, void *rsp_org)
{ {
struct ksmbd_file *fp; struct ksmbd_file *fp;
struct smb_ntsd *pntsd = (struct smb_ntsd *)rsp->Buffer, *ppntsd = NULL; struct smb_ntsd *pntsd = (struct smb_ntsd *)rsp->Buffer, *ppntsd = NULL;
...@@ -4815,7 +4818,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work, ...@@ -4815,7 +4818,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
if (addition_info & ~(OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO)) { if (addition_info & ~(OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO)) {
ksmbd_debug(SMB, "Unsupported addition info: 0x%x)\n", ksmbd_debug(SMB, "Unsupported addition info: 0x%x)\n",
addition_info); addition_info);
pntsd->revision = cpu_to_le16(1); pntsd->revision = cpu_to_le16(1);
pntsd->type = cpu_to_le16(SELF_RELATIVE | DACL_PROTECTED); pntsd->type = cpu_to_le16(SELF_RELATIVE | DACL_PROTECTED);
...@@ -4834,7 +4837,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work, ...@@ -4834,7 +4837,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
if (work->next_smb2_rcv_hdr_off) { if (work->next_smb2_rcv_hdr_off) {
if (!HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) { if (!HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) {
ksmbd_debug(SMB, "Compound request set FID = %u\n", ksmbd_debug(SMB, "Compound request set FID = %u\n",
work->compound_fid); work->compound_fid);
id = work->compound_fid; id = work->compound_fid;
pid = work->compound_pfid; pid = work->compound_pfid;
} }
...@@ -4901,7 +4904,7 @@ int smb2_query_info(struct ksmbd_work *work) ...@@ -4901,7 +4904,7 @@ int smb2_query_info(struct ksmbd_work *work)
break; break;
default: default:
ksmbd_debug(SMB, "InfoType %d not supported yet\n", ksmbd_debug(SMB, "InfoType %d not supported yet\n",
req->InfoType); req->InfoType);
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
} }
...@@ -4917,7 +4920,7 @@ int smb2_query_info(struct ksmbd_work *work) ...@@ -4917,7 +4920,7 @@ int smb2_query_info(struct ksmbd_work *work)
smb2_set_err_rsp(work); smb2_set_err_rsp(work);
ksmbd_debug(SMB, "error while processing smb2 query rc = %d\n", ksmbd_debug(SMB, "error while processing smb2 query rc = %d\n",
rc); rc);
return rc; return rc;
} }
rsp->StructureSize = cpu_to_le16(9); rsp->StructureSize = cpu_to_le16(9);
...@@ -5008,8 +5011,8 @@ int smb2_close(struct ksmbd_work *work) ...@@ -5008,8 +5011,8 @@ int smb2_close(struct ksmbd_work *work)
goto out; goto out;
} else { } else {
ksmbd_debug(SMB, "Compound request set FID = %u:%u\n", ksmbd_debug(SMB, "Compound request set FID = %u:%u\n",
work->compound_fid, work->compound_fid,
work->compound_pfid); work->compound_pfid);
volatile_id = work->compound_fid; volatile_id = work->compound_fid;
/* file closed, stored id is not valid anymore */ /* file closed, stored id is not valid anymore */
...@@ -5086,8 +5089,8 @@ int smb2_echo(struct ksmbd_work *work) ...@@ -5086,8 +5089,8 @@ int smb2_echo(struct ksmbd_work *work)
} }
static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp, static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
struct smb2_file_rename_info *file_info, struct smb2_file_rename_info *file_info,
struct nls_table *local_nls) struct nls_table *local_nls)
{ {
struct ksmbd_share_config *share = fp->tcon->share_conf; struct ksmbd_share_config *share = fp->tcon->share_conf;
char *new_name = NULL, *abs_oldname = NULL, *old_name = NULL; char *new_name = NULL, *abs_oldname = NULL, *old_name = NULL;
...@@ -5111,7 +5114,7 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -5111,7 +5114,7 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
old_name++; old_name++;
} else { } else {
ksmbd_debug(SMB, "can't get last component in path %s\n", ksmbd_debug(SMB, "can't get last component in path %s\n",
abs_oldname); abs_oldname);
rc = -ENOENT; rc = -ENOENT;
goto out; goto out;
} }
...@@ -5154,7 +5157,7 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -5154,7 +5157,7 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
NULL, 0, 0); NULL, 0, 0);
if (rc < 0) { if (rc < 0) {
ksmbd_err("failed to store stream name in xattr: %d\n", ksmbd_err("failed to store stream name in xattr: %d\n",
rc); rc);
rc = -EINVAL; rc = -EINVAL;
goto out; goto out;
} }
...@@ -5182,7 +5185,7 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -5182,7 +5185,7 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
if (rc != -ENOTEMPTY) if (rc != -ENOTEMPTY)
rc = -EINVAL; rc = -EINVAL;
ksmbd_debug(SMB, "cannot delete %s, rc %d\n", ksmbd_debug(SMB, "cannot delete %s, rc %d\n",
new_name, rc); new_name, rc);
goto out; goto out;
} }
} }
...@@ -5191,7 +5194,7 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -5191,7 +5194,7 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
strncmp(old_name, path.dentry->d_name.name, strlen(old_name))) { strncmp(old_name, path.dentry->d_name.name, strlen(old_name))) {
rc = -EEXIST; rc = -EEXIST;
ksmbd_debug(SMB, ksmbd_debug(SMB,
"cannot rename already existing file\n"); "cannot rename already existing file\n");
goto out; goto out;
} }
} }
...@@ -5205,9 +5208,10 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -5205,9 +5208,10 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
} }
static int smb2_create_link(struct ksmbd_work *work, static int smb2_create_link(struct ksmbd_work *work,
struct ksmbd_share_config *share, struct ksmbd_share_config *share,
struct smb2_file_link_info *file_info, struct file *filp, struct smb2_file_link_info *file_info,
struct nls_table *local_nls) struct file *filp,
struct nls_table *local_nls)
{ {
char *link_name = NULL, *target_name = NULL, *pathname = NULL; char *link_name = NULL, *target_name = NULL, *pathname = NULL;
struct path path; struct path path;
...@@ -5248,7 +5252,7 @@ static int smb2_create_link(struct ksmbd_work *work, ...@@ -5248,7 +5252,7 @@ static int smb2_create_link(struct ksmbd_work *work,
if (rc) { if (rc) {
rc = -EINVAL; rc = -EINVAL;
ksmbd_debug(SMB, "cannot delete %s\n", ksmbd_debug(SMB, "cannot delete %s\n",
link_name); link_name);
goto out; goto out;
} }
} }
...@@ -5271,7 +5275,7 @@ static int smb2_create_link(struct ksmbd_work *work, ...@@ -5271,7 +5275,7 @@ static int smb2_create_link(struct ksmbd_work *work,
} }
static int set_file_basic_info(struct ksmbd_file *fp, char *buf, static int set_file_basic_info(struct ksmbd_file *fp, char *buf,
struct ksmbd_share_config *share) struct ksmbd_share_config *share)
{ {
struct smb2_file_all_info *file_info; struct smb2_file_all_info *file_info;
struct iattr attrs; struct iattr attrs;
...@@ -5335,7 +5339,7 @@ static int set_file_basic_info(struct ksmbd_file *fp, char *buf, ...@@ -5335,7 +5339,7 @@ static int set_file_basic_info(struct ksmbd_file *fp, char *buf,
rc = ksmbd_vfs_set_dos_attrib_xattr(filp->f_path.dentry, &da); rc = ksmbd_vfs_set_dos_attrib_xattr(filp->f_path.dentry, &da);
if (rc) if (rc)
ksmbd_debug(SMB, ksmbd_debug(SMB,
"failed to restore file attribute in EA\n"); "failed to restore file attribute in EA\n");
rc = 0; rc = 0;
} }
...@@ -5367,7 +5371,7 @@ static int set_file_basic_info(struct ksmbd_file *fp, char *buf, ...@@ -5367,7 +5371,7 @@ static int set_file_basic_info(struct ksmbd_file *fp, char *buf,
} }
static int set_file_allocation_info(struct ksmbd_work *work, static int set_file_allocation_info(struct ksmbd_work *work,
struct ksmbd_file *fp, char *buf) struct ksmbd_file *fp, char *buf)
{ {
/* /*
* TODO : It's working fine only when store dos attributes * TODO : It's working fine only when store dos attributes
...@@ -5417,7 +5421,7 @@ static int set_file_allocation_info(struct ksmbd_work *work, ...@@ -5417,7 +5421,7 @@ static int set_file_allocation_info(struct ksmbd_work *work,
} }
static int set_end_of_file_info(struct ksmbd_work *work, struct ksmbd_file *fp, static int set_end_of_file_info(struct ksmbd_work *work, struct ksmbd_file *fp,
char *buf) char *buf)
{ {
struct smb2_file_eof_info *file_eof_info; struct smb2_file_eof_info *file_eof_info;
loff_t newsize; loff_t newsize;
...@@ -5440,11 +5444,11 @@ static int set_end_of_file_info(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -5440,11 +5444,11 @@ static int set_end_of_file_info(struct ksmbd_work *work, struct ksmbd_file *fp,
*/ */
if (inode->i_sb->s_magic != MSDOS_SUPER_MAGIC) { if (inode->i_sb->s_magic != MSDOS_SUPER_MAGIC) {
ksmbd_debug(SMB, "filename : %s truncated to newsize %lld\n", ksmbd_debug(SMB, "filename : %s truncated to newsize %lld\n",
fp->filename, newsize); fp->filename, newsize);
rc = ksmbd_vfs_truncate(work, NULL, fp, newsize); rc = ksmbd_vfs_truncate(work, NULL, fp, newsize);
if (rc) { if (rc) {
ksmbd_debug(SMB, "truncate failed! filename : %s err %d\n", ksmbd_debug(SMB, "truncate failed! filename : %s err %d\n",
fp->filename, rc); fp->filename, rc);
if (rc != -EAGAIN) if (rc != -EAGAIN)
rc = -EBADF; rc = -EBADF;
return rc; return rc;
...@@ -5454,7 +5458,7 @@ static int set_end_of_file_info(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -5454,7 +5458,7 @@ static int set_end_of_file_info(struct ksmbd_work *work, struct ksmbd_file *fp,
} }
static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp, static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp,
char *buf) char *buf)
{ {
struct ksmbd_file *parent_fp; struct ksmbd_file *parent_fp;
...@@ -5518,7 +5522,7 @@ static int set_file_position_info(struct ksmbd_file *fp, char *buf) ...@@ -5518,7 +5522,7 @@ static int set_file_position_info(struct ksmbd_file *fp, char *buf)
(fp->coption == FILE_NO_INTERMEDIATE_BUFFERING_LE && (fp->coption == FILE_NO_INTERMEDIATE_BUFFERING_LE &&
current_byte_offset & (sector_size - 1))) { current_byte_offset & (sector_size - 1))) {
ksmbd_err("CurrentByteOffset is not valid : %llu\n", ksmbd_err("CurrentByteOffset is not valid : %llu\n",
current_byte_offset); current_byte_offset);
return -EINVAL; return -EINVAL;
} }
...@@ -5561,7 +5565,8 @@ static int set_file_mode_info(struct ksmbd_file *fp, char *buf) ...@@ -5561,7 +5565,8 @@ static int set_file_mode_info(struct ksmbd_file *fp, char *buf)
* TODO: need to implement an error handling for STATUS_INFO_LENGTH_MISMATCH * TODO: need to implement an error handling for STATUS_INFO_LENGTH_MISMATCH
*/ */
static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
int info_class, char *buf, struct ksmbd_share_config *share) int info_class, char *buf,
struct ksmbd_share_config *share)
{ {
switch (info_class) { switch (info_class) {
case FILE_BASIC_INFORMATION: case FILE_BASIC_INFORMATION:
...@@ -5576,20 +5581,20 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -5576,20 +5581,20 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
case FILE_RENAME_INFORMATION: case FILE_RENAME_INFORMATION:
if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) { if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"User does not have write permission\n"); "User does not have write permission\n");
return -EACCES; return -EACCES;
} }
return set_rename_info(work, fp, buf); return set_rename_info(work, fp, buf);
case FILE_LINK_INFORMATION: case FILE_LINK_INFORMATION:
return smb2_create_link(work, work->tcon->share_conf, return smb2_create_link(work, work->tcon->share_conf,
(struct smb2_file_link_info *)buf, fp->filp, (struct smb2_file_link_info *)buf, fp->filp,
work->sess->conn->local_nls); work->sess->conn->local_nls);
case FILE_DISPOSITION_INFORMATION: case FILE_DISPOSITION_INFORMATION:
if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) { if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"User does not have write permission\n"); "User does not have write permission\n");
return -EACCES; return -EACCES;
} }
return set_file_disposition_info(fp, buf); return set_file_disposition_info(fp, buf);
...@@ -5618,7 +5623,7 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -5618,7 +5623,7 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
} }
static int smb2_set_info_sec(struct ksmbd_file *fp, int addition_info, static int smb2_set_info_sec(struct ksmbd_file *fp, int addition_info,
char *buffer, int buf_len) char *buffer, int buf_len)
{ {
struct smb_ntsd *pntsd = (struct smb_ntsd *)buffer; struct smb_ntsd *pntsd = (struct smb_ntsd *)buffer;
...@@ -5650,7 +5655,7 @@ int smb2_set_info(struct ksmbd_work *work) ...@@ -5650,7 +5655,7 @@ int smb2_set_info(struct ksmbd_work *work)
rsp = RESPONSE_BUF_NEXT(work); rsp = RESPONSE_BUF_NEXT(work);
if (!HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) { if (!HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) {
ksmbd_debug(SMB, "Compound request set FID = %u\n", ksmbd_debug(SMB, "Compound request set FID = %u\n",
work->compound_fid); work->compound_fid);
id = work->compound_fid; id = work->compound_fid;
pid = work->compound_pfid; pid = work->compound_pfid;
} }
...@@ -5680,8 +5685,9 @@ int smb2_set_info(struct ksmbd_work *work) ...@@ -5680,8 +5685,9 @@ int smb2_set_info(struct ksmbd_work *work)
case SMB2_O_INFO_SECURITY: case SMB2_O_INFO_SECURITY:
ksmbd_debug(SMB, "GOT SMB2_O_INFO_SECURITY\n"); ksmbd_debug(SMB, "GOT SMB2_O_INFO_SECURITY\n");
rc = smb2_set_info_sec(fp, rc = smb2_set_info_sec(fp,
le32_to_cpu(req->AdditionalInformation), req->Buffer, le32_to_cpu(req->AdditionalInformation),
le32_to_cpu(req->BufferLength)); req->Buffer,
le32_to_cpu(req->BufferLength));
break; break;
default: default:
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
...@@ -5716,8 +5722,7 @@ int smb2_set_info(struct ksmbd_work *work) ...@@ -5716,8 +5722,7 @@ int smb2_set_info(struct ksmbd_work *work)
rsp->hdr.Status = STATUS_INVALID_INFO_CLASS; rsp->hdr.Status = STATUS_INVALID_INFO_CLASS;
smb2_set_err_rsp(work); smb2_set_err_rsp(work);
ksmbd_fd_put(work, fp); ksmbd_fd_put(work, fp);
ksmbd_debug(SMB, "error while processing smb2 query rc = %d\n", ksmbd_debug(SMB, "error while processing smb2 query rc = %d\n", rc);
rc);
return rc; return rc;
} }
...@@ -5753,7 +5758,7 @@ static noinline int smb2_read_pipe(struct ksmbd_work *work) ...@@ -5753,7 +5758,7 @@ static noinline int smb2_read_pipe(struct ksmbd_work *work)
} }
memcpy(work->aux_payload_buf, rpc_resp->payload, memcpy(work->aux_payload_buf, rpc_resp->payload,
rpc_resp->payload_sz); rpc_resp->payload_sz);
nbytes = rpc_resp->payload_sz; nbytes = rpc_resp->payload_sz;
work->resp_hdr_sz = get_rfc1002_len(rsp) + 4; work->resp_hdr_sz = get_rfc1002_len(rsp) + 4;
...@@ -5778,7 +5783,8 @@ static noinline int smb2_read_pipe(struct ksmbd_work *work) ...@@ -5778,7 +5783,8 @@ static noinline int smb2_read_pipe(struct ksmbd_work *work)
} }
static ssize_t smb2_read_rdma_channel(struct ksmbd_work *work, static ssize_t smb2_read_rdma_channel(struct ksmbd_work *work,
struct smb2_read_req *req, void *data_buf, size_t length) struct smb2_read_req *req, void *data_buf,
size_t length)
{ {
struct smb2_buffer_desc_v1 *desc = struct smb2_buffer_desc_v1 *desc =
(struct smb2_buffer_desc_v1 *)&req->Buffer[0]; (struct smb2_buffer_desc_v1 *)&req->Buffer[0];
...@@ -5797,8 +5803,9 @@ static ssize_t smb2_read_rdma_channel(struct ksmbd_work *work, ...@@ -5797,8 +5803,9 @@ static ssize_t smb2_read_rdma_channel(struct ksmbd_work *work,
work->remote_key = le32_to_cpu(desc->token); work->remote_key = le32_to_cpu(desc->token);
err = ksmbd_conn_rdma_write(work->conn, data_buf, length, err = ksmbd_conn_rdma_write(work->conn, data_buf, length,
le32_to_cpu(desc->token), le64_to_cpu(desc->offset), le32_to_cpu(desc->token),
le32_to_cpu(desc->length)); le64_to_cpu(desc->offset),
le32_to_cpu(desc->length));
if (err) if (err)
return err; return err;
...@@ -5831,9 +5838,8 @@ int smb2_read(struct ksmbd_work *work) ...@@ -5831,9 +5838,8 @@ int smb2_read(struct ksmbd_work *work)
return smb2_read_pipe(work); return smb2_read_pipe(work);
} }
fp = ksmbd_lookup_fd_slow(work, fp = ksmbd_lookup_fd_slow(work, le64_to_cpu(req->VolatileFileId),
le64_to_cpu(req->VolatileFileId), le64_to_cpu(req->PersistentFileId));
le64_to_cpu(req->PersistentFileId));
if (!fp) { if (!fp) {
err = -ENOENT; err = -ENOENT;
goto out; goto out;
...@@ -5857,7 +5863,7 @@ int smb2_read(struct ksmbd_work *work) ...@@ -5857,7 +5863,7 @@ int smb2_read(struct ksmbd_work *work)
} }
ksmbd_debug(SMB, "filename %s, offset %lld, len %zu\n", FP_FILENAME(fp), ksmbd_debug(SMB, "filename %s, offset %lld, len %zu\n", FP_FILENAME(fp),
offset, length); offset, length);
if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_RBUF) { if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_RBUF) {
work->aux_payload_buf = work->aux_payload_buf =
...@@ -5890,13 +5896,14 @@ int smb2_read(struct ksmbd_work *work) ...@@ -5890,13 +5896,14 @@ int smb2_read(struct ksmbd_work *work)
} }
ksmbd_debug(SMB, "nbytes %zu, offset %lld mincount %zu\n", ksmbd_debug(SMB, "nbytes %zu, offset %lld mincount %zu\n",
nbytes, offset, mincount); nbytes, offset, mincount);
if (req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE || if (req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE ||
req->Channel == SMB2_CHANNEL_RDMA_V1) { req->Channel == SMB2_CHANNEL_RDMA_V1) {
/* write data to the client using rdma channel */ /* write data to the client using rdma channel */
remain_bytes = smb2_read_rdma_channel(work, req, remain_bytes = smb2_read_rdma_channel(work, req,
work->aux_payload_buf, nbytes); work->aux_payload_buf,
nbytes);
if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_RBUF) if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_RBUF)
ksmbd_release_buffer(work->aux_payload_buf); ksmbd_release_buffer(work->aux_payload_buf);
else else
...@@ -5972,7 +5979,8 @@ static noinline int smb2_write_pipe(struct ksmbd_work *work) ...@@ -5972,7 +5979,8 @@ static noinline int smb2_write_pipe(struct ksmbd_work *work)
if ((le16_to_cpu(req->DataOffset) > get_rfc1002_len(req)) || if ((le16_to_cpu(req->DataOffset) > get_rfc1002_len(req)) ||
(le16_to_cpu(req->DataOffset) + length > get_rfc1002_len(req))) { (le16_to_cpu(req->DataOffset) + length > get_rfc1002_len(req))) {
ksmbd_err("invalid write data offset %u, smb_len %u\n", ksmbd_err("invalid write data offset %u, smb_len %u\n",
le16_to_cpu(req->DataOffset), get_rfc1002_len(req)); le16_to_cpu(req->DataOffset),
get_rfc1002_len(req));
err = -EINVAL; err = -EINVAL;
goto out; goto out;
} }
...@@ -6016,8 +6024,9 @@ static noinline int smb2_write_pipe(struct ksmbd_work *work) ...@@ -6016,8 +6024,9 @@ static noinline int smb2_write_pipe(struct ksmbd_work *work)
} }
static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work, static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work,
struct smb2_write_req *req, struct ksmbd_file *fp, struct smb2_write_req *req,
loff_t offset, size_t length, bool sync) struct ksmbd_file *fp,
loff_t offset, size_t length, bool sync)
{ {
struct smb2_buffer_desc_v1 *desc; struct smb2_buffer_desc_v1 *desc;
char *data_buf; char *data_buf;
...@@ -6046,9 +6055,9 @@ static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work, ...@@ -6046,9 +6055,9 @@ static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work,
return -ENOMEM; return -ENOMEM;
ret = ksmbd_conn_rdma_read(work->conn, data_buf, length, ret = ksmbd_conn_rdma_read(work->conn, data_buf, length,
le32_to_cpu(desc->token), le32_to_cpu(desc->token),
le64_to_cpu(desc->offset), le64_to_cpu(desc->offset),
le32_to_cpu(desc->length)); le32_to_cpu(desc->length));
if (ret < 0) { if (ret < 0) {
kvfree(data_buf); kvfree(data_buf);
return ret; return ret;
...@@ -6095,7 +6104,7 @@ int smb2_write(struct ksmbd_work *work) ...@@ -6095,7 +6104,7 @@ int smb2_write(struct ksmbd_work *work)
} }
fp = ksmbd_lookup_fd_slow(work, le64_to_cpu(req->VolatileFileId), fp = ksmbd_lookup_fd_slow(work, le64_to_cpu(req->VolatileFileId),
le64_to_cpu(req->PersistentFileId)); le64_to_cpu(req->PersistentFileId));
if (!fp) { if (!fp) {
err = -ENOENT; err = -ENOENT;
goto out; goto out;
...@@ -6123,14 +6132,14 @@ int smb2_write(struct ksmbd_work *work) ...@@ -6123,14 +6132,14 @@ int smb2_write(struct ksmbd_work *work)
if (req->Channel != SMB2_CHANNEL_RDMA_V1 && if (req->Channel != SMB2_CHANNEL_RDMA_V1 &&
req->Channel != SMB2_CHANNEL_RDMA_V1_INVALIDATE) { req->Channel != SMB2_CHANNEL_RDMA_V1_INVALIDATE) {
if (le16_to_cpu(req->DataOffset) == if (le16_to_cpu(req->DataOffset) ==
(offsetof(struct smb2_write_req, Buffer) - 4)) { (offsetof(struct smb2_write_req, Buffer) - 4)) {
data_buf = (char *)&req->Buffer[0]; data_buf = (char *)&req->Buffer[0];
} else { } else {
if ((le16_to_cpu(req->DataOffset) > get_rfc1002_len(req)) || if ((le16_to_cpu(req->DataOffset) > get_rfc1002_len(req)) ||
(le16_to_cpu(req->DataOffset) + length > get_rfc1002_len(req))) { (le16_to_cpu(req->DataOffset) + length > get_rfc1002_len(req))) {
ksmbd_err("invalid write data offset %u, smb_len %u\n", ksmbd_err("invalid write data offset %u, smb_len %u\n",
le16_to_cpu(req->DataOffset), le16_to_cpu(req->DataOffset),
get_rfc1002_len(req)); get_rfc1002_len(req));
err = -EINVAL; err = -EINVAL;
goto out; goto out;
} }
...@@ -6144,7 +6153,7 @@ int smb2_write(struct ksmbd_work *work) ...@@ -6144,7 +6153,7 @@ int smb2_write(struct ksmbd_work *work)
writethrough = true; writethrough = true;
ksmbd_debug(SMB, "filename %s, offset %lld, len %zu\n", ksmbd_debug(SMB, "filename %s, offset %lld, len %zu\n",
FP_FILENAME(fp), offset, length); FP_FILENAME(fp), offset, length);
err = ksmbd_vfs_write(work, fp, data_buf, length, &offset, err = ksmbd_vfs_write(work, fp, data_buf, length, &offset,
writethrough, &nbytes); writethrough, &nbytes);
if (err < 0) if (err < 0)
...@@ -6154,8 +6163,8 @@ int smb2_write(struct ksmbd_work *work) ...@@ -6154,8 +6163,8 @@ int smb2_write(struct ksmbd_work *work)
* write the data. * write the data.
*/ */
nbytes = smb2_write_rdma_channel(work, req, fp, offset, nbytes = smb2_write_rdma_channel(work, req, fp, offset,
le32_to_cpu(req->RemainingBytes), le32_to_cpu(req->RemainingBytes),
writethrough); writethrough);
if (nbytes < 0) { if (nbytes < 0) {
err = (int)nbytes; err = (int)nbytes;
goto out; goto out;
...@@ -6209,7 +6218,7 @@ int smb2_flush(struct ksmbd_work *work) ...@@ -6209,7 +6218,7 @@ int smb2_flush(struct ksmbd_work *work)
WORK_BUFFERS(work, req, rsp); WORK_BUFFERS(work, req, rsp);
ksmbd_debug(SMB, "SMB2_FLUSH called for fid %llu\n", ksmbd_debug(SMB, "SMB2_FLUSH called for fid %llu\n",
le64_to_cpu(req->VolatileFileId)); le64_to_cpu(req->VolatileFileId));
err = ksmbd_vfs_fsync(work, err = ksmbd_vfs_fsync(work,
le64_to_cpu(req->VolatileFileId), le64_to_cpu(req->VolatileFileId),
...@@ -6248,7 +6257,7 @@ int smb2_cancel(struct ksmbd_work *work) ...@@ -6248,7 +6257,7 @@ int smb2_cancel(struct ksmbd_work *work)
struct list_head *command_list; struct list_head *command_list;
ksmbd_debug(SMB, "smb2 cancel called on mid %llu, async flags 0x%x\n", ksmbd_debug(SMB, "smb2 cancel called on mid %llu, async flags 0x%x\n",
hdr->MessageId, hdr->Flags); hdr->MessageId, hdr->Flags);
if (hdr->Flags & SMB2_FLAGS_ASYNC_COMMAND) { if (hdr->Flags & SMB2_FLAGS_ASYNC_COMMAND) {
command_list = &conn->async_requests; command_list = &conn->async_requests;
...@@ -6256,7 +6265,7 @@ int smb2_cancel(struct ksmbd_work *work) ...@@ -6256,7 +6265,7 @@ int smb2_cancel(struct ksmbd_work *work)
spin_lock(&conn->request_lock); spin_lock(&conn->request_lock);
list_for_each(tmp, command_list) { list_for_each(tmp, command_list) {
cancel_work = list_entry(tmp, struct ksmbd_work, cancel_work = list_entry(tmp, struct ksmbd_work,
async_request_entry); async_request_entry);
chdr = cancel_work->request_buf; chdr = cancel_work->request_buf;
if (cancel_work->async_id != if (cancel_work->async_id !=
...@@ -6264,9 +6273,9 @@ int smb2_cancel(struct ksmbd_work *work) ...@@ -6264,9 +6273,9 @@ int smb2_cancel(struct ksmbd_work *work)
continue; continue;
ksmbd_debug(SMB, ksmbd_debug(SMB,
"smb2 with AsyncId %llu cancelled command = 0x%x\n", "smb2 with AsyncId %llu cancelled command = 0x%x\n",
le64_to_cpu(hdr->Id.AsyncId), le64_to_cpu(hdr->Id.AsyncId),
le16_to_cpu(chdr->Command)); le16_to_cpu(chdr->Command));
canceled = 1; canceled = 1;
break; break;
} }
...@@ -6277,7 +6286,7 @@ int smb2_cancel(struct ksmbd_work *work) ...@@ -6277,7 +6286,7 @@ int smb2_cancel(struct ksmbd_work *work)
spin_lock(&conn->request_lock); spin_lock(&conn->request_lock);
list_for_each(tmp, command_list) { list_for_each(tmp, command_list) {
cancel_work = list_entry(tmp, struct ksmbd_work, cancel_work = list_entry(tmp, struct ksmbd_work,
request_entry); request_entry);
chdr = cancel_work->request_buf; chdr = cancel_work->request_buf;
if (chdr->MessageId != hdr->MessageId || if (chdr->MessageId != hdr->MessageId ||
...@@ -6285,9 +6294,9 @@ int smb2_cancel(struct ksmbd_work *work) ...@@ -6285,9 +6294,9 @@ int smb2_cancel(struct ksmbd_work *work)
continue; continue;
ksmbd_debug(SMB, ksmbd_debug(SMB,
"smb2 with mid %llu cancelled command = 0x%x\n", "smb2 with mid %llu cancelled command = 0x%x\n",
le64_to_cpu(hdr->MessageId), le64_to_cpu(hdr->MessageId),
le16_to_cpu(chdr->Command)); le16_to_cpu(chdr->Command));
canceled = 1; canceled = 1;
break; break;
} }
...@@ -6346,13 +6355,13 @@ static int smb2_set_flock_flags(struct file_lock *flock, int flags) ...@@ -6346,13 +6355,13 @@ static int smb2_set_flock_flags(struct file_lock *flock, int flags)
break; break;
case SMB2_LOCKFLAG_SHARED | SMB2_LOCKFLAG_FAIL_IMMEDIATELY: case SMB2_LOCKFLAG_SHARED | SMB2_LOCKFLAG_FAIL_IMMEDIATELY:
ksmbd_debug(SMB, ksmbd_debug(SMB,
"received shared & fail immediately request\n"); "received shared & fail immediately request\n");
cmd = F_SETLK; cmd = F_SETLK;
flock->fl_type = F_RDLCK; flock->fl_type = F_RDLCK;
break; break;
case SMB2_LOCKFLAG_EXCLUSIVE | SMB2_LOCKFLAG_FAIL_IMMEDIATELY: case SMB2_LOCKFLAG_EXCLUSIVE | SMB2_LOCKFLAG_FAIL_IMMEDIATELY:
ksmbd_debug(SMB, ksmbd_debug(SMB,
"received exclusive & fail immediately request\n"); "received exclusive & fail immediately request\n");
cmd = F_SETLK; cmd = F_SETLK;
flock->fl_type = F_WRLCK; flock->fl_type = F_WRLCK;
break; break;
...@@ -6367,7 +6376,8 @@ static int smb2_set_flock_flags(struct file_lock *flock, int flags) ...@@ -6367,7 +6376,8 @@ static int smb2_set_flock_flags(struct file_lock *flock, int flags)
} }
static struct ksmbd_lock *smb2_lock_init(struct file_lock *flock, static struct ksmbd_lock *smb2_lock_init(struct file_lock *flock,
unsigned int cmd, int flags, struct list_head *lock_list) unsigned int cmd, int flags,
struct list_head *lock_list)
{ {
struct ksmbd_lock *lock; struct ksmbd_lock *lock;
...@@ -6430,11 +6440,11 @@ int smb2_lock(struct ksmbd_work *work) ...@@ -6430,11 +6440,11 @@ int smb2_lock(struct ksmbd_work *work)
ksmbd_debug(SMB, "Received lock request\n"); ksmbd_debug(SMB, "Received lock request\n");
fp = ksmbd_lookup_fd_slow(work, fp = ksmbd_lookup_fd_slow(work,
le64_to_cpu(req->VolatileFileId), le64_to_cpu(req->VolatileFileId),
le64_to_cpu(req->PersistentFileId)); le64_to_cpu(req->PersistentFileId));
if (!fp) { if (!fp) {
ksmbd_debug(SMB, "Invalid file id for lock : %llu\n", ksmbd_debug(SMB, "Invalid file id for lock : %llu\n",
le64_to_cpu(req->VolatileFileId)); le64_to_cpu(req->VolatileFileId));
rsp->hdr.Status = STATUS_FILE_CLOSED; rsp->hdr.Status = STATUS_FILE_CLOSED;
goto out2; goto out2;
} }
...@@ -6444,7 +6454,7 @@ int smb2_lock(struct ksmbd_work *work) ...@@ -6444,7 +6454,7 @@ int smb2_lock(struct ksmbd_work *work)
lock_ele = req->locks; lock_ele = req->locks;
ksmbd_debug(SMB, "lock count is %d\n", lock_count); ksmbd_debug(SMB, "lock count is %d\n", lock_count);
if (!lock_count) { if (!lock_count) {
rsp->hdr.Status = STATUS_INVALID_PARAMETER; rsp->hdr.Status = STATUS_INVALID_PARAMETER;
goto out2; goto out2;
} }
...@@ -6481,8 +6491,8 @@ int smb2_lock(struct ksmbd_work *work) ...@@ -6481,8 +6491,8 @@ int smb2_lock(struct ksmbd_work *work)
if (flock->fl_end < flock->fl_start) { if (flock->fl_end < flock->fl_start) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"the end offset(%llx) is smaller than the start offset(%llx)\n", "the end offset(%llx) is smaller than the start offset(%llx)\n",
flock->fl_end, flock->fl_start); flock->fl_end, flock->fl_start);
rsp->hdr.Status = STATUS_INVALID_LOCK_RANGE; rsp->hdr.Status = STATUS_INVALID_LOCK_RANGE;
goto out; goto out;
} }
...@@ -6621,9 +6631,9 @@ int smb2_lock(struct ksmbd_work *work) ...@@ -6621,9 +6631,9 @@ int smb2_lock(struct ksmbd_work *work)
void **argv; void **argv;
ksmbd_debug(SMB, ksmbd_debug(SMB,
"would have to wait for getting lock\n"); "would have to wait for getting lock\n");
list_add_tail(&smb_lock->glist, list_add_tail(&smb_lock->glist,
&global_lock_list); &global_lock_list);
list_add(&smb_lock->llist, &rollback_list); list_add(&smb_lock->llist, &rollback_list);
argv = kmalloc(sizeof(void *), GFP_KERNEL); argv = kmalloc(sizeof(void *), GFP_KERNEL);
...@@ -6634,7 +6644,8 @@ int smb2_lock(struct ksmbd_work *work) ...@@ -6634,7 +6644,8 @@ int smb2_lock(struct ksmbd_work *work)
argv[0] = flock; argv[0] = flock;
err = setup_async_work(work, err = setup_async_work(work,
smb2_remove_blocked_lock, argv); smb2_remove_blocked_lock,
argv);
if (err) { if (err) {
rsp->hdr.Status = rsp->hdr.Status =
STATUS_INSUFFICIENT_RESOURCES; STATUS_INSUFFICIENT_RESOURCES;
...@@ -6661,7 +6672,7 @@ int smb2_lock(struct ksmbd_work *work) ...@@ -6661,7 +6672,7 @@ int smb2_lock(struct ksmbd_work *work)
STATUS_CANCELLED; STATUS_CANCELLED;
kfree(smb_lock); kfree(smb_lock);
smb2_send_interim_resp(work, smb2_send_interim_resp(work,
STATUS_CANCELLED); STATUS_CANCELLED);
work->send_no_response = 1; work->send_no_response = 1;
goto out; goto out;
} }
...@@ -6681,7 +6692,7 @@ int smb2_lock(struct ksmbd_work *work) ...@@ -6681,7 +6692,7 @@ int smb2_lock(struct ksmbd_work *work)
goto retry; goto retry;
} else if (!err) { } else if (!err) {
list_add_tail(&smb_lock->glist, list_add_tail(&smb_lock->glist,
&global_lock_list); &global_lock_list);
list_add(&smb_lock->llist, &rollback_list); list_add(&smb_lock->llist, &rollback_list);
ksmbd_debug(SMB, "successful in taking lock\n"); ksmbd_debug(SMB, "successful in taking lock\n");
} else { } else {
...@@ -6734,7 +6745,7 @@ int smb2_lock(struct ksmbd_work *work) ...@@ -6734,7 +6745,7 @@ int smb2_lock(struct ksmbd_work *work)
} }
static int fsctl_copychunk(struct ksmbd_work *work, struct smb2_ioctl_req *req, static int fsctl_copychunk(struct ksmbd_work *work, struct smb2_ioctl_req *req,
struct smb2_ioctl_rsp *rsp) struct smb2_ioctl_rsp *rsp)
{ {
struct copychunk_ioctl_req *ci_req; struct copychunk_ioctl_req *ci_req;
struct copychunk_ioctl_rsp *ci_rsp; struct copychunk_ioctl_rsp *ci_rsp;
...@@ -6785,10 +6796,10 @@ static int fsctl_copychunk(struct ksmbd_work *work, struct smb2_ioctl_req *req, ...@@ -6785,10 +6796,10 @@ static int fsctl_copychunk(struct ksmbd_work *work, struct smb2_ioctl_req *req,
} }
src_fp = ksmbd_lookup_foreign_fd(work, src_fp = ksmbd_lookup_foreign_fd(work,
le64_to_cpu(ci_req->ResumeKey[0])); le64_to_cpu(ci_req->ResumeKey[0]));
dst_fp = ksmbd_lookup_fd_slow(work, dst_fp = ksmbd_lookup_fd_slow(work,
le64_to_cpu(req->VolatileFileId), le64_to_cpu(req->VolatileFileId),
le64_to_cpu(req->PersistentFileId)); le64_to_cpu(req->PersistentFileId));
ret = -EINVAL; ret = -EINVAL;
if (!src_fp || if (!src_fp ||
src_fp->persistent_id != le64_to_cpu(ci_req->ResumeKey[1])) { src_fp->persistent_id != le64_to_cpu(ci_req->ResumeKey[1])) {
...@@ -6805,16 +6816,17 @@ static int fsctl_copychunk(struct ksmbd_work *work, struct smb2_ioctl_req *req, ...@@ -6805,16 +6816,17 @@ static int fsctl_copychunk(struct ksmbd_work *work, struct smb2_ioctl_req *req,
* FILE_READ_DATA should only be included in * FILE_READ_DATA should only be included in
* the FSCTL_COPYCHUNK case * the FSCTL_COPYCHUNK case
*/ */
if (cnt_code == FSCTL_COPYCHUNK && !(dst_fp->daccess & if (cnt_code == FSCTL_COPYCHUNK &&
(FILE_READ_DATA_LE | FILE_GENERIC_READ_LE))) { !(dst_fp->daccess & (FILE_READ_DATA_LE | FILE_GENERIC_READ_LE))) {
rsp->hdr.Status = STATUS_ACCESS_DENIED; rsp->hdr.Status = STATUS_ACCESS_DENIED;
goto out; goto out;
} }
ret = ksmbd_vfs_copy_file_ranges(work, src_fp, dst_fp, ret = ksmbd_vfs_copy_file_ranges(work, src_fp, dst_fp,
chunks, chunk_count, chunks, chunk_count,
&chunk_count_written, &chunk_size_written, &chunk_count_written,
&total_size_written); &chunk_size_written,
&total_size_written);
if (ret < 0) { if (ret < 0) {
if (ret == -EACCES) if (ret == -EACCES)
rsp->hdr.Status = STATUS_ACCESS_DENIED; rsp->hdr.Status = STATUS_ACCESS_DENIED;
...@@ -6862,7 +6874,8 @@ static __be32 idev_ipv4_address(struct in_device *idev) ...@@ -6862,7 +6874,8 @@ static __be32 idev_ipv4_address(struct in_device *idev)
} }
static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn, static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn,
struct smb2_ioctl_req *req, struct smb2_ioctl_rsp *rsp) struct smb2_ioctl_req *req,
struct smb2_ioctl_rsp *rsp)
{ {
struct network_interface_info_ioctl_rsp *nii_rsp = NULL; struct network_interface_info_ioctl_rsp *nii_rsp = NULL;
int nbytes = 0; int nbytes = 0;
...@@ -6905,7 +6918,7 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn, ...@@ -6905,7 +6918,7 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn,
speed = cmd.base.speed; speed = cmd.base.speed;
} else { } else {
ksmbd_err("%s %s\n", netdev->name, ksmbd_err("%s %s\n", netdev->name,
"speed is unknown, defaulting to 1Gb/sec"); "speed is unknown, defaulting to 1Gb/sec");
speed = SPEED_1000; speed = SPEED_1000;
} }
...@@ -6969,14 +6982,14 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn, ...@@ -6969,14 +6982,14 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn,
} }
static int fsctl_validate_negotiate_info(struct ksmbd_conn *conn, static int fsctl_validate_negotiate_info(struct ksmbd_conn *conn,
struct validate_negotiate_info_req *neg_req, struct validate_negotiate_info_req *neg_req,
struct validate_negotiate_info_rsp *neg_rsp) struct validate_negotiate_info_rsp *neg_rsp)
{ {
int ret = 0; int ret = 0;
int dialect; int dialect;
dialect = ksmbd_lookup_dialect_by_id(neg_req->Dialects, dialect = ksmbd_lookup_dialect_by_id(neg_req->Dialects,
neg_req->DialectCount); neg_req->DialectCount);
if (dialect == BAD_PROT_ID || dialect != conn->dialect) { if (dialect == BAD_PROT_ID || dialect != conn->dialect) {
ret = -EINVAL; ret = -EINVAL;
goto err_out; goto err_out;
...@@ -7006,9 +7019,9 @@ static int fsctl_validate_negotiate_info(struct ksmbd_conn *conn, ...@@ -7006,9 +7019,9 @@ static int fsctl_validate_negotiate_info(struct ksmbd_conn *conn,
} }
static int fsctl_query_allocated_ranges(struct ksmbd_work *work, u64 id, static int fsctl_query_allocated_ranges(struct ksmbd_work *work, u64 id,
struct file_allocated_range_buffer *qar_req, struct file_allocated_range_buffer *qar_req,
struct file_allocated_range_buffer *qar_rsp, struct file_allocated_range_buffer *qar_rsp,
int in_count, int *out_count) int in_count, int *out_count)
{ {
struct ksmbd_file *fp; struct ksmbd_file *fp;
loff_t start, length; loff_t start, length;
...@@ -7026,7 +7039,7 @@ static int fsctl_query_allocated_ranges(struct ksmbd_work *work, u64 id, ...@@ -7026,7 +7039,7 @@ static int fsctl_query_allocated_ranges(struct ksmbd_work *work, u64 id,
length = le64_to_cpu(qar_req->length); length = le64_to_cpu(qar_req->length);
ret = ksmbd_vfs_fqar_lseek(fp, start, length, ret = ksmbd_vfs_fqar_lseek(fp, start, length,
qar_rsp, in_count, out_count); qar_rsp, in_count, out_count);
if (ret && ret != -E2BIG) if (ret && ret != -E2BIG)
*out_count = 0; *out_count = 0;
...@@ -7035,15 +7048,15 @@ static int fsctl_query_allocated_ranges(struct ksmbd_work *work, u64 id, ...@@ -7035,15 +7048,15 @@ static int fsctl_query_allocated_ranges(struct ksmbd_work *work, u64 id,
} }
static int fsctl_pipe_transceive(struct ksmbd_work *work, u64 id, static int fsctl_pipe_transceive(struct ksmbd_work *work, u64 id,
int out_buf_len, struct smb2_ioctl_req *req, int out_buf_len, struct smb2_ioctl_req *req,
struct smb2_ioctl_rsp *rsp) struct smb2_ioctl_rsp *rsp)
{ {
struct ksmbd_rpc_command *rpc_resp; struct ksmbd_rpc_command *rpc_resp;
char *data_buf = (char *)&req->Buffer[0]; char *data_buf = (char *)&req->Buffer[0];
int nbytes = 0; int nbytes = 0;
rpc_resp = ksmbd_rpc_ioctl(work->sess, id, data_buf, rpc_resp = ksmbd_rpc_ioctl(work->sess, id, data_buf,
le32_to_cpu(req->InputCount)); le32_to_cpu(req->InputCount));
if (rpc_resp) { if (rpc_resp) {
if (rpc_resp->flags == KSMBD_RPC_SOME_NOT_MAPPED) { if (rpc_resp->flags == KSMBD_RPC_SOME_NOT_MAPPED) {
/* /*
...@@ -7079,7 +7092,7 @@ static int fsctl_pipe_transceive(struct ksmbd_work *work, u64 id, ...@@ -7079,7 +7092,7 @@ static int fsctl_pipe_transceive(struct ksmbd_work *work, u64 id,
} }
static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id, static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id,
struct file_sparse *sparse) struct file_sparse *sparse)
{ {
struct ksmbd_file *fp; struct ksmbd_file *fp;
int ret = 0; int ret = 0;
...@@ -7116,14 +7129,14 @@ static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id, ...@@ -7116,14 +7129,14 @@ static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id,
} }
static int fsctl_request_resume_key(struct ksmbd_work *work, static int fsctl_request_resume_key(struct ksmbd_work *work,
struct smb2_ioctl_req *req, struct smb2_ioctl_req *req,
struct resume_key_ioctl_rsp *key_rsp) struct resume_key_ioctl_rsp *key_rsp)
{ {
struct ksmbd_file *fp; struct ksmbd_file *fp;
fp = ksmbd_lookup_fd_slow(work, fp = ksmbd_lookup_fd_slow(work,
le64_to_cpu(req->VolatileFileId), le64_to_cpu(req->VolatileFileId),
le64_to_cpu(req->PersistentFileId)); le64_to_cpu(req->PersistentFileId));
if (!fp) if (!fp)
return -ENOENT; return -ENOENT;
...@@ -7157,7 +7170,7 @@ int smb2_ioctl(struct ksmbd_work *work) ...@@ -7157,7 +7170,7 @@ int smb2_ioctl(struct ksmbd_work *work)
rsp = RESPONSE_BUF_NEXT(work); rsp = RESPONSE_BUF_NEXT(work);
if (!HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) { if (!HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) {
ksmbd_debug(SMB, "Compound request set FID = %u\n", ksmbd_debug(SMB, "Compound request set FID = %u\n",
work->compound_fid); work->compound_fid);
id = work->compound_fid; id = work->compound_fid;
} }
} else { } else {
...@@ -7233,7 +7246,7 @@ int smb2_ioctl(struct ksmbd_work *work) ...@@ -7233,7 +7246,7 @@ int smb2_ioctl(struct ksmbd_work *work)
} }
ret = fsctl_request_resume_key(work, req, ret = fsctl_request_resume_key(work, req,
(struct resume_key_ioctl_rsp *)&rsp->Buffer[0]); (struct resume_key_ioctl_rsp *)&rsp->Buffer[0]);
if (ret < 0) if (ret < 0)
goto out; goto out;
rsp->PersistentFileId = req->PersistentFileId; rsp->PersistentFileId = req->PersistentFileId;
...@@ -7244,7 +7257,7 @@ int smb2_ioctl(struct ksmbd_work *work) ...@@ -7244,7 +7257,7 @@ int smb2_ioctl(struct ksmbd_work *work)
case FSCTL_COPYCHUNK_WRITE: case FSCTL_COPYCHUNK_WRITE:
if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) { if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"User does not have write permission\n"); "User does not have write permission\n");
ret = -EACCES; ret = -EACCES;
goto out; goto out;
} }
...@@ -7259,7 +7272,7 @@ int smb2_ioctl(struct ksmbd_work *work) ...@@ -7259,7 +7272,7 @@ int smb2_ioctl(struct ksmbd_work *work)
break; break;
case FSCTL_SET_SPARSE: case FSCTL_SET_SPARSE:
ret = fsctl_set_sparse(work, id, ret = fsctl_set_sparse(work, id,
(struct file_sparse *)&req->Buffer[0]); (struct file_sparse *)&req->Buffer[0]);
if (ret < 0) if (ret < 0)
goto out; goto out;
break; break;
...@@ -7271,7 +7284,7 @@ int smb2_ioctl(struct ksmbd_work *work) ...@@ -7271,7 +7284,7 @@ int smb2_ioctl(struct ksmbd_work *work)
if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) { if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"User does not have write permission\n"); "User does not have write permission\n");
ret = -EACCES; ret = -EACCES;
goto out; goto out;
} }
...@@ -7338,7 +7351,7 @@ int smb2_ioctl(struct ksmbd_work *work) ...@@ -7338,7 +7351,7 @@ int smb2_ioctl(struct ksmbd_work *work)
dup_ext = (struct duplicate_extents_to_file *)&req->Buffer[0]; dup_ext = (struct duplicate_extents_to_file *)&req->Buffer[0];
fp_in = ksmbd_lookup_fd_slow(work, dup_ext->VolatileFileHandle, fp_in = ksmbd_lookup_fd_slow(work, dup_ext->VolatileFileHandle,
dup_ext->PersistentFileHandle); dup_ext->PersistentFileHandle);
if (!fp_in) { if (!fp_in) {
ksmbd_err("not found file handle in duplicate extent to file\n"); ksmbd_err("not found file handle in duplicate extent to file\n");
ret = -ENOENT; ret = -ENOENT;
...@@ -7356,13 +7369,13 @@ int smb2_ioctl(struct ksmbd_work *work) ...@@ -7356,13 +7369,13 @@ int smb2_ioctl(struct ksmbd_work *work)
dst_off = le64_to_cpu(dup_ext->TargetFileOffset); dst_off = le64_to_cpu(dup_ext->TargetFileOffset);
length = le64_to_cpu(dup_ext->ByteCount); length = le64_to_cpu(dup_ext->ByteCount);
cloned = vfs_clone_file_range(fp_in->filp, src_off, fp_out->filp, cloned = vfs_clone_file_range(fp_in->filp, src_off, fp_out->filp,
dst_off, length, 0); dst_off, length, 0);
if (cloned == -EXDEV || cloned == -EOPNOTSUPP) { if (cloned == -EXDEV || cloned == -EOPNOTSUPP) {
ret = -EOPNOTSUPP; ret = -EOPNOTSUPP;
goto dup_ext_out; goto dup_ext_out;
} else if (cloned != length) { } else if (cloned != length) {
cloned = ksmbd_vfs_copy_file_range(fp_in->filp, src_off, cloned = ksmbd_vfs_copy_file_range(fp_in->filp, src_off,
fp_out->filp, dst_off, length); fp_out->filp, dst_off, length);
if (cloned != length) { if (cloned != length) {
if (cloned < 0) if (cloned < 0)
ret = cloned; ret = cloned;
...@@ -7380,7 +7393,7 @@ int smb2_ioctl(struct ksmbd_work *work) ...@@ -7380,7 +7393,7 @@ int smb2_ioctl(struct ksmbd_work *work)
} }
default: default:
ksmbd_debug(SMB, "not implemented yet ioctl command 0x%x\n", ksmbd_debug(SMB, "not implemented yet ioctl command 0x%x\n",
cnt_code); cnt_code);
ret = -EOPNOTSUPP; ret = -EOPNOTSUPP;
goto out; goto out;
} }
...@@ -7508,7 +7521,7 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work) ...@@ -7508,7 +7521,7 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work)
break; break;
default: default:
ksmbd_err("unknown oplock change 0x%x -> 0x%x\n", ksmbd_err("unknown oplock change 0x%x -> 0x%x\n",
opinfo->level, rsp_oplevel); opinfo->level, rsp_oplevel);
} }
if (ret < 0) { if (ret < 0) {
...@@ -7573,7 +7586,7 @@ static void smb21_lease_break_ack(struct ksmbd_work *work) ...@@ -7573,7 +7586,7 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
struct lease *lease; struct lease *lease;
ksmbd_debug(OPLOCK, "smb21 lease break, lease state(0x%x)\n", ksmbd_debug(OPLOCK, "smb21 lease break, lease state(0x%x)\n",
le32_to_cpu(req->LeaseState)); le32_to_cpu(req->LeaseState));
opinfo = lookup_lease_in_table(conn, req->LeaseKey); opinfo = lookup_lease_in_table(conn, req->LeaseKey);
if (!opinfo) { if (!opinfo) {
ksmbd_debug(OPLOCK, "file not opened\n"); ksmbd_debug(OPLOCK, "file not opened\n");
...@@ -7585,7 +7598,7 @@ static void smb21_lease_break_ack(struct ksmbd_work *work) ...@@ -7585,7 +7598,7 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
if (opinfo->op_state == OPLOCK_STATE_NONE) { if (opinfo->op_state == OPLOCK_STATE_NONE) {
ksmbd_err("unexpected lease break state 0x%x\n", ksmbd_err("unexpected lease break state 0x%x\n",
opinfo->op_state); opinfo->op_state);
rsp->hdr.Status = STATUS_UNSUCCESSFUL; rsp->hdr.Status = STATUS_UNSUCCESSFUL;
goto err_out; goto err_out;
} }
...@@ -7593,8 +7606,8 @@ static void smb21_lease_break_ack(struct ksmbd_work *work) ...@@ -7593,8 +7606,8 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
if (check_lease_state(lease, req->LeaseState)) { if (check_lease_state(lease, req->LeaseState)) {
rsp->hdr.Status = STATUS_REQUEST_NOT_ACCEPTED; rsp->hdr.Status = STATUS_REQUEST_NOT_ACCEPTED;
ksmbd_debug(OPLOCK, ksmbd_debug(OPLOCK,
"req lease state: 0x%x, expected state: 0x%x\n", "req lease state: 0x%x, expected state: 0x%x\n",
req->LeaseState, lease->new_state); req->LeaseState, lease->new_state);
goto err_out; goto err_out;
} }
...@@ -7604,23 +7617,23 @@ static void smb21_lease_break_ack(struct ksmbd_work *work) ...@@ -7604,23 +7617,23 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
} }
/* check for bad lease state */ /* check for bad lease state */
if (req->LeaseState & (~(SMB2_LEASE_READ_CACHING_LE | if (req->LeaseState &
SMB2_LEASE_HANDLE_CACHING_LE))) { (~(SMB2_LEASE_READ_CACHING_LE | SMB2_LEASE_HANDLE_CACHING_LE))) {
err = STATUS_INVALID_OPLOCK_PROTOCOL; err = STATUS_INVALID_OPLOCK_PROTOCOL;
if (lease->state & SMB2_LEASE_WRITE_CACHING_LE) if (lease->state & SMB2_LEASE_WRITE_CACHING_LE)
lease_change_type = OPLOCK_WRITE_TO_NONE; lease_change_type = OPLOCK_WRITE_TO_NONE;
else else
lease_change_type = OPLOCK_READ_TO_NONE; lease_change_type = OPLOCK_READ_TO_NONE;
ksmbd_debug(OPLOCK, "handle bad lease state 0x%x -> 0x%x\n", ksmbd_debug(OPLOCK, "handle bad lease state 0x%x -> 0x%x\n",
le32_to_cpu(lease->state), le32_to_cpu(lease->state),
le32_to_cpu(req->LeaseState)); le32_to_cpu(req->LeaseState));
} else if (lease->state == SMB2_LEASE_READ_CACHING_LE && } else if (lease->state == SMB2_LEASE_READ_CACHING_LE &&
req->LeaseState != SMB2_LEASE_NONE_LE) { req->LeaseState != SMB2_LEASE_NONE_LE) {
err = STATUS_INVALID_OPLOCK_PROTOCOL; err = STATUS_INVALID_OPLOCK_PROTOCOL;
lease_change_type = OPLOCK_READ_TO_NONE; lease_change_type = OPLOCK_READ_TO_NONE;
ksmbd_debug(OPLOCK, "handle bad lease state 0x%x -> 0x%x\n", ksmbd_debug(OPLOCK, "handle bad lease state 0x%x -> 0x%x\n",
le32_to_cpu(lease->state), le32_to_cpu(lease->state),
le32_to_cpu(req->LeaseState)); le32_to_cpu(req->LeaseState));
} else { } else {
/* valid lease state changes */ /* valid lease state changes */
err = STATUS_INVALID_DEVICE_STATE; err = STATUS_INVALID_DEVICE_STATE;
...@@ -7654,8 +7667,8 @@ static void smb21_lease_break_ack(struct ksmbd_work *work) ...@@ -7654,8 +7667,8 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
break; break;
default: default:
ksmbd_debug(OPLOCK, "unknown lease change 0x%x -> 0x%x\n", ksmbd_debug(OPLOCK, "unknown lease change 0x%x -> 0x%x\n",
le32_to_cpu(lease->state), le32_to_cpu(lease->state),
le32_to_cpu(req->LeaseState)); le32_to_cpu(req->LeaseState));
} }
lease_state = lease->state; lease_state = lease->state;
...@@ -7709,7 +7722,7 @@ int smb2_oplock_break(struct ksmbd_work *work) ...@@ -7709,7 +7722,7 @@ int smb2_oplock_break(struct ksmbd_work *work)
break; break;
default: default:
ksmbd_debug(OPLOCK, "invalid break cmd %d\n", ksmbd_debug(OPLOCK, "invalid break cmd %d\n",
le16_to_cpu(req->StructureSize)); le16_to_cpu(req->StructureSize));
rsp->hdr.Status = STATUS_INVALID_PARAMETER; rsp->hdr.Status = STATUS_INVALID_PARAMETER;
smb2_set_err_rsp(work); smb2_set_err_rsp(work);
} }
...@@ -7999,7 +8012,7 @@ void smb3_preauth_hash_rsp(struct ksmbd_work *work) ...@@ -7999,7 +8012,7 @@ void smb3_preauth_hash_rsp(struct ksmbd_work *work)
if (le16_to_cpu(req->Command) == SMB2_NEGOTIATE_HE) if (le16_to_cpu(req->Command) == SMB2_NEGOTIATE_HE)
ksmbd_gen_preauth_integrity_hash(conn, (char *)rsp, ksmbd_gen_preauth_integrity_hash(conn, (char *)rsp,
conn->preauth_info->Preauth_HashValue); conn->preauth_info->Preauth_HashValue);
if (le16_to_cpu(rsp->Command) == SMB2_SESSION_SETUP_HE && if (le16_to_cpu(rsp->Command) == SMB2_SESSION_SETUP_HE &&
sess && sess->state == SMB2_SESSION_IN_PROGRESS) { sess && sess->state == SMB2_SESSION_IN_PROGRESS) {
...@@ -8007,12 +8020,12 @@ void smb3_preauth_hash_rsp(struct ksmbd_work *work) ...@@ -8007,12 +8020,12 @@ void smb3_preauth_hash_rsp(struct ksmbd_work *work)
hash_value = sess->Preauth_HashValue; hash_value = sess->Preauth_HashValue;
ksmbd_gen_preauth_integrity_hash(conn, (char *)rsp, ksmbd_gen_preauth_integrity_hash(conn, (char *)rsp,
hash_value); hash_value);
} }
} }
static void fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, char *old_buf, static void fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, char *old_buf,
__le16 cipher_type) __le16 cipher_type)
{ {
struct smb2_hdr *hdr = (struct smb2_hdr *)old_buf; struct smb2_hdr *hdr = (struct smb2_hdr *)old_buf;
unsigned int orig_len = get_rfc1002_len(old_buf); unsigned int orig_len = get_rfc1002_len(old_buf);
...@@ -8100,14 +8113,14 @@ int smb3_decrypt_req(struct ksmbd_work *work) ...@@ -8100,14 +8113,14 @@ int smb3_decrypt_req(struct ksmbd_work *work)
sess = ksmbd_session_lookup(conn, le64_to_cpu(tr_hdr->SessionId)); sess = ksmbd_session_lookup(conn, le64_to_cpu(tr_hdr->SessionId));
if (!sess) { if (!sess) {
ksmbd_err("invalid session id(%llx) in transform header\n", ksmbd_err("invalid session id(%llx) in transform header\n",
le64_to_cpu(tr_hdr->SessionId)); le64_to_cpu(tr_hdr->SessionId));
return -ECONNABORTED; return -ECONNABORTED;
} }
if (pdu_length + 4 < sizeof(struct smb2_transform_hdr) + if (pdu_length + 4 <
sizeof(struct smb2_hdr)) { sizeof(struct smb2_transform_hdr) + sizeof(struct smb2_hdr)) {
ksmbd_err("Transform message is too small (%u)\n", ksmbd_err("Transform message is too small (%u)\n",
pdu_length); pdu_length);
return -ECONNABORTED; return -ECONNABORTED;
} }
......
...@@ -98,7 +98,7 @@ int ksmbd_lookup_protocol_idx(char *str) ...@@ -98,7 +98,7 @@ int ksmbd_lookup_protocol_idx(char *str)
while (offt >= 0) { while (offt >= 0) {
if (!strncmp(str, smb_protos[offt].prot, len)) { if (!strncmp(str, smb_protos[offt].prot, len)) {
ksmbd_debug(SMB, "selected %s dialect idx = %d\n", ksmbd_debug(SMB, "selected %s dialect idx = %d\n",
smb_protos[offt].prot, offt); smb_protos[offt].prot, offt);
return smb_protos[offt].index; return smb_protos[offt].index;
} }
offt--; offt--;
...@@ -156,7 +156,7 @@ static bool supported_protocol(int idx) ...@@ -156,7 +156,7 @@ static bool supported_protocol(int idx)
return true; return true;
return (server_conf.min_protocol <= idx && return (server_conf.min_protocol <= idx &&
idx <= server_conf.max_protocol); idx <= server_conf.max_protocol);
} }
static char *next_dialect(char *dialect, int *next_off) static char *next_dialect(char *dialect, int *next_off)
...@@ -179,12 +179,12 @@ static int ksmbd_lookup_dialect_by_name(char *cli_dialects, __le16 byte_count) ...@@ -179,12 +179,12 @@ static int ksmbd_lookup_dialect_by_name(char *cli_dialects, __le16 byte_count)
do { do {
dialect = next_dialect(dialect, &next); dialect = next_dialect(dialect, &next);
ksmbd_debug(SMB, "client requested dialect %s\n", ksmbd_debug(SMB, "client requested dialect %s\n",
dialect); dialect);
if (!strcmp(dialect, smb_protos[i].name)) { if (!strcmp(dialect, smb_protos[i].name)) {
if (supported_protocol(smb_protos[i].index)) { if (supported_protocol(smb_protos[i].index)) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"selected %s dialect\n", "selected %s dialect\n",
smb_protos[i].name); smb_protos[i].name);
if (smb_protos[i].index == SMB1_PROT) if (smb_protos[i].index == SMB1_PROT)
return seq_num; return seq_num;
return smb_protos[i].prot_id; return smb_protos[i].prot_id;
...@@ -207,14 +207,14 @@ int ksmbd_lookup_dialect_by_id(__le16 *cli_dialects, __le16 dialects_count) ...@@ -207,14 +207,14 @@ int ksmbd_lookup_dialect_by_id(__le16 *cli_dialects, __le16 dialects_count)
count = le16_to_cpu(dialects_count); count = le16_to_cpu(dialects_count);
while (--count >= 0) { while (--count >= 0) {
ksmbd_debug(SMB, "client requested dialect 0x%x\n", ksmbd_debug(SMB, "client requested dialect 0x%x\n",
le16_to_cpu(cli_dialects[count])); le16_to_cpu(cli_dialects[count]));
if (le16_to_cpu(cli_dialects[count]) != if (le16_to_cpu(cli_dialects[count]) !=
smb_protos[i].prot_id) smb_protos[i].prot_id)
continue; continue;
if (supported_protocol(smb_protos[i].index)) { if (supported_protocol(smb_protos[i].index)) {
ksmbd_debug(SMB, "selected %s dialect\n", ksmbd_debug(SMB, "selected %s dialect\n",
smb_protos[i].name); smb_protos[i].name);
return smb_protos[i].prot_id; return smb_protos[i].prot_id;
} }
} }
...@@ -269,9 +269,12 @@ bool ksmbd_pdu_size_has_room(unsigned int pdu) ...@@ -269,9 +269,12 @@ bool ksmbd_pdu_size_has_room(unsigned int pdu)
} }
int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level, int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level,
struct ksmbd_file *dir, struct ksmbd_dir_info *d_info, struct ksmbd_file *dir,
char *search_pattern, int (*fn)(struct ksmbd_conn *, int, struct ksmbd_dir_info *d_info,
struct ksmbd_dir_info *, struct ksmbd_kstat *)) char *search_pattern,
int (*fn)(struct ksmbd_conn *, int,
struct ksmbd_dir_info *,
struct ksmbd_kstat *))
{ {
int i, rc = 0; int i, rc = 0;
struct ksmbd_conn *conn = work->conn; struct ksmbd_conn *conn = work->conn;
...@@ -297,8 +300,8 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level, ...@@ -297,8 +300,8 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level,
ksmbd_kstat.kstat = &kstat; ksmbd_kstat.kstat = &kstat;
ksmbd_vfs_fill_dentry_attrs(work, ksmbd_vfs_fill_dentry_attrs(work,
dir->filp->f_path.dentry->d_parent, dir->filp->f_path.dentry->d_parent,
&ksmbd_kstat); &ksmbd_kstat);
rc = fn(conn, info_level, d_info, &ksmbd_kstat); rc = fn(conn, info_level, d_info, &ksmbd_kstat);
if (rc) if (rc)
break; break;
...@@ -327,7 +330,7 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level, ...@@ -327,7 +330,7 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level,
* but the result is different with Windows 7's one. need to check. * but the result is different with Windows 7's one. need to check.
*/ */
int ksmbd_extract_shortname(struct ksmbd_conn *conn, const char *longname, int ksmbd_extract_shortname(struct ksmbd_conn *conn, const char *longname,
char *shortname) char *shortname)
{ {
const char *p; const char *p;
char base[9], extension[4]; char base[9], extension[4];
...@@ -390,7 +393,7 @@ int ksmbd_extract_shortname(struct ksmbd_conn *conn, const char *longname, ...@@ -390,7 +393,7 @@ int ksmbd_extract_shortname(struct ksmbd_conn *conn, const char *longname,
else else
out[baselen + 4] = '\0'; out[baselen + 4] = '\0';
smbConvertToUTF16((__le16 *)shortname, out, PATH_MAX, smbConvertToUTF16((__le16 *)shortname, out, PATH_MAX,
conn->local_nls, 0); conn->local_nls, 0);
len = strlen(out) * 2; len = strlen(out) * 2;
return len; return len;
} }
...@@ -398,7 +401,7 @@ int ksmbd_extract_shortname(struct ksmbd_conn *conn, const char *longname, ...@@ -398,7 +401,7 @@ int ksmbd_extract_shortname(struct ksmbd_conn *conn, const char *longname,
static int __smb2_negotiate(struct ksmbd_conn *conn) static int __smb2_negotiate(struct ksmbd_conn *conn)
{ {
return (conn->dialect >= SMB20_PROT_ID && return (conn->dialect >= SMB20_PROT_ID &&
conn->dialect <= SMB311_PROT_ID); conn->dialect <= SMB311_PROT_ID);
} }
static int smb_handle_negotiate(struct ksmbd_work *work) static int smb_handle_negotiate(struct ksmbd_work *work)
...@@ -467,11 +470,11 @@ static const char * const shared_mode_errors[] = { ...@@ -467,11 +470,11 @@ static const char * const shared_mode_errors[] = {
}; };
static void smb_shared_mode_error(int error, struct ksmbd_file *prev_fp, static void smb_shared_mode_error(int error, struct ksmbd_file *prev_fp,
struct ksmbd_file *curr_fp) struct ksmbd_file *curr_fp)
{ {
ksmbd_debug(SMB, "%s\n", shared_mode_errors[error]); ksmbd_debug(SMB, "%s\n", shared_mode_errors[error]);
ksmbd_debug(SMB, "Current mode: 0x%x Desired mode: 0x%x\n", ksmbd_debug(SMB, "Current mode: 0x%x Desired mode: 0x%x\n",
prev_fp->saccess, curr_fp->daccess); prev_fp->saccess, curr_fp->daccess);
} }
int ksmbd_smb_check_shared_mode(struct file *filp, struct ksmbd_file *curr_fp) int ksmbd_smb_check_shared_mode(struct file *filp, struct ksmbd_file *curr_fp)
......
...@@ -131,7 +131,7 @@ static void smb_copy_sid(struct smb_sid *dst, const struct smb_sid *src) ...@@ -131,7 +131,7 @@ static void smb_copy_sid(struct smb_sid *dst, const struct smb_sid *src)
* bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007 * bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
*/ */
static umode_t access_flags_to_mode(struct smb_fattr *fattr, __le32 ace_flags, static umode_t access_flags_to_mode(struct smb_fattr *fattr, __le32 ace_flags,
int type) int type)
{ {
__u32 flags = le32_to_cpu(ace_flags); __u32 flags = le32_to_cpu(ace_flags);
umode_t mode = 0; umode_t mode = 0;
...@@ -166,7 +166,7 @@ static umode_t access_flags_to_mode(struct smb_fattr *fattr, __le32 ace_flags, ...@@ -166,7 +166,7 @@ static umode_t access_flags_to_mode(struct smb_fattr *fattr, __le32 ace_flags,
* with either owner or group or everyone. * with either owner or group or everyone.
*/ */
static void mode_to_access_flags(umode_t mode, umode_t bits_to_use, static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
__u32 *pace_flags) __u32 *pace_flags)
{ {
/* reset access mask */ /* reset access mask */
*pace_flags = 0x0; *pace_flags = 0x0;
...@@ -187,12 +187,12 @@ static void mode_to_access_flags(umode_t mode, umode_t bits_to_use, ...@@ -187,12 +187,12 @@ static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
*pace_flags |= SET_FILE_EXEC_RIGHTS; *pace_flags |= SET_FILE_EXEC_RIGHTS;
ksmbd_debug(SMB, "mode: %o, access flags now 0x%x\n", ksmbd_debug(SMB, "mode: %o, access flags now 0x%x\n",
mode, *pace_flags); mode, *pace_flags);
} }
static __u16 fill_ace_for_sid(struct smb_ace *pntace, static __u16 fill_ace_for_sid(struct smb_ace *pntace,
const struct smb_sid *psid, int type, int flags, const struct smb_sid *psid, int type, int flags,
umode_t mode, umode_t bits) umode_t mode, umode_t bits)
{ {
int i; int i;
__u16 size = 0; __u16 size = 0;
...@@ -255,7 +255,7 @@ void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid) ...@@ -255,7 +255,7 @@ void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
} }
static int sid_to_id(struct smb_sid *psid, uint sidtype, static int sid_to_id(struct smb_sid *psid, uint sidtype,
struct smb_fattr *fattr) struct smb_fattr *fattr)
{ {
int rc = -EINVAL; int rc = -EINVAL;
...@@ -265,7 +265,7 @@ static int sid_to_id(struct smb_sid *psid, uint sidtype, ...@@ -265,7 +265,7 @@ static int sid_to_id(struct smb_sid *psid, uint sidtype,
*/ */
if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) { if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
ksmbd_err("%s: %u subauthorities is too many!\n", ksmbd_err("%s: %u subauthorities is too many!\n",
__func__, psid->num_subauth); __func__, psid->num_subauth);
return -EIO; return -EIO;
} }
...@@ -299,7 +299,7 @@ static int sid_to_id(struct smb_sid *psid, uint sidtype, ...@@ -299,7 +299,7 @@ static int sid_to_id(struct smb_sid *psid, uint sidtype,
} }
void posix_state_to_acl(struct posix_acl_state *state, void posix_state_to_acl(struct posix_acl_state *state,
struct posix_acl_entry *pace) struct posix_acl_entry *pace)
{ {
int i; int i;
...@@ -364,8 +364,8 @@ void free_acl_state(struct posix_acl_state *state) ...@@ -364,8 +364,8 @@ void free_acl_state(struct posix_acl_state *state)
} }
static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
struct smb_sid *pownersid, struct smb_sid *pgrpsid, struct smb_sid *pownersid, struct smb_sid *pgrpsid,
struct smb_fattr *fattr) struct smb_fattr *fattr)
{ {
int i, ret; int i, ret;
int num_aces = 0; int num_aces = 0;
...@@ -388,8 +388,8 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, ...@@ -388,8 +388,8 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
} }
ksmbd_debug(SMB, "DACL revision %d size %d num aces %d\n", ksmbd_debug(SMB, "DACL revision %d size %d num aces %d\n",
le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size), le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
le32_to_cpu(pdacl->num_aces)); le32_to_cpu(pdacl->num_aces));
acl_base = (char *)pdacl; acl_base = (char *)pdacl;
acl_size = sizeof(struct smb_acl); acl_size = sizeof(struct smb_acl);
...@@ -401,8 +401,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, ...@@ -401,8 +401,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
if (num_aces > ULONG_MAX / sizeof(struct smb_ace *)) if (num_aces > ULONG_MAX / sizeof(struct smb_ace *))
return; return;
ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *), ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *), GFP_KERNEL);
GFP_KERNEL);
if (!ppace) if (!ppace)
return; return;
...@@ -433,7 +432,8 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, ...@@ -433,7 +432,8 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
break; break;
} else if (!compare_sids(&ppace[i]->sid, pownersid)) { } else if (!compare_sids(&ppace[i]->sid, pownersid)) {
acl_mode = access_flags_to_mode(fattr, acl_mode = access_flags_to_mode(fattr,
ppace[i]->access_req, ppace[i]->type); ppace[i]->access_req,
ppace[i]->type);
acl_mode &= 0700; acl_mode &= 0700;
if (!owner_found) { if (!owner_found) {
...@@ -445,7 +445,8 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, ...@@ -445,7 +445,8 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
ppace[i]->sid.sub_auth[ppace[i]->sid.num_subauth - 1] == ppace[i]->sid.sub_auth[ppace[i]->sid.num_subauth - 1] ==
DOMAIN_USER_RID_LE) { DOMAIN_USER_RID_LE) {
acl_mode = access_flags_to_mode(fattr, acl_mode = access_flags_to_mode(fattr,
ppace[i]->access_req, ppace[i]->type); ppace[i]->access_req,
ppace[i]->type);
acl_mode &= 0070; acl_mode &= 0070;
if (!group_found) { if (!group_found) {
mode &= ~(0070); mode &= ~(0070);
...@@ -454,7 +455,8 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, ...@@ -454,7 +455,8 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
group_found = true; group_found = true;
} else if (!compare_sids(&ppace[i]->sid, &sid_everyone)) { } else if (!compare_sids(&ppace[i]->sid, &sid_everyone)) {
acl_mode = access_flags_to_mode(fattr, acl_mode = access_flags_to_mode(fattr,
ppace[i]->access_req, ppace[i]->type); ppace[i]->access_req,
ppace[i]->type);
acl_mode &= 0007; acl_mode &= 0007;
if (!others_found) { if (!others_found) {
mode &= ~(0007); mode &= ~(0007);
...@@ -471,12 +473,12 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, ...@@ -471,12 +473,12 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
struct smb_fattr temp_fattr; struct smb_fattr temp_fattr;
acl_mode = access_flags_to_mode(fattr, ppace[i]->access_req, acl_mode = access_flags_to_mode(fattr, ppace[i]->access_req,
ppace[i]->type); ppace[i]->type);
temp_fattr.cf_uid = INVALID_UID; temp_fattr.cf_uid = INVALID_UID;
ret = sid_to_id(&ppace[i]->sid, SIDOWNER, &temp_fattr); ret = sid_to_id(&ppace[i]->sid, SIDOWNER, &temp_fattr);
if (ret || uid_eq(temp_fattr.cf_uid, INVALID_UID)) { if (ret || uid_eq(temp_fattr.cf_uid, INVALID_UID)) {
ksmbd_err("%s: Error %d mapping Owner SID to uid\n", ksmbd_err("%s: Error %d mapping Owner SID to uid\n",
__func__, ret); __func__, ret);
continue; continue;
} }
...@@ -553,7 +555,8 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, ...@@ -553,7 +555,8 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
} }
static void set_posix_acl_entries_dacl(struct smb_ace *pndace, static void set_posix_acl_entries_dacl(struct smb_ace *pndace,
struct smb_fattr *fattr, u32 *num_aces, u16 *size, u32 nt_aces_num) struct smb_fattr *fattr, u32 *num_aces,
u16 *size, u32 nt_aces_num)
{ {
struct posix_acl_entry *pace; struct posix_acl_entry *pace;
struct smb_sid *sid; struct smb_sid *sid;
...@@ -665,8 +668,9 @@ static void set_posix_acl_entries_dacl(struct smb_ace *pndace, ...@@ -665,8 +668,9 @@ static void set_posix_acl_entries_dacl(struct smb_ace *pndace,
} }
static void set_ntacl_dacl(struct smb_acl *pndacl, struct smb_acl *nt_dacl, static void set_ntacl_dacl(struct smb_acl *pndacl, struct smb_acl *nt_dacl,
const struct smb_sid *pownersid, const struct smb_sid *pgrpsid, const struct smb_sid *pownersid,
struct smb_fattr *fattr) const struct smb_sid *pgrpsid,
struct smb_fattr *fattr)
{ {
struct smb_ace *ntace, *pndace; struct smb_ace *ntace, *pndace;
int nt_num_aces = le32_to_cpu(nt_dacl->num_aces), num_aces = 0; int nt_num_aces = le32_to_cpu(nt_dacl->num_aces), num_aces = 0;
...@@ -711,7 +715,7 @@ static void set_mode_dacl(struct smb_acl *pndacl, struct smb_fattr *fattr) ...@@ -711,7 +715,7 @@ static void set_mode_dacl(struct smb_acl *pndacl, struct smb_fattr *fattr)
else else
sid = &sid_unix_users; sid = &sid_unix_users;
ace_size = fill_ace_for_sid(pace, sid, ACCESS_ALLOWED, 0, ace_size = fill_ace_for_sid(pace, sid, ACCESS_ALLOWED, 0,
fattr->cf_mode, 0700); fattr->cf_mode, 0700);
pace->sid.sub_auth[pace->sid.num_subauth++] = cpu_to_le32(uid); pace->sid.sub_auth[pace->sid.num_subauth++] = cpu_to_le32(uid);
pace->access_req |= FILE_DELETE_LE | FILE_DELETE_CHILD_LE; pace->access_req |= FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
pace->size = cpu_to_le16(ace_size + 4); pace->size = cpu_to_le16(ace_size + 4);
...@@ -720,7 +724,7 @@ static void set_mode_dacl(struct smb_acl *pndacl, struct smb_fattr *fattr) ...@@ -720,7 +724,7 @@ static void set_mode_dacl(struct smb_acl *pndacl, struct smb_fattr *fattr)
/* Group RID */ /* Group RID */
ace_size = fill_ace_for_sid(pace, &sid_unix_groups, ace_size = fill_ace_for_sid(pace, &sid_unix_groups,
ACCESS_ALLOWED, 0, fattr->cf_mode, 0070); ACCESS_ALLOWED, 0, fattr->cf_mode, 0070);
pace->sid.sub_auth[pace->sid.num_subauth++] = pace->sid.sub_auth[pace->sid.num_subauth++] =
cpu_to_le32(from_kgid(&init_user_ns, fattr->cf_gid)); cpu_to_le32(from_kgid(&init_user_ns, fattr->cf_gid));
pace->size = cpu_to_le16(ace_size + 4); pace->size = cpu_to_le16(ace_size + 4);
...@@ -733,20 +737,20 @@ static void set_mode_dacl(struct smb_acl *pndacl, struct smb_fattr *fattr) ...@@ -733,20 +737,20 @@ static void set_mode_dacl(struct smb_acl *pndacl, struct smb_fattr *fattr)
/* creator owner */ /* creator owner */
size += fill_ace_for_sid(pace, &creator_owner, ACCESS_ALLOWED, size += fill_ace_for_sid(pace, &creator_owner, ACCESS_ALLOWED,
0x0b, fattr->cf_mode, 0700); 0x0b, fattr->cf_mode, 0700);
pace->access_req |= FILE_DELETE_LE | FILE_DELETE_CHILD_LE; pace->access_req |= FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
pace = (struct smb_ace *)((char *)pndace + size); pace = (struct smb_ace *)((char *)pndace + size);
/* creator group */ /* creator group */
size += fill_ace_for_sid(pace, &creator_group, ACCESS_ALLOWED, size += fill_ace_for_sid(pace, &creator_group, ACCESS_ALLOWED,
0x0b, fattr->cf_mode, 0070); 0x0b, fattr->cf_mode, 0070);
pace = (struct smb_ace *)((char *)pndace + size); pace = (struct smb_ace *)((char *)pndace + size);
num_aces = 5; num_aces = 5;
} }
/* other */ /* other */
size += fill_ace_for_sid(pace, &sid_everyone, ACCESS_ALLOWED, 0, size += fill_ace_for_sid(pace, &sid_everyone, ACCESS_ALLOWED, 0,
fattr->cf_mode, 0007); fattr->cf_mode, 0007);
out: out:
pndacl->num_aces = cpu_to_le32(num_aces); pndacl->num_aces = cpu_to_le32(num_aces);
...@@ -769,7 +773,7 @@ static int parse_sid(struct smb_sid *psid, char *end_of_acl) ...@@ -769,7 +773,7 @@ static int parse_sid(struct smb_sid *psid, char *end_of_acl)
/* Convert CIFS ACL to POSIX form */ /* Convert CIFS ACL to POSIX form */
int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len, int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len,
struct smb_fattr *fattr) struct smb_fattr *fattr)
{ {
int rc = 0; int rc = 0;
struct smb_sid *owner_sid_ptr, *group_sid_ptr; struct smb_sid *owner_sid_ptr, *group_sid_ptr;
...@@ -788,10 +792,10 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len, ...@@ -788,10 +792,10 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len,
dacloffset = le32_to_cpu(pntsd->dacloffset); dacloffset = le32_to_cpu(pntsd->dacloffset);
dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset); dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
ksmbd_debug(SMB, ksmbd_debug(SMB,
"revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n", "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset), pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
le32_to_cpu(pntsd->gsidoffset), le32_to_cpu(pntsd->gsidoffset),
le32_to_cpu(pntsd->sacloffset), dacloffset); le32_to_cpu(pntsd->sacloffset), dacloffset);
pntsd_type = le16_to_cpu(pntsd->type); pntsd_type = le16_to_cpu(pntsd->type);
if (!(pntsd_type & DACL_PRESENT)) { if (!(pntsd_type & DACL_PRESENT)) {
...@@ -811,7 +815,7 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len, ...@@ -811,7 +815,7 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len,
rc = sid_to_id(owner_sid_ptr, SIDOWNER, fattr); rc = sid_to_id(owner_sid_ptr, SIDOWNER, fattr);
if (rc) { if (rc) {
ksmbd_err("%s: Error %d mapping Owner SID to uid\n", ksmbd_err("%s: Error %d mapping Owner SID to uid\n",
__func__, rc); __func__, rc);
owner_sid_ptr = NULL; owner_sid_ptr = NULL;
} }
} }
...@@ -820,19 +824,18 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len, ...@@ -820,19 +824,18 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len,
rc = parse_sid(group_sid_ptr, end_of_acl); rc = parse_sid(group_sid_ptr, end_of_acl);
if (rc) { if (rc) {
ksmbd_err("%s: Error %d mapping Owner SID to gid\n", ksmbd_err("%s: Error %d mapping Owner SID to gid\n",
__func__, rc); __func__, rc);
return rc; return rc;
} }
rc = sid_to_id(group_sid_ptr, SIDUNIX_GROUP, fattr); rc = sid_to_id(group_sid_ptr, SIDUNIX_GROUP, fattr);
if (rc) { if (rc) {
ksmbd_err("%s: Error %d mapping Group SID to gid\n", ksmbd_err("%s: Error %d mapping Group SID to gid\n",
__func__, rc); __func__, rc);
group_sid_ptr = NULL; group_sid_ptr = NULL;
} }
} }
if ((pntsd_type & if ((pntsd_type & (DACL_AUTO_INHERITED | DACL_AUTO_INHERIT_REQ)) ==
(DACL_AUTO_INHERITED | DACL_AUTO_INHERIT_REQ)) ==
(DACL_AUTO_INHERITED | DACL_AUTO_INHERIT_REQ)) (DACL_AUTO_INHERITED | DACL_AUTO_INHERIT_REQ))
pntsd->type |= cpu_to_le16(DACL_AUTO_INHERITED); pntsd->type |= cpu_to_le16(DACL_AUTO_INHERITED);
if (pntsd_type & DACL_PROTECTED) if (pntsd_type & DACL_PROTECTED)
...@@ -840,7 +843,7 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len, ...@@ -840,7 +843,7 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len,
if (dacloffset) { if (dacloffset) {
parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr, parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr,
fattr); fattr);
} }
return 0; return 0;
...@@ -848,7 +851,8 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len, ...@@ -848,7 +851,8 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len,
/* Convert permission bits from mode to equivalent CIFS ACL */ /* Convert permission bits from mode to equivalent CIFS ACL */
int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd, int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
int addition_info, __u32 *secdesclen, struct smb_fattr *fattr) int addition_info, __u32 *secdesclen,
struct smb_fattr *fattr)
{ {
int rc = 0; int rc = 0;
__u32 offset; __u32 offset;
...@@ -929,7 +933,7 @@ int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd, ...@@ -929,7 +933,7 @@ int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
} }
static void smb_set_ace(struct smb_ace *ace, const struct smb_sid *sid, u8 type, static void smb_set_ace(struct smb_ace *ace, const struct smb_sid *sid, u8 type,
u8 flags, __le32 access_req) u8 flags, __le32 access_req)
{ {
ace->type = type; ace->type = type;
ace->flags = flags; ace->flags = flags;
...@@ -939,7 +943,7 @@ static void smb_set_ace(struct smb_ace *ace, const struct smb_sid *sid, u8 type, ...@@ -939,7 +943,7 @@ static void smb_set_ace(struct smb_ace *ace, const struct smb_sid *sid, u8 type,
} }
int smb_inherit_dacl(struct ksmbd_conn *conn, struct dentry *dentry, int smb_inherit_dacl(struct ksmbd_conn *conn, struct dentry *dentry,
unsigned int uid, unsigned int gid) unsigned int uid, unsigned int gid)
{ {
const struct smb_sid *psid, *creator = NULL; const struct smb_sid *psid, *creator = NULL;
struct smb_ace *parent_aces, *aces; struct smb_ace *parent_aces, *aces;
...@@ -1003,7 +1007,7 @@ int smb_inherit_dacl(struct ksmbd_conn *conn, struct dentry *dentry, ...@@ -1003,7 +1007,7 @@ int smb_inherit_dacl(struct ksmbd_conn *conn, struct dentry *dentry,
if (is_dir && creator && flags & CONTAINER_INHERIT_ACE) { if (is_dir && creator && flags & CONTAINER_INHERIT_ACE) {
smb_set_ace(aces, psid, parent_aces->type, inherited_flags, smb_set_ace(aces, psid, parent_aces->type, inherited_flags,
parent_aces->access_req); parent_aces->access_req);
nt_size += le16_to_cpu(aces->size); nt_size += le16_to_cpu(aces->size);
ace_cnt++; ace_cnt++;
aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size)); aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size));
...@@ -1014,7 +1018,7 @@ int smb_inherit_dacl(struct ksmbd_conn *conn, struct dentry *dentry, ...@@ -1014,7 +1018,7 @@ int smb_inherit_dacl(struct ksmbd_conn *conn, struct dentry *dentry,
} }
smb_set_ace(aces, psid, parent_aces->type, flags | inherited_flags, smb_set_ace(aces, psid, parent_aces->type, flags | inherited_flags,
parent_aces->access_req); parent_aces->access_req);
nt_size += le16_to_cpu(aces->size); nt_size += le16_to_cpu(aces->size);
aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size)); aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size));
ace_cnt++; ace_cnt++;
...@@ -1107,7 +1111,7 @@ bool smb_inherit_flags(int flags, bool is_dir) ...@@ -1107,7 +1111,7 @@ bool smb_inherit_flags(int flags, bool is_dir)
} }
int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry, int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry,
__le32 *pdaccess, int uid) __le32 *pdaccess, int uid)
{ {
struct smb_ntsd *pntsd = NULL; struct smb_ntsd *pntsd = NULL;
struct smb_acl *pdacl; struct smb_acl *pdacl;
...@@ -1243,10 +1247,10 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry, ...@@ -1243,10 +1247,10 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry,
} }
check_access_bits: check_access_bits:
if (granted & ~(access_bits | FILE_READ_ATTRIBUTES | if (granted &
READ_CONTROL | WRITE_DAC | DELETE)) { ~(access_bits | FILE_READ_ATTRIBUTES | READ_CONTROL | WRITE_DAC | DELETE)) {
ksmbd_debug(SMB, "Access denied with winACL, granted : %x, access_req : %x\n", ksmbd_debug(SMB, "Access denied with winACL, granted : %x, access_req : %x\n",
granted, le32_to_cpu(ace->access_req)); granted, le32_to_cpu(ace->access_req));
rc = -EACCES; rc = -EACCES;
goto err_out; goto err_out;
} }
...@@ -1258,8 +1262,8 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry, ...@@ -1258,8 +1262,8 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry,
} }
int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
struct dentry *dentry, struct smb_ntsd *pntsd, int ntsd_len, struct dentry *dentry, struct smb_ntsd *pntsd, int ntsd_len,
bool type_check) bool type_check)
{ {
int rc; int rc;
struct smb_fattr fattr = {{0}}; struct smb_fattr fattr = {{0}};
...@@ -1284,10 +1288,10 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, ...@@ -1284,10 +1288,10 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
/* Update posix acls */ /* Update posix acls */
if (fattr.cf_dacls) { if (fattr.cf_dacls) {
rc = ksmbd_vfs_set_posix_acl(inode, ACL_TYPE_ACCESS, rc = ksmbd_vfs_set_posix_acl(inode, ACL_TYPE_ACCESS,
fattr.cf_acls); fattr.cf_acls);
if (S_ISDIR(inode->i_mode) && fattr.cf_dacls) if (S_ISDIR(inode->i_mode) && fattr.cf_dacls)
rc = ksmbd_vfs_set_posix_acl(inode, ACL_TYPE_DEFAULT, rc = ksmbd_vfs_set_posix_acl(inode, ACL_TYPE_DEFAULT,
fattr.cf_dacls); fattr.cf_dacls);
} }
/* Check it only calling from SD BUFFER context */ /* Check it only calling from SD BUFFER context */
......
...@@ -269,7 +269,7 @@ static int handle_response(int type, void *payload, size_t sz) ...@@ -269,7 +269,7 @@ static int handle_response(int type, void *payload, size_t sz)
*/ */
if (entry->type + 1 != type) { if (entry->type + 1 != type) {
ksmbd_err("Waiting for IPC type %d, got %d. Ignore.\n", ksmbd_err("Waiting for IPC type %d, got %d. Ignore.\n",
entry->type + 1, type); entry->type + 1, type);
} }
entry->response = kvmalloc(sz, GFP_KERNEL | __GFP_ZERO); entry->response = kvmalloc(sz, GFP_KERNEL | __GFP_ZERO);
...@@ -315,9 +315,8 @@ static int ipc_server_config_on_startup(struct ksmbd_startup_request *req) ...@@ -315,9 +315,8 @@ static int ipc_server_config_on_startup(struct ksmbd_startup_request *req)
req->ifc_list_sz); req->ifc_list_sz);
if (ret) { if (ret) {
ksmbd_err("Server configuration error: %s %s %s\n", ksmbd_err("Server configuration error: %s %s %s\n",
req->netbios_name, req->netbios_name, req->server_string,
req->server_string, req->work_group);
req->work_group);
return ret; return ret;
} }
...@@ -547,9 +546,9 @@ ksmbd_ipc_spnego_authen_request(const char *spnego_blob, int blob_len) ...@@ -547,9 +546,9 @@ ksmbd_ipc_spnego_authen_request(const char *spnego_blob, int blob_len)
struct ksmbd_tree_connect_response * struct ksmbd_tree_connect_response *
ksmbd_ipc_tree_connect_request(struct ksmbd_session *sess, ksmbd_ipc_tree_connect_request(struct ksmbd_session *sess,
struct ksmbd_share_config *share, struct ksmbd_share_config *share,
struct ksmbd_tree_connect *tree_conn, struct ksmbd_tree_connect *tree_conn,
struct sockaddr *peer_addr) struct sockaddr *peer_addr)
{ {
struct ksmbd_ipc_msg *msg; struct ksmbd_ipc_msg *msg;
struct ksmbd_tree_connect_request *req; struct ksmbd_tree_connect_request *req;
...@@ -588,7 +587,7 @@ ksmbd_ipc_tree_connect_request(struct ksmbd_session *sess, ...@@ -588,7 +587,7 @@ ksmbd_ipc_tree_connect_request(struct ksmbd_session *sess,
} }
int ksmbd_ipc_tree_disconnect_request(unsigned long long session_id, int ksmbd_ipc_tree_disconnect_request(unsigned long long session_id,
unsigned long long connect_id) unsigned long long connect_id)
{ {
struct ksmbd_ipc_msg *msg; struct ksmbd_ipc_msg *msg;
struct ksmbd_tree_disconnect_request *req; struct ksmbd_tree_disconnect_request *req;
...@@ -700,7 +699,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_close(struct ksmbd_session *sess, int handle ...@@ -700,7 +699,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_close(struct ksmbd_session *sess, int handle
} }
struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle, struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle,
void *payload, size_t payload_sz) void *payload, size_t payload_sz)
{ {
struct ksmbd_ipc_msg *msg; struct ksmbd_ipc_msg *msg;
struct ksmbd_rpc_command *req; struct ksmbd_rpc_command *req;
...@@ -748,7 +747,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess, int handle) ...@@ -748,7 +747,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess, int handle)
} }
struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle, struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle,
void *payload, size_t payload_sz) void *payload, size_t payload_sz)
{ {
struct ksmbd_ipc_msg *msg; struct ksmbd_ipc_msg *msg;
struct ksmbd_rpc_command *req; struct ksmbd_rpc_command *req;
...@@ -773,7 +772,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle ...@@ -773,7 +772,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle
} }
struct ksmbd_rpc_command *ksmbd_rpc_rap(struct ksmbd_session *sess, void *payload, struct ksmbd_rpc_command *ksmbd_rpc_rap(struct ksmbd_session *sess, void *payload,
size_t payload_sz) size_t payload_sz)
{ {
struct ksmbd_ipc_msg *msg; struct ksmbd_ipc_msg *msg;
struct ksmbd_rpc_command *req; struct ksmbd_rpc_command *req;
......
...@@ -23,31 +23,24 @@ ksmbd_ipc_tree_connect_request(struct ksmbd_session *sess, ...@@ -23,31 +23,24 @@ ksmbd_ipc_tree_connect_request(struct ksmbd_session *sess,
struct ksmbd_share_config *share, struct ksmbd_share_config *share,
struct ksmbd_tree_connect *tree_conn, struct ksmbd_tree_connect *tree_conn,
struct sockaddr *peer_addr); struct sockaddr *peer_addr);
int ksmbd_ipc_tree_disconnect_request(unsigned long long session_id, int ksmbd_ipc_tree_disconnect_request(unsigned long long session_id,
unsigned long long connect_id); unsigned long long connect_id);
int ksmbd_ipc_logout_request(const char *account); int ksmbd_ipc_logout_request(const char *account);
struct ksmbd_share_config_response * struct ksmbd_share_config_response *
ksmbd_ipc_share_config_request(const char *name); ksmbd_ipc_share_config_request(const char *name);
struct ksmbd_spnego_authen_response * struct ksmbd_spnego_authen_response *
ksmbd_ipc_spnego_authen_request(const char *spnego_blob, int blob_len); ksmbd_ipc_spnego_authen_request(const char *spnego_blob, int blob_len);
int ksmbd_ipc_id_alloc(void); int ksmbd_ipc_id_alloc(void);
void ksmbd_rpc_id_free(int handle); void ksmbd_rpc_id_free(int handle);
struct ksmbd_rpc_command *ksmbd_rpc_open(struct ksmbd_session *sess, int handle); struct ksmbd_rpc_command *ksmbd_rpc_open(struct ksmbd_session *sess, int handle);
struct ksmbd_rpc_command *ksmbd_rpc_close(struct ksmbd_session *sess, int handle); struct ksmbd_rpc_command *ksmbd_rpc_close(struct ksmbd_session *sess, int handle);
struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle, struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle,
void *payload, size_t payload_sz); void *payload, size_t payload_sz);
struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess, int handle); struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess, int handle);
struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle, struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle,
void *payload, size_t payload_sz); void *payload, size_t payload_sz);
struct ksmbd_rpc_command *ksmbd_rpc_rap(struct ksmbd_session *sess, void *payload, struct ksmbd_rpc_command *ksmbd_rpc_rap(struct ksmbd_session *sess, void *payload,
size_t payload_sz); size_t payload_sz);
void ksmbd_ipc_release(void); void ksmbd_ipc_release(void);
void ksmbd_ipc_soft_reset(void); void ksmbd_ipc_soft_reset(void);
int ksmbd_ipc_init(void); int ksmbd_ipc_init(void);
......
...@@ -212,8 +212,9 @@ struct smb_direct_rdma_rw_msg { ...@@ -212,8 +212,9 @@ struct smb_direct_rdma_rw_msg {
static void smb_direct_destroy_pools(struct smb_direct_transport *transport); static void smb_direct_destroy_pools(struct smb_direct_transport *transport);
static void smb_direct_post_recv_credits(struct work_struct *work); static void smb_direct_post_recv_credits(struct work_struct *work);
static int smb_direct_post_send_data(struct smb_direct_transport *t, static int smb_direct_post_send_data(struct smb_direct_transport *t,
struct smb_direct_send_ctx *send_ctx, struct smb_direct_send_ctx *send_ctx,
struct kvec *iov, int niov, int remaining_data_length); struct kvec *iov, int niov,
int remaining_data_length);
static inline void static inline void
*smb_direct_recvmsg_payload(struct smb_direct_recvmsg *recvmsg) *smb_direct_recvmsg_payload(struct smb_direct_recvmsg *recvmsg)
...@@ -222,7 +223,7 @@ static inline void ...@@ -222,7 +223,7 @@ static inline void
} }
static inline bool is_receive_credit_post_required(int receive_credits, static inline bool is_receive_credit_post_required(int receive_credits,
int avail_recvmsg_count) int avail_recvmsg_count)
{ {
return receive_credits <= (smb_direct_receive_credit_max >> 3) && return receive_credits <= (smb_direct_receive_credit_max >> 3) &&
avail_recvmsg_count >= (receive_credits >> 2); avail_recvmsg_count >= (receive_credits >> 2);
...@@ -245,10 +246,10 @@ smb_direct_recvmsg *get_free_recvmsg(struct smb_direct_transport *t) ...@@ -245,10 +246,10 @@ smb_direct_recvmsg *get_free_recvmsg(struct smb_direct_transport *t)
} }
static void put_recvmsg(struct smb_direct_transport *t, static void put_recvmsg(struct smb_direct_transport *t,
struct smb_direct_recvmsg *recvmsg) struct smb_direct_recvmsg *recvmsg)
{ {
ib_dma_unmap_single(t->cm_id->device, recvmsg->sge.addr, ib_dma_unmap_single(t->cm_id->device, recvmsg->sge.addr,
recvmsg->sge.length, DMA_FROM_DEVICE); recvmsg->sge.length, DMA_FROM_DEVICE);
spin_lock(&t->recvmsg_queue_lock); spin_lock(&t->recvmsg_queue_lock);
list_add(&recvmsg->list, &t->recvmsg_queue); list_add(&recvmsg->list, &t->recvmsg_queue);
...@@ -263,7 +264,7 @@ smb_direct_recvmsg *get_empty_recvmsg(struct smb_direct_transport *t) ...@@ -263,7 +264,7 @@ smb_direct_recvmsg *get_empty_recvmsg(struct smb_direct_transport *t)
spin_lock(&t->empty_recvmsg_queue_lock); spin_lock(&t->empty_recvmsg_queue_lock);
if (!list_empty(&t->empty_recvmsg_queue)) { if (!list_empty(&t->empty_recvmsg_queue)) {
recvmsg = list_first_entry(&t->empty_recvmsg_queue, recvmsg = list_first_entry(&t->empty_recvmsg_queue,
struct smb_direct_recvmsg, list); struct smb_direct_recvmsg, list);
list_del(&recvmsg->list); list_del(&recvmsg->list);
} }
spin_unlock(&t->empty_recvmsg_queue_lock); spin_unlock(&t->empty_recvmsg_queue_lock);
...@@ -271,10 +272,10 @@ smb_direct_recvmsg *get_empty_recvmsg(struct smb_direct_transport *t) ...@@ -271,10 +272,10 @@ smb_direct_recvmsg *get_empty_recvmsg(struct smb_direct_transport *t)
} }
static void put_empty_recvmsg(struct smb_direct_transport *t, static void put_empty_recvmsg(struct smb_direct_transport *t,
struct smb_direct_recvmsg *recvmsg) struct smb_direct_recvmsg *recvmsg)
{ {
ib_dma_unmap_single(t->cm_id->device, recvmsg->sge.addr, ib_dma_unmap_single(t->cm_id->device, recvmsg->sge.addr,
recvmsg->sge.length, DMA_FROM_DEVICE); recvmsg->sge.length, DMA_FROM_DEVICE);
spin_lock(&t->empty_recvmsg_queue_lock); spin_lock(&t->empty_recvmsg_queue_lock);
list_add_tail(&recvmsg->list, &t->empty_recvmsg_queue); list_add_tail(&recvmsg->list, &t->empty_recvmsg_queue);
...@@ -282,7 +283,8 @@ static void put_empty_recvmsg(struct smb_direct_transport *t, ...@@ -282,7 +283,8 @@ static void put_empty_recvmsg(struct smb_direct_transport *t,
} }
static void enqueue_reassembly(struct smb_direct_transport *t, static void enqueue_reassembly(struct smb_direct_transport *t,
struct smb_direct_recvmsg *recvmsg, int data_length) struct smb_direct_recvmsg *recvmsg,
int data_length)
{ {
spin_lock(&t->reassembly_queue_lock); spin_lock(&t->reassembly_queue_lock);
list_add_tail(&recvmsg->list, &t->reassembly_queue); list_add_tail(&recvmsg->list, &t->reassembly_queue);
...@@ -398,9 +400,9 @@ static void free_transport(struct smb_direct_transport *t) ...@@ -398,9 +400,9 @@ static void free_transport(struct smb_direct_transport *t)
ksmbd_debug(RDMA, "wait for all send posted to IB to finish\n"); ksmbd_debug(RDMA, "wait for all send posted to IB to finish\n");
wait_event(t->wait_send_payload_pending, wait_event(t->wait_send_payload_pending,
atomic_read(&t->send_payload_pending) == 0); atomic_read(&t->send_payload_pending) == 0);
wait_event(t->wait_send_pending, wait_event(t->wait_send_pending,
atomic_read(&t->send_pending) == 0); atomic_read(&t->send_pending) == 0);
cancel_work_sync(&t->disconnect_work); cancel_work_sync(&t->disconnect_work);
cancel_delayed_work_sync(&t->post_recv_credits_work); cancel_delayed_work_sync(&t->post_recv_credits_work);
...@@ -454,18 +456,18 @@ static struct smb_direct_sendmsg ...@@ -454,18 +456,18 @@ static struct smb_direct_sendmsg
} }
static void smb_direct_free_sendmsg(struct smb_direct_transport *t, static void smb_direct_free_sendmsg(struct smb_direct_transport *t,
struct smb_direct_sendmsg *msg) struct smb_direct_sendmsg *msg)
{ {
int i; int i;
if (msg->num_sge > 0) { if (msg->num_sge > 0) {
ib_dma_unmap_single(t->cm_id->device, ib_dma_unmap_single(t->cm_id->device,
msg->sge[0].addr, msg->sge[0].length, msg->sge[0].addr, msg->sge[0].length,
DMA_TO_DEVICE); DMA_TO_DEVICE);
for (i = 1; i < msg->num_sge; i++) for (i = 1; i < msg->num_sge; i++)
ib_dma_unmap_page(t->cm_id->device, ib_dma_unmap_page(t->cm_id->device,
msg->sge[i].addr, msg->sge[i].length, msg->sge[i].addr, msg->sge[i].length,
DMA_TO_DEVICE); DMA_TO_DEVICE);
} }
mempool_free(msg, t->sendmsg_mempool); mempool_free(msg, t->sendmsg_mempool);
} }
...@@ -479,24 +481,24 @@ static int smb_direct_check_recvmsg(struct smb_direct_recvmsg *recvmsg) ...@@ -479,24 +481,24 @@ static int smb_direct_check_recvmsg(struct smb_direct_recvmsg *recvmsg)
struct smb2_hdr *hdr = (struct smb2_hdr *)(recvmsg->packet struct smb2_hdr *hdr = (struct smb2_hdr *)(recvmsg->packet
+ le32_to_cpu(req->data_offset) - 4); + le32_to_cpu(req->data_offset) - 4);
ksmbd_debug(RDMA, ksmbd_debug(RDMA,
"CreditGranted: %u, CreditRequested: %u, DataLength: %u, RemainingDataLength: %u, SMB: %x, Command: %u\n", "CreditGranted: %u, CreditRequested: %u, DataLength: %u, RemainingDataLength: %u, SMB: %x, Command: %u\n",
le16_to_cpu(req->credits_granted), le16_to_cpu(req->credits_granted),
le16_to_cpu(req->credits_requested), le16_to_cpu(req->credits_requested),
req->data_length, req->remaining_data_length, req->data_length, req->remaining_data_length,
hdr->ProtocolId, hdr->Command); hdr->ProtocolId, hdr->Command);
break; break;
} }
case SMB_DIRECT_MSG_NEGOTIATE_REQ: { case SMB_DIRECT_MSG_NEGOTIATE_REQ: {
struct smb_direct_negotiate_req *req = struct smb_direct_negotiate_req *req =
(struct smb_direct_negotiate_req *)recvmsg->packet; (struct smb_direct_negotiate_req *)recvmsg->packet;
ksmbd_debug(RDMA, ksmbd_debug(RDMA,
"MinVersion: %u, MaxVersion: %u, CreditRequested: %u, MaxSendSize: %u, MaxRecvSize: %u, MaxFragmentedSize: %u\n", "MinVersion: %u, MaxVersion: %u, CreditRequested: %u, MaxSendSize: %u, MaxRecvSize: %u, MaxFragmentedSize: %u\n",
le16_to_cpu(req->min_version), le16_to_cpu(req->min_version),
le16_to_cpu(req->max_version), le16_to_cpu(req->max_version),
le16_to_cpu(req->credits_requested), le16_to_cpu(req->credits_requested),
le32_to_cpu(req->preferred_send_size), le32_to_cpu(req->preferred_send_size),
le32_to_cpu(req->max_receive_size), le32_to_cpu(req->max_receive_size),
le32_to_cpu(req->max_fragmented_size)); le32_to_cpu(req->max_fragmented_size));
if (le16_to_cpu(req->min_version) > 0x0100 || if (le16_to_cpu(req->min_version) > 0x0100 ||
le16_to_cpu(req->max_version) < 0x0100) le16_to_cpu(req->max_version) < 0x0100)
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -525,8 +527,8 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) ...@@ -525,8 +527,8 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_RECV) { if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_RECV) {
if (wc->status != IB_WC_WR_FLUSH_ERR) { if (wc->status != IB_WC_WR_FLUSH_ERR) {
ksmbd_err("Recv error. status='%s (%d)' opcode=%d\n", ksmbd_err("Recv error. status='%s (%d)' opcode=%d\n",
ib_wc_status_msg(wc->status), wc->status, ib_wc_status_msg(wc->status), wc->status,
wc->opcode); wc->opcode);
smb_direct_disconnect_rdma_connection(t); smb_direct_disconnect_rdma_connection(t);
} }
put_empty_recvmsg(t, recvmsg); put_empty_recvmsg(t, recvmsg);
...@@ -534,11 +536,11 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) ...@@ -534,11 +536,11 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
} }
ksmbd_debug(RDMA, "Recv completed. status='%s (%d)', opcode=%d\n", ksmbd_debug(RDMA, "Recv completed. status='%s (%d)', opcode=%d\n",
ib_wc_status_msg(wc->status), wc->status, ib_wc_status_msg(wc->status), wc->status,
wc->opcode); wc->opcode);
ib_dma_sync_single_for_cpu(wc->qp->device, recvmsg->sge.addr, ib_dma_sync_single_for_cpu(wc->qp->device, recvmsg->sge.addr,
recvmsg->sge.length, DMA_FROM_DEVICE); recvmsg->sge.length, DMA_FROM_DEVICE);
switch (recvmsg->type) { switch (recvmsg->type) {
case SMB_DIRECT_MSG_NEGOTIATE_REQ: case SMB_DIRECT_MSG_NEGOTIATE_REQ:
...@@ -580,10 +582,10 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) ...@@ -580,10 +582,10 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
t->recv_credit_target = t->recv_credit_target =
le16_to_cpu(data_transfer->credits_requested); le16_to_cpu(data_transfer->credits_requested);
atomic_add(le16_to_cpu(data_transfer->credits_granted), atomic_add(le16_to_cpu(data_transfer->credits_granted),
&t->send_credits); &t->send_credits);
if (le16_to_cpu(data_transfer->flags) & if (le16_to_cpu(data_transfer->flags) &
SMB_DIRECT_RESPONSE_REQUESTED) SMB_DIRECT_RESPONSE_REQUESTED)
queue_work(smb_direct_wq, &t->send_immediate_work); queue_work(smb_direct_wq, &t->send_immediate_work);
if (atomic_read(&t->send_credits) > 0) if (atomic_read(&t->send_credits) > 0)
...@@ -591,7 +593,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) ...@@ -591,7 +593,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
if (is_receive_credit_post_required(receive_credits, avail_recvmsg_count)) if (is_receive_credit_post_required(receive_credits, avail_recvmsg_count))
mod_delayed_work(smb_direct_wq, mod_delayed_work(smb_direct_wq,
&t->post_recv_credits_work, 0); &t->post_recv_credits_work, 0);
break; break;
} }
default: default:
...@@ -600,14 +602,14 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) ...@@ -600,14 +602,14 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
} }
static int smb_direct_post_recv(struct smb_direct_transport *t, static int smb_direct_post_recv(struct smb_direct_transport *t,
struct smb_direct_recvmsg *recvmsg) struct smb_direct_recvmsg *recvmsg)
{ {
struct ib_recv_wr wr; struct ib_recv_wr wr;
int ret; int ret;
recvmsg->sge.addr = ib_dma_map_single(t->cm_id->device, recvmsg->sge.addr = ib_dma_map_single(t->cm_id->device,
recvmsg->packet, t->max_recv_size, recvmsg->packet, t->max_recv_size,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
ret = ib_dma_mapping_error(t->cm_id->device, recvmsg->sge.addr); ret = ib_dma_mapping_error(t->cm_id->device, recvmsg->sge.addr);
if (ret) if (ret)
return ret; return ret;
...@@ -624,8 +626,8 @@ static int smb_direct_post_recv(struct smb_direct_transport *t, ...@@ -624,8 +626,8 @@ static int smb_direct_post_recv(struct smb_direct_transport *t,
if (ret) { if (ret) {
ksmbd_err("Can't post recv: %d\n", ret); ksmbd_err("Can't post recv: %d\n", ret);
ib_dma_unmap_single(t->cm_id->device, ib_dma_unmap_single(t->cm_id->device,
recvmsg->sge.addr, recvmsg->sge.length, recvmsg->sge.addr, recvmsg->sge.length,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
smb_direct_disconnect_rdma_connection(t); smb_direct_disconnect_rdma_connection(t);
return ret; return ret;
} }
...@@ -633,7 +635,7 @@ static int smb_direct_post_recv(struct smb_direct_transport *t, ...@@ -633,7 +635,7 @@ static int smb_direct_post_recv(struct smb_direct_transport *t,
} }
static int smb_direct_read(struct ksmbd_transport *t, char *buf, static int smb_direct_read(struct ksmbd_transport *t, char *buf,
unsigned int size) unsigned int size)
{ {
struct smb_direct_recvmsg *recvmsg; struct smb_direct_recvmsg *recvmsg;
struct smb_direct_data_transfer *data_transfer; struct smb_direct_data_transfer *data_transfer;
...@@ -692,14 +694,14 @@ static int smb_direct_read(struct ksmbd_transport *t, char *buf, ...@@ -692,14 +694,14 @@ static int smb_direct_read(struct ksmbd_transport *t, char *buf,
data_read = 4; data_read = 4;
recvmsg->first_segment = false; recvmsg->first_segment = false;
ksmbd_debug(RDMA, ksmbd_debug(RDMA,
"returning rfc1002 length %d\n", "returning rfc1002 length %d\n",
rfc1002_len); rfc1002_len);
goto read_rfc1002_done; goto read_rfc1002_done;
} }
to_copy = min_t(int, data_length - offset, to_read); to_copy = min_t(int, data_length - offset, to_read);
memcpy(buf + data_read, (char *)data_transfer + data_offset + offset, memcpy(buf + data_read, (char *)data_transfer + data_offset + offset,
to_copy); to_copy);
/* move on to the next buffer? */ /* move on to the next buffer? */
if (to_copy == data_length - offset) { if (to_copy == data_length - offset) {
...@@ -736,23 +738,24 @@ static int smb_direct_read(struct ksmbd_transport *t, char *buf, ...@@ -736,23 +738,24 @@ static int smb_direct_read(struct ksmbd_transport *t, char *buf,
if (is_receive_credit_post_required(st->recv_credits, st->count_avail_recvmsg)) { if (is_receive_credit_post_required(st->recv_credits, st->count_avail_recvmsg)) {
spin_unlock(&st->receive_credit_lock); spin_unlock(&st->receive_credit_lock);
mod_delayed_work(smb_direct_wq, mod_delayed_work(smb_direct_wq,
&st->post_recv_credits_work, 0); &st->post_recv_credits_work, 0);
} else { } else {
spin_unlock(&st->receive_credit_lock); spin_unlock(&st->receive_credit_lock);
} }
st->first_entry_offset = offset; st->first_entry_offset = offset;
ksmbd_debug(RDMA, ksmbd_debug(RDMA,
"returning to thread data_read=%d reassembly_data_length=%d first_entry_offset=%d\n", "returning to thread data_read=%d reassembly_data_length=%d first_entry_offset=%d\n",
data_read, st->reassembly_data_length, data_read, st->reassembly_data_length,
st->first_entry_offset); st->first_entry_offset);
read_rfc1002_done: read_rfc1002_done:
return data_read; return data_read;
} }
ksmbd_debug(RDMA, "wait_event on more data\n"); ksmbd_debug(RDMA, "wait_event on more data\n");
rc = wait_event_interruptible(st->wait_reassembly_queue, rc = wait_event_interruptible(st->wait_reassembly_queue,
st->reassembly_data_length >= size || st->status != SMB_DIRECT_CS_CONNECTED); st->reassembly_data_length >= size ||
st->status != SMB_DIRECT_CS_CONNECTED);
if (rc) if (rc)
return -EINTR; return -EINTR;
...@@ -823,13 +826,13 @@ static void send_done(struct ib_cq *cq, struct ib_wc *wc) ...@@ -823,13 +826,13 @@ static void send_done(struct ib_cq *cq, struct ib_wc *wc)
t = sendmsg->transport; t = sendmsg->transport;
ksmbd_debug(RDMA, "Send completed. status='%s (%d)', opcode=%d\n", ksmbd_debug(RDMA, "Send completed. status='%s (%d)', opcode=%d\n",
ib_wc_status_msg(wc->status), wc->status, ib_wc_status_msg(wc->status), wc->status,
wc->opcode); wc->opcode);
if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_SEND) { if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_SEND) {
ksmbd_err("Send error. status='%s (%d)', opcode=%d\n", ksmbd_err("Send error. status='%s (%d)', opcode=%d\n",
ib_wc_status_msg(wc->status), wc->status, ib_wc_status_msg(wc->status), wc->status,
wc->opcode); wc->opcode);
smb_direct_disconnect_rdma_connection(t); smb_direct_disconnect_rdma_connection(t);
} }
...@@ -845,7 +848,7 @@ static void send_done(struct ib_cq *cq, struct ib_wc *wc) ...@@ -845,7 +848,7 @@ static void send_done(struct ib_cq *cq, struct ib_wc *wc)
* is invalid. * is invalid.
*/ */
for (pos = &sendmsg->list, prev = pos->prev, end = sendmsg->list.next; for (pos = &sendmsg->list, prev = pos->prev, end = sendmsg->list.next;
prev != end; pos = prev, prev = prev->prev) { prev != end; pos = prev, prev = prev->prev) {
sibling = container_of(pos, struct smb_direct_sendmsg, list); sibling = container_of(pos, struct smb_direct_sendmsg, list);
smb_direct_free_sendmsg(t, sibling); smb_direct_free_sendmsg(t, sibling);
} }
...@@ -867,7 +870,7 @@ static int manage_credits_prior_sending(struct smb_direct_transport *t) ...@@ -867,7 +870,7 @@ static int manage_credits_prior_sending(struct smb_direct_transport *t)
} }
static int smb_direct_post_send(struct smb_direct_transport *t, static int smb_direct_post_send(struct smb_direct_transport *t,
struct ib_send_wr *wr) struct ib_send_wr *wr)
{ {
int ret; int ret;
...@@ -892,8 +895,9 @@ static int smb_direct_post_send(struct smb_direct_transport *t, ...@@ -892,8 +895,9 @@ static int smb_direct_post_send(struct smb_direct_transport *t,
} }
static void smb_direct_send_ctx_init(struct smb_direct_transport *t, static void smb_direct_send_ctx_init(struct smb_direct_transport *t,
struct smb_direct_send_ctx *send_ctx, struct smb_direct_send_ctx *send_ctx,
bool need_invalidate_rkey, unsigned int remote_key) bool need_invalidate_rkey,
unsigned int remote_key)
{ {
INIT_LIST_HEAD(&send_ctx->msg_list); INIT_LIST_HEAD(&send_ctx->msg_list);
send_ctx->wr_cnt = 0; send_ctx->wr_cnt = 0;
...@@ -902,7 +906,8 @@ static void smb_direct_send_ctx_init(struct smb_direct_transport *t, ...@@ -902,7 +906,8 @@ static void smb_direct_send_ctx_init(struct smb_direct_transport *t,
} }
static int smb_direct_flush_send_list(struct smb_direct_transport *t, static int smb_direct_flush_send_list(struct smb_direct_transport *t,
struct smb_direct_send_ctx *send_ctx, bool is_last) struct smb_direct_send_ctx *send_ctx,
bool is_last)
{ {
struct smb_direct_sendmsg *first, *last; struct smb_direct_sendmsg *first, *last;
int ret; int ret;
...@@ -911,11 +916,11 @@ static int smb_direct_flush_send_list(struct smb_direct_transport *t, ...@@ -911,11 +916,11 @@ static int smb_direct_flush_send_list(struct smb_direct_transport *t,
return 0; return 0;
first = list_first_entry(&send_ctx->msg_list, first = list_first_entry(&send_ctx->msg_list,
struct smb_direct_sendmsg, struct smb_direct_sendmsg,
list); list);
last = list_last_entry(&send_ctx->msg_list, last = list_last_entry(&send_ctx->msg_list,
struct smb_direct_sendmsg, struct smb_direct_sendmsg,
list); list);
last->wr.send_flags = IB_SEND_SIGNALED; last->wr.send_flags = IB_SEND_SIGNALED;
last->wr.wr_cqe = &last->cqe; last->wr.wr_cqe = &last->cqe;
...@@ -927,12 +932,13 @@ static int smb_direct_flush_send_list(struct smb_direct_transport *t, ...@@ -927,12 +932,13 @@ static int smb_direct_flush_send_list(struct smb_direct_transport *t,
ret = smb_direct_post_send(t, &first->wr); ret = smb_direct_post_send(t, &first->wr);
if (!ret) { if (!ret) {
smb_direct_send_ctx_init(t, send_ctx, smb_direct_send_ctx_init(t, send_ctx,
send_ctx->need_invalidate_rkey, send_ctx->remote_key); send_ctx->need_invalidate_rkey,
send_ctx->remote_key);
} else { } else {
atomic_add(send_ctx->wr_cnt, &t->send_credits); atomic_add(send_ctx->wr_cnt, &t->send_credits);
wake_up(&t->wait_send_credits); wake_up(&t->wait_send_credits);
list_for_each_entry_safe(first, last, &send_ctx->msg_list, list_for_each_entry_safe(first, last, &send_ctx->msg_list,
list) { list) {
smb_direct_free_sendmsg(t, first); smb_direct_free_sendmsg(t, first);
} }
} }
...@@ -940,7 +946,7 @@ static int smb_direct_flush_send_list(struct smb_direct_transport *t, ...@@ -940,7 +946,7 @@ static int smb_direct_flush_send_list(struct smb_direct_transport *t,
} }
static int wait_for_credits(struct smb_direct_transport *t, static int wait_for_credits(struct smb_direct_transport *t,
wait_queue_head_t *waitq, atomic_t *credits) wait_queue_head_t *waitq, atomic_t *credits)
{ {
int ret; int ret;
...@@ -950,8 +956,8 @@ static int wait_for_credits(struct smb_direct_transport *t, ...@@ -950,8 +956,8 @@ static int wait_for_credits(struct smb_direct_transport *t,
atomic_inc(credits); atomic_inc(credits);
ret = wait_event_interruptible(*waitq, ret = wait_event_interruptible(*waitq,
atomic_read(credits) > 0 || atomic_read(credits) > 0 ||
t->status != SMB_DIRECT_CS_CONNECTED); t->status != SMB_DIRECT_CS_CONNECTED);
if (t->status != SMB_DIRECT_CS_CONNECTED) if (t->status != SMB_DIRECT_CS_CONNECTED)
return -ENOTCONN; return -ENOTCONN;
...@@ -961,12 +967,12 @@ static int wait_for_credits(struct smb_direct_transport *t, ...@@ -961,12 +967,12 @@ static int wait_for_credits(struct smb_direct_transport *t,
} }
static int wait_for_send_credits(struct smb_direct_transport *t, static int wait_for_send_credits(struct smb_direct_transport *t,
struct smb_direct_send_ctx *send_ctx) struct smb_direct_send_ctx *send_ctx)
{ {
int ret; int ret;
if (send_ctx && (send_ctx->wr_cnt >= 16 || if (send_ctx &&
atomic_read(&t->send_credits) <= 1)) { (send_ctx->wr_cnt >= 16 || atomic_read(&t->send_credits) <= 1)) {
ret = smb_direct_flush_send_list(t, send_ctx, false); ret = smb_direct_flush_send_list(t, send_ctx, false);
if (ret) if (ret)
return ret; return ret;
...@@ -976,8 +982,8 @@ static int wait_for_send_credits(struct smb_direct_transport *t, ...@@ -976,8 +982,8 @@ static int wait_for_send_credits(struct smb_direct_transport *t,
} }
static int smb_direct_create_header(struct smb_direct_transport *t, static int smb_direct_create_header(struct smb_direct_transport *t,
int size, int remaining_data_length, int size, int remaining_data_length,
struct smb_direct_sendmsg **sendmsg_out) struct smb_direct_sendmsg **sendmsg_out)
{ {
struct smb_direct_sendmsg *sendmsg; struct smb_direct_sendmsg *sendmsg;
struct smb_direct_data_transfer *packet; struct smb_direct_data_transfer *packet;
...@@ -1004,12 +1010,12 @@ static int smb_direct_create_header(struct smb_direct_transport *t, ...@@ -1004,12 +1010,12 @@ static int smb_direct_create_header(struct smb_direct_transport *t,
packet->padding = 0; packet->padding = 0;
ksmbd_debug(RDMA, ksmbd_debug(RDMA,
"credits_requested=%d credits_granted=%d data_offset=%d data_length=%d remaining_data_length=%d\n", "credits_requested=%d credits_granted=%d data_offset=%d data_length=%d remaining_data_length=%d\n",
le16_to_cpu(packet->credits_requested), le16_to_cpu(packet->credits_requested),
le16_to_cpu(packet->credits_granted), le16_to_cpu(packet->credits_granted),
le32_to_cpu(packet->data_offset), le32_to_cpu(packet->data_offset),
le32_to_cpu(packet->data_length), le32_to_cpu(packet->data_length),
le32_to_cpu(packet->remaining_data_length)); le32_to_cpu(packet->remaining_data_length));
/* Map the packet to DMA */ /* Map the packet to DMA */
header_length = sizeof(struct smb_direct_data_transfer); header_length = sizeof(struct smb_direct_data_transfer);
...@@ -1069,8 +1075,8 @@ static int get_sg_list(void *buf, int size, struct scatterlist *sg_list, int nen ...@@ -1069,8 +1075,8 @@ static int get_sg_list(void *buf, int size, struct scatterlist *sg_list, int nen
} }
static int get_mapped_sg_list(struct ib_device *device, void *buf, int size, static int get_mapped_sg_list(struct ib_device *device, void *buf, int size,
struct scatterlist *sg_list, int nentries, struct scatterlist *sg_list, int nentries,
enum dma_data_direction dir) enum dma_data_direction dir)
{ {
int npages; int npages;
...@@ -1081,15 +1087,15 @@ static int get_mapped_sg_list(struct ib_device *device, void *buf, int size, ...@@ -1081,15 +1087,15 @@ static int get_mapped_sg_list(struct ib_device *device, void *buf, int size,
} }
static int post_sendmsg(struct smb_direct_transport *t, static int post_sendmsg(struct smb_direct_transport *t,
struct smb_direct_send_ctx *send_ctx, struct smb_direct_send_ctx *send_ctx,
struct smb_direct_sendmsg *msg) struct smb_direct_sendmsg *msg)
{ {
int i; int i;
for (i = 0; i < msg->num_sge; i++) for (i = 0; i < msg->num_sge; i++)
ib_dma_sync_single_for_device(t->cm_id->device, ib_dma_sync_single_for_device(t->cm_id->device,
msg->sge[i].addr, msg->sge[i].length, msg->sge[i].addr, msg->sge[i].length,
DMA_TO_DEVICE); DMA_TO_DEVICE);
msg->cqe.done = send_done; msg->cqe.done = send_done;
msg->wr.opcode = IB_WR_SEND; msg->wr.opcode = IB_WR_SEND;
...@@ -1119,8 +1125,9 @@ static int post_sendmsg(struct smb_direct_transport *t, ...@@ -1119,8 +1125,9 @@ static int post_sendmsg(struct smb_direct_transport *t,
} }
static int smb_direct_post_send_data(struct smb_direct_transport *t, static int smb_direct_post_send_data(struct smb_direct_transport *t,
struct smb_direct_send_ctx *send_ctx, struct smb_direct_send_ctx *send_ctx,
struct kvec *iov, int niov, int remaining_data_length) struct kvec *iov, int niov,
int remaining_data_length)
{ {
int i, j, ret; int i, j, ret;
struct smb_direct_sendmsg *msg; struct smb_direct_sendmsg *msg;
...@@ -1148,8 +1155,9 @@ static int smb_direct_post_send_data(struct smb_direct_transport *t, ...@@ -1148,8 +1155,9 @@ static int smb_direct_post_send_data(struct smb_direct_transport *t,
sg_init_table(sg, SMB_DIRECT_MAX_SEND_SGES - 1); sg_init_table(sg, SMB_DIRECT_MAX_SEND_SGES - 1);
sg_cnt = get_mapped_sg_list(t->cm_id->device, sg_cnt = get_mapped_sg_list(t->cm_id->device,
iov[i].iov_base, iov[i].iov_len, iov[i].iov_base, iov[i].iov_len,
sg, SMB_DIRECT_MAX_SEND_SGES - 1, DMA_TO_DEVICE); sg, SMB_DIRECT_MAX_SEND_SGES - 1,
DMA_TO_DEVICE);
if (sg_cnt <= 0) { if (sg_cnt <= 0) {
ksmbd_err("failed to map buffer\n"); ksmbd_err("failed to map buffer\n");
ret = -ENOMEM; ret = -ENOMEM;
...@@ -1182,8 +1190,8 @@ static int smb_direct_post_send_data(struct smb_direct_transport *t, ...@@ -1182,8 +1190,8 @@ static int smb_direct_post_send_data(struct smb_direct_transport *t,
} }
static int smb_direct_writev(struct ksmbd_transport *t, static int smb_direct_writev(struct ksmbd_transport *t,
struct kvec *iov, int niovs, int buflen, struct kvec *iov, int niovs, int buflen,
bool need_invalidate, unsigned int remote_key) bool need_invalidate, unsigned int remote_key)
{ {
struct smb_direct_transport *st = SMB_DIRECT_TRANS(t); struct smb_direct_transport *st = SMB_DIRECT_TRANS(t);
int remaining_data_length; int remaining_data_length;
...@@ -1217,8 +1225,8 @@ static int smb_direct_writev(struct ksmbd_transport *t, ...@@ -1217,8 +1225,8 @@ static int smb_direct_writev(struct ksmbd_transport *t,
remaining_data_length -= remaining_data_length -=
(buflen - iov[i].iov_len); (buflen - iov[i].iov_len);
ret = smb_direct_post_send_data(st, &send_ctx, ret = smb_direct_post_send_data(st, &send_ctx,
&iov[start], i - start, &iov[start], i - start,
remaining_data_length); remaining_data_length);
if (ret) if (ret)
goto done; goto done;
} else { } else {
...@@ -1232,11 +1240,10 @@ static int smb_direct_writev(struct ksmbd_transport *t, ...@@ -1232,11 +1240,10 @@ static int smb_direct_writev(struct ksmbd_transport *t,
j * max_iov_size; j * max_iov_size;
vec.iov_len = vec.iov_len =
min_t(int, max_iov_size, min_t(int, max_iov_size,
buflen - max_iov_size * j); buflen - max_iov_size * j);
remaining_data_length -= vec.iov_len; remaining_data_length -= vec.iov_len;
ret = smb_direct_post_send_data(st, ret = smb_direct_post_send_data(st, &send_ctx, &vec, 1,
&send_ctx, &vec, 1, remaining_data_length);
remaining_data_length);
if (ret) if (ret)
goto done; goto done;
} }
...@@ -1252,8 +1259,8 @@ static int smb_direct_writev(struct ksmbd_transport *t, ...@@ -1252,8 +1259,8 @@ static int smb_direct_writev(struct ksmbd_transport *t,
/* send out all remaining vecs */ /* send out all remaining vecs */
remaining_data_length -= buflen; remaining_data_length -= buflen;
ret = smb_direct_post_send_data(st, &send_ctx, ret = smb_direct_post_send_data(st, &send_ctx,
&iov[start], i - start, &iov[start], i - start,
remaining_data_length); remaining_data_length);
if (ret) if (ret)
goto done; goto done;
break; break;
...@@ -1272,20 +1279,20 @@ static int smb_direct_writev(struct ksmbd_transport *t, ...@@ -1272,20 +1279,20 @@ static int smb_direct_writev(struct ksmbd_transport *t,
*/ */
wait_event(st->wait_send_payload_pending, wait_event(st->wait_send_payload_pending,
atomic_read(&st->send_payload_pending) == 0); atomic_read(&st->send_payload_pending) == 0);
return ret; return ret;
} }
static void read_write_done(struct ib_cq *cq, struct ib_wc *wc, static void read_write_done(struct ib_cq *cq, struct ib_wc *wc,
enum dma_data_direction dir) enum dma_data_direction dir)
{ {
struct smb_direct_rdma_rw_msg *msg = container_of(wc->wr_cqe, struct smb_direct_rdma_rw_msg *msg = container_of(wc->wr_cqe,
struct smb_direct_rdma_rw_msg, cqe); struct smb_direct_rdma_rw_msg, cqe);
struct smb_direct_transport *t = msg->t; struct smb_direct_transport *t = msg->t;
if (wc->status != IB_WC_SUCCESS) { if (wc->status != IB_WC_SUCCESS) {
ksmbd_err("read/write error. opcode = %d, status = %s(%d)\n", ksmbd_err("read/write error. opcode = %d, status = %s(%d)\n",
wc->opcode, ib_wc_status_msg(wc->status), wc->status); wc->opcode, ib_wc_status_msg(wc->status), wc->status);
smb_direct_disconnect_rdma_connection(t); smb_direct_disconnect_rdma_connection(t);
} }
...@@ -1293,7 +1300,7 @@ static void read_write_done(struct ib_cq *cq, struct ib_wc *wc, ...@@ -1293,7 +1300,7 @@ static void read_write_done(struct ib_cq *cq, struct ib_wc *wc,
wake_up(&t->wait_rw_avail_ops); wake_up(&t->wait_rw_avail_ops);
rdma_rw_ctx_destroy(&msg->rw_ctx, t->qp, t->qp->port, rdma_rw_ctx_destroy(&msg->rw_ctx, t->qp, t->qp->port,
msg->sg_list, msg->sgt.nents, dir); msg->sg_list, msg->sgt.nents, dir);
sg_free_table_chained(&msg->sgt, SG_CHUNK_SIZE); sg_free_table_chained(&msg->sgt, SG_CHUNK_SIZE);
complete(msg->completion); complete(msg->completion);
kfree(msg); kfree(msg);
...@@ -1310,8 +1317,8 @@ static void write_done(struct ib_cq *cq, struct ib_wc *wc) ...@@ -1310,8 +1317,8 @@ static void write_done(struct ib_cq *cq, struct ib_wc *wc)
} }
static int smb_direct_rdma_xmit(struct smb_direct_transport *t, void *buf, static int smb_direct_rdma_xmit(struct smb_direct_transport *t, void *buf,
int buf_len, u32 remote_key, u64 remote_offset, u32 remote_len, int buf_len, u32 remote_key, u64 remote_offset,
bool is_read) u32 remote_len, bool is_read)
{ {
struct smb_direct_rdma_rw_msg *msg; struct smb_direct_rdma_rw_msg *msg;
int ret; int ret;
...@@ -1324,7 +1331,7 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, void *buf, ...@@ -1324,7 +1331,7 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, void *buf,
/* TODO: mempool */ /* TODO: mempool */
msg = kmalloc(offsetof(struct smb_direct_rdma_rw_msg, sg_list) + msg = kmalloc(offsetof(struct smb_direct_rdma_rw_msg, sg_list) +
sizeof(struct scatterlist) * SG_CHUNK_SIZE, GFP_KERNEL); sizeof(struct scatterlist) * SG_CHUNK_SIZE, GFP_KERNEL);
if (!msg) { if (!msg) {
atomic_inc(&t->rw_avail_ops); atomic_inc(&t->rw_avail_ops);
return -ENOMEM; return -ENOMEM;
...@@ -1332,8 +1339,8 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, void *buf, ...@@ -1332,8 +1339,8 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, void *buf,
msg->sgt.sgl = &msg->sg_list[0]; msg->sgt.sgl = &msg->sg_list[0];
ret = sg_alloc_table_chained(&msg->sgt, ret = sg_alloc_table_chained(&msg->sgt,
BUFFER_NR_PAGES(buf, buf_len), BUFFER_NR_PAGES(buf, buf_len),
msg->sg_list, SG_CHUNK_SIZE); msg->sg_list, SG_CHUNK_SIZE);
if (ret) { if (ret) {
atomic_inc(&t->rw_avail_ops); atomic_inc(&t->rw_avail_ops);
kfree(msg); kfree(msg);
...@@ -1347,9 +1354,9 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, void *buf, ...@@ -1347,9 +1354,9 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, void *buf,
} }
ret = rdma_rw_ctx_init(&msg->rw_ctx, t->qp, t->qp->port, ret = rdma_rw_ctx_init(&msg->rw_ctx, t->qp, t->qp->port,
msg->sg_list, BUFFER_NR_PAGES(buf, buf_len), msg->sg_list, BUFFER_NR_PAGES(buf, buf_len),
0, remote_offset, remote_key, 0, remote_offset, remote_key,
is_read ? DMA_FROM_DEVICE : DMA_TO_DEVICE); is_read ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
if (ret < 0) { if (ret < 0) {
ksmbd_err("failed to init rdma_rw_ctx: %d\n", ret); ksmbd_err("failed to init rdma_rw_ctx: %d\n", ret);
goto err; goto err;
...@@ -1359,7 +1366,7 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, void *buf, ...@@ -1359,7 +1366,7 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, void *buf,
msg->cqe.done = is_read ? read_done : write_done; msg->cqe.done = is_read ? read_done : write_done;
msg->completion = &completion; msg->completion = &completion;
first_wr = rdma_rw_ctx_wrs(&msg->rw_ctx, t->qp, t->qp->port, first_wr = rdma_rw_ctx_wrs(&msg->rw_ctx, t->qp, t->qp->port,
&msg->cqe, NULL); &msg->cqe, NULL);
ret = ib_post_send(t->qp, first_wr, NULL); ret = ib_post_send(t->qp, first_wr, NULL);
if (ret) { if (ret) {
...@@ -1374,29 +1381,29 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, void *buf, ...@@ -1374,29 +1381,29 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, void *buf,
atomic_inc(&t->rw_avail_ops); atomic_inc(&t->rw_avail_ops);
if (first_wr) if (first_wr)
rdma_rw_ctx_destroy(&msg->rw_ctx, t->qp, t->qp->port, rdma_rw_ctx_destroy(&msg->rw_ctx, t->qp, t->qp->port,
msg->sg_list, msg->sgt.nents, msg->sg_list, msg->sgt.nents,
is_read ? DMA_FROM_DEVICE : DMA_TO_DEVICE); is_read ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
sg_free_table_chained(&msg->sgt, SG_CHUNK_SIZE); sg_free_table_chained(&msg->sgt, SG_CHUNK_SIZE);
kfree(msg); kfree(msg);
return ret; return ret;
} }
static int smb_direct_rdma_write(struct ksmbd_transport *t, void *buf, static int smb_direct_rdma_write(struct ksmbd_transport *t, void *buf,
unsigned int buflen, u32 remote_key, u64 remote_offset, unsigned int buflen, u32 remote_key,
u32 remote_len) u64 remote_offset, u32 remote_len)
{ {
return smb_direct_rdma_xmit(SMB_DIRECT_TRANS(t), buf, buflen, return smb_direct_rdma_xmit(SMB_DIRECT_TRANS(t), buf, buflen,
remote_key, remote_offset, remote_key, remote_offset,
remote_len, false); remote_len, false);
} }
static int smb_direct_rdma_read(struct ksmbd_transport *t, void *buf, static int smb_direct_rdma_read(struct ksmbd_transport *t, void *buf,
unsigned int buflen, u32 remote_key, u64 remote_offset, unsigned int buflen, u32 remote_key,
u32 remote_len) u64 remote_offset, u32 remote_len)
{ {
return smb_direct_rdma_xmit(SMB_DIRECT_TRANS(t), buf, buflen, return smb_direct_rdma_xmit(SMB_DIRECT_TRANS(t), buf, buflen,
remote_key, remote_offset, remote_key, remote_offset,
remote_len, true); remote_len, true);
} }
static void smb_direct_disconnect(struct ksmbd_transport *t) static void smb_direct_disconnect(struct ksmbd_transport *t)
...@@ -1407,17 +1414,17 @@ static void smb_direct_disconnect(struct ksmbd_transport *t) ...@@ -1407,17 +1414,17 @@ static void smb_direct_disconnect(struct ksmbd_transport *t)
smb_direct_disconnect_rdma_connection(st); smb_direct_disconnect_rdma_connection(st);
wait_event_interruptible(st->wait_status, wait_event_interruptible(st->wait_status,
st->status == SMB_DIRECT_CS_DISCONNECTED); st->status == SMB_DIRECT_CS_DISCONNECTED);
free_transport(st); free_transport(st);
} }
static int smb_direct_cm_handler(struct rdma_cm_id *cm_id, static int smb_direct_cm_handler(struct rdma_cm_id *cm_id,
struct rdma_cm_event *event) struct rdma_cm_event *event)
{ {
struct smb_direct_transport *t = cm_id->context; struct smb_direct_transport *t = cm_id->context;
ksmbd_debug(RDMA, "RDMA CM event. cm_id=%p event=%s (%d)\n", ksmbd_debug(RDMA, "RDMA CM event. cm_id=%p event=%s (%d)\n",
cm_id, rdma_event_msg(event->event), event->event); cm_id, rdma_event_msg(event->event), event->event);
switch (event->event) { switch (event->event) {
case RDMA_CM_EVENT_ESTABLISHED: { case RDMA_CM_EVENT_ESTABLISHED: {
...@@ -1440,8 +1447,8 @@ static int smb_direct_cm_handler(struct rdma_cm_id *cm_id, ...@@ -1440,8 +1447,8 @@ static int smb_direct_cm_handler(struct rdma_cm_id *cm_id,
} }
default: default:
ksmbd_err("Unexpected RDMA CM event. cm_id=%p, event=%s (%d)\n", ksmbd_err("Unexpected RDMA CM event. cm_id=%p, event=%s (%d)\n",
cm_id, rdma_event_msg(event->event), cm_id, rdma_event_msg(event->event),
event->event); event->event);
break; break;
} }
return 0; return 0;
...@@ -1452,7 +1459,7 @@ static void smb_direct_qpair_handler(struct ib_event *event, void *context) ...@@ -1452,7 +1459,7 @@ static void smb_direct_qpair_handler(struct ib_event *event, void *context)
struct smb_direct_transport *t = context; struct smb_direct_transport *t = context;
ksmbd_debug(RDMA, "Received QP event. cm_id=%p, event=%s (%d)\n", ksmbd_debug(RDMA, "Received QP event. cm_id=%p, event=%s (%d)\n",
t->cm_id, ib_event_msg(event->event), event->event); t->cm_id, ib_event_msg(event->event), event->event);
switch (event->event) { switch (event->event) {
case IB_EVENT_CQ_ERR: case IB_EVENT_CQ_ERR:
...@@ -1465,7 +1472,7 @@ static void smb_direct_qpair_handler(struct ib_event *event, void *context) ...@@ -1465,7 +1472,7 @@ static void smb_direct_qpair_handler(struct ib_event *event, void *context)
} }
static int smb_direct_send_negotiate_response(struct smb_direct_transport *t, static int smb_direct_send_negotiate_response(struct smb_direct_transport *t,
int failed) int failed)
{ {
struct smb_direct_sendmsg *sendmsg; struct smb_direct_sendmsg *sendmsg;
struct smb_direct_negotiate_resp *resp; struct smb_direct_negotiate_resp *resp;
...@@ -1498,9 +1505,9 @@ static int smb_direct_send_negotiate_response(struct smb_direct_transport *t, ...@@ -1498,9 +1505,9 @@ static int smb_direct_send_negotiate_response(struct smb_direct_transport *t,
} }
sendmsg->sge[0].addr = ib_dma_map_single(t->cm_id->device, sendmsg->sge[0].addr = ib_dma_map_single(t->cm_id->device,
(void *)resp, sizeof(*resp), DMA_TO_DEVICE); (void *)resp, sizeof(*resp),
ret = ib_dma_mapping_error(t->cm_id->device, DMA_TO_DEVICE);
sendmsg->sge[0].addr); ret = ib_dma_mapping_error(t->cm_id->device, sendmsg->sge[0].addr);
if (ret) { if (ret) {
smb_direct_free_sendmsg(t, sendmsg); smb_direct_free_sendmsg(t, sendmsg);
return ret; return ret;
...@@ -1517,7 +1524,7 @@ static int smb_direct_send_negotiate_response(struct smb_direct_transport *t, ...@@ -1517,7 +1524,7 @@ static int smb_direct_send_negotiate_response(struct smb_direct_transport *t,
} }
wait_event(t->wait_send_pending, wait_event(t->wait_send_pending,
atomic_read(&t->send_pending) == 0); atomic_read(&t->send_pending) == 0);
return 0; return 0;
} }
...@@ -1529,13 +1536,13 @@ static int smb_direct_accept_client(struct smb_direct_transport *t) ...@@ -1529,13 +1536,13 @@ static int smb_direct_accept_client(struct smb_direct_transport *t)
int ret; int ret;
memset(&conn_param, 0, sizeof(conn_param)); memset(&conn_param, 0, sizeof(conn_param));
conn_param.initiator_depth = min_t(u8, conn_param.initiator_depth = min_t(u8, t->cm_id->device->attrs.max_qp_rd_atom,
t->cm_id->device->attrs.max_qp_rd_atom, SMB_DIRECT_CM_INITIATOR_DEPTH);
SMB_DIRECT_CM_INITIATOR_DEPTH);
conn_param.responder_resources = 0; conn_param.responder_resources = 0;
t->cm_id->device->ops.get_port_immutable(t->cm_id->device, t->cm_id->device->ops.get_port_immutable(t->cm_id->device,
t->cm_id->port_num, &port_immutable); t->cm_id->port_num,
&port_immutable);
if (port_immutable.core_cap_flags & RDMA_CORE_PORT_IWARP) { if (port_immutable.core_cap_flags & RDMA_CORE_PORT_IWARP) {
ird_ord_hdr[0] = conn_param.responder_resources; ird_ord_hdr[0] = conn_param.responder_resources;
ird_ord_hdr[1] = 1; ird_ord_hdr[1] = 1;
...@@ -1590,9 +1597,9 @@ static int smb_direct_negotiate(struct smb_direct_transport *t) ...@@ -1590,9 +1597,9 @@ static int smb_direct_negotiate(struct smb_direct_transport *t)
ksmbd_debug(RDMA, "Waiting for SMB_DIRECT negotiate request\n"); ksmbd_debug(RDMA, "Waiting for SMB_DIRECT negotiate request\n");
ret = wait_event_interruptible_timeout(t->wait_status, ret = wait_event_interruptible_timeout(t->wait_status,
t->negotiation_requested || t->negotiation_requested ||
t->status == SMB_DIRECT_CS_DISCONNECTED, t->status == SMB_DIRECT_CS_DISCONNECTED,
SMB_DIRECT_NEGOTIATE_TIMEOUT * HZ); SMB_DIRECT_NEGOTIATE_TIMEOUT * HZ);
if (ret <= 0 || t->status == SMB_DIRECT_CS_DISCONNECTED) { if (ret <= 0 || t->status == SMB_DIRECT_CS_DISCONNECTED) {
ret = ret < 0 ? ret : -ETIMEDOUT; ret = ret < 0 ? ret : -ETIMEDOUT;
goto out; goto out;
...@@ -1604,9 +1611,9 @@ static int smb_direct_negotiate(struct smb_direct_transport *t) ...@@ -1604,9 +1611,9 @@ static int smb_direct_negotiate(struct smb_direct_transport *t)
req = (struct smb_direct_negotiate_req *)recvmsg->packet; req = (struct smb_direct_negotiate_req *)recvmsg->packet;
t->max_recv_size = min_t(int, t->max_recv_size, t->max_recv_size = min_t(int, t->max_recv_size,
le32_to_cpu(req->preferred_send_size)); le32_to_cpu(req->preferred_send_size));
t->max_send_size = min_t(int, t->max_send_size, t->max_send_size = min_t(int, t->max_send_size,
le32_to_cpu(req->max_receive_size)); le32_to_cpu(req->max_receive_size));
t->max_fragmented_send_size = t->max_fragmented_send_size =
le32_to_cpu(req->max_fragmented_size); le32_to_cpu(req->max_fragmented_size);
...@@ -1618,7 +1625,7 @@ static int smb_direct_negotiate(struct smb_direct_transport *t) ...@@ -1618,7 +1625,7 @@ static int smb_direct_negotiate(struct smb_direct_transport *t)
} }
static int smb_direct_init_params(struct smb_direct_transport *t, static int smb_direct_init_params(struct smb_direct_transport *t,
struct ib_qp_cap *cap) struct ib_qp_cap *cap)
{ {
struct ib_device *device = t->cm_id->device; struct ib_device *device = t->cm_id->device;
int max_send_sges, max_pages, max_rw_wrs, max_send_wrs; int max_send_sges, max_pages, max_rw_wrs, max_send_wrs;
...@@ -1650,30 +1657,30 @@ static int smb_direct_init_params(struct smb_direct_transport *t, ...@@ -1650,30 +1657,30 @@ static int smb_direct_init_params(struct smb_direct_transport *t,
if (max_send_wrs > device->attrs.max_cqe || if (max_send_wrs > device->attrs.max_cqe ||
max_send_wrs > device->attrs.max_qp_wr) { max_send_wrs > device->attrs.max_qp_wr) {
ksmbd_err("consider lowering send_credit_target = %d, or max_outstanding_rw_ops = %d\n", ksmbd_err("consider lowering send_credit_target = %d, or max_outstanding_rw_ops = %d\n",
smb_direct_send_credit_target, smb_direct_send_credit_target,
smb_direct_max_outstanding_rw_ops); smb_direct_max_outstanding_rw_ops);
ksmbd_err("Possible CQE overrun, device reporting max_cqe %d max_qp_wr %d\n", ksmbd_err("Possible CQE overrun, device reporting max_cqe %d max_qp_wr %d\n",
device->attrs.max_cqe, device->attrs.max_qp_wr); device->attrs.max_cqe, device->attrs.max_qp_wr);
return -EINVAL; return -EINVAL;
} }
if (smb_direct_receive_credit_max > device->attrs.max_cqe || if (smb_direct_receive_credit_max > device->attrs.max_cqe ||
smb_direct_receive_credit_max > device->attrs.max_qp_wr) { smb_direct_receive_credit_max > device->attrs.max_qp_wr) {
ksmbd_err("consider lowering receive_credit_max = %d\n", ksmbd_err("consider lowering receive_credit_max = %d\n",
smb_direct_receive_credit_max); smb_direct_receive_credit_max);
ksmbd_err("Possible CQE overrun, device reporting max_cpe %d max_qp_wr %d\n", ksmbd_err("Possible CQE overrun, device reporting max_cpe %d max_qp_wr %d\n",
device->attrs.max_cqe, device->attrs.max_qp_wr); device->attrs.max_cqe, device->attrs.max_qp_wr);
return -EINVAL; return -EINVAL;
} }
if (device->attrs.max_send_sge < SMB_DIRECT_MAX_SEND_SGES) { if (device->attrs.max_send_sge < SMB_DIRECT_MAX_SEND_SGES) {
ksmbd_err("warning: device max_send_sge = %d too small\n", ksmbd_err("warning: device max_send_sge = %d too small\n",
device->attrs.max_send_sge); device->attrs.max_send_sge);
return -EINVAL; return -EINVAL;
} }
if (device->attrs.max_recv_sge < SMB_DIRECT_MAX_RECV_SGES) { if (device->attrs.max_recv_sge < SMB_DIRECT_MAX_RECV_SGES) {
ksmbd_err("warning: device max_recv_sge = %d too small\n", ksmbd_err("warning: device max_recv_sge = %d too small\n",
device->attrs.max_recv_sge); device->attrs.max_recv_sge);
return -EINVAL; return -EINVAL;
} }
...@@ -1731,29 +1738,29 @@ static int smb_direct_create_pools(struct smb_direct_transport *t) ...@@ -1731,29 +1738,29 @@ static int smb_direct_create_pools(struct smb_direct_transport *t)
snprintf(name, sizeof(name), "smb_direct_rqst_pool_%p", t); snprintf(name, sizeof(name), "smb_direct_rqst_pool_%p", t);
t->sendmsg_cache = kmem_cache_create(name, t->sendmsg_cache = kmem_cache_create(name,
sizeof(struct smb_direct_sendmsg) + sizeof(struct smb_direct_sendmsg) +
sizeof(struct smb_direct_negotiate_resp), sizeof(struct smb_direct_negotiate_resp),
0, SLAB_HWCACHE_ALIGN, NULL); 0, SLAB_HWCACHE_ALIGN, NULL);
if (!t->sendmsg_cache) if (!t->sendmsg_cache)
return -ENOMEM; return -ENOMEM;
t->sendmsg_mempool = mempool_create(t->send_credit_target, t->sendmsg_mempool = mempool_create(t->send_credit_target,
mempool_alloc_slab, mempool_free_slab, mempool_alloc_slab, mempool_free_slab,
t->sendmsg_cache); t->sendmsg_cache);
if (!t->sendmsg_mempool) if (!t->sendmsg_mempool)
goto err; goto err;
snprintf(name, sizeof(name), "smb_direct_resp_%p", t); snprintf(name, sizeof(name), "smb_direct_resp_%p", t);
t->recvmsg_cache = kmem_cache_create(name, t->recvmsg_cache = kmem_cache_create(name,
sizeof(struct smb_direct_recvmsg) + sizeof(struct smb_direct_recvmsg) +
t->max_recv_size, t->max_recv_size,
0, SLAB_HWCACHE_ALIGN, NULL); 0, SLAB_HWCACHE_ALIGN, NULL);
if (!t->recvmsg_cache) if (!t->recvmsg_cache)
goto err; goto err;
t->recvmsg_mempool = t->recvmsg_mempool =
mempool_create(t->recv_credit_max, mempool_alloc_slab, mempool_create(t->recv_credit_max, mempool_alloc_slab,
mempool_free_slab, t->recvmsg_cache); mempool_free_slab, t->recvmsg_cache);
if (!t->recvmsg_mempool) if (!t->recvmsg_mempool)
goto err; goto err;
...@@ -1775,7 +1782,7 @@ static int smb_direct_create_pools(struct smb_direct_transport *t) ...@@ -1775,7 +1782,7 @@ static int smb_direct_create_pools(struct smb_direct_transport *t)
} }
static int smb_direct_create_qpair(struct smb_direct_transport *t, static int smb_direct_create_qpair(struct smb_direct_transport *t,
struct ib_qp_cap *cap) struct ib_qp_cap *cap)
{ {
int ret; int ret;
struct ib_qp_init_attr qp_attr; struct ib_qp_init_attr qp_attr;
...@@ -1789,7 +1796,7 @@ static int smb_direct_create_qpair(struct smb_direct_transport *t, ...@@ -1789,7 +1796,7 @@ static int smb_direct_create_qpair(struct smb_direct_transport *t,
} }
t->send_cq = ib_alloc_cq(t->cm_id->device, t, t->send_cq = ib_alloc_cq(t->cm_id->device, t,
t->send_credit_target, 0, IB_POLL_WORKQUEUE); t->send_credit_target, 0, IB_POLL_WORKQUEUE);
if (IS_ERR(t->send_cq)) { if (IS_ERR(t->send_cq)) {
ksmbd_err("Can't create RDMA send CQ\n"); ksmbd_err("Can't create RDMA send CQ\n");
ret = PTR_ERR(t->send_cq); ret = PTR_ERR(t->send_cq);
...@@ -1798,8 +1805,8 @@ static int smb_direct_create_qpair(struct smb_direct_transport *t, ...@@ -1798,8 +1805,8 @@ static int smb_direct_create_qpair(struct smb_direct_transport *t,
} }
t->recv_cq = ib_alloc_cq(t->cm_id->device, t, t->recv_cq = ib_alloc_cq(t->cm_id->device, t,
cap->max_send_wr + cap->max_rdma_ctxs, cap->max_send_wr + cap->max_rdma_ctxs,
0, IB_POLL_WORKQUEUE); 0, IB_POLL_WORKQUEUE);
if (IS_ERR(t->recv_cq)) { if (IS_ERR(t->recv_cq)) {
ksmbd_err("Can't create RDMA recv CQ\n"); ksmbd_err("Can't create RDMA recv CQ\n");
ret = PTR_ERR(t->recv_cq); ret = PTR_ERR(t->recv_cq);
...@@ -1896,8 +1903,8 @@ static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id) ...@@ -1896,8 +1903,8 @@ static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id)
if (!rdma_frwr_is_supported(&new_cm_id->device->attrs)) { if (!rdma_frwr_is_supported(&new_cm_id->device->attrs)) {
ksmbd_debug(RDMA, ksmbd_debug(RDMA,
"Fast Registration Work Requests is not supported. device capabilities=%llx\n", "Fast Registration Work Requests is not supported. device capabilities=%llx\n",
new_cm_id->device->attrs.device_cap_flags); new_cm_id->device->attrs.device_cap_flags);
return -EPROTONOSUPPORT; return -EPROTONOSUPPORT;
} }
...@@ -1906,7 +1913,8 @@ static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id) ...@@ -1906,7 +1913,8 @@ static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id)
return -ENOMEM; return -ENOMEM;
KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop, KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop,
KSMBD_TRANS(t)->conn, "ksmbd:r%u", SMB_DIRECT_PORT); KSMBD_TRANS(t)->conn, "ksmbd:r%u",
SMB_DIRECT_PORT);
if (IS_ERR(KSMBD_TRANS(t)->handler)) { if (IS_ERR(KSMBD_TRANS(t)->handler)) {
int ret = PTR_ERR(KSMBD_TRANS(t)->handler); int ret = PTR_ERR(KSMBD_TRANS(t)->handler);
...@@ -1919,7 +1927,7 @@ static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id) ...@@ -1919,7 +1927,7 @@ static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id)
} }
static int smb_direct_listen_handler(struct rdma_cm_id *cm_id, static int smb_direct_listen_handler(struct rdma_cm_id *cm_id,
struct rdma_cm_event *event) struct rdma_cm_event *event)
{ {
switch (event->event) { switch (event->event) {
case RDMA_CM_EVENT_CONNECT_REQUEST: { case RDMA_CM_EVENT_CONNECT_REQUEST: {
...@@ -1931,13 +1939,12 @@ static int smb_direct_listen_handler(struct rdma_cm_id *cm_id, ...@@ -1931,13 +1939,12 @@ static int smb_direct_listen_handler(struct rdma_cm_id *cm_id,
} }
ksmbd_debug(RDMA, "Received connection request. cm_id=%p\n", ksmbd_debug(RDMA, "Received connection request. cm_id=%p\n",
cm_id); cm_id);
break; break;
} }
default: default:
ksmbd_err("Unexpected listen event. cm_id=%p, event=%s (%d)\n", ksmbd_err("Unexpected listen event. cm_id=%p, event=%s (%d)\n",
cm_id, cm_id, rdma_event_msg(event->event), event->event);
rdma_event_msg(event->event), event->event);
break; break;
} }
return 0; return 0;
...@@ -1954,10 +1961,9 @@ static int smb_direct_listen(int port) ...@@ -1954,10 +1961,9 @@ static int smb_direct_listen(int port)
}; };
cm_id = rdma_create_id(&init_net, smb_direct_listen_handler, cm_id = rdma_create_id(&init_net, smb_direct_listen_handler,
&smb_direct_listener, RDMA_PS_TCP, IB_QPT_RC); &smb_direct_listener, RDMA_PS_TCP, IB_QPT_RC);
if (IS_ERR(cm_id)) { if (IS_ERR(cm_id)) {
ksmbd_err("Can't create cm id: %ld\n", ksmbd_err("Can't create cm id: %ld\n", PTR_ERR(cm_id));
PTR_ERR(cm_id));
return PTR_ERR(cm_id); return PTR_ERR(cm_id);
} }
...@@ -1993,7 +1999,7 @@ int ksmbd_rdma_init(void) ...@@ -1993,7 +1999,7 @@ int ksmbd_rdma_init(void)
* for lack of credits * for lack of credits
*/ */
smb_direct_wq = alloc_workqueue("ksmbd-smb_direct-wq", smb_direct_wq = alloc_workqueue("ksmbd-smb_direct-wq",
WQ_HIGHPRI | WQ_MEM_RECLAIM, 0); WQ_HIGHPRI | WQ_MEM_RECLAIM, 0);
if (!smb_direct_wq) if (!smb_direct_wq)
return -ENOMEM; return -ENOMEM;
...@@ -2006,7 +2012,7 @@ int ksmbd_rdma_init(void) ...@@ -2006,7 +2012,7 @@ int ksmbd_rdma_init(void)
} }
ksmbd_debug(RDMA, "init RDMA listener. cm_id=%p\n", ksmbd_debug(RDMA, "init RDMA listener. cm_id=%p\n",
smb_direct_listener.cm_id); smb_direct_listener.cm_id);
return 0; return 0;
} }
......
...@@ -113,7 +113,7 @@ static void free_transport(struct tcp_transport *t) ...@@ -113,7 +113,7 @@ static void free_transport(struct tcp_transport *t)
* Return: Number of IO segments * Return: Number of IO segments
*/ */
static unsigned int kvec_array_init(struct kvec *new, struct kvec *iov, static unsigned int kvec_array_init(struct kvec *new, struct kvec *iov,
unsigned int nr_segs, size_t bytes) unsigned int nr_segs, size_t bytes)
{ {
size_t base = 0; size_t base = 0;
...@@ -197,8 +197,9 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk) ...@@ -197,8 +197,9 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk)
} }
KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop, KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop,
KSMBD_TRANS(t)->conn, KSMBD_TRANS(t)->conn,
"ksmbd:%u", ksmbd_tcp_get_port(csin)); "ksmbd:%u",
ksmbd_tcp_get_port(csin));
if (IS_ERR(KSMBD_TRANS(t)->handler)) { if (IS_ERR(KSMBD_TRANS(t)->handler)) {
ksmbd_err("cannot start conn thread\n"); ksmbd_err("cannot start conn thread\n");
rc = PTR_ERR(KSMBD_TRANS(t)->handler); rc = PTR_ERR(KSMBD_TRANS(t)->handler);
...@@ -230,7 +231,7 @@ static int ksmbd_kthread_fn(void *p) ...@@ -230,7 +231,7 @@ static int ksmbd_kthread_fn(void *p)
break; break;
} }
ret = kernel_accept(iface->ksmbd_socket, &client_sk, ret = kernel_accept(iface->ksmbd_socket, &client_sk,
O_NONBLOCK); O_NONBLOCK);
mutex_unlock(&iface->sock_release_lock); mutex_unlock(&iface->sock_release_lock);
if (ret) { if (ret) {
if (ret == -EAGAIN) if (ret == -EAGAIN)
...@@ -265,8 +266,8 @@ static int ksmbd_tcp_run_kthread(struct interface *iface) ...@@ -265,8 +266,8 @@ static int ksmbd_tcp_run_kthread(struct interface *iface)
int rc; int rc;
struct task_struct *kthread; struct task_struct *kthread;
kthread = kthread_run(ksmbd_kthread_fn, (void *)iface, kthread = kthread_run(ksmbd_kthread_fn, (void *)iface, "ksmbd-%s",
"ksmbd-%s", iface->name); iface->name);
if (IS_ERR(kthread)) { if (IS_ERR(kthread)) {
rc = PTR_ERR(kthread); rc = PTR_ERR(kthread);
return rc; return rc;
...@@ -287,7 +288,7 @@ static int ksmbd_tcp_run_kthread(struct interface *iface) ...@@ -287,7 +288,7 @@ static int ksmbd_tcp_run_kthread(struct interface *iface)
* otherwise return error number * otherwise return error number
*/ */
static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig, static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
unsigned int nr_segs, unsigned int to_read) unsigned int nr_segs, unsigned int to_read)
{ {
int length = 0; int length = 0;
int total_read; int total_read;
...@@ -353,7 +354,8 @@ static int ksmbd_tcp_read(struct ksmbd_transport *t, char *buf, unsigned int to_ ...@@ -353,7 +354,8 @@ static int ksmbd_tcp_read(struct ksmbd_transport *t, char *buf, unsigned int to_
} }
static int ksmbd_tcp_writev(struct ksmbd_transport *t, struct kvec *iov, static int ksmbd_tcp_writev(struct ksmbd_transport *t, struct kvec *iov,
int nvecs, int size, bool need_invalidate, unsigned int remote_key) int nvecs, int size, bool need_invalidate,
unsigned int remote_key)
{ {
struct msghdr smb_msg = {.msg_flags = MSG_NOSIGNAL}; struct msghdr smb_msg = {.msg_flags = MSG_NOSIGNAL};
...@@ -401,7 +403,7 @@ static int create_socket(struct interface *iface) ...@@ -401,7 +403,7 @@ static int create_socket(struct interface *iface)
if (ret) { if (ret) {
ksmbd_err("Can't create socket for ipv6, try ipv4: %d\n", ret); ksmbd_err("Can't create socket for ipv6, try ipv4: %d\n", ret);
ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP,
&ksmbd_socket); &ksmbd_socket);
if (ret) { if (ret) {
ksmbd_err("Can't create socket for ipv4: %d\n", ret); ksmbd_err("Can't create socket for ipv4: %d\n", ret);
goto out_error; goto out_error;
...@@ -432,10 +434,10 @@ static int create_socket(struct interface *iface) ...@@ -432,10 +434,10 @@ static int create_socket(struct interface *iface)
if (ipv4) if (ipv4)
ret = kernel_bind(ksmbd_socket, (struct sockaddr *)&sin, ret = kernel_bind(ksmbd_socket, (struct sockaddr *)&sin,
sizeof(sin)); sizeof(sin));
else else
ret = kernel_bind(ksmbd_socket, (struct sockaddr *)&sin6, ret = kernel_bind(ksmbd_socket, (struct sockaddr *)&sin6,
sizeof(sin6)); sizeof(sin6));
if (ret) { if (ret) {
ksmbd_err("Failed to bind socket: %d\n", ret); ksmbd_err("Failed to bind socket: %d\n", ret);
goto out_error; goto out_error;
...@@ -467,7 +469,7 @@ static int create_socket(struct interface *iface) ...@@ -467,7 +469,7 @@ static int create_socket(struct interface *iface)
} }
static int ksmbd_netdev_event(struct notifier_block *nb, unsigned long event, static int ksmbd_netdev_event(struct notifier_block *nb, unsigned long event,
void *ptr) void *ptr)
{ {
struct net_device *netdev = netdev_notifier_info_to_dev(ptr); struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
struct interface *iface; struct interface *iface;
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
* Return: string length after conversion * Return: string length after conversion
*/ */
static int smb_utf16_bytes(const __le16 *from, int maxbytes, static int smb_utf16_bytes(const __le16 *from, int maxbytes,
const struct nls_table *codepage) const struct nls_table *codepage)
{ {
int i; int i;
int charlen, outlen = 0; int charlen, outlen = 0;
...@@ -65,7 +65,7 @@ static int smb_utf16_bytes(const __le16 *from, int maxbytes, ...@@ -65,7 +65,7 @@ static int smb_utf16_bytes(const __le16 *from, int maxbytes,
*/ */
static int static int
cifs_mapchar(char *target, const __u16 src_char, const struct nls_table *cp, cifs_mapchar(char *target, const __u16 src_char, const struct nls_table *cp,
bool mapchar) bool mapchar)
{ {
int len = 1; int len = 1;
...@@ -156,7 +156,7 @@ static inline int is_char_allowed(char *ch) ...@@ -156,7 +156,7 @@ static inline int is_char_allowed(char *ch)
* Return: string length after conversion * Return: string length after conversion
*/ */
static int smb_from_utf16(char *to, const __le16 *from, int tolen, int fromlen, static int smb_from_utf16(char *to, const __le16 *from, int tolen, int fromlen,
const struct nls_table *codepage, bool mapchar) const struct nls_table *codepage, bool mapchar)
{ {
int i, charlen, safelen; int i, charlen, safelen;
int outlen = 0; int outlen = 0;
...@@ -210,7 +210,7 @@ static int smb_from_utf16(char *to, const __le16 *from, int tolen, int fromlen, ...@@ -210,7 +210,7 @@ static int smb_from_utf16(char *to, const __le16 *from, int tolen, int fromlen,
* Return: string length after conversion * Return: string length after conversion
*/ */
int smb_strtoUTF16(__le16 *to, const char *from, int len, int smb_strtoUTF16(__le16 *to, const char *from, int len,
const struct nls_table *codepage) const struct nls_table *codepage)
{ {
int charlen; int charlen;
int i; int i;
...@@ -224,7 +224,7 @@ int smb_strtoUTF16(__le16 *to, const char *from, int len, ...@@ -224,7 +224,7 @@ int smb_strtoUTF16(__le16 *to, const char *from, int len,
* in destination len is length in wchar_t units (16bits) * in destination len is length in wchar_t units (16bits)
*/ */
i = utf8s_to_utf16s(from, len, UTF16_LITTLE_ENDIAN, i = utf8s_to_utf16s(from, len, UTF16_LITTLE_ENDIAN,
(wchar_t *)to, len); (wchar_t *)to, len);
/* if success terminate and exit */ /* if success terminate and exit */
if (i >= 0) if (i >= 0)
...@@ -267,7 +267,8 @@ int smb_strtoUTF16(__le16 *to, const char *from, int len, ...@@ -267,7 +267,8 @@ int smb_strtoUTF16(__le16 *to, const char *from, int len,
* Return: destination string buffer or error ptr * Return: destination string buffer or error ptr
*/ */
char *smb_strndup_from_utf16(const char *src, const int maxlen, char *smb_strndup_from_utf16(const char *src, const int maxlen,
const bool is_unicode, const struct nls_table *codepage) const bool is_unicode,
const struct nls_table *codepage)
{ {
int len, ret; int len, ret;
char *dst; char *dst;
...@@ -279,7 +280,7 @@ char *smb_strndup_from_utf16(const char *src, const int maxlen, ...@@ -279,7 +280,7 @@ char *smb_strndup_from_utf16(const char *src, const int maxlen,
if (!dst) if (!dst)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
ret = smb_from_utf16(dst, (__le16 *)src, len, maxlen, codepage, ret = smb_from_utf16(dst, (__le16 *)src, len, maxlen, codepage,
false); false);
if (ret < 0) { if (ret < 0) {
kfree(dst); kfree(dst);
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
...@@ -318,7 +319,7 @@ char *smb_strndup_from_utf16(const char *src, const int maxlen, ...@@ -318,7 +319,7 @@ char *smb_strndup_from_utf16(const char *src, const int maxlen,
* Return: char length after conversion * Return: char length after conversion
*/ */
int smbConvertToUTF16(__le16 *target, const char *source, int srclen, int smbConvertToUTF16(__le16 *target, const char *source, int srclen,
const struct nls_table *cp, int mapchars) const struct nls_table *cp, int mapchars)
{ {
int i, j, charlen; int i, j, charlen;
char src_char; char src_char;
......
...@@ -63,11 +63,12 @@ extern const struct UniCaseRange CifsUniLowerRange[]; ...@@ -63,11 +63,12 @@ extern const struct UniCaseRange CifsUniLowerRange[];
#ifdef __KERNEL__ #ifdef __KERNEL__
int smb_strtoUTF16(__le16 *to, const char *from, int len, int smb_strtoUTF16(__le16 *to, const char *from, int len,
const struct nls_table *codepage); const struct nls_table *codepage);
char *smb_strndup_from_utf16(const char *src, const int maxlen, char *smb_strndup_from_utf16(const char *src, const int maxlen,
const bool is_unicode, const struct nls_table *codepage); const bool is_unicode,
const struct nls_table *codepage);
int smbConvertToUTF16(__le16 *target, const char *source, int srclen, int smbConvertToUTF16(__le16 *target, const char *source, int srclen,
const struct nls_table *cp, int mapchars); const struct nls_table *cp, int mapchars);
char *ksmbd_extract_sharename(char *treename); char *ksmbd_extract_sharename(char *treename);
#endif #endif
...@@ -198,7 +199,7 @@ static inline int UniStrncmp(const wchar_t *ucs1, const wchar_t *ucs2, size_t n) ...@@ -198,7 +199,7 @@ static inline int UniStrncmp(const wchar_t *ucs1, const wchar_t *ucs2, size_t n)
/* /*
* UniStrncmp_le: Compare length limited string - native to little-endian * UniStrncmp_le: Compare length limited string - native to little-endian
*/ */
static inline int static inline int
UniStrncmp_le(const wchar_t *ucs1, const wchar_t *ucs2, size_t n) UniStrncmp_le(const wchar_t *ucs1, const wchar_t *ucs2, size_t n)
{ {
if (!n) if (!n)
......
...@@ -52,7 +52,8 @@ static char *extract_last_component(char *path) ...@@ -52,7 +52,8 @@ static char *extract_last_component(char *path)
} }
static void ksmbd_vfs_inherit_owner(struct ksmbd_work *work, static void ksmbd_vfs_inherit_owner(struct ksmbd_work *work,
struct inode *parent_inode, struct inode *inode) struct inode *parent_inode,
struct inode *inode)
{ {
if (!test_share_config_flag(work->tcon->share_conf, if (!test_share_config_flag(work->tcon->share_conf,
KSMBD_SHARE_FLAG_INHERIT_OWNER)) KSMBD_SHARE_FLAG_INHERIT_OWNER))
...@@ -84,7 +85,7 @@ int ksmbd_vfs_inode_permission(struct dentry *dentry, int acc_mode, bool delete) ...@@ -84,7 +85,7 @@ int ksmbd_vfs_inode_permission(struct dentry *dentry, int acc_mode, bool delete)
parent = dget_parent(dentry); parent = dget_parent(dentry);
inode_lock_nested(d_inode(parent), I_MUTEX_PARENT); inode_lock_nested(d_inode(parent), I_MUTEX_PARENT);
child = lookup_one_len(dentry->d_name.name, parent, child = lookup_one_len(dentry->d_name.name, parent,
dentry->d_name.len); dentry->d_name.len);
if (IS_ERR(child)) { if (IS_ERR(child)) {
ret = PTR_ERR(child); ret = PTR_ERR(child);
goto out_lock; goto out_lock;
...@@ -130,7 +131,7 @@ int ksmbd_vfs_query_maximal_access(struct dentry *dentry, __le32 *daccess) ...@@ -130,7 +131,7 @@ int ksmbd_vfs_query_maximal_access(struct dentry *dentry, __le32 *daccess)
parent = dget_parent(dentry); parent = dget_parent(dentry);
inode_lock_nested(d_inode(parent), I_MUTEX_PARENT); inode_lock_nested(d_inode(parent), I_MUTEX_PARENT);
child = lookup_one_len(dentry->d_name.name, parent, child = lookup_one_len(dentry->d_name.name, parent,
dentry->d_name.len); dentry->d_name.len);
if (IS_ERR(child)) { if (IS_ERR(child)) {
ret = PTR_ERR(child); ret = PTR_ERR(child);
goto out_lock; goto out_lock;
...@@ -171,7 +172,7 @@ int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode) ...@@ -171,7 +172,7 @@ int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode)
err = PTR_ERR(dentry); err = PTR_ERR(dentry);
if (err != -ENOENT) if (err != -ENOENT)
ksmbd_err("path create failed for %s, err %d\n", ksmbd_err("path create failed for %s, err %d\n",
name, err); name, err);
return err; return err;
} }
...@@ -179,7 +180,7 @@ int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode) ...@@ -179,7 +180,7 @@ int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode)
err = vfs_create(&init_user_ns, d_inode(path.dentry), dentry, mode, true); err = vfs_create(&init_user_ns, d_inode(path.dentry), dentry, mode, true);
if (!err) { if (!err) {
ksmbd_vfs_inherit_owner(work, d_inode(path.dentry), ksmbd_vfs_inherit_owner(work, d_inode(path.dentry),
d_inode(dentry)); d_inode(dentry));
} else { } else {
ksmbd_err("File(%s): creation failed (err:%d)\n", name, err); ksmbd_err("File(%s): creation failed (err:%d)\n", name, err);
} }
...@@ -206,7 +207,7 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode) ...@@ -206,7 +207,7 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode)
err = PTR_ERR(dentry); err = PTR_ERR(dentry);
if (err != -EEXIST) if (err != -EEXIST)
ksmbd_debug(VFS, "path create failed for %s, err %d\n", ksmbd_debug(VFS, "path create failed for %s, err %d\n",
name, err); name, err);
return err; return err;
} }
...@@ -217,9 +218,8 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode) ...@@ -217,9 +218,8 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode)
} else if (d_unhashed(dentry)) { } else if (d_unhashed(dentry)) {
struct dentry *d; struct dentry *d;
d = lookup_one_len(dentry->d_name.name, d = lookup_one_len(dentry->d_name.name, dentry->d_parent,
dentry->d_parent, dentry->d_name.len);
dentry->d_name.len);
if (IS_ERR(d)) { if (IS_ERR(d)) {
err = PTR_ERR(d); err = PTR_ERR(d);
goto out; goto out;
...@@ -230,8 +230,7 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode) ...@@ -230,8 +230,7 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode)
goto out; goto out;
} }
ksmbd_vfs_inherit_owner(work, d_inode(path.dentry), ksmbd_vfs_inherit_owner(work, d_inode(path.dentry), d_inode(d));
d_inode(d));
dput(d); dput(d);
} }
out: out:
...@@ -242,7 +241,7 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode) ...@@ -242,7 +241,7 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode)
} }
static ssize_t ksmbd_vfs_getcasexattr(struct dentry *dentry, char *attr_name, static ssize_t ksmbd_vfs_getcasexattr(struct dentry *dentry, char *attr_name,
int attr_name_len, char **attr_value) int attr_name_len, char **attr_value)
{ {
char *name, *xattr_list = NULL; char *name, *xattr_list = NULL;
ssize_t value_len = -ENOENT, xattr_list_len; ssize_t value_len = -ENOENT, xattr_list_len;
...@@ -271,14 +270,14 @@ static ssize_t ksmbd_vfs_getcasexattr(struct dentry *dentry, char *attr_name, ...@@ -271,14 +270,14 @@ static ssize_t ksmbd_vfs_getcasexattr(struct dentry *dentry, char *attr_name,
} }
static int ksmbd_vfs_stream_read(struct ksmbd_file *fp, char *buf, loff_t *pos, static int ksmbd_vfs_stream_read(struct ksmbd_file *fp, char *buf, loff_t *pos,
size_t count) size_t count)
{ {
ssize_t v_len; ssize_t v_len;
char *stream_buf = NULL; char *stream_buf = NULL;
int err; int err;
ksmbd_debug(VFS, "read stream data pos : %llu, count : %zd\n", ksmbd_debug(VFS, "read stream data pos : %llu, count : %zd\n",
*pos, count); *pos, count);
v_len = ksmbd_vfs_getcasexattr(fp->filp->f_path.dentry, v_len = ksmbd_vfs_getcasexattr(fp->filp->f_path.dentry,
fp->stream.name, fp->stream.name,
...@@ -304,7 +303,7 @@ static int ksmbd_vfs_stream_read(struct ksmbd_file *fp, char *buf, loff_t *pos, ...@@ -304,7 +303,7 @@ static int ksmbd_vfs_stream_read(struct ksmbd_file *fp, char *buf, loff_t *pos,
* Return: 0 on success, otherwise error * Return: 0 on success, otherwise error
*/ */
static int check_lock_range(struct file *filp, loff_t start, loff_t end, static int check_lock_range(struct file *filp, loff_t start, loff_t end,
unsigned char type) unsigned char type)
{ {
struct file_lock *flock; struct file_lock *flock;
struct file_lock_context *ctx = file_inode(filp)->i_flctx; struct file_lock_context *ctx = file_inode(filp)->i_flctx;
...@@ -348,7 +347,7 @@ static int check_lock_range(struct file *filp, loff_t start, loff_t end, ...@@ -348,7 +347,7 @@ static int check_lock_range(struct file *filp, loff_t start, loff_t end,
* Return: number of read bytes on success, otherwise error * Return: number of read bytes on success, otherwise error
*/ */
int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count, int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count,
loff_t *pos) loff_t *pos)
{ {
struct file *filp; struct file *filp;
ssize_t nbytes = 0; ssize_t nbytes = 0;
...@@ -377,8 +376,7 @@ int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count, ...@@ -377,8 +376,7 @@ int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count,
if (!work->tcon->posix_extensions) { if (!work->tcon->posix_extensions) {
int ret; int ret;
ret = check_lock_range(filp, *pos, *pos + count - 1, ret = check_lock_range(filp, *pos, *pos + count - 1, READ);
READ);
if (ret) { if (ret) {
ksmbd_err("unable to read due to lock\n"); ksmbd_err("unable to read due to lock\n");
return -EAGAIN; return -EAGAIN;
...@@ -388,7 +386,7 @@ int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count, ...@@ -388,7 +386,7 @@ int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count,
nbytes = kernel_read(filp, rbuf, count, pos); nbytes = kernel_read(filp, rbuf, count, pos);
if (nbytes < 0) { if (nbytes < 0) {
ksmbd_err("smb read failed for (%s), err = %zd\n", ksmbd_err("smb read failed for (%s), err = %zd\n",
fp->filename, nbytes); fp->filename, nbytes);
return nbytes; return nbytes;
} }
...@@ -397,14 +395,14 @@ int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count, ...@@ -397,14 +395,14 @@ int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count,
} }
static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos, static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
size_t count) size_t count)
{ {
char *stream_buf = NULL, *wbuf; char *stream_buf = NULL, *wbuf;
size_t size, v_len; size_t size, v_len;
int err = 0; int err = 0;
ksmbd_debug(VFS, "write stream data pos : %llu, count : %zd\n", ksmbd_debug(VFS, "write stream data pos : %llu, count : %zd\n",
*pos, count); *pos, count);
size = *pos + count; size = *pos + count;
if (size > XATTR_SIZE_MAX) { if (size > XATTR_SIZE_MAX) {
...@@ -464,8 +462,8 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos, ...@@ -464,8 +462,8 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
* Return: 0 on success, otherwise error * Return: 0 on success, otherwise error
*/ */
int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp, int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp,
char *buf, size_t count, loff_t *pos, bool sync, char *buf, size_t count, loff_t *pos, bool sync,
ssize_t *written) ssize_t *written)
{ {
struct ksmbd_session *sess = work->sess; struct ksmbd_session *sess = work->sess;
struct file *filp; struct file *filp;
...@@ -514,7 +512,7 @@ int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -514,7 +512,7 @@ int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp,
err = vfs_fsync_range(filp, offset, offset + *written, 0); err = vfs_fsync_range(filp, offset, offset + *written, 0);
if (err < 0) if (err < 0)
ksmbd_err("fsync failed for filename = %s, err = %d\n", ksmbd_err("fsync failed for filename = %s, err = %d\n",
FP_FILENAME(fp), err); FP_FILENAME(fp), err);
} }
out: out:
...@@ -588,11 +586,11 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name) ...@@ -588,11 +586,11 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name)
parent = dget_parent(path.dentry); parent = dget_parent(path.dentry);
inode_lock_nested(d_inode(parent), I_MUTEX_PARENT); inode_lock_nested(d_inode(parent), I_MUTEX_PARENT);
dentry = lookup_one_len(path.dentry->d_name.name, parent, dentry = lookup_one_len(path.dentry->d_name.name, parent,
strlen(path.dentry->d_name.name)); strlen(path.dentry->d_name.name));
if (IS_ERR(dentry)) { if (IS_ERR(dentry)) {
err = PTR_ERR(dentry); err = PTR_ERR(dentry);
ksmbd_debug(VFS, "%s: lookup failed, err %d\n", ksmbd_debug(VFS, "%s: lookup failed, err %d\n",
path.dentry->d_name.name, err); path.dentry->d_name.name, err);
goto out_err; goto out_err;
} }
...@@ -606,12 +604,12 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name) ...@@ -606,12 +604,12 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name)
err = vfs_rmdir(&init_user_ns, d_inode(parent), dentry); err = vfs_rmdir(&init_user_ns, d_inode(parent), dentry);
if (err && err != -ENOTEMPTY) if (err && err != -ENOTEMPTY)
ksmbd_debug(VFS, "%s: rmdir failed, err %d\n", name, ksmbd_debug(VFS, "%s: rmdir failed, err %d\n", name,
err); err);
} else { } else {
err = vfs_unlink(&init_user_ns, d_inode(parent), dentry, NULL); err = vfs_unlink(&init_user_ns, d_inode(parent), dentry, NULL);
if (err) if (err)
ksmbd_debug(VFS, "%s: unlink failed, err %d\n", name, ksmbd_debug(VFS, "%s: unlink failed, err %d\n", name,
err); err);
} }
dput(dentry); dput(dentry);
...@@ -631,7 +629,7 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name) ...@@ -631,7 +629,7 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name)
* Return: 0 on success, otherwise error * Return: 0 on success, otherwise error
*/ */
int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname, int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname,
const char *newname) const char *newname)
{ {
struct path oldpath, newpath; struct path oldpath, newpath;
struct dentry *dentry; struct dentry *dentry;
...@@ -643,12 +641,12 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname, ...@@ -643,12 +641,12 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname,
err = kern_path(oldname, LOOKUP_FOLLOW, &oldpath); err = kern_path(oldname, LOOKUP_FOLLOW, &oldpath);
if (err) { if (err) {
ksmbd_err("cannot get linux path for %s, err = %d\n", ksmbd_err("cannot get linux path for %s, err = %d\n",
oldname, err); oldname, err);
goto out1; goto out1;
} }
dentry = kern_path_create(AT_FDCWD, newname, &newpath, dentry = kern_path_create(AT_FDCWD, newname, &newpath,
LOOKUP_FOLLOW | LOOKUP_REVAL); LOOKUP_FOLLOW | LOOKUP_REVAL);
if (IS_ERR(dentry)) { if (IS_ERR(dentry)) {
err = PTR_ERR(dentry); err = PTR_ERR(dentry);
ksmbd_err("path create err for %s, err %d\n", newname, err); ksmbd_err("path create err for %s, err %d\n", newname, err);
...@@ -662,7 +660,7 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname, ...@@ -662,7 +660,7 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname,
} }
err = vfs_link(oldpath.dentry, &init_user_ns, d_inode(newpath.dentry), err = vfs_link(oldpath.dentry, &init_user_ns, d_inode(newpath.dentry),
dentry, NULL); dentry, NULL);
if (err) if (err)
ksmbd_debug(VFS, "vfs_link failed err %d\n", err); ksmbd_debug(VFS, "vfs_link failed err %d\n", err);
...@@ -676,9 +674,11 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname, ...@@ -676,9 +674,11 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname,
} }
static int __ksmbd_vfs_rename(struct ksmbd_work *work, static int __ksmbd_vfs_rename(struct ksmbd_work *work,
struct dentry *src_dent_parent, struct dentry *src_dent, struct dentry *src_dent_parent,
struct dentry *dst_dent_parent, struct dentry *trap_dent, struct dentry *src_dent,
char *dst_name) struct dentry *dst_dent_parent,
struct dentry *trap_dent,
char *dst_name)
{ {
struct dentry *dst_dent; struct dentry *dst_dent;
int err; int err;
...@@ -742,7 +742,7 @@ static int __ksmbd_vfs_rename(struct ksmbd_work *work, ...@@ -742,7 +742,7 @@ static int __ksmbd_vfs_rename(struct ksmbd_work *work,
} }
int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp, int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
char *newname) char *newname)
{ {
struct path dst_path; struct path dst_path;
struct dentry *src_dent_parent, *dst_dent_parent; struct dentry *src_dent_parent, *dst_dent_parent;
...@@ -768,7 +768,7 @@ int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -768,7 +768,7 @@ int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
dget(src_dent); dget(src_dent);
dget(dst_dent_parent); dget(dst_dent_parent);
src_child = lookup_one_len(src_dent->d_name.name, src_dent_parent, src_child = lookup_one_len(src_dent->d_name.name, src_dent_parent,
src_dent->d_name.len); src_dent->d_name.len);
if (IS_ERR(src_child)) { if (IS_ERR(src_child)) {
err = PTR_ERR(src_child); err = PTR_ERR(src_child);
goto out_lock; goto out_lock;
...@@ -807,7 +807,7 @@ int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -807,7 +807,7 @@ int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
* Return: 0 on success, otherwise error * Return: 0 on success, otherwise error
*/ */
int ksmbd_vfs_truncate(struct ksmbd_work *work, const char *name, int ksmbd_vfs_truncate(struct ksmbd_work *work, const char *name,
struct ksmbd_file *fp, loff_t size) struct ksmbd_file *fp, loff_t size)
{ {
struct path path; struct path path;
int err = 0; int err = 0;
...@@ -816,13 +816,13 @@ int ksmbd_vfs_truncate(struct ksmbd_work *work, const char *name, ...@@ -816,13 +816,13 @@ int ksmbd_vfs_truncate(struct ksmbd_work *work, const char *name,
err = kern_path(name, 0, &path); err = kern_path(name, 0, &path);
if (err) { if (err) {
ksmbd_err("cannot get linux path for %s, err %d\n", ksmbd_err("cannot get linux path for %s, err %d\n",
name, err); name, err);
return err; return err;
} }
err = vfs_truncate(&path, size); err = vfs_truncate(&path, size);
if (err) if (err)
ksmbd_err("truncate failed for %s err %d\n", ksmbd_err("truncate failed for %s err %d\n",
name, err); name, err);
path_put(&path); path_put(&path);
} else { } else {
struct file *filp; struct file *filp;
...@@ -837,10 +837,10 @@ int ksmbd_vfs_truncate(struct ksmbd_work *work, const char *name, ...@@ -837,10 +837,10 @@ int ksmbd_vfs_truncate(struct ksmbd_work *work, const char *name,
if (size < inode->i_size) { if (size < inode->i_size) {
err = check_lock_range(filp, size, err = check_lock_range(filp, size,
inode->i_size - 1, WRITE); inode->i_size - 1, WRITE);
} else { } else {
err = check_lock_range(filp, inode->i_size, err = check_lock_range(filp, inode->i_size,
size - 1, WRITE); size - 1, WRITE);
} }
if (err) { if (err) {
...@@ -852,7 +852,7 @@ int ksmbd_vfs_truncate(struct ksmbd_work *work, const char *name, ...@@ -852,7 +852,7 @@ int ksmbd_vfs_truncate(struct ksmbd_work *work, const char *name,
err = vfs_truncate(&filp->f_path, size); err = vfs_truncate(&filp->f_path, size);
if (err) if (err)
ksmbd_err("truncate failed for filename : %s err %d\n", ksmbd_err("truncate failed for filename : %s err %d\n",
fp->filename, err); fp->filename, err);
} }
return err; return err;
...@@ -904,7 +904,7 @@ static ssize_t ksmbd_vfs_xattr_len(struct dentry *dentry, char *xattr_name) ...@@ -904,7 +904,7 @@ static ssize_t ksmbd_vfs_xattr_len(struct dentry *dentry, char *xattr_name)
* Return: read xattr value length on success, otherwise error * Return: read xattr value length on success, otherwise error
*/ */
ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name, ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name,
char **xattr_buf) char **xattr_buf)
{ {
ssize_t xattr_len; ssize_t xattr_len;
char *buf; char *buf;
...@@ -938,7 +938,7 @@ ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name, ...@@ -938,7 +938,7 @@ ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name,
* Return: 0 on success, otherwise error * Return: 0 on success, otherwise error
*/ */
int ksmbd_vfs_setxattr(struct dentry *dentry, const char *attr_name, int ksmbd_vfs_setxattr(struct dentry *dentry, const char *attr_name,
const void *attr_value, size_t attr_size, int flags) const void *attr_value, size_t attr_size, int flags)
{ {
int err; int err;
...@@ -988,8 +988,7 @@ void ksmbd_vfs_set_fadvise(struct file *filp, __le32 option) ...@@ -988,8 +988,7 @@ void ksmbd_vfs_set_fadvise(struct file *filp, __le32 option)
* *
* Return: 0 on success, otherwise error * Return: 0 on success, otherwise error
*/ */
int ksmbd_vfs_lock(struct file *filp, int cmd, int ksmbd_vfs_lock(struct file *filp, int cmd, struct file_lock *flock)
struct file_lock *flock)
{ {
ksmbd_debug(VFS, "calling vfs_lock_file\n"); ksmbd_debug(VFS, "calling vfs_lock_file\n");
return vfs_lock_file(filp, cmd, flock, NULL); return vfs_lock_file(filp, cmd, flock, NULL);
...@@ -1001,26 +1000,27 @@ int ksmbd_vfs_readdir(struct file *file, struct ksmbd_readdir_data *rdata) ...@@ -1001,26 +1000,27 @@ int ksmbd_vfs_readdir(struct file *file, struct ksmbd_readdir_data *rdata)
} }
int ksmbd_vfs_alloc_size(struct ksmbd_work *work, struct ksmbd_file *fp, int ksmbd_vfs_alloc_size(struct ksmbd_work *work, struct ksmbd_file *fp,
loff_t len) loff_t len)
{ {
smb_break_all_levII_oplock(work, fp, 1); smb_break_all_levII_oplock(work, fp, 1);
return vfs_fallocate(fp->filp, FALLOC_FL_KEEP_SIZE, 0, len); return vfs_fallocate(fp->filp, FALLOC_FL_KEEP_SIZE, 0, len);
} }
int ksmbd_vfs_zero_data(struct ksmbd_work *work, struct ksmbd_file *fp, int ksmbd_vfs_zero_data(struct ksmbd_work *work, struct ksmbd_file *fp,
loff_t off, loff_t len) loff_t off, loff_t len)
{ {
smb_break_all_levII_oplock(work, fp, 1); smb_break_all_levII_oplock(work, fp, 1);
if (fp->f_ci->m_fattr & ATTR_SPARSE_FILE_LE) if (fp->f_ci->m_fattr & ATTR_SPARSE_FILE_LE)
return vfs_fallocate(fp->filp, return vfs_fallocate(fp->filp,
FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, off, len); FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
off, len);
return vfs_fallocate(fp->filp, FALLOC_FL_ZERO_RANGE, off, len); return vfs_fallocate(fp->filp, FALLOC_FL_ZERO_RANGE, off, len);
} }
int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length, int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length,
struct file_allocated_range_buffer *ranges, struct file_allocated_range_buffer *ranges,
int in_count, int *out_count) int in_count, int *out_count)
{ {
struct file *f = fp->filp; struct file *f = fp->filp;
struct inode *inode = FP_INODE(fp); struct inode *inode = FP_INODE(fp);
...@@ -1087,8 +1087,7 @@ int ksmbd_vfs_unlink(struct dentry *dir, struct dentry *dentry) ...@@ -1087,8 +1087,7 @@ int ksmbd_vfs_unlink(struct dentry *dir, struct dentry *dentry)
inode_lock_nested(d_inode(dir), I_MUTEX_PARENT); inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
dget(dentry); dget(dentry);
child = lookup_one_len(dentry->d_name.name, dir, child = lookup_one_len(dentry->d_name.name, dir, dentry->d_name.len);
dentry->d_name.len);
if (IS_ERR(child)) { if (IS_ERR(child)) {
err = PTR_ERR(child); err = PTR_ERR(child);
goto out; goto out;
...@@ -1143,7 +1142,7 @@ unsigned short ksmbd_vfs_logical_sector_size(struct inode *inode) ...@@ -1143,7 +1142,7 @@ unsigned short ksmbd_vfs_logical_sector_size(struct inode *inode)
* @fs_ss: fs sector size struct * @fs_ss: fs sector size struct
*/ */
void ksmbd_vfs_smb2_sector_size(struct inode *inode, void ksmbd_vfs_smb2_sector_size(struct inode *inode,
struct ksmbd_fs_sector_size *fs_ss) struct ksmbd_fs_sector_size *fs_ss)
{ {
struct request_queue *q; struct request_queue *q;
...@@ -1169,7 +1168,7 @@ void ksmbd_vfs_smb2_sector_size(struct inode *inode, ...@@ -1169,7 +1168,7 @@ void ksmbd_vfs_smb2_sector_size(struct inode *inode,
} }
static int __dir_empty(struct dir_context *ctx, const char *name, int namlen, static int __dir_empty(struct dir_context *ctx, const char *name, int namlen,
loff_t offset, u64 ino, unsigned int d_type) loff_t offset, u64 ino, unsigned int d_type)
{ {
struct ksmbd_readdir_data *buf; struct ksmbd_readdir_data *buf;
...@@ -1206,7 +1205,8 @@ int ksmbd_vfs_empty_dir(struct ksmbd_file *fp) ...@@ -1206,7 +1205,8 @@ int ksmbd_vfs_empty_dir(struct ksmbd_file *fp)
} }
static int __caseless_lookup(struct dir_context *ctx, const char *name, static int __caseless_lookup(struct dir_context *ctx, const char *name,
int namlen, loff_t offset, u64 ino, unsigned int d_type) int namlen, loff_t offset, u64 ino,
unsigned int d_type)
{ {
struct ksmbd_readdir_data *buf; struct ksmbd_readdir_data *buf;
...@@ -1263,7 +1263,7 @@ static int ksmbd_vfs_lookup_in_dir(struct path *dir, char *name, size_t namelen) ...@@ -1263,7 +1263,7 @@ static int ksmbd_vfs_lookup_in_dir(struct path *dir, char *name, size_t namelen)
* Return: 0 on success, otherwise error * Return: 0 on success, otherwise error
*/ */
int ksmbd_vfs_kern_path(char *name, unsigned int flags, struct path *path, int ksmbd_vfs_kern_path(char *name, unsigned int flags, struct path *path,
bool caseless) bool caseless)
{ {
int err; int err;
...@@ -1346,7 +1346,7 @@ int ksmbd_vfs_remove_acl_xattrs(struct dentry *dentry) ...@@ -1346,7 +1346,7 @@ int ksmbd_vfs_remove_acl_xattrs(struct dentry *dentry)
} }
for (name = xattr_list; name - xattr_list < xattr_list_len; for (name = xattr_list; name - xattr_list < xattr_list_len;
name += strlen(name) + 1) { name += strlen(name) + 1) {
ksmbd_debug(SMB, "%s, len %zd\n", name, strlen(name)); ksmbd_debug(SMB, "%s, len %zd\n", name, strlen(name));
if (!strncmp(name, XATTR_NAME_POSIX_ACL_ACCESS, if (!strncmp(name, XATTR_NAME_POSIX_ACL_ACCESS,
...@@ -1356,7 +1356,7 @@ int ksmbd_vfs_remove_acl_xattrs(struct dentry *dentry) ...@@ -1356,7 +1356,7 @@ int ksmbd_vfs_remove_acl_xattrs(struct dentry *dentry)
err = ksmbd_vfs_remove_xattr(dentry, name); err = ksmbd_vfs_remove_xattr(dentry, name);
if (err) if (err)
ksmbd_debug(SMB, ksmbd_debug(SMB,
"remove acl xattr failed : %s\n", name); "remove acl xattr failed : %s\n", name);
} }
} }
out: out:
...@@ -1394,7 +1394,7 @@ int ksmbd_vfs_remove_sd_xattrs(struct dentry *dentry) ...@@ -1394,7 +1394,7 @@ int ksmbd_vfs_remove_sd_xattrs(struct dentry *dentry)
} }
static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct inode *inode, static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct inode *inode,
int acl_type) int acl_type)
{ {
struct xattr_smb_acl *smb_acl = NULL; struct xattr_smb_acl *smb_acl = NULL;
struct posix_acl *posix_acls; struct posix_acl *posix_acls;
...@@ -1455,7 +1455,7 @@ static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct inode *inode, ...@@ -1455,7 +1455,7 @@ static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct inode *inode,
} }
int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
struct smb_ntsd *pntsd, int len) struct smb_ntsd *pntsd, int len)
{ {
int rc; int rc;
struct ndr sd_ndr = {0}, acl_ndr = {0}; struct ndr sd_ndr = {0}, acl_ndr = {0};
...@@ -1489,7 +1489,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, ...@@ -1489,7 +1489,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
smb_acl = ksmbd_vfs_make_xattr_posix_acl(inode, ACL_TYPE_ACCESS); smb_acl = ksmbd_vfs_make_xattr_posix_acl(inode, ACL_TYPE_ACCESS);
if (S_ISDIR(inode->i_mode)) if (S_ISDIR(inode->i_mode))
def_smb_acl = ksmbd_vfs_make_xattr_posix_acl(inode, def_smb_acl = ksmbd_vfs_make_xattr_posix_acl(inode,
ACL_TYPE_DEFAULT); ACL_TYPE_DEFAULT);
rc = ndr_encode_posix_acl(&acl_ndr, inode, smb_acl, def_smb_acl); rc = ndr_encode_posix_acl(&acl_ndr, inode, smb_acl, def_smb_acl);
if (rc) { if (rc) {
...@@ -1498,7 +1498,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, ...@@ -1498,7 +1498,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
} }
rc = ksmbd_gen_sd_hash(conn, acl_ndr.data, acl_ndr.offset, rc = ksmbd_gen_sd_hash(conn, acl_ndr.data, acl_ndr.offset,
acl.posix_acl_hash); acl.posix_acl_hash);
if (rc) { if (rc) {
ksmbd_err("failed to generate hash for ndr acl\n"); ksmbd_err("failed to generate hash for ndr acl\n");
goto out; goto out;
...@@ -1511,7 +1511,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, ...@@ -1511,7 +1511,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
} }
rc = ksmbd_vfs_setxattr(dentry, XATTR_NAME_SD, sd_ndr.data, rc = ksmbd_vfs_setxattr(dentry, XATTR_NAME_SD, sd_ndr.data,
sd_ndr.offset, 0); sd_ndr.offset, 0);
if (rc < 0) if (rc < 0)
ksmbd_err("Failed to store XATTR ntacl :%d\n", rc); ksmbd_err("Failed to store XATTR ntacl :%d\n", rc);
...@@ -1524,7 +1524,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, ...@@ -1524,7 +1524,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
} }
int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
struct smb_ntsd **pntsd) struct smb_ntsd **pntsd)
{ {
int rc; int rc;
struct ndr n; struct ndr n;
...@@ -1543,10 +1543,10 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, ...@@ -1543,10 +1543,10 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
return rc; return rc;
smb_acl = ksmbd_vfs_make_xattr_posix_acl(inode, smb_acl = ksmbd_vfs_make_xattr_posix_acl(inode,
ACL_TYPE_ACCESS); ACL_TYPE_ACCESS);
if (S_ISDIR(inode->i_mode)) if (S_ISDIR(inode->i_mode))
def_smb_acl = ksmbd_vfs_make_xattr_posix_acl(inode, def_smb_acl = ksmbd_vfs_make_xattr_posix_acl(inode,
ACL_TYPE_DEFAULT); ACL_TYPE_DEFAULT);
rc = ndr_encode_posix_acl(&acl_ndr, inode, smb_acl, def_smb_acl); rc = ndr_encode_posix_acl(&acl_ndr, inode, smb_acl, def_smb_acl);
if (rc) { if (rc) {
...@@ -1555,7 +1555,7 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, ...@@ -1555,7 +1555,7 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
} }
rc = ksmbd_gen_sd_hash(conn, acl_ndr.data, acl_ndr.offset, rc = ksmbd_gen_sd_hash(conn, acl_ndr.data, acl_ndr.offset,
cmp_hash); cmp_hash);
if (rc) { if (rc) {
ksmbd_err("failed to generate hash for ndr acl\n"); ksmbd_err("failed to generate hash for ndr acl\n");
goto out; goto out;
...@@ -1587,7 +1587,7 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, ...@@ -1587,7 +1587,7 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
} }
int ksmbd_vfs_set_dos_attrib_xattr(struct dentry *dentry, int ksmbd_vfs_set_dos_attrib_xattr(struct dentry *dentry,
struct xattr_dos_attrib *da) struct xattr_dos_attrib *da)
{ {
struct ndr n; struct ndr n;
int err; int err;
...@@ -1596,11 +1596,8 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct dentry *dentry, ...@@ -1596,11 +1596,8 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct dentry *dentry,
if (err) if (err)
return err; return err;
err = ksmbd_vfs_setxattr(dentry, err = ksmbd_vfs_setxattr(dentry, XATTR_NAME_DOS_ATTRIBUTE,
XATTR_NAME_DOS_ATTRIBUTE, (void *)n.data, n.offset, 0);
(void *)n.data,
n.offset,
0);
if (err) if (err)
ksmbd_debug(SMB, "failed to store dos attribute in xattr\n"); ksmbd_debug(SMB, "failed to store dos attribute in xattr\n");
kfree(n.data); kfree(n.data);
...@@ -1609,14 +1606,13 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct dentry *dentry, ...@@ -1609,14 +1606,13 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct dentry *dentry,
} }
int ksmbd_vfs_get_dos_attrib_xattr(struct dentry *dentry, int ksmbd_vfs_get_dos_attrib_xattr(struct dentry *dentry,
struct xattr_dos_attrib *da) struct xattr_dos_attrib *da)
{ {
struct ndr n; struct ndr n;
int err; int err;
err = ksmbd_vfs_getxattr(dentry, err = ksmbd_vfs_getxattr(dentry, XATTR_NAME_DOS_ATTRIBUTE,
XATTR_NAME_DOS_ATTRIBUTE, (char **)&n.data);
(char **)&n.data);
if (err > 0) { if (err > 0) {
n.length = err; n.length = err;
if (ndr_decode_dos_attr(&n, da)) if (ndr_decode_dos_attr(&n, da))
...@@ -1648,7 +1644,7 @@ struct posix_acl *ksmbd_vfs_get_acl(struct inode *inode, int type) ...@@ -1648,7 +1644,7 @@ struct posix_acl *ksmbd_vfs_get_acl(struct inode *inode, int type)
} }
int ksmbd_vfs_set_posix_acl(struct inode *inode, int type, int ksmbd_vfs_set_posix_acl(struct inode *inode, int type,
struct posix_acl *acl) struct posix_acl *acl)
{ {
#if IS_ENABLED(CONFIG_FS_POSIX_ACL) #if IS_ENABLED(CONFIG_FS_POSIX_ACL)
return set_posix_acl(&init_user_ns, inode, type, acl); return set_posix_acl(&init_user_ns, inode, type, acl);
...@@ -1690,7 +1686,7 @@ void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat) ...@@ -1690,7 +1686,7 @@ void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat)
} }
int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, struct dentry *dentry, int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, struct dentry *dentry,
struct ksmbd_kstat *ksmbd_kstat) struct ksmbd_kstat *ksmbd_kstat)
{ {
u64 time; u64 time;
int rc; int rc;
...@@ -1726,7 +1722,7 @@ int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, struct dentry *dentry, ...@@ -1726,7 +1722,7 @@ int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, struct dentry *dentry,
} }
ssize_t ksmbd_vfs_casexattr_len(struct dentry *dentry, char *attr_name, ssize_t ksmbd_vfs_casexattr_len(struct dentry *dentry, char *attr_name,
int attr_name_len) int attr_name_len)
{ {
char *name, *xattr_list = NULL; char *name, *xattr_list = NULL;
ssize_t value_len = -ENOENT, xattr_list_len; ssize_t value_len = -ENOENT, xattr_list_len;
...@@ -1751,7 +1747,7 @@ ssize_t ksmbd_vfs_casexattr_len(struct dentry *dentry, char *attr_name, ...@@ -1751,7 +1747,7 @@ ssize_t ksmbd_vfs_casexattr_len(struct dentry *dentry, char *attr_name,
} }
int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name, int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name,
size_t *xattr_stream_name_size, int s_type) size_t *xattr_stream_name_size, int s_type)
{ {
int stream_name_size; int stream_name_size;
char *xattr_stream_name_buf; char *xattr_stream_name_buf;
...@@ -1767,18 +1763,15 @@ int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name, ...@@ -1767,18 +1763,15 @@ int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name,
stream_name_size = strlen(stream_name); stream_name_size = strlen(stream_name);
*xattr_stream_name_size = stream_name_size + XATTR_NAME_STREAM_LEN + 1; *xattr_stream_name_size = stream_name_size + XATTR_NAME_STREAM_LEN + 1;
xattr_stream_name_buf = kmalloc(*xattr_stream_name_size + type_len, xattr_stream_name_buf = kmalloc(*xattr_stream_name_size + type_len,
GFP_KERNEL); GFP_KERNEL);
if (!xattr_stream_name_buf) if (!xattr_stream_name_buf)
return -ENOMEM; return -ENOMEM;
memcpy(xattr_stream_name_buf, memcpy(xattr_stream_name_buf, XATTR_NAME_STREAM, XATTR_NAME_STREAM_LEN);
XATTR_NAME_STREAM,
XATTR_NAME_STREAM_LEN);
if (stream_name_size) { if (stream_name_size) {
memcpy(&xattr_stream_name_buf[XATTR_NAME_STREAM_LEN], memcpy(&xattr_stream_name_buf[XATTR_NAME_STREAM_LEN],
stream_name, stream_name, stream_name_size);
stream_name_size);
} }
memcpy(&xattr_stream_name_buf[*xattr_stream_name_size - 1], type, type_len); memcpy(&xattr_stream_name_buf[*xattr_stream_name_size - 1], type, type_len);
*xattr_stream_name_size += type_len; *xattr_stream_name_size += type_len;
...@@ -1790,7 +1783,7 @@ int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name, ...@@ -1790,7 +1783,7 @@ int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name,
} }
int ksmbd_vfs_copy_file_range(struct file *file_in, loff_t pos_in, int ksmbd_vfs_copy_file_range(struct file *file_in, loff_t pos_in,
struct file *file_out, loff_t pos_out, size_t len) struct file *file_out, loff_t pos_out, size_t len)
{ {
struct inode *inode_in = file_inode(file_in); struct inode *inode_in = file_inode(file_in);
struct inode *inode_out = file_inode(file_out); struct inode *inode_out = file_inode(file_out);
...@@ -1820,7 +1813,7 @@ int ksmbd_vfs_copy_file_range(struct file *file_in, loff_t pos_in, ...@@ -1820,7 +1813,7 @@ int ksmbd_vfs_copy_file_range(struct file *file_in, loff_t pos_in,
* in do_splice_direct * in do_splice_direct
*/ */
ret = do_splice_direct(file_in, &pos_in, file_out, &pos_out, ret = do_splice_direct(file_in, &pos_in, file_out, &pos_out,
len > MAX_RW_COUNT ? MAX_RW_COUNT : len, 0); len > MAX_RW_COUNT ? MAX_RW_COUNT : len, 0);
if (ret > 0) { if (ret > 0) {
fsnotify_access(file_in); fsnotify_access(file_in);
add_rchar(current, ret); add_rchar(current, ret);
...@@ -1836,10 +1829,13 @@ int ksmbd_vfs_copy_file_range(struct file *file_in, loff_t pos_in, ...@@ -1836,10 +1829,13 @@ int ksmbd_vfs_copy_file_range(struct file *file_in, loff_t pos_in,
} }
int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work, int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work,
struct ksmbd_file *src_fp, struct ksmbd_file *dst_fp, struct ksmbd_file *src_fp,
struct srv_copychunk *chunks, unsigned int chunk_count, struct ksmbd_file *dst_fp,
unsigned int *chunk_count_written, struct srv_copychunk *chunks,
unsigned int *chunk_size_written, loff_t *total_size_written) unsigned int chunk_count,
unsigned int *chunk_count_written,
unsigned int *chunk_size_written,
loff_t *total_size_written)
{ {
unsigned int i; unsigned int i;
loff_t src_off, dst_off, src_file_size; loff_t src_off, dst_off, src_file_size;
...@@ -1890,7 +1886,7 @@ int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work, ...@@ -1890,7 +1886,7 @@ int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work,
return -E2BIG; return -E2BIG;
ret = ksmbd_vfs_copy_file_range(src_fp->filp, src_off, ret = ksmbd_vfs_copy_file_range(src_fp->filp, src_off,
dst_fp->filp, dst_off, len); dst_fp->filp, dst_off, len);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -1949,13 +1945,13 @@ int ksmbd_vfs_set_init_posix_acl(struct inode *inode) ...@@ -1949,13 +1945,13 @@ int ksmbd_vfs_set_init_posix_acl(struct inode *inode)
rc = ksmbd_vfs_set_posix_acl(inode, ACL_TYPE_ACCESS, acls); rc = ksmbd_vfs_set_posix_acl(inode, ACL_TYPE_ACCESS, acls);
if (rc < 0) if (rc < 0)
ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n", ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
rc); rc);
else if (S_ISDIR(inode->i_mode)) { else if (S_ISDIR(inode->i_mode)) {
posix_state_to_acl(&acl_state, acls->a_entries); posix_state_to_acl(&acl_state, acls->a_entries);
rc = ksmbd_vfs_set_posix_acl(inode, ACL_TYPE_DEFAULT, acls); rc = ksmbd_vfs_set_posix_acl(inode, ACL_TYPE_DEFAULT, acls);
if (rc < 0) if (rc < 0)
ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n", ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
rc); rc);
} }
free_acl_state(&acl_state); free_acl_state(&acl_state);
posix_acl_release(acls); posix_acl_release(acls);
...@@ -1983,12 +1979,12 @@ int ksmbd_vfs_inherit_posix_acl(struct inode *inode, struct inode *parent_inode) ...@@ -1983,12 +1979,12 @@ int ksmbd_vfs_inherit_posix_acl(struct inode *inode, struct inode *parent_inode)
rc = ksmbd_vfs_set_posix_acl(inode, ACL_TYPE_ACCESS, acls); rc = ksmbd_vfs_set_posix_acl(inode, ACL_TYPE_ACCESS, acls);
if (rc < 0) if (rc < 0)
ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n", ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
rc); rc);
if (S_ISDIR(inode->i_mode)) { if (S_ISDIR(inode->i_mode)) {
rc = ksmbd_vfs_set_posix_acl(inode, ACL_TYPE_DEFAULT, acls); rc = ksmbd_vfs_set_posix_acl(inode, ACL_TYPE_DEFAULT, acls);
if (rc < 0) if (rc < 0)
ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n", ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
rc); rc);
} }
posix_acl_release(acls); posix_acl_release(acls);
return rc; return rc;
......
...@@ -191,84 +191,85 @@ struct ksmbd_fs_sector_size { ...@@ -191,84 +191,85 @@ struct ksmbd_fs_sector_size {
}; };
int ksmbd_vfs_inode_permission(struct dentry *dentry, int acc_mode, int ksmbd_vfs_inode_permission(struct dentry *dentry, int acc_mode,
bool delete); bool delete);
int ksmbd_vfs_query_maximal_access(struct dentry *dentry, __le32 *daccess); int ksmbd_vfs_query_maximal_access(struct dentry *dentry, __le32 *daccess);
int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode); int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode);
int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode); int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode);
int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp,
size_t count, loff_t *pos); size_t count, loff_t *pos);
int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp, int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp,
char *buf, size_t count, loff_t *pos, bool sync, char *buf, size_t count, loff_t *pos, bool sync,
ssize_t *written); ssize_t *written);
int ksmbd_vfs_fsync(struct ksmbd_work *work, u64 fid, u64 p_id); int ksmbd_vfs_fsync(struct ksmbd_work *work, u64 fid, u64 p_id);
int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name); int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name);
int ksmbd_vfs_link(struct ksmbd_work *work, int ksmbd_vfs_link(struct ksmbd_work *work,
const char *oldname, const char *newname); const char *oldname, const char *newname);
int ksmbd_vfs_getattr(struct path *path, struct kstat *stat); int ksmbd_vfs_getattr(struct path *path, struct kstat *stat);
int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp, int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
char *newname); char *newname);
int ksmbd_vfs_truncate(struct ksmbd_work *work, const char *name, int ksmbd_vfs_truncate(struct ksmbd_work *work, const char *name,
struct ksmbd_file *fp, loff_t size); struct ksmbd_file *fp, loff_t size);
struct srv_copychunk; struct srv_copychunk;
int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work, int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work,
struct ksmbd_file *src_fp, struct ksmbd_file *dst_fp, struct ksmbd_file *src_fp,
struct srv_copychunk *chunks, unsigned int chunk_count, struct ksmbd_file *dst_fp,
unsigned int *chunk_count_written, struct srv_copychunk *chunks,
unsigned int *chunk_size_written, loff_t *total_size_written); unsigned int chunk_count,
unsigned int *chunk_count_written,
unsigned int *chunk_size_written,
loff_t *total_size_written);
int ksmbd_vfs_copy_file_range(struct file *file_in, loff_t pos_in, int ksmbd_vfs_copy_file_range(struct file *file_in, loff_t pos_in,
struct file *file_out, loff_t pos_out, size_t len); struct file *file_out, loff_t pos_out,
size_t len);
ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list); ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list);
ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name, ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name,
char **xattr_buf); char **xattr_buf);
ssize_t ksmbd_vfs_casexattr_len(struct dentry *dentry, char *attr_name, ssize_t ksmbd_vfs_casexattr_len(struct dentry *dentry, char *attr_name,
int attr_name_len); int attr_name_len);
int ksmbd_vfs_setxattr(struct dentry *dentry, const char *attr_name, int ksmbd_vfs_setxattr(struct dentry *dentry, const char *attr_name,
const void *attr_value, size_t attr_size, int flags); const void *attr_value, size_t attr_size, int flags);
int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name, int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name,
size_t *xattr_stream_name_size, int s_type); size_t *xattr_stream_name_size, int s_type);
int ksmbd_vfs_remove_xattr(struct dentry *dentry, char *attr_name); int ksmbd_vfs_remove_xattr(struct dentry *dentry, char *attr_name);
int ksmbd_vfs_kern_path(char *name, unsigned int flags, struct path *path, int ksmbd_vfs_kern_path(char *name, unsigned int flags, struct path *path,
bool caseless); bool caseless);
int ksmbd_vfs_empty_dir(struct ksmbd_file *fp); int ksmbd_vfs_empty_dir(struct ksmbd_file *fp);
void ksmbd_vfs_set_fadvise(struct file *filp, __le32 option); void ksmbd_vfs_set_fadvise(struct file *filp, __le32 option);
int ksmbd_vfs_lock(struct file *filp, int cmd, struct file_lock *flock); int ksmbd_vfs_lock(struct file *filp, int cmd, struct file_lock *flock);
int ksmbd_vfs_readdir(struct file *file, struct ksmbd_readdir_data *rdata); int ksmbd_vfs_readdir(struct file *file, struct ksmbd_readdir_data *rdata);
int ksmbd_vfs_alloc_size(struct ksmbd_work *work, struct ksmbd_file *fp, int ksmbd_vfs_alloc_size(struct ksmbd_work *work, struct ksmbd_file *fp,
loff_t len); loff_t len);
int ksmbd_vfs_zero_data(struct ksmbd_work *work, struct ksmbd_file *fp, int ksmbd_vfs_zero_data(struct ksmbd_work *work, struct ksmbd_file *fp,
loff_t off, loff_t len); loff_t off, loff_t len);
struct file_allocated_range_buffer; struct file_allocated_range_buffer;
int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length, int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length,
struct file_allocated_range_buffer *ranges, struct file_allocated_range_buffer *ranges,
int in_count, int *out_count); int in_count, int *out_count);
int ksmbd_vfs_unlink(struct dentry *dir, struct dentry *dentry); int ksmbd_vfs_unlink(struct dentry *dir, struct dentry *dentry);
unsigned short ksmbd_vfs_logical_sector_size(struct inode *inode); unsigned short ksmbd_vfs_logical_sector_size(struct inode *inode);
void ksmbd_vfs_smb2_sector_size(struct inode *inode, void ksmbd_vfs_smb2_sector_size(struct inode *inode,
struct ksmbd_fs_sector_size *fs_ss); struct ksmbd_fs_sector_size *fs_ss);
void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat); void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat);
int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, struct dentry *dentry, int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, struct dentry *dentry,
struct ksmbd_kstat *ksmbd_kstat); struct ksmbd_kstat *ksmbd_kstat);
int ksmbd_vfs_posix_lock_wait(struct file_lock *flock); int ksmbd_vfs_posix_lock_wait(struct file_lock *flock);
int ksmbd_vfs_posix_lock_wait_timeout(struct file_lock *flock, long timeout); int ksmbd_vfs_posix_lock_wait_timeout(struct file_lock *flock, long timeout);
void ksmbd_vfs_posix_lock_unblock(struct file_lock *flock); void ksmbd_vfs_posix_lock_unblock(struct file_lock *flock);
int ksmbd_vfs_remove_acl_xattrs(struct dentry *dentry); int ksmbd_vfs_remove_acl_xattrs(struct dentry *dentry);
int ksmbd_vfs_remove_sd_xattrs(struct dentry *dentry); int ksmbd_vfs_remove_sd_xattrs(struct dentry *dentry);
int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
struct smb_ntsd *pntsd, int len); struct smb_ntsd *pntsd, int len);
int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry,
struct smb_ntsd **pntsd); struct smb_ntsd **pntsd);
int ksmbd_vfs_set_dos_attrib_xattr(struct dentry *dentry, int ksmbd_vfs_set_dos_attrib_xattr(struct dentry *dentry,
struct xattr_dos_attrib *da); struct xattr_dos_attrib *da);
int ksmbd_vfs_get_dos_attrib_xattr(struct dentry *dentry, int ksmbd_vfs_get_dos_attrib_xattr(struct dentry *dentry,
struct xattr_dos_attrib *da); struct xattr_dos_attrib *da);
struct posix_acl *ksmbd_vfs_posix_acl_alloc(int count, gfp_t flags); struct posix_acl *ksmbd_vfs_posix_acl_alloc(int count, gfp_t flags);
struct posix_acl *ksmbd_vfs_get_acl(struct inode *inode, int type); struct posix_acl *ksmbd_vfs_get_acl(struct inode *inode, int type);
int ksmbd_vfs_set_posix_acl(struct inode *inode, int type, int ksmbd_vfs_set_posix_acl(struct inode *inode, int type,
struct posix_acl *acl); struct posix_acl *acl);
int ksmbd_vfs_set_init_posix_acl(struct inode *inode); int ksmbd_vfs_set_init_posix_acl(struct inode *inode);
int ksmbd_vfs_inherit_posix_acl(struct inode *inode, int ksmbd_vfs_inherit_posix_acl(struct inode *inode,
struct inode *parent_inode); struct inode *parent_inode);
#endif /* __KSMBD_VFS_H__ */ #endif /* __KSMBD_VFS_H__ */
...@@ -255,7 +255,7 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp) ...@@ -255,7 +255,7 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp)
fp->stream.name); fp->stream.name);
if (err) if (err)
ksmbd_err("remove xattr failed : %s\n", ksmbd_err("remove xattr failed : %s\n",
fp->stream.name); fp->stream.name);
} }
if (atomic_dec_and_test(&ci->m_count)) { if (atomic_dec_and_test(&ci->m_count)) {
...@@ -326,7 +326,7 @@ static struct ksmbd_file *ksmbd_fp_get(struct ksmbd_file *fp) ...@@ -326,7 +326,7 @@ static struct ksmbd_file *ksmbd_fp_get(struct ksmbd_file *fp)
} }
static struct ksmbd_file *__ksmbd_lookup_fd(struct ksmbd_file_table *ft, static struct ksmbd_file *__ksmbd_lookup_fd(struct ksmbd_file_table *ft,
unsigned int id) unsigned int id)
{ {
struct ksmbd_file *fp; struct ksmbd_file *fp;
...@@ -350,7 +350,7 @@ static void set_close_state_blocked_works(struct ksmbd_file *fp) ...@@ -350,7 +350,7 @@ static void set_close_state_blocked_works(struct ksmbd_file *fp)
spin_lock(&fp->f_lock); spin_lock(&fp->f_lock);
list_for_each_entry_safe(cancel_work, ctmp, &fp->blocked_works, list_for_each_entry_safe(cancel_work, ctmp, &fp->blocked_works,
fp_entry) { fp_entry) {
list_del(&cancel_work->fp_entry); list_del(&cancel_work->fp_entry);
cancel_work->state = KSMBD_WORK_CLOSED; cancel_work->state = KSMBD_WORK_CLOSED;
cancel_work->cancel_fn(cancel_work->cancel_argv); cancel_work->cancel_fn(cancel_work->cancel_argv);
...@@ -420,7 +420,7 @@ struct ksmbd_file *ksmbd_lookup_fd_fast(struct ksmbd_work *work, unsigned int id ...@@ -420,7 +420,7 @@ struct ksmbd_file *ksmbd_lookup_fd_fast(struct ksmbd_work *work, unsigned int id
} }
struct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work, unsigned int id, struct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work, unsigned int id,
unsigned int pid) unsigned int pid)
{ {
struct ksmbd_file *fp; struct ksmbd_file *fp;
...@@ -577,8 +577,10 @@ struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp) ...@@ -577,8 +577,10 @@ struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp)
} }
static int static int
__close_file_table_ids(struct ksmbd_file_table *ft, struct ksmbd_tree_connect *tcon, __close_file_table_ids(struct ksmbd_file_table *ft,
bool (*skip)(struct ksmbd_tree_connect *tcon, struct ksmbd_file *fp)) struct ksmbd_tree_connect *tcon,
bool (*skip)(struct ksmbd_tree_connect *tcon,
struct ksmbd_file *fp))
{ {
unsigned int id; unsigned int id;
struct ksmbd_file *fp; struct ksmbd_file *fp;
......
...@@ -149,7 +149,7 @@ int ksmbd_close_fd(struct ksmbd_work *work, unsigned int id); ...@@ -149,7 +149,7 @@ int ksmbd_close_fd(struct ksmbd_work *work, unsigned int id);
struct ksmbd_file *ksmbd_lookup_fd_fast(struct ksmbd_work *work, unsigned int id); struct ksmbd_file *ksmbd_lookup_fd_fast(struct ksmbd_work *work, unsigned int id);
struct ksmbd_file *ksmbd_lookup_foreign_fd(struct ksmbd_work *work, unsigned int id); struct ksmbd_file *ksmbd_lookup_foreign_fd(struct ksmbd_work *work, unsigned int id);
struct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work, unsigned int id, struct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work, unsigned int id,
unsigned int pid); unsigned int pid);
void ksmbd_fd_put(struct ksmbd_work *work, struct ksmbd_file *fp); void ksmbd_fd_put(struct ksmbd_work *work, struct ksmbd_file *fp);
struct ksmbd_file *ksmbd_lookup_durable_fd(unsigned long long id); struct ksmbd_file *ksmbd_lookup_durable_fd(unsigned long long id);
struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid); struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册