cifsd: clean-up codes using chechpatch.pl --strict
Dan Carpenter suggested to run chechpatch.pl --strict on ksmbd to fix check warnings. This patch does not fix all warnings but only things that I can understand. Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
7cb82de3cd
commit
64b39f4a2f
117
fs/cifsd/auth.c
117
fs/cifsd/auth.c
|
@ -64,7 +64,6 @@ static char NEGOTIATE_GSS_HEADER[AUTH_GSS_LENGTH] = {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void ksmbd_copy_gss_neg_header(void *buf)
|
void ksmbd_copy_gss_neg_header(void *buf)
|
||||||
{
|
{
|
||||||
memcpy(buf, NEGOTIATE_GSS_HEADER, AUTH_GSS_LENGTH);
|
memcpy(buf, NEGOTIATE_GSS_HEADER, AUTH_GSS_LENGTH);
|
||||||
|
@ -107,9 +106,7 @@ smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ksmbd_enc_p24(unsigned char *p21,
|
static int ksmbd_enc_p24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
|
||||||
const unsigned char *c8,
|
|
||||||
unsigned char *p24)
|
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -124,9 +121,8 @@ static int ksmbd_enc_p24(unsigned char *p21,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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,
|
static int ksmbd_enc_md4(unsigned char *md4_hash, unsigned char *link_str,
|
||||||
unsigned char *link_str,
|
int link_len)
|
||||||
int link_len)
|
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
struct ksmbd_crypto_ctx *ctx;
|
struct ksmbd_crypto_ctx *ctx;
|
||||||
|
@ -157,10 +153,8 @@ static int ksmbd_enc_md4(unsigned char *md4_hash,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ksmbd_enc_update_sess_key(unsigned char *md5_hash,
|
static int ksmbd_enc_update_sess_key(unsigned char *md5_hash, char *nonce,
|
||||||
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;
|
||||||
|
@ -204,9 +198,8 @@ static int ksmbd_enc_update_sess_key(unsigned char *md5_hash,
|
||||||
* @hmac: source hmac value to be used for finding session key
|
* @hmac: source hmac value to be used for finding session key
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int ksmbd_gen_sess_key(struct ksmbd_session *sess,
|
static int ksmbd_gen_sess_key(struct ksmbd_session *sess, char *hash,
|
||||||
char *hash,
|
char *hmac)
|
||||||
char *hmac)
|
|
||||||
{
|
{
|
||||||
struct ksmbd_crypto_ctx *ctx;
|
struct ksmbd_crypto_ctx *ctx;
|
||||||
int rc = -EINVAL;
|
int rc = -EINVAL;
|
||||||
|
@ -251,7 +244,7 @@ static int ksmbd_gen_sess_key(struct ksmbd_session *sess,
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = -EINVAL, len;
|
int ret = -EINVAL, len;
|
||||||
wchar_t *domain = NULL;
|
wchar_t *domain = NULL;
|
||||||
|
@ -361,8 +354,9 @@ int ksmbd_auth_ntlm(struct ksmbd_session *sess, char *pw_buf)
|
||||||
if (strncmp(pw_buf, key, CIFS_AUTH_RESP_SIZE) != 0) {
|
if (strncmp(pw_buf, key, CIFS_AUTH_RESP_SIZE) != 0) {
|
||||||
ksmbd_debug(AUTH, "ntlmv1 authentication failed\n");
|
ksmbd_debug(AUTH, "ntlmv1 authentication failed\n");
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
} else
|
} else {
|
||||||
ksmbd_debug(AUTH, "ntlmv1 authentication pass\n");
|
ksmbd_debug(AUTH, "ntlmv1 authentication pass\n");
|
||||||
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -376,10 +370,8 @@ 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,
|
int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
|
||||||
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];
|
||||||
|
@ -457,9 +449,8 @@ int ksmbd_auth_ntlmv2(struct ksmbd_session *sess,
|
||||||
*
|
*
|
||||||
* 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,
|
static int __ksmbd_auth_ntlmv2(struct ksmbd_session *sess, char *client_nonce,
|
||||||
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;
|
||||||
|
@ -497,8 +488,7 @@ static int __ksmbd_auth_ntlmv2(struct ksmbd_session *sess,
|
||||||
* 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,
|
int blob_len, struct ksmbd_session *sess)
|
||||||
struct ksmbd_session *sess)
|
|
||||||
{
|
{
|
||||||
char *domain_name;
|
char *domain_name;
|
||||||
unsigned int lm_off, nt_off;
|
unsigned int lm_off, nt_off;
|
||||||
|
@ -523,8 +513,8 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
|
||||||
|
|
||||||
/* process NTLM authentication */
|
/* process NTLM authentication */
|
||||||
if (nt_len == CIFS_AUTH_RESP_SIZE) {
|
if (nt_len == CIFS_AUTH_RESP_SIZE) {
|
||||||
if (le32_to_cpu(authblob->NegotiateFlags)
|
if (le32_to_cpu(authblob->NegotiateFlags) &
|
||||||
& NTLMSSP_NEGOTIATE_EXTENDED_SEC)
|
NTLMSSP_NEGOTIATE_EXTENDED_SEC)
|
||||||
return __ksmbd_auth_ntlmv2(sess, (char *)authblob +
|
return __ksmbd_auth_ntlmv2(sess, (char *)authblob +
|
||||||
lm_off, (char *)authblob + nt_off);
|
lm_off, (char *)authblob + nt_off);
|
||||||
else
|
else
|
||||||
|
@ -533,8 +523,7 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO : use domain name that imported from configuration file */
|
/* TODO : use domain name that imported from configuration file */
|
||||||
domain_name = smb_strndup_from_utf16(
|
domain_name = smb_strndup_from_utf16((const char *)authblob +
|
||||||
(const char *)authblob +
|
|
||||||
le32_to_cpu(authblob->DomainName.BufferOffset),
|
le32_to_cpu(authblob->DomainName.BufferOffset),
|
||||||
le16_to_cpu(authblob->DomainName.Length), true,
|
le16_to_cpu(authblob->DomainName.Length), true,
|
||||||
sess->conn->local_nls);
|
sess->conn->local_nls);
|
||||||
|
@ -561,8 +550,7 @@ 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,
|
int blob_len, struct ksmbd_session *sess)
|
||||||
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",
|
||||||
|
@ -618,7 +606,7 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
|
||||||
flags |= NTLMSSP_REQUEST_TARGET;
|
flags |= NTLMSSP_REQUEST_TARGET;
|
||||||
|
|
||||||
if (sess->conn->use_spnego &&
|
if (sess->conn->use_spnego &&
|
||||||
(cflags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
|
(cflags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
|
||||||
flags |= NTLMSSP_NEGOTIATE_EXTENDED_SEC;
|
flags |= NTLMSSP_NEGOTIATE_EXTENDED_SEC;
|
||||||
|
|
||||||
chgblob->NegotiateFlags = cpu_to_le32(flags);
|
chgblob->NegotiateFlags = cpu_to_le32(flags);
|
||||||
|
@ -675,9 +663,8 @@ 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,
|
int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
|
||||||
char *in_blob, int in_len,
|
int in_len, char *out_blob, int *out_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;
|
||||||
|
@ -726,9 +713,8 @@ int ksmbd_krb5_authenticate(struct ksmbd_session *sess,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int ksmbd_krb5_authenticate(struct ksmbd_session *sess,
|
int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
|
||||||
char *in_blob, int in_len,
|
int in_len, char *out_blob, int *out_len)
|
||||||
char *out_blob, int *out_len)
|
|
||||||
{
|
{
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
@ -743,11 +729,8 @@ int ksmbd_krb5_authenticate(struct ksmbd_session *sess,
|
||||||
* @sig: signature value generated for client request packet
|
* @sig: signature value generated for client request packet
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn,
|
int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
|
||||||
char *key,
|
int n_vec, char *sig)
|
||||||
struct kvec *iov,
|
|
||||||
int n_vec,
|
|
||||||
char *sig)
|
|
||||||
{
|
{
|
||||||
struct ksmbd_crypto_ctx *ctx;
|
struct ksmbd_crypto_ctx *ctx;
|
||||||
int rc = -EINVAL;
|
int rc = -EINVAL;
|
||||||
|
@ -798,11 +781,8 @@ int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn,
|
||||||
* @sig: signature value generated for client request packet
|
* @sig: signature value generated for client request packet
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn,
|
int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
|
||||||
char *key,
|
int n_vec, char *sig)
|
||||||
struct kvec *iov,
|
|
||||||
int n_vec,
|
|
||||||
char *sig)
|
|
||||||
{
|
{
|
||||||
struct ksmbd_crypto_ctx *ctx;
|
struct ksmbd_crypto_ctx *ctx;
|
||||||
int rc = -EINVAL;
|
int rc = -EINVAL;
|
||||||
|
@ -851,7 +831,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};
|
||||||
|
@ -931,7 +911,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;
|
||||||
|
@ -995,7 +975,7 @@ 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;
|
||||||
|
|
||||||
|
@ -1062,9 +1042,8 @@ int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess)
|
||||||
return generate_smb3encryptionkey(sess, &twin);
|
return generate_smb3encryptionkey(sess, &twin);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn,
|
int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
|
||||||
char *buf,
|
__u8 *pi_hash)
|
||||||
__u8 *pi_hash)
|
|
||||||
{
|
{
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
struct smb2_hdr *rcv_hdr = (struct smb2_hdr *)buf;
|
struct smb2_hdr *rcv_hdr = (struct smb2_hdr *)buf;
|
||||||
|
@ -1073,14 +1052,15 @@ int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn,
|
||||||
struct ksmbd_crypto_ctx *ctx = NULL;
|
struct ksmbd_crypto_ctx *ctx = NULL;
|
||||||
|
|
||||||
if (conn->preauth_info->Preauth_HashId ==
|
if (conn->preauth_info->Preauth_HashId ==
|
||||||
SMB2_PREAUTH_INTEGRITY_SHA512) {
|
SMB2_PREAUTH_INTEGRITY_SHA512) {
|
||||||
ctx = ksmbd_crypto_ctx_find_sha512();
|
ctx = ksmbd_crypto_ctx_find_sha512();
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
ksmbd_debug(AUTH, "could not alloc sha512 rc %d\n", rc);
|
ksmbd_debug(AUTH, "could not alloc sha512 rc %d\n", rc);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
rc = crypto_shash_init(CRYPTO_SHA512(ctx));
|
rc = crypto_shash_init(CRYPTO_SHA512(ctx));
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@ -1144,10 +1124,8 @@ int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ksmbd_get_encryption_key(struct ksmbd_conn *conn,
|
static int ksmbd_get_encryption_key(struct ksmbd_conn *conn, __u64 ses_id,
|
||||||
__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;
|
||||||
|
@ -1175,9 +1153,8 @@ static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
|
||||||
sg_set_page(sg, addr, buflen, offset_in_page(buf));
|
sg_set_page(sg, addr, buflen, offset_in_page(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct scatterlist *ksmbd_init_sg(struct kvec *iov,
|
static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
|
||||||
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;
|
||||||
|
@ -1190,8 +1167,9 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov,
|
||||||
nr_entries[i] = ((kaddr + iov[i + 1].iov_len +
|
nr_entries[i] = ((kaddr + iov[i + 1].iov_len +
|
||||||
PAGE_SIZE - 1) >> PAGE_SHIFT) -
|
PAGE_SIZE - 1) >> PAGE_SHIFT) -
|
||||||
(kaddr >> PAGE_SHIFT);
|
(kaddr >> PAGE_SHIFT);
|
||||||
} else
|
} else {
|
||||||
nr_entries[i]++;
|
nr_entries[i]++;
|
||||||
|
}
|
||||||
total_entries += nr_entries[i];
|
total_entries += nr_entries[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1232,16 +1210,13 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov,
|
||||||
sg_set_page(&sg[sg_idx++], virt_to_page(data), len,
|
sg_set_page(&sg[sg_idx++], virt_to_page(data), len,
|
||||||
offset_in_page(data));
|
offset_in_page(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
smb2_sg_set_buf(&sg[sg_idx], sign, SMB2_SIGNATURE_SIZE);
|
smb2_sg_set_buf(&sg[sg_idx], sign, SMB2_SIGNATURE_SIZE);
|
||||||
return sg;
|
return sg;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
@ -1319,9 +1294,9 @@ int ksmbd_crypt_message(struct ksmbd_conn *conn,
|
||||||
goto free_sg;
|
goto free_sg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM)
|
if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM) {
|
||||||
memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES128GCM_NONCE);
|
memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES128GCM_NONCE);
|
||||||
else {
|
} else {
|
||||||
iv[0] = 3;
|
iv[0] = 3;
|
||||||
memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES128CCM_NONCE);
|
memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES128CCM_NONCE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -278,8 +278,7 @@ 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,
|
sizeof(struct ksmbd_file), 0, SLAB_HWCACHE_ALIGN, NULL);
|
||||||
SLAB_HWCACHE_ALIGN, NULL);
|
|
||||||
if (!filp_cache)
|
if (!filp_cache)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
|
@ -119,7 +119,7 @@ int ksmbd_conn_try_dequeue_request(struct ksmbd_work *work)
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
|
|
||||||
if (list_empty(&work->request_entry) &&
|
if (list_empty(&work->request_entry) &&
|
||||||
list_empty(&work->async_request_entry))
|
list_empty(&work->async_request_entry))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
atomic_dec(&conn->req_running);
|
atomic_dec(&conn->req_running);
|
||||||
|
@ -201,10 +201,9 @@ int ksmbd_conn_write(struct ksmbd_work *work)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksmbd_conn_rdma_read(struct ksmbd_conn *conn,
|
int ksmbd_conn_rdma_read(struct ksmbd_conn *conn, void *buf,
|
||||||
void *buf, unsigned int buflen,
|
unsigned int buflen, u32 remote_key, u64 remote_offset,
|
||||||
u32 remote_key, u64 remote_offset,
|
u32 remote_len)
|
||||||
u32 remote_len)
|
|
||||||
{
|
{
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
|
||||||
|
@ -216,10 +215,9 @@ int ksmbd_conn_rdma_read(struct ksmbd_conn *conn,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksmbd_conn_rdma_write(struct ksmbd_conn *conn,
|
int ksmbd_conn_rdma_write(struct ksmbd_conn *conn, void *buf,
|
||||||
void *buf, unsigned int buflen,
|
unsigned int buflen, u32 remote_key, u64 remote_offset,
|
||||||
u32 remote_key, u64 remote_offset,
|
u32 remote_len)
|
||||||
u32 remote_len)
|
|
||||||
{
|
{
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
|
||||||
|
@ -251,7 +249,7 @@ bool ksmbd_conn_alive(struct ksmbd_conn *conn)
|
||||||
* zero.
|
* zero.
|
||||||
*/
|
*/
|
||||||
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;
|
||||||
|
@ -393,14 +391,13 @@ 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->comm, task_pid_nr(task));
|
||||||
task_pid_nr(task));
|
|
||||||
conn->status = KSMBD_SESS_EXITING;
|
conn->status = KSMBD_SESS_EXITING;
|
||||||
}
|
}
|
||||||
read_unlock(&conn_list_lock);
|
read_unlock(&conn_list_lock);
|
||||||
|
|
||||||
if (!list_empty(&conn_list)) {
|
if (!list_empty(&conn_list)) {
|
||||||
schedule_timeout_interruptible(HZ/10); /* 100ms */
|
schedule_timeout_interruptible(HZ / 10); /* 100ms */
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,17 +116,15 @@ struct ksmbd_conn_ops {
|
||||||
struct ksmbd_transport_ops {
|
struct ksmbd_transport_ops {
|
||||||
int (*prepare)(struct ksmbd_transport *t);
|
int (*prepare)(struct ksmbd_transport *t);
|
||||||
void (*disconnect)(struct ksmbd_transport *t);
|
void (*disconnect)(struct ksmbd_transport *t);
|
||||||
int (*read)(struct ksmbd_transport *t,
|
int (*read)(struct ksmbd_transport *t, char *buf, unsigned int size);
|
||||||
char *buf, unsigned int size);
|
int (*writev)(struct ksmbd_transport *t, struct kvec *iovs, int niov,
|
||||||
int (*writev)(struct ksmbd_transport *t,
|
int size, bool need_invalidate_rkey,
|
||||||
struct kvec *iovs, int niov, int size,
|
unsigned int remote_key);
|
||||||
bool need_invalidate_rkey, unsigned int remote_key);
|
int (*rdma_read)(struct ksmbd_transport *t, void *buf, unsigned int len,
|
||||||
int (*rdma_read)(struct ksmbd_transport *t,
|
u32 remote_key, u64 remote_offset, u32 remote_len);
|
||||||
void *buf, unsigned int len, u32 remote_key,
|
int (*rdma_write)(struct ksmbd_transport *t, void *buf,
|
||||||
u64 remote_offset, u32 remote_len);
|
unsigned int len, u32 remote_key, u64 remote_offset,
|
||||||
int (*rdma_write)(struct ksmbd_transport *t,
|
u32 remote_len);
|
||||||
void *buf, unsigned int len, u32 remote_key,
|
|
||||||
u64 remote_offset, u32 remote_len);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ksmbd_transport {
|
struct ksmbd_transport {
|
||||||
|
@ -146,14 +144,12 @@ 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,
|
int ksmbd_conn_rdma_read(struct ksmbd_conn *conn, void *buf,
|
||||||
void *buf, unsigned int buflen,
|
unsigned int buflen, u32 remote_key, u64 remote_offset,
|
||||||
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,
|
unsigned int buflen, u32 remote_key, u64 remote_offset,
|
||||||
void *buf, unsigned int buflen,
|
u32 remote_len);
|
||||||
u32 remote_key, u64 remote_offset,
|
|
||||||
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);
|
||||||
|
|
|
@ -24,13 +24,13 @@ extern int ksmbd_caseless_search;
|
||||||
#define DATA_STREAM 1
|
#define DATA_STREAM 1
|
||||||
#define DIR_STREAM 2
|
#define DIR_STREAM 2
|
||||||
|
|
||||||
#define KSMBD_DEBUG_SMB (1 << 0)
|
#define KSMBD_DEBUG_SMB BIT(0)
|
||||||
#define KSMBD_DEBUG_AUTH (1 << 1)
|
#define KSMBD_DEBUG_AUTH BIT(1)
|
||||||
#define KSMBD_DEBUG_VFS (1 << 2)
|
#define KSMBD_DEBUG_VFS BIT(2)
|
||||||
#define KSMBD_DEBUG_OPLOCK (1 << 3)
|
#define KSMBD_DEBUG_OPLOCK BIT(3)
|
||||||
#define KSMBD_DEBUG_IPC (1 << 4)
|
#define KSMBD_DEBUG_IPC BIT(4)
|
||||||
#define KSMBD_DEBUG_CONN (1 << 5)
|
#define KSMBD_DEBUG_CONN BIT(5)
|
||||||
#define KSMBD_DEBUG_RDMA (1 << 6)
|
#define KSMBD_DEBUG_RDMA BIT(6)
|
||||||
#define KSMBD_DEBUG_ALL (KSMBD_DEBUG_SMB | KSMBD_DEBUG_AUTH | \
|
#define KSMBD_DEBUG_ALL (KSMBD_DEBUG_SMB | KSMBD_DEBUG_AUTH | \
|
||||||
KSMBD_DEBUG_VFS | KSMBD_DEBUG_OPLOCK | \
|
KSMBD_DEBUG_VFS | KSMBD_DEBUG_OPLOCK | \
|
||||||
KSMBD_DEBUG_IPC | KSMBD_DEBUG_CONN | \
|
KSMBD_DEBUG_IPC | KSMBD_DEBUG_CONN | \
|
||||||
|
|
|
@ -29,11 +29,11 @@ struct ksmbd_heartbeat {
|
||||||
* Global config flags.
|
* Global config flags.
|
||||||
*/
|
*/
|
||||||
#define KSMBD_GLOBAL_FLAG_INVALID (0)
|
#define KSMBD_GLOBAL_FLAG_INVALID (0)
|
||||||
#define KSMBD_GLOBAL_FLAG_SMB2_LEASES (1 << 0)
|
#define KSMBD_GLOBAL_FLAG_SMB2_LEASES BIT(0)
|
||||||
#define KSMBD_GLOBAL_FLAG_CACHE_TBUF (1 << 1)
|
#define KSMBD_GLOBAL_FLAG_CACHE_TBUF BIT(1)
|
||||||
#define KSMBD_GLOBAL_FLAG_CACHE_RBUF (1 << 2)
|
#define KSMBD_GLOBAL_FLAG_CACHE_RBUF BIT(2)
|
||||||
#define KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION (1 << 3)
|
#define KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION BIT(3)
|
||||||
#define KSMBD_GLOBAL_FLAG_DURABLE_HANDLE (1 << 4)
|
#define KSMBD_GLOBAL_FLAG_DURABLE_HANDLE BIT(4)
|
||||||
|
|
||||||
struct ksmbd_startup_request {
|
struct ksmbd_startup_request {
|
||||||
__u32 flags;
|
__u32 flags;
|
||||||
|
@ -204,66 +204,66 @@ enum KSMBD_TREE_CONN_STATUS {
|
||||||
* User config flags.
|
* User config flags.
|
||||||
*/
|
*/
|
||||||
#define KSMBD_USER_FLAG_INVALID (0)
|
#define KSMBD_USER_FLAG_INVALID (0)
|
||||||
#define KSMBD_USER_FLAG_OK (1 << 0)
|
#define KSMBD_USER_FLAG_OK BIT(0)
|
||||||
#define KSMBD_USER_FLAG_BAD_PASSWORD (1 << 1)
|
#define KSMBD_USER_FLAG_BAD_PASSWORD BIT(1)
|
||||||
#define KSMBD_USER_FLAG_BAD_UID (1 << 2)
|
#define KSMBD_USER_FLAG_BAD_UID BIT(2)
|
||||||
#define KSMBD_USER_FLAG_BAD_USER (1 << 3)
|
#define KSMBD_USER_FLAG_BAD_USER BIT(3)
|
||||||
#define KSMBD_USER_FLAG_GUEST_ACCOUNT (1 << 4)
|
#define KSMBD_USER_FLAG_GUEST_ACCOUNT BIT(4)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Share config flags.
|
* Share config flags.
|
||||||
*/
|
*/
|
||||||
#define KSMBD_SHARE_FLAG_INVALID (0)
|
#define KSMBD_SHARE_FLAG_INVALID (0)
|
||||||
#define KSMBD_SHARE_FLAG_AVAILABLE (1 << 0)
|
#define KSMBD_SHARE_FLAG_AVAILABLE BIT(0)
|
||||||
#define KSMBD_SHARE_FLAG_BROWSEABLE (1 << 1)
|
#define KSMBD_SHARE_FLAG_BROWSEABLE BIT(1)
|
||||||
#define KSMBD_SHARE_FLAG_WRITEABLE (1 << 2)
|
#define KSMBD_SHARE_FLAG_WRITEABLE BIT(2)
|
||||||
#define KSMBD_SHARE_FLAG_READONLY (1 << 3)
|
#define KSMBD_SHARE_FLAG_READONLY BIT(3)
|
||||||
#define KSMBD_SHARE_FLAG_GUEST_OK (1 << 4)
|
#define KSMBD_SHARE_FLAG_GUEST_OK BIT(4)
|
||||||
#define KSMBD_SHARE_FLAG_GUEST_ONLY (1 << 5)
|
#define KSMBD_SHARE_FLAG_GUEST_ONLY BIT(5)
|
||||||
#define KSMBD_SHARE_FLAG_STORE_DOS_ATTRS (1 << 6)
|
#define KSMBD_SHARE_FLAG_STORE_DOS_ATTRS BIT(6)
|
||||||
#define KSMBD_SHARE_FLAG_OPLOCKS (1 << 7)
|
#define KSMBD_SHARE_FLAG_OPLOCKS BIT(7)
|
||||||
#define KSMBD_SHARE_FLAG_PIPE (1 << 8)
|
#define KSMBD_SHARE_FLAG_PIPE BIT(8)
|
||||||
#define KSMBD_SHARE_FLAG_HIDE_DOT_FILES (1 << 9)
|
#define KSMBD_SHARE_FLAG_HIDE_DOT_FILES BIT(9)
|
||||||
#define KSMBD_SHARE_FLAG_INHERIT_SMACK (1 << 10)
|
#define KSMBD_SHARE_FLAG_INHERIT_SMACK BIT(10)
|
||||||
#define KSMBD_SHARE_FLAG_INHERIT_OWNER (1 << 11)
|
#define KSMBD_SHARE_FLAG_INHERIT_OWNER BIT(11)
|
||||||
#define KSMBD_SHARE_FLAG_STREAMS (1 << 12)
|
#define KSMBD_SHARE_FLAG_STREAMS BIT(12)
|
||||||
#define KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS (1 << 13)
|
#define KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS BIT(13)
|
||||||
#define KSMBD_SHARE_FLAG_ACL_XATTR (1 << 14)
|
#define KSMBD_SHARE_FLAG_ACL_XATTR BIT(14)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tree connect request flags.
|
* Tree connect request flags.
|
||||||
*/
|
*/
|
||||||
#define KSMBD_TREE_CONN_FLAG_REQUEST_SMB1 (0)
|
#define KSMBD_TREE_CONN_FLAG_REQUEST_SMB1 (0)
|
||||||
#define KSMBD_TREE_CONN_FLAG_REQUEST_IPV6 (1 << 0)
|
#define KSMBD_TREE_CONN_FLAG_REQUEST_IPV6 BIT(0)
|
||||||
#define KSMBD_TREE_CONN_FLAG_REQUEST_SMB2 (1 << 1)
|
#define KSMBD_TREE_CONN_FLAG_REQUEST_SMB2 BIT(1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tree connect flags.
|
* Tree connect flags.
|
||||||
*/
|
*/
|
||||||
#define KSMBD_TREE_CONN_FLAG_GUEST_ACCOUNT (1 << 0)
|
#define KSMBD_TREE_CONN_FLAG_GUEST_ACCOUNT BIT(0)
|
||||||
#define KSMBD_TREE_CONN_FLAG_READ_ONLY (1 << 1)
|
#define KSMBD_TREE_CONN_FLAG_READ_ONLY BIT(1)
|
||||||
#define KSMBD_TREE_CONN_FLAG_WRITABLE (1 << 2)
|
#define KSMBD_TREE_CONN_FLAG_WRITABLE BIT(2)
|
||||||
#define KSMBD_TREE_CONN_FLAG_ADMIN_ACCOUNT (1 << 3)
|
#define KSMBD_TREE_CONN_FLAG_ADMIN_ACCOUNT BIT(3)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RPC over IPC.
|
* RPC over IPC.
|
||||||
*/
|
*/
|
||||||
#define KSMBD_RPC_METHOD_RETURN (1 << 0)
|
#define KSMBD_RPC_METHOD_RETURN BIT(0)
|
||||||
#define KSMBD_RPC_SRVSVC_METHOD_INVOKE (1 << 1)
|
#define KSMBD_RPC_SRVSVC_METHOD_INVOKE BIT(1)
|
||||||
#define KSMBD_RPC_SRVSVC_METHOD_RETURN ((1 << 1) | KSMBD_RPC_METHOD_RETURN)
|
#define KSMBD_RPC_SRVSVC_METHOD_RETURN (KSMBD_RPC_SRVSVC_METHOD_INVOKE | KSMBD_RPC_METHOD_RETURN)
|
||||||
#define KSMBD_RPC_WKSSVC_METHOD_INVOKE (1 << 2)
|
#define KSMBD_RPC_WKSSVC_METHOD_INVOKE BIT(2)
|
||||||
#define KSMBD_RPC_WKSSVC_METHOD_RETURN ((1 << 2) | KSMBD_RPC_METHOD_RETURN)
|
#define KSMBD_RPC_WKSSVC_METHOD_RETURN (KSMBD_RPC_WKSSVC_METHOD_INVOKE | KSMBD_RPC_METHOD_RETURN)
|
||||||
#define KSMBD_RPC_IOCTL_METHOD ((1 << 3) | KSMBD_RPC_METHOD_RETURN)
|
#define KSMBD_RPC_IOCTL_METHOD (BIT(3) | KSMBD_RPC_METHOD_RETURN)
|
||||||
#define KSMBD_RPC_OPEN_METHOD (1 << 4)
|
#define KSMBD_RPC_OPEN_METHOD BIT(4)
|
||||||
#define KSMBD_RPC_WRITE_METHOD (1 << 5)
|
#define KSMBD_RPC_WRITE_METHOD BIT(5)
|
||||||
#define KSMBD_RPC_READ_METHOD ((1 << 6) | KSMBD_RPC_METHOD_RETURN)
|
#define KSMBD_RPC_READ_METHOD (BIT(6) | KSMBD_RPC_METHOD_RETURN)
|
||||||
#define KSMBD_RPC_CLOSE_METHOD (1 << 7)
|
#define KSMBD_RPC_CLOSE_METHOD BIT(7)
|
||||||
#define KSMBD_RPC_RAP_METHOD ((1 << 8) | KSMBD_RPC_METHOD_RETURN)
|
#define KSMBD_RPC_RAP_METHOD (BIT(8) | KSMBD_RPC_METHOD_RETURN)
|
||||||
#define KSMBD_RPC_RESTRICTED_CONTEXT (1 << 9)
|
#define KSMBD_RPC_RESTRICTED_CONTEXT BIT(9)
|
||||||
#define KSMBD_RPC_SAMR_METHOD_INVOKE (1 << 10)
|
#define KSMBD_RPC_SAMR_METHOD_INVOKE BIT(10)
|
||||||
#define KSMBD_RPC_SAMR_METHOD_RETURN ((1 << 10) | KSMBD_RPC_METHOD_RETURN)
|
#define KSMBD_RPC_SAMR_METHOD_RETURN (KSMBD_RPC_SAMR_METHOD_INVOKE | KSMBD_RPC_METHOD_RETURN)
|
||||||
#define KSMBD_RPC_LSARPC_METHOD_INVOKE (1 << 11)
|
#define KSMBD_RPC_LSARPC_METHOD_INVOKE BIT(11)
|
||||||
#define KSMBD_RPC_LSARPC_METHOD_RETURN ((1 << 11) | KSMBD_RPC_METHOD_RETURN)
|
#define KSMBD_RPC_LSARPC_METHOD_RETURN (KSMBD_RPC_LSARPC_METHOD_INVOKE | KSMBD_RPC_METHOD_RETURN)
|
||||||
|
|
||||||
#define KSMBD_RPC_OK 0
|
#define KSMBD_RPC_OK 0
|
||||||
#define KSMBD_RPC_EBAD_FUNC 0x00000001
|
#define KSMBD_RPC_EBAD_FUNC 0x00000001
|
||||||
|
|
|
@ -26,12 +26,12 @@ struct channel {
|
||||||
|
|
||||||
struct preauth_session {
|
struct preauth_session {
|
||||||
__u8 Preauth_HashValue[PREAUTH_HASHVALUE_SIZE];
|
__u8 Preauth_HashValue[PREAUTH_HASHVALUE_SIZE];
|
||||||
uint64_t sess_id;
|
u64 sess_id;
|
||||||
struct list_head list_entry;
|
struct list_head list_entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ksmbd_session {
|
struct ksmbd_session {
|
||||||
uint64_t id;
|
u64 id;
|
||||||
|
|
||||||
struct ksmbd_user *user;
|
struct ksmbd_user *user;
|
||||||
struct ksmbd_conn *conn;
|
struct ksmbd_conn *conn;
|
||||||
|
|
|
@ -78,9 +78,9 @@ static inline int is_char_allowed(char ch)
|
||||||
{
|
{
|
||||||
/* check for control chars, wildcards etc. */
|
/* check for control chars, wildcards etc. */
|
||||||
if (!(ch & 0x80) &&
|
if (!(ch & 0x80) &&
|
||||||
(ch <= 0x1f ||
|
(ch <= 0x1f ||
|
||||||
ch == '?' || ch == '"' || ch == '<' ||
|
ch == '?' || ch == '"' || ch == '<' ||
|
||||||
ch == '>' || ch == '|' || ch == '*'))
|
ch == '>' || ch == '|' || ch == '*'))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -268,8 +268,7 @@ 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,
|
const struct nls_table *local_nls, int *conv_len)
|
||||||
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);
|
||||||
|
|
|
@ -159,8 +159,9 @@ int ndr_encode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da)
|
||||||
ndr_write_int32(n, da->ea_size);
|
ndr_write_int32(n, da->ea_size);
|
||||||
ndr_write_int64(n, da->size);
|
ndr_write_int64(n, da->size);
|
||||||
ndr_write_int64(n, da->alloc_size);
|
ndr_write_int64(n, da->alloc_size);
|
||||||
} else
|
} else {
|
||||||
ndr_write_int64(n, da->itime);
|
ndr_write_int64(n, da->itime);
|
||||||
|
}
|
||||||
ndr_write_int64(n, da->create_time);
|
ndr_write_int64(n, da->create_time);
|
||||||
if (da->version == 3)
|
if (da->version == 3)
|
||||||
ndr_write_int64(n, da->change_time);
|
ndr_write_int64(n, da->change_time);
|
||||||
|
@ -248,15 +249,17 @@ int ndr_encode_posix_acl(struct ndr *n, struct inode *inode,
|
||||||
/* ACL ACCESS */
|
/* ACL ACCESS */
|
||||||
ndr_write_int32(n, ref_id);
|
ndr_write_int32(n, ref_id);
|
||||||
ref_id += 4;
|
ref_id += 4;
|
||||||
} else
|
} else {
|
||||||
ndr_write_int32(n, 0);
|
ndr_write_int32(n, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (def_acl) {
|
if (def_acl) {
|
||||||
/* DEFAULT ACL ACCESS */
|
/* DEFAULT ACL ACCESS */
|
||||||
ndr_write_int32(n, ref_id);
|
ndr_write_int32(n, ref_id);
|
||||||
ref_id += 4;
|
ref_id += 4;
|
||||||
} else
|
} else {
|
||||||
ndr_write_int32(n, 0);
|
ndr_write_int32(n, 0);
|
||||||
|
}
|
||||||
|
|
||||||
ndr_write_int64(n, from_kuid(&init_user_ns, inode->i_uid));
|
ndr_write_int64(n, from_kuid(&init_user_ns, inode->i_uid));
|
||||||
ndr_write_int64(n, from_kgid(&init_user_ns, inode->i_gid));
|
ndr_write_int64(n, from_kgid(&init_user_ns, inode->i_gid));
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/*
|
/*
|
||||||
* fs/ksmbd/netmisc.c
|
|
||||||
*
|
|
||||||
* Copyright (c) International Business Machines Corp., 2002,2008
|
* Copyright (c) International Business Machines Corp., 2002,2008
|
||||||
* Author(s): Steve French (sfrench@us.ibm.com)
|
* Author(s): Steve French (sfrench@us.ibm.com)
|
||||||
*
|
*
|
||||||
|
|
|
@ -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,
|
||||||
uint64_t 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;
|
||||||
|
@ -89,8 +89,7 @@ static void lb_add(struct lease_table *lb)
|
||||||
write_unlock(&lease_list_lock);
|
write_unlock(&lease_list_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int alloc_lease(struct oplock_info *opinfo,
|
static int alloc_lease(struct oplock_info *opinfo, struct lease_ctx_info *lctx)
|
||||||
struct lease_ctx_info *lctx)
|
|
||||||
{
|
{
|
||||||
struct lease *lease;
|
struct lease *lease;
|
||||||
|
|
||||||
|
@ -227,8 +226,8 @@ int opinfo_write_to_read(struct oplock_info *opinfo)
|
||||||
{
|
{
|
||||||
struct lease *lease = opinfo->o_lease;
|
struct lease *lease = opinfo->o_lease;
|
||||||
|
|
||||||
if (!((opinfo->level == SMB2_OPLOCK_LEVEL_BATCH) ||
|
if (!(opinfo->level == SMB2_OPLOCK_LEVEL_BATCH ||
|
||||||
(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", lease->state);
|
ksmbd_err("lease state(0x%x)\n", lease->state);
|
||||||
|
@ -266,8 +265,8 @@ int opinfo_write_to_none(struct oplock_info *opinfo)
|
||||||
{
|
{
|
||||||
struct lease *lease = opinfo->o_lease;
|
struct lease *lease = opinfo->o_lease;
|
||||||
|
|
||||||
if (!((opinfo->level == SMB2_OPLOCK_LEVEL_BATCH) ||
|
if (!(opinfo->level == SMB2_OPLOCK_LEVEL_BATCH ||
|
||||||
(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",
|
||||||
|
@ -334,8 +333,7 @@ int lease_read_to_write(struct oplock_info *opinfo)
|
||||||
*
|
*
|
||||||
* Return: 0 on success, otherwise -EINVAL
|
* Return: 0 on success, otherwise -EINVAL
|
||||||
*/
|
*/
|
||||||
static int lease_none_upgrade(struct oplock_info *opinfo,
|
static int lease_none_upgrade(struct oplock_info *opinfo, __le32 new_state)
|
||||||
__le32 new_state)
|
|
||||||
{
|
{
|
||||||
struct lease *lease = opinfo->o_lease;
|
struct lease *lease = opinfo->o_lease;
|
||||||
|
|
||||||
|
@ -401,7 +399,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;
|
||||||
|
|
||||||
|
@ -425,7 +423,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;
|
||||||
|
|
||||||
|
@ -448,7 +446,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;
|
||||||
|
|
||||||
|
@ -469,7 +467,7 @@ static inline int compare_guid_key(struct oplock_info *opinfo,
|
||||||
guid2 = opinfo->conn->ClientGUID;
|
guid2 = opinfo->conn->ClientGUID;
|
||||||
key2 = opinfo->o_lease->lease_key;
|
key2 = opinfo->o_lease->lease_key;
|
||||||
if (!memcmp(guid1, guid2, SMB2_CLIENT_GUID_SIZE) &&
|
if (!memcmp(guid1, guid2, SMB2_CLIENT_GUID_SIZE) &&
|
||||||
!memcmp(key1, key2, SMB2_LEASE_KEY_SIZE))
|
!memcmp(key1, key2, SMB2_LEASE_KEY_SIZE))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -485,7 +483,7 @@ 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;
|
||||||
|
@ -649,13 +647,12 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
|
||||||
rsp_hdr->SessionId = 0;
|
rsp_hdr->SessionId = 0;
|
||||||
memset(rsp_hdr->Signature, 0, 16);
|
memset(rsp_hdr->Signature, 0, 16);
|
||||||
|
|
||||||
|
|
||||||
rsp = work->response_buf;
|
rsp = work->response_buf;
|
||||||
|
|
||||||
rsp->StructureSize = cpu_to_le16(24);
|
rsp->StructureSize = cpu_to_le16(24);
|
||||||
if (!br_info->open_trunc &&
|
if (!br_info->open_trunc &&
|
||||||
(br_info->level == SMB2_OPLOCK_LEVEL_BATCH ||
|
(br_info->level == SMB2_OPLOCK_LEVEL_BATCH ||
|
||||||
br_info->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE))
|
br_info->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE))
|
||||||
rsp->OplockLevel = SMB2_OPLOCK_LEVEL_II;
|
rsp->OplockLevel = SMB2_OPLOCK_LEVEL_II;
|
||||||
else
|
else
|
||||||
rsp->OplockLevel = SMB2_OPLOCK_LEVEL_NONE;
|
rsp->OplockLevel = SMB2_OPLOCK_LEVEL_NONE;
|
||||||
|
@ -845,10 +842,8 @@ static void wait_lease_breaking(struct oplock_info *opinfo)
|
||||||
if (atomic_read(&opinfo->breaking_cnt)) {
|
if (atomic_read(&opinfo->breaking_cnt)) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
ret = wait_event_interruptible_timeout(
|
ret = wait_event_interruptible_timeout(opinfo->oplock_brk,
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -907,7 +902,7 @@ static int oplock_break(struct oplock_info *brk_opinfo, int req_op_level)
|
||||||
return err < 0 ? err : 0;
|
return err < 0 ? err : 0;
|
||||||
|
|
||||||
if (brk_opinfo->level == SMB2_OPLOCK_LEVEL_BATCH ||
|
if (brk_opinfo->level == SMB2_OPLOCK_LEVEL_BATCH ||
|
||||||
brk_opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)
|
brk_opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)
|
||||||
brk_opinfo->op_state = OPLOCK_ACK_WAIT;
|
brk_opinfo->op_state = OPLOCK_ACK_WAIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -939,7 +934,7 @@ void destroy_lease_table(struct ksmbd_conn *conn)
|
||||||
|
|
||||||
list_for_each_entry_safe(lb, lbtmp, &lease_table_list, l_entry) {
|
list_for_each_entry_safe(lb, lbtmp, &lease_table_list, l_entry) {
|
||||||
if (conn && memcmp(lb->client_guid, conn->ClientGUID,
|
if (conn && memcmp(lb->client_guid, conn->ClientGUID,
|
||||||
SMB2_CLIENT_GUID_SIZE))
|
SMB2_CLIENT_GUID_SIZE))
|
||||||
continue;
|
continue;
|
||||||
again:
|
again:
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
|
@ -974,7 +969,7 @@ int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci,
|
||||||
|
|
||||||
list_for_each_entry(lb, &lease_table_list, l_entry) {
|
list_for_each_entry(lb, &lease_table_list, l_entry) {
|
||||||
if (!memcmp(lb->client_guid, sess->conn->ClientGUID,
|
if (!memcmp(lb->client_guid, sess->conn->ClientGUID,
|
||||||
SMB2_CLIENT_GUID_SIZE))
|
SMB2_CLIENT_GUID_SIZE))
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
read_unlock(&lease_list_lock);
|
read_unlock(&lease_list_lock);
|
||||||
|
@ -1031,7 +1026,7 @@ static int add_lease_global_list(struct oplock_info *opinfo)
|
||||||
read_lock(&lease_list_lock);
|
read_lock(&lease_list_lock);
|
||||||
list_for_each_entry(lb, &lease_table_list, l_entry) {
|
list_for_each_entry(lb, &lease_table_list, l_entry) {
|
||||||
if (!memcmp(lb->client_guid, opinfo->conn->ClientGUID,
|
if (!memcmp(lb->client_guid, opinfo->conn->ClientGUID,
|
||||||
SMB2_CLIENT_GUID_SIZE)) {
|
SMB2_CLIENT_GUID_SIZE)) {
|
||||||
opinfo->o_lease->l_lb = lb;
|
opinfo->o_lease->l_lb = lb;
|
||||||
lease_add_list(opinfo);
|
lease_add_list(opinfo);
|
||||||
read_unlock(&lease_list_lock);
|
read_unlock(&lease_list_lock);
|
||||||
|
@ -1055,13 +1050,12 @@ 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:
|
||||||
case SMB2_OPLOCK_LEVEL_EXCLUSIVE:
|
case SMB2_OPLOCK_LEVEL_EXCLUSIVE:
|
||||||
grant_write_oplock(opinfo,
|
grant_write_oplock(opinfo, level, lctx);
|
||||||
level, lctx);
|
|
||||||
break;
|
break;
|
||||||
case SMB2_OPLOCK_LEVEL_II:
|
case SMB2_OPLOCK_LEVEL_II:
|
||||||
grant_read_oplock(opinfo, lctx);
|
grant_read_oplock(opinfo, lctx);
|
||||||
|
@ -1084,13 +1078,9 @@ 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 smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid,
|
||||||
int req_op_level,
|
struct ksmbd_file *fp, __u16 tid, struct lease_ctx_info *lctx,
|
||||||
uint64_t pid,
|
int share_ret)
|
||||||
struct ksmbd_file *fp,
|
|
||||||
__u16 tid,
|
|
||||||
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;
|
||||||
|
@ -1150,14 +1140,14 @@ int smb_grant_oplock(struct ksmbd_work *work,
|
||||||
prev_op_state = prev_opinfo->o_lease->state;
|
prev_op_state = prev_opinfo->o_lease->state;
|
||||||
|
|
||||||
if (share_ret < 0 &&
|
if (share_ret < 0 &&
|
||||||
(prev_opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)) {
|
prev_opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE) {
|
||||||
err = share_ret;
|
err = share_ret;
|
||||||
opinfo_put(prev_opinfo);
|
opinfo_put(prev_opinfo);
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((prev_opinfo->level != SMB2_OPLOCK_LEVEL_BATCH) &&
|
if (prev_opinfo->level != SMB2_OPLOCK_LEVEL_BATCH &&
|
||||||
(prev_opinfo->level != SMB2_OPLOCK_LEVEL_EXCLUSIVE)) {
|
prev_opinfo->level != SMB2_OPLOCK_LEVEL_EXCLUSIVE) {
|
||||||
opinfo_put(prev_opinfo);
|
opinfo_put(prev_opinfo);
|
||||||
goto op_break_not_needed;
|
goto op_break_not_needed;
|
||||||
}
|
}
|
||||||
|
@ -1218,7 +1208,7 @@ int smb_grant_oplock(struct ksmbd_work *work,
|
||||||
* @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;
|
||||||
|
|
||||||
|
@ -1226,7 +1216,7 @@ static void smb_break_all_write_oplock(struct ksmbd_work *work,
|
||||||
if (!brk_opinfo)
|
if (!brk_opinfo)
|
||||||
return;
|
return;
|
||||||
if (brk_opinfo->level != SMB2_OPLOCK_LEVEL_BATCH &&
|
if (brk_opinfo->level != SMB2_OPLOCK_LEVEL_BATCH &&
|
||||||
brk_opinfo->level != SMB2_OPLOCK_LEVEL_EXCLUSIVE) {
|
brk_opinfo->level != SMB2_OPLOCK_LEVEL_EXCLUSIVE) {
|
||||||
opinfo_put(brk_opinfo);
|
opinfo_put(brk_opinfo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1244,17 +1234,16 @@ static void smb_break_all_write_oplock(struct ksmbd_work *work,
|
||||||
* @fp: ksmbd file pointer
|
* @fp: ksmbd file pointer
|
||||||
* @is_trunc: truncate on open
|
* @is_trunc: truncate on open
|
||||||
*/
|
*/
|
||||||
void smb_break_all_levII_oplock(struct ksmbd_work *work,
|
void smb_break_all_levII_oplock(struct ksmbd_work *work, struct ksmbd_file *fp,
|
||||||
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;
|
||||||
struct ksmbd_conn *conn = work->sess->conn;
|
struct ksmbd_conn *conn = work->sess->conn;
|
||||||
|
|
||||||
if (!test_share_config_flag(work->tcon->share_conf,
|
if (!test_share_config_flag(work->tcon->share_conf,
|
||||||
KSMBD_SHARE_FLAG_OPLOCKS)) {
|
KSMBD_SHARE_FLAG_OPLOCKS))
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
ci = fp->f_ci;
|
ci = fp->f_ci;
|
||||||
op = opinfo_get(fp);
|
op = opinfo_get(fp);
|
||||||
|
@ -1283,13 +1272,11 @@ void smb_break_all_levII_oplock(struct ksmbd_work *work,
|
||||||
atomic_read(&brk_op->breaking_cnt))
|
atomic_read(&brk_op->breaking_cnt))
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
if (op && op->is_lease &&
|
if (op && op->is_lease && brk_op->is_lease &&
|
||||||
brk_op->is_lease &&
|
!memcmp(conn->ClientGUID, brk_op->conn->ClientGUID,
|
||||||
!memcmp(conn->ClientGUID, brk_op->conn->ClientGUID,
|
SMB2_CLIENT_GUID_SIZE) &&
|
||||||
SMB2_CLIENT_GUID_SIZE) &&
|
!memcmp(op->o_lease->lease_key, brk_op->o_lease->lease_key,
|
||||||
!memcmp(op->o_lease->lease_key,
|
SMB2_LEASE_KEY_SIZE))
|
||||||
brk_op->o_lease->lease_key,
|
|
||||||
SMB2_LEASE_KEY_SIZE))
|
|
||||||
goto next;
|
goto next;
|
||||||
brk_op->open_trunc = is_trunc;
|
brk_op->open_trunc = is_trunc;
|
||||||
oplock_break(brk_op, SMB2_OPLOCK_LEVEL_NONE);
|
oplock_break(brk_op, SMB2_OPLOCK_LEVEL_NONE);
|
||||||
|
@ -1311,7 +1298,7 @@ void smb_break_all_levII_oplock(struct ksmbd_work *work,
|
||||||
void smb_break_all_oplock(struct ksmbd_work *work, struct ksmbd_file *fp)
|
void smb_break_all_oplock(struct ksmbd_work *work, struct ksmbd_file *fp)
|
||||||
{
|
{
|
||||||
if (!test_share_config_flag(work->tcon->share_conf,
|
if (!test_share_config_flag(work->tcon->share_conf,
|
||||||
KSMBD_SHARE_FLAG_OPLOCKS))
|
KSMBD_SHARE_FLAG_OPLOCKS))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
smb_break_all_write_oplock(work, fp, 1);
|
smb_break_all_write_oplock(work, fp, 1);
|
||||||
|
@ -1327,14 +1314,16 @@ void smb_break_all_oplock(struct ksmbd_work *work, struct ksmbd_file *fp)
|
||||||
__u8 smb2_map_lease_to_oplock(__le32 lease_state)
|
__u8 smb2_map_lease_to_oplock(__le32 lease_state)
|
||||||
{
|
{
|
||||||
if (lease_state == (SMB2_LEASE_HANDLE_CACHING_LE |
|
if (lease_state == (SMB2_LEASE_HANDLE_CACHING_LE |
|
||||||
SMB2_LEASE_READ_CACHING_LE | SMB2_LEASE_WRITE_CACHING_LE))
|
SMB2_LEASE_READ_CACHING_LE |
|
||||||
|
SMB2_LEASE_WRITE_CACHING_LE)) {
|
||||||
return SMB2_OPLOCK_LEVEL_BATCH;
|
return SMB2_OPLOCK_LEVEL_BATCH;
|
||||||
else if (lease_state != SMB2_LEASE_WRITE_CACHING_LE &&
|
} else if (lease_state != SMB2_LEASE_WRITE_CACHING_LE &&
|
||||||
lease_state & SMB2_LEASE_WRITE_CACHING_LE) {
|
lease_state & SMB2_LEASE_WRITE_CACHING_LE) {
|
||||||
if (!(lease_state & SMB2_LEASE_HANDLE_CACHING_LE))
|
if (!(lease_state & SMB2_LEASE_HANDLE_CACHING_LE))
|
||||||
return SMB2_OPLOCK_LEVEL_EXCLUSIVE;
|
return SMB2_OPLOCK_LEVEL_EXCLUSIVE;
|
||||||
} else if (lease_state & SMB2_LEASE_READ_CACHING_LE)
|
} else if (lease_state & SMB2_LEASE_READ_CACHING_LE) {
|
||||||
return SMB2_OPLOCK_LEVEL_II;
|
return SMB2_OPLOCK_LEVEL_II;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1390,7 +1379,7 @@ struct lease_ctx_info *parse_lease_state(void *open_req)
|
||||||
cc = (struct create_context *)((char *)cc + next);
|
cc = (struct create_context *)((char *)cc + next);
|
||||||
name = le16_to_cpu(cc->NameOffset) + (char *)cc;
|
name = le16_to_cpu(cc->NameOffset) + (char *)cc;
|
||||||
if (le16_to_cpu(cc->NameLength) != 4 ||
|
if (le16_to_cpu(cc->NameLength) != 4 ||
|
||||||
strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4)) {
|
strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4)) {
|
||||||
next = le32_to_cpu(cc->Next);
|
next = le32_to_cpu(cc->Next);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1603,7 +1592,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;
|
||||||
|
@ -1612,7 +1601,7 @@ struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn,
|
||||||
read_lock(&lease_list_lock);
|
read_lock(&lease_list_lock);
|
||||||
list_for_each_entry(lt, &lease_table_list, l_entry) {
|
list_for_each_entry(lt, &lease_table_list, l_entry) {
|
||||||
if (!memcmp(lt->client_guid, conn->ClientGUID,
|
if (!memcmp(lt->client_guid, conn->ClientGUID,
|
||||||
SMB2_CLIENT_GUID_SIZE))
|
SMB2_CLIENT_GUID_SIZE))
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1625,12 +1614,11 @@ struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn,
|
||||||
if (!atomic_inc_not_zero(&opinfo->refcount))
|
if (!atomic_inc_not_zero(&opinfo->refcount))
|
||||||
continue;
|
continue;
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
if (!opinfo->op_state ||
|
if (!opinfo->op_state || opinfo->op_state == OPLOCK_CLOSING)
|
||||||
opinfo->op_state == OPLOCK_CLOSING)
|
|
||||||
goto op_next;
|
goto op_next;
|
||||||
if (!(opinfo->o_lease->state &
|
if (!(opinfo->o_lease->state &
|
||||||
(SMB2_LEASE_HANDLE_CACHING_LE |
|
(SMB2_LEASE_HANDLE_CACHING_LE |
|
||||||
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);
|
||||||
|
@ -1651,7 +1639,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;
|
||||||
|
@ -1663,7 +1651,7 @@ int smb2_check_durable_oplock(struct ksmbd_file *fp,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (memcmp(opinfo->o_lease->lease_key, lctx->lease_key,
|
if (memcmp(opinfo->o_lease->lease_key, lctx->lease_key,
|
||||||
SMB2_LEASE_KEY_SIZE)) {
|
SMB2_LEASE_KEY_SIZE)) {
|
||||||
ksmbd_err("invalid lease key\n");
|
ksmbd_err("invalid lease key\n");
|
||||||
ret = -EBADF;
|
ret = -EBADF;
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
#include "smb_common.h"
|
#include "smb_common.h"
|
||||||
|
|
||||||
#define OPLOCK_WAIT_TIME (35*HZ)
|
#define OPLOCK_WAIT_TIME (35 * HZ)
|
||||||
|
|
||||||
/* SMB Oplock levels */
|
/* SMB Oplock levels */
|
||||||
#define OPLOCK_NONE 0
|
#define OPLOCK_NONE 0
|
||||||
|
@ -68,7 +68,7 @@ struct oplock_info {
|
||||||
int level;
|
int level;
|
||||||
int op_state;
|
int op_state;
|
||||||
unsigned long pending_break;
|
unsigned long pending_break;
|
||||||
uint64_t fid;
|
u64 fid;
|
||||||
atomic_t breaking_cnt;
|
atomic_t breaking_cnt;
|
||||||
atomic_t refcount;
|
atomic_t refcount;
|
||||||
__u16 Tid;
|
__u16 Tid;
|
||||||
|
@ -95,11 +95,11 @@ struct oplock_break_info {
|
||||||
int fid;
|
int fid;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int smb_grant_oplock(struct ksmbd_work *work, int req_op_level,
|
int smb_grant_oplock(struct ksmbd_work *work, int req_op_level,
|
||||||
uint64_t 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);
|
||||||
extern 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);
|
||||||
|
@ -124,15 +124,13 @@ 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);
|
||||||
int ksmbd_durable_verify_and_del_oplock(struct ksmbd_session *curr_sess,
|
int ksmbd_durable_verify_and_del_oplock(struct ksmbd_session *curr_sess,
|
||||||
struct ksmbd_session *prev_sess,
|
struct ksmbd_session *prev_sess, int fid, struct file **filp,
|
||||||
int fid, struct file **filp,
|
u64 sess_id);
|
||||||
uint64_t sess_id);
|
|
||||||
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 */
|
||||||
|
|
|
@ -105,9 +105,8 @@ static inline int check_conn_state(struct ksmbd_work *work)
|
||||||
#define TCP_HANDLER_CONTINUE 0
|
#define TCP_HANDLER_CONTINUE 0
|
||||||
#define TCP_HANDLER_ABORT 1
|
#define TCP_HANDLER_ABORT 1
|
||||||
|
|
||||||
static int __process_request(struct ksmbd_work *work,
|
static int __process_request(struct ksmbd_work *work, struct ksmbd_conn *conn,
|
||||||
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;
|
||||||
|
@ -160,16 +159,16 @@ static int __process_request(struct ksmbd_work *work,
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
uint16_t command = 0;
|
u16 command = 0;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (conn->ops->allocate_rsp_buf(work))
|
if (conn->ops->allocate_rsp_buf(work))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (conn->ops->is_transform_hdr &&
|
if (conn->ops->is_transform_hdr &&
|
||||||
conn->ops->is_transform_hdr(work->request_buf)) {
|
conn->ops->is_transform_hdr(work->request_buf)) {
|
||||||
rc = conn->ops->decrypt_req(work);
|
rc = conn->ops->decrypt_req(work);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
|
conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
|
||||||
|
@ -224,7 +223,7 @@ static void __handle_ksmbd_work(struct ksmbd_work *work,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (work->sess && (work->sess->sign ||
|
if (work->sess && (work->sess->sign ||
|
||||||
smb3_11_final_sess_setup_resp(work) ||
|
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));
|
||||||
|
@ -235,7 +234,7 @@ static void __handle_ksmbd_work(struct ksmbd_work *work,
|
||||||
send:
|
send:
|
||||||
smb3_preauth_hash_rsp(work);
|
smb3_preauth_hash_rsp(work);
|
||||||
if (work->sess && work->sess->enc && work->encrypted &&
|
if (work->sess && work->sess->enc && work->encrypted &&
|
||||||
conn->ops->encrypt_resp) {
|
conn->ops->encrypt_resp) {
|
||||||
rc = conn->ops->encrypt_resp(work);
|
rc = conn->ops->encrypt_resp(work);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
|
conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
|
||||||
|
@ -416,9 +415,8 @@ int server_queue_ctrl_reset_work(void)
|
||||||
return __queue_ctrl_work(SERVER_CTRL_TYPE_RESET);
|
return __queue_ctrl_work(SERVER_CTRL_TYPE_RESET);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t stats_show(struct class *class,
|
static ssize_t stats_show(struct class *class, struct class_attribute *attr,
|
||||||
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,
|
||||||
|
@ -443,9 +441,8 @@ static ssize_t stats_show(struct class *class,
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t kill_server_store(struct class *class,
|
static ssize_t kill_server_store(struct class *class,
|
||||||
struct class_attribute *attr,
|
struct class_attribute *attr, const char *buf,
|
||||||
const char *buf,
|
size_t len)
|
||||||
size_t len)
|
|
||||||
{
|
{
|
||||||
if (!sysfs_streq(buf, "hard"))
|
if (!sysfs_streq(buf, "hard"))
|
||||||
return len;
|
return len;
|
||||||
|
@ -464,8 +461,7 @@ 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,
|
static ssize_t debug_show(struct class *class, struct class_attribute *attr,
|
||||||
struct class_attribute *attr,
|
|
||||||
char *buf)
|
char *buf)
|
||||||
{
|
{
|
||||||
ssize_t sz = 0;
|
ssize_t sz = 0;
|
||||||
|
@ -484,16 +480,13 @@ static ssize_t debug_show(struct class *class,
|
||||||
debug_type_strings[i]);
|
debug_type_strings[i]);
|
||||||
}
|
}
|
||||||
sz += pos;
|
sz += pos;
|
||||||
|
|
||||||
}
|
}
|
||||||
sz += scnprintf(buf + sz, PAGE_SIZE - sz, "\n");
|
sz += scnprintf(buf + sz, PAGE_SIZE - sz, "\n");
|
||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t debug_store(struct class *class,
|
static ssize_t debug_store(struct class *class, struct class_attribute *attr,
|
||||||
struct class_attribute *attr,
|
const char *buf, size_t len)
|
||||||
const char *buf,
|
|
||||||
size_t len)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
|
@ -90,8 +90,7 @@ static char *smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
|
||||||
|
|
||||||
/* error reqeusts do not have data area */
|
/* error reqeusts do not have data area */
|
||||||
if (hdr->Status && hdr->Status != STATUS_MORE_PROCESSING_REQUIRED &&
|
if (hdr->Status && hdr->Status != STATUS_MORE_PROCESSING_REQUIRED &&
|
||||||
(((struct smb2_err_rsp *)hdr)->StructureSize) ==
|
(((struct smb2_err_rsp *)hdr)->StructureSize) == SMB2_ERROR_STRUCTURE_SIZE2_LE)
|
||||||
SMB2_ERROR_STRUCTURE_SIZE2_LE)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -101,16 +100,12 @@ static char *smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
|
||||||
*/
|
*/
|
||||||
switch (hdr->Command) {
|
switch (hdr->Command) {
|
||||||
case SMB2_SESSION_SETUP:
|
case SMB2_SESSION_SETUP:
|
||||||
*off = le16_to_cpu(
|
*off = le16_to_cpu(((struct smb2_sess_setup_req *)hdr)->SecurityBufferOffset);
|
||||||
((struct smb2_sess_setup_req *)hdr)->SecurityBufferOffset);
|
*len = le16_to_cpu(((struct smb2_sess_setup_req *)hdr)->SecurityBufferLength);
|
||||||
*len = le16_to_cpu(
|
|
||||||
((struct smb2_sess_setup_req *)hdr)->SecurityBufferLength);
|
|
||||||
break;
|
break;
|
||||||
case SMB2_TREE_CONNECT:
|
case SMB2_TREE_CONNECT:
|
||||||
*off = le16_to_cpu(
|
*off = le16_to_cpu(((struct smb2_tree_connect_req *)hdr)->PathOffset);
|
||||||
((struct smb2_tree_connect_req *)hdr)->PathOffset);
|
*len = le16_to_cpu(((struct smb2_tree_connect_req *)hdr)->PathLength);
|
||||||
*len = le16_to_cpu(
|
|
||||||
((struct smb2_tree_connect_req *)hdr)->PathLength);
|
|
||||||
break;
|
break;
|
||||||
case SMB2_CREATE:
|
case SMB2_CREATE:
|
||||||
{
|
{
|
||||||
|
@ -122,49 +117,35 @@ static char *smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
*off = le16_to_cpu(
|
*off = le16_to_cpu(((struct smb2_create_req *)hdr)->NameOffset);
|
||||||
((struct smb2_create_req *)hdr)->NameOffset);
|
*len = le16_to_cpu(((struct smb2_create_req *)hdr)->NameLength);
|
||||||
*len = le16_to_cpu(
|
|
||||||
((struct smb2_create_req *)hdr)->NameLength);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SMB2_QUERY_INFO:
|
case SMB2_QUERY_INFO:
|
||||||
*off = le16_to_cpu(
|
*off = le16_to_cpu(((struct smb2_query_info_req *)hdr)->InputBufferOffset);
|
||||||
((struct smb2_query_info_req *)hdr)->InputBufferOffset);
|
*len = le32_to_cpu(((struct smb2_query_info_req *)hdr)->InputBufferLength);
|
||||||
*len = le32_to_cpu(
|
|
||||||
((struct smb2_query_info_req *)hdr)->InputBufferLength);
|
|
||||||
break;
|
break;
|
||||||
case SMB2_SET_INFO:
|
case SMB2_SET_INFO:
|
||||||
*off = le16_to_cpu(
|
*off = le16_to_cpu(((struct smb2_set_info_req *)hdr)->BufferOffset);
|
||||||
((struct smb2_set_info_req *)hdr)->BufferOffset);
|
*len = le32_to_cpu(((struct smb2_set_info_req *)hdr)->BufferLength);
|
||||||
*len = le32_to_cpu(
|
|
||||||
((struct smb2_set_info_req *)hdr)->BufferLength);
|
|
||||||
break;
|
break;
|
||||||
case SMB2_READ:
|
case SMB2_READ:
|
||||||
*off = le16_to_cpu(
|
*off = le16_to_cpu(((struct smb2_read_req *)hdr)->ReadChannelInfoOffset);
|
||||||
((struct smb2_read_req *)hdr)->ReadChannelInfoOffset);
|
*len = le16_to_cpu(((struct smb2_read_req *)hdr)->ReadChannelInfoLength);
|
||||||
*len = le16_to_cpu(
|
|
||||||
((struct smb2_read_req *)hdr)->ReadChannelInfoLength);
|
|
||||||
break;
|
break;
|
||||||
case SMB2_WRITE:
|
case SMB2_WRITE:
|
||||||
if (((struct smb2_write_req *)hdr)->DataOffset) {
|
if (((struct smb2_write_req *)hdr)->DataOffset) {
|
||||||
*off = le16_to_cpu(
|
*off = le16_to_cpu(((struct smb2_write_req *)hdr)->DataOffset);
|
||||||
((struct smb2_write_req *)hdr)->DataOffset);
|
*len = le32_to_cpu(((struct smb2_write_req *)hdr)->Length);
|
||||||
*len = le32_to_cpu(
|
|
||||||
((struct smb2_write_req *)hdr)->Length);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
*off = le16_to_cpu(
|
*off = le16_to_cpu(((struct smb2_write_req *)hdr)->WriteChannelInfoOffset);
|
||||||
((struct smb2_write_req *)hdr)->WriteChannelInfoOffset);
|
*len = le16_to_cpu(((struct smb2_write_req *)hdr)->WriteChannelInfoLength);
|
||||||
*len = le16_to_cpu(
|
|
||||||
((struct smb2_write_req *)hdr)->WriteChannelInfoLength);
|
|
||||||
break;
|
break;
|
||||||
case SMB2_QUERY_DIRECTORY:
|
case SMB2_QUERY_DIRECTORY:
|
||||||
*off = le16_to_cpu(
|
*off = le16_to_cpu(((struct smb2_query_directory_req *)hdr)->FileNameOffset);
|
||||||
((struct smb2_query_directory_req *)hdr)->FileNameOffset);
|
*len = le16_to_cpu(((struct smb2_query_directory_req *)hdr)->FileNameLength);
|
||||||
*len = le16_to_cpu(
|
|
||||||
((struct smb2_query_directory_req *)hdr)->FileNameLength);
|
|
||||||
break;
|
break;
|
||||||
case SMB2_LOCK:
|
case SMB2_LOCK:
|
||||||
{
|
{
|
||||||
|
@ -174,8 +155,7 @@ static char *smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
|
||||||
* smb2_lock request size is 48 included single
|
* smb2_lock request size is 48 included single
|
||||||
* smb2_lock_element structure size.
|
* smb2_lock_element structure size.
|
||||||
*/
|
*/
|
||||||
lock_count = le16_to_cpu(
|
lock_count = le16_to_cpu(((struct smb2_lock_req *)hdr)->LockCount) - 1;
|
||||||
((struct smb2_lock_req *)hdr)->LockCount) - 1;
|
|
||||||
if (lock_count > 0) {
|
if (lock_count > 0) {
|
||||||
*off = __SMB2_HEADER_STRUCTURE_SIZE + 48;
|
*off = __SMB2_HEADER_STRUCTURE_SIZE + 48;
|
||||||
*len = sizeof(struct smb2_lock_element) * lock_count;
|
*len = sizeof(struct smb2_lock_element) * lock_count;
|
||||||
|
@ -183,8 +163,7 @@ static char *smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SMB2_IOCTL:
|
case SMB2_IOCTL:
|
||||||
*off = le32_to_cpu(
|
*off = le32_to_cpu(((struct smb2_ioctl_req *)hdr)->InputOffset);
|
||||||
((struct smb2_ioctl_req *)hdr)->InputOffset);
|
|
||||||
*len = le32_to_cpu(((struct smb2_ioctl_req *)hdr)->InputCount);
|
*len = le32_to_cpu(((struct smb2_ioctl_req *)hdr)->InputCount);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -366,9 +345,9 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
|
||||||
hdr = &pdu->hdr;
|
hdr = &pdu->hdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (le32_to_cpu(hdr->NextCommand) > 0)
|
if (le32_to_cpu(hdr->NextCommand) > 0) {
|
||||||
len = le32_to_cpu(hdr->NextCommand);
|
len = le32_to_cpu(hdr->NextCommand);
|
||||||
else if (work->next_smb2_rcv_hdr_off) {
|
} else if (work->next_smb2_rcv_hdr_off) {
|
||||||
len -= work->next_smb2_rcv_hdr_off;
|
len -= work->next_smb2_rcv_hdr_off;
|
||||||
len = round_up(len, 8);
|
len = round_up(len, 8);
|
||||||
}
|
}
|
||||||
|
@ -389,19 +368,17 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (smb2_req_struct_sizes[command] != pdu->StructureSize2) {
|
if (smb2_req_struct_sizes[command] != pdu->StructureSize2) {
|
||||||
if (command != SMB2_OPLOCK_BREAK_HE && (hdr->Status == 0 ||
|
if (command != SMB2_OPLOCK_BREAK_HE &&
|
||||||
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 &&
|
||||||
&& (le16_to_cpu(pdu->StructureSize2) !=
|
le16_to_cpu(pdu->StructureSize2) != OP_BREAK_STRUCT_SIZE_20 &&
|
||||||
OP_BREAK_STRUCT_SIZE_20)
|
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",
|
||||||
|
|
|
@ -248,7 +248,7 @@ void init_smb3_02_server(struct ksmbd_conn *conn)
|
||||||
conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING;
|
conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING;
|
||||||
|
|
||||||
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION &&
|
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION &&
|
||||||
conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION)
|
conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION)
|
||||||
conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
|
conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -346,8 +346,8 @@ struct smb2_negotiate_rsp {
|
||||||
#define SMB2_SESSION_REQ_FLAG_ENCRYPT_DATA 0x04
|
#define SMB2_SESSION_REQ_FLAG_ENCRYPT_DATA 0x04
|
||||||
|
|
||||||
#define SMB2_SESSION_EXPIRED (0)
|
#define SMB2_SESSION_EXPIRED (0)
|
||||||
#define SMB2_SESSION_IN_PROGRESS (1 << 0)
|
#define SMB2_SESSION_IN_PROGRESS BIT(0)
|
||||||
#define SMB2_SESSION_VALID (1 << 1)
|
#define SMB2_SESSION_VALID BIT(1)
|
||||||
|
|
||||||
/* Flags */
|
/* Flags */
|
||||||
#define SMB2_SESSION_REQ_FLAG_BINDING 0x01
|
#define SMB2_SESSION_REQ_FLAG_BINDING 0x01
|
||||||
|
@ -1161,7 +1161,6 @@ struct smb2_set_info_rsp {
|
||||||
__le16 StructureSize; /* Must be 2 */
|
__le16 StructureSize; /* Must be 2 */
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
|
||||||
/* FILE Info response size */
|
/* FILE Info response size */
|
||||||
#define FILE_DIRECTORY_INFORMATION_SIZE 1
|
#define FILE_DIRECTORY_INFORMATION_SIZE 1
|
||||||
#define FILE_FULL_DIRECTORY_INFORMATION_SIZE 2
|
#define FILE_FULL_DIRECTORY_INFORMATION_SIZE 2
|
||||||
|
@ -1199,7 +1198,6 @@ struct smb2_set_info_rsp {
|
||||||
#define FILE_NETWORK_OPEN_INFORMATION_SIZE 56
|
#define FILE_NETWORK_OPEN_INFORMATION_SIZE 56
|
||||||
#define FILE_ATTRIBUTE_TAG_INFORMATION_SIZE 8
|
#define FILE_ATTRIBUTE_TAG_INFORMATION_SIZE 8
|
||||||
|
|
||||||
|
|
||||||
/* FS Info response size */
|
/* FS Info response size */
|
||||||
#define FS_DEVICE_INFORMATION_SIZE 8
|
#define FS_DEVICE_INFORMATION_SIZE 8
|
||||||
#define FS_ATTRIBUTE_INFORMATION_SIZE 16
|
#define FS_ATTRIBUTE_INFORMATION_SIZE 16
|
||||||
|
@ -1579,71 +1577,70 @@ struct smb2_posix_info {
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
/* functions */
|
/* functions */
|
||||||
|
int init_smb2_0_server(struct ksmbd_conn *conn);
|
||||||
|
void init_smb2_1_server(struct ksmbd_conn *conn);
|
||||||
|
void init_smb3_0_server(struct ksmbd_conn *conn);
|
||||||
|
void init_smb3_02_server(struct ksmbd_conn *conn);
|
||||||
|
int init_smb3_11_server(struct ksmbd_conn *conn);
|
||||||
|
|
||||||
extern int init_smb2_0_server(struct ksmbd_conn *conn);
|
void init_smb2_max_read_size(unsigned int sz);
|
||||||
extern void init_smb2_1_server(struct ksmbd_conn *conn);
|
void init_smb2_max_write_size(unsigned int sz);
|
||||||
extern void init_smb3_0_server(struct ksmbd_conn *conn);
|
void init_smb2_max_trans_size(unsigned int sz);
|
||||||
extern void init_smb3_02_server(struct ksmbd_conn *conn);
|
|
||||||
extern int init_smb3_11_server(struct ksmbd_conn *conn);
|
|
||||||
|
|
||||||
extern void init_smb2_max_read_size(unsigned int sz);
|
int is_smb2_neg_cmd(struct ksmbd_work *work);
|
||||||
extern void init_smb2_max_write_size(unsigned int sz);
|
int is_smb2_rsp(struct ksmbd_work *work);
|
||||||
extern void init_smb2_max_trans_size(unsigned int sz);
|
|
||||||
|
|
||||||
extern int is_smb2_neg_cmd(struct ksmbd_work *work);
|
u16 get_smb2_cmd_val(struct ksmbd_work *work);
|
||||||
extern int is_smb2_rsp(struct ksmbd_work *work);
|
void set_smb2_rsp_status(struct ksmbd_work *work, __le32 err);
|
||||||
|
int init_smb2_rsp_hdr(struct ksmbd_work *work);
|
||||||
extern uint16_t get_smb2_cmd_val(struct ksmbd_work *work);
|
int smb2_allocate_rsp_buf(struct ksmbd_work *work);
|
||||||
extern void set_smb2_rsp_status(struct ksmbd_work *work, __le32 err);
|
bool is_chained_smb2_message(struct ksmbd_work *work);
|
||||||
extern int init_smb2_rsp_hdr(struct ksmbd_work *work);
|
int init_smb2_neg_rsp(struct ksmbd_work *work);
|
||||||
extern int smb2_allocate_rsp_buf(struct ksmbd_work *work);
|
void smb2_set_err_rsp(struct ksmbd_work *work);
|
||||||
extern bool is_chained_smb2_message(struct ksmbd_work *work);
|
int smb2_check_user_session(struct ksmbd_work *work);
|
||||||
extern int init_smb2_neg_rsp(struct ksmbd_work *work);
|
int smb2_get_ksmbd_tcon(struct ksmbd_work *work);
|
||||||
extern void smb2_set_err_rsp(struct ksmbd_work *work);
|
bool smb2_is_sign_req(struct ksmbd_work *work, unsigned int command);
|
||||||
extern int smb2_check_user_session(struct ksmbd_work *work);
|
int smb2_check_sign_req(struct ksmbd_work *work);
|
||||||
extern int smb2_get_ksmbd_tcon(struct ksmbd_work *work);
|
void smb2_set_sign_rsp(struct ksmbd_work *work);
|
||||||
extern bool smb2_is_sign_req(struct ksmbd_work *work, unsigned int command);
|
int smb3_check_sign_req(struct ksmbd_work *work);
|
||||||
extern int smb2_check_sign_req(struct ksmbd_work *work);
|
void smb3_set_sign_rsp(struct ksmbd_work *work);
|
||||||
extern void smb2_set_sign_rsp(struct ksmbd_work *work);
|
int find_matching_smb2_dialect(int start_index, __le16 *cli_dialects,
|
||||||
extern int smb3_check_sign_req(struct ksmbd_work *work);
|
__le16 dialects_count);
|
||||||
extern void smb3_set_sign_rsp(struct ksmbd_work *work);
|
struct file_lock *smb_flock_init(struct file *f);
|
||||||
extern int find_matching_smb2_dialect(int start_index, __le16 *cli_dialects,
|
int setup_async_work(struct ksmbd_work *work, void (*fn)(void **),
|
||||||
__le16 dialects_count);
|
void **arg);
|
||||||
extern struct file_lock *smb_flock_init(struct file *f);
|
void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status);
|
||||||
extern int setup_async_work(struct ksmbd_work *work, void (*fn)(void **),
|
struct channel *lookup_chann_list(struct ksmbd_session *sess);
|
||||||
void **arg);
|
void smb3_preauth_hash_rsp(struct ksmbd_work *work);
|
||||||
extern void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status);
|
int smb3_is_transform_hdr(void *buf);
|
||||||
extern struct channel *lookup_chann_list(struct ksmbd_session *sess);
|
int smb3_decrypt_req(struct ksmbd_work *work);
|
||||||
extern void smb3_preauth_hash_rsp(struct ksmbd_work *work);
|
int smb3_encrypt_resp(struct ksmbd_work *work);
|
||||||
extern int smb3_is_transform_hdr(void *buf);
|
bool smb3_11_final_sess_setup_resp(struct ksmbd_work *work);
|
||||||
extern int smb3_decrypt_req(struct ksmbd_work *work);
|
int smb2_set_rsp_credits(struct ksmbd_work *work);
|
||||||
extern int smb3_encrypt_resp(struct ksmbd_work *work);
|
|
||||||
extern bool smb3_11_final_sess_setup_resp(struct ksmbd_work *work);
|
|
||||||
extern int smb2_set_rsp_credits(struct ksmbd_work *work);
|
|
||||||
|
|
||||||
/* smb2 misc functions */
|
/* smb2 misc functions */
|
||||||
extern int ksmbd_smb2_check_message(struct ksmbd_work *work);
|
int ksmbd_smb2_check_message(struct ksmbd_work *work);
|
||||||
|
|
||||||
/* smb2 command handlers */
|
/* smb2 command handlers */
|
||||||
extern int smb2_handle_negotiate(struct ksmbd_work *work);
|
int smb2_handle_negotiate(struct ksmbd_work *work);
|
||||||
extern int smb2_negotiate_request(struct ksmbd_work *work);
|
int smb2_negotiate_request(struct ksmbd_work *work);
|
||||||
extern int smb2_sess_setup(struct ksmbd_work *work);
|
int smb2_sess_setup(struct ksmbd_work *work);
|
||||||
extern int smb2_tree_connect(struct ksmbd_work *work);
|
int smb2_tree_connect(struct ksmbd_work *work);
|
||||||
extern int smb2_tree_disconnect(struct ksmbd_work *work);
|
int smb2_tree_disconnect(struct ksmbd_work *work);
|
||||||
extern int smb2_session_logoff(struct ksmbd_work *work);
|
int smb2_session_logoff(struct ksmbd_work *work);
|
||||||
extern int smb2_open(struct ksmbd_work *work);
|
int smb2_open(struct ksmbd_work *work);
|
||||||
extern int smb2_query_info(struct ksmbd_work *work);
|
int smb2_query_info(struct ksmbd_work *work);
|
||||||
extern int smb2_query_dir(struct ksmbd_work *work);
|
int smb2_query_dir(struct ksmbd_work *work);
|
||||||
extern int smb2_close(struct ksmbd_work *work);
|
int smb2_close(struct ksmbd_work *work);
|
||||||
extern int smb2_echo(struct ksmbd_work *work);
|
int smb2_echo(struct ksmbd_work *work);
|
||||||
extern int smb2_set_info(struct ksmbd_work *work);
|
int smb2_set_info(struct ksmbd_work *work);
|
||||||
extern int smb2_read(struct ksmbd_work *work);
|
int smb2_read(struct ksmbd_work *work);
|
||||||
extern int smb2_write(struct ksmbd_work *work);
|
int smb2_write(struct ksmbd_work *work);
|
||||||
extern int smb2_flush(struct ksmbd_work *work);
|
int smb2_flush(struct ksmbd_work *work);
|
||||||
extern int smb2_cancel(struct ksmbd_work *work);
|
int smb2_cancel(struct ksmbd_work *work);
|
||||||
extern int smb2_lock(struct ksmbd_work *work);
|
int smb2_lock(struct ksmbd_work *work);
|
||||||
extern int smb2_ioctl(struct ksmbd_work *work);
|
int smb2_ioctl(struct ksmbd_work *work);
|
||||||
extern int smb2_oplock_break(struct ksmbd_work *work);
|
int smb2_oplock_break(struct ksmbd_work *work);
|
||||||
extern int smb2_notify(struct ksmbd_work *ksmbd_work);
|
int smb2_notify(struct ksmbd_work *ksmbd_work);
|
||||||
|
|
||||||
#endif /* _SMB2PDU_H */
|
#endif /* _SMB2PDU_H */
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
/*for shortname implementation */
|
/*for shortname implementation */
|
||||||
static const char basechars[43] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-!@#$%";
|
static const char basechars[43] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-!@#$%";
|
||||||
#define MANGLE_BASE (sizeof(basechars)/sizeof(char)-1)
|
#define MANGLE_BASE (sizeof(basechars) / sizeof(char) - 1)
|
||||||
#define MAGIC_CHAR '~'
|
#define MAGIC_CHAR '~'
|
||||||
#define PERIOD '.'
|
#define PERIOD '.'
|
||||||
#define mangle(V) ((char)(basechars[(V) % MANGLE_BASE]))
|
#define mangle(V) ((char)(basechars[(V) % MANGLE_BASE]))
|
||||||
|
@ -268,15 +268,10 @@ bool ksmbd_pdu_size_has_room(unsigned int pdu)
|
||||||
return (pdu >= KSMBD_MIN_SUPPORTED_HEADER_SIZE - 4);
|
return (pdu >= KSMBD_MIN_SUPPORTED_HEADER_SIZE - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work,
|
int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level,
|
||||||
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;
|
||||||
|
@ -295,7 +290,7 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!match_pattern(d_info->name, d_info->name_len,
|
if (!match_pattern(d_info->name, d_info->name_len,
|
||||||
search_pattern)) {
|
search_pattern)) {
|
||||||
dir->dot_dotdot[i] = 1;
|
dir->dot_dotdot[i] = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -331,9 +326,8 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work,
|
||||||
* TODO: Though this function comforms the restriction of 8.3 Filename spec,
|
* TODO: Though this function comforms the restriction of 8.3 Filename spec,
|
||||||
* 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,
|
int ksmbd_extract_shortname(struct ksmbd_conn *conn, const char *longname,
|
||||||
const char *longname,
|
char *shortname)
|
||||||
char *shortname)
|
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
char base[9], extension[4];
|
char base[9], extension[4];
|
||||||
|
@ -354,7 +348,7 @@ int ksmbd_extract_shortname(struct ksmbd_conn *conn,
|
||||||
if (p == longname) { /*name starts with a dot*/
|
if (p == longname) { /*name starts with a dot*/
|
||||||
strscpy(extension, "___", strlen("___"));
|
strscpy(extension, "___", strlen("___"));
|
||||||
} else {
|
} else {
|
||||||
if (p != NULL) {
|
if (p) {
|
||||||
p++;
|
p++;
|
||||||
while (*p && extlen < 3) {
|
while (*p && extlen < 3) {
|
||||||
if (*p != '.')
|
if (*p != '.')
|
||||||
|
@ -362,8 +356,9 @@ int ksmbd_extract_shortname(struct ksmbd_conn *conn,
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
extension[extlen] = '\0';
|
extension[extlen] = '\0';
|
||||||
} else
|
} else {
|
||||||
dot_present = false;
|
dot_present = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p = longname;
|
p = longname;
|
||||||
|
@ -378,7 +373,7 @@ int ksmbd_extract_shortname(struct ksmbd_conn *conn,
|
||||||
}
|
}
|
||||||
|
|
||||||
base[baselen] = MAGIC_CHAR;
|
base[baselen] = MAGIC_CHAR;
|
||||||
memcpy(out, base, baselen+1);
|
memcpy(out, base, baselen + 1);
|
||||||
|
|
||||||
ptr = longname;
|
ptr = longname;
|
||||||
len = strlen(longname);
|
len = strlen(longname);
|
||||||
|
@ -386,14 +381,14 @@ int ksmbd_extract_shortname(struct ksmbd_conn *conn,
|
||||||
csum += *ptr;
|
csum += *ptr;
|
||||||
|
|
||||||
csum = csum % (MANGLE_BASE * MANGLE_BASE);
|
csum = csum % (MANGLE_BASE * MANGLE_BASE);
|
||||||
out[baselen+1] = mangle(csum/MANGLE_BASE);
|
out[baselen + 1] = mangle(csum / MANGLE_BASE);
|
||||||
out[baselen+2] = mangle(csum);
|
out[baselen + 2] = mangle(csum);
|
||||||
out[baselen+3] = PERIOD;
|
out[baselen + 3] = PERIOD;
|
||||||
|
|
||||||
if (dot_present)
|
if (dot_present)
|
||||||
memcpy(&out[baselen+4], extension, 4);
|
memcpy(&out[baselen + 4], extension, 4);
|
||||||
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;
|
||||||
|
@ -471,9 +466,8 @@ static const char * const shared_mode_errors[] = {
|
||||||
"Desired access mode does not permit FILE_DELETE",
|
"Desired access mode does not permit FILE_DELETE",
|
||||||
};
|
};
|
||||||
|
|
||||||
static void smb_shared_mode_error(int error,
|
static void smb_shared_mode_error(int error, struct ksmbd_file *prev_fp,
|
||||||
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",
|
||||||
|
@ -512,7 +506,7 @@ int ksmbd_smb_check_shared_mode(struct file *filp, struct ksmbd_file *curr_fp)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!(prev_fp->saccess & FILE_SHARE_DELETE_LE) &&
|
if (!(prev_fp->saccess & FILE_SHARE_DELETE_LE) &&
|
||||||
curr_fp->daccess & FILE_DELETE_LE) {
|
curr_fp->daccess & FILE_DELETE_LE) {
|
||||||
smb_shared_mode_error(SHARE_DELETE_ERROR,
|
smb_shared_mode_error(SHARE_DELETE_ERROR,
|
||||||
prev_fp,
|
prev_fp,
|
||||||
curr_fp);
|
curr_fp);
|
||||||
|
@ -528,8 +522,7 @@ int ksmbd_smb_check_shared_mode(struct file *filp, struct ksmbd_file *curr_fp)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!(prev_fp->saccess & FILE_SHARE_READ_LE) &&
|
if (!(prev_fp->saccess & FILE_SHARE_READ_LE) &&
|
||||||
curr_fp->daccess & (FILE_EXECUTE_LE |
|
curr_fp->daccess & (FILE_EXECUTE_LE | FILE_READ_DATA_LE)) {
|
||||||
FILE_READ_DATA_LE)) {
|
|
||||||
smb_shared_mode_error(SHARE_READ_ERROR,
|
smb_shared_mode_error(SHARE_READ_ERROR,
|
||||||
prev_fp,
|
prev_fp,
|
||||||
curr_fp);
|
curr_fp);
|
||||||
|
@ -538,8 +531,7 @@ int ksmbd_smb_check_shared_mode(struct file *filp, struct ksmbd_file *curr_fp)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(prev_fp->saccess & FILE_SHARE_WRITE_LE) &&
|
if (!(prev_fp->saccess & FILE_SHARE_WRITE_LE) &&
|
||||||
curr_fp->daccess & (FILE_WRITE_DATA_LE |
|
curr_fp->daccess & (FILE_WRITE_DATA_LE | FILE_APPEND_DATA_LE)) {
|
||||||
FILE_APPEND_DATA_LE)) {
|
|
||||||
smb_shared_mode_error(SHARE_WRITE_ERROR,
|
smb_shared_mode_error(SHARE_WRITE_ERROR,
|
||||||
prev_fp,
|
prev_fp,
|
||||||
curr_fp);
|
curr_fp);
|
||||||
|
@ -547,9 +539,8 @@ int ksmbd_smb_check_shared_mode(struct file *filp, struct ksmbd_file *curr_fp)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prev_fp->daccess & (FILE_EXECUTE_LE |
|
if (prev_fp->daccess & (FILE_EXECUTE_LE | FILE_READ_DATA_LE) &&
|
||||||
FILE_READ_DATA_LE) &&
|
!(curr_fp->saccess & FILE_SHARE_READ_LE)) {
|
||||||
!(curr_fp->saccess & FILE_SHARE_READ_LE)) {
|
|
||||||
smb_shared_mode_error(FILE_READ_ERROR,
|
smb_shared_mode_error(FILE_READ_ERROR,
|
||||||
prev_fp,
|
prev_fp,
|
||||||
curr_fp);
|
curr_fp);
|
||||||
|
@ -557,9 +548,8 @@ int ksmbd_smb_check_shared_mode(struct file *filp, struct ksmbd_file *curr_fp)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prev_fp->daccess & (FILE_WRITE_DATA_LE |
|
if (prev_fp->daccess & (FILE_WRITE_DATA_LE | FILE_APPEND_DATA_LE) &&
|
||||||
FILE_APPEND_DATA_LE) &&
|
!(curr_fp->saccess & FILE_SHARE_WRITE_LE)) {
|
||||||
!(curr_fp->saccess & FILE_SHARE_WRITE_LE)) {
|
|
||||||
smb_shared_mode_error(FILE_WRITE_ERROR,
|
smb_shared_mode_error(FILE_WRITE_ERROR,
|
||||||
prev_fp,
|
prev_fp,
|
||||||
curr_fp);
|
curr_fp);
|
||||||
|
@ -568,7 +558,7 @@ int ksmbd_smb_check_shared_mode(struct file *filp, struct ksmbd_file *curr_fp)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prev_fp->daccess & FILE_DELETE_LE &&
|
if (prev_fp->daccess & FILE_DELETE_LE &&
|
||||||
!(curr_fp->saccess & FILE_SHARE_DELETE_LE)) {
|
!(curr_fp->saccess & FILE_SHARE_DELETE_LE)) {
|
||||||
smb_shared_mode_error(FILE_DELETE_ERROR,
|
smb_shared_mode_error(FILE_DELETE_ERROR,
|
||||||
prev_fp,
|
prev_fp,
|
||||||
curr_fp);
|
curr_fp);
|
||||||
|
@ -620,7 +610,7 @@ int ksmbd_override_fsids(struct ksmbd_work *work)
|
||||||
if (!uid_eq(cred->fsuid, GLOBAL_ROOT_UID))
|
if (!uid_eq(cred->fsuid, GLOBAL_ROOT_UID))
|
||||||
cred->cap_effective = cap_drop_fs_set(cred->cap_effective);
|
cred->cap_effective = cap_drop_fs_set(cred->cap_effective);
|
||||||
|
|
||||||
WARN_ON(work->saved_cred != NULL);
|
WARN_ON(work->saved_cred);
|
||||||
work->saved_cred = override_creds(cred);
|
work->saved_cred = override_creds(cred);
|
||||||
if (!work->saved_cred) {
|
if (!work->saved_cred) {
|
||||||
abort_creds(cred);
|
abort_creds(cred);
|
||||||
|
@ -633,7 +623,7 @@ void ksmbd_revert_fsids(struct ksmbd_work *work)
|
||||||
{
|
{
|
||||||
const struct cred *cred;
|
const struct cred *cred;
|
||||||
|
|
||||||
WARN_ON(work->saved_cred == NULL);
|
WARN_ON(!work->saved_cred);
|
||||||
|
|
||||||
cred = current_cred();
|
cred = current_cred();
|
||||||
revert_creds(work->saved_cred);
|
revert_creds(work->saved_cred);
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
#define SMB311_PROT_ID 0x0311
|
#define SMB311_PROT_ID 0x0311
|
||||||
#define BAD_PROT_ID 0xFFFF
|
#define BAD_PROT_ID 0xFFFF
|
||||||
|
|
||||||
#define SMB_ECHO_INTERVAL (60*HZ)
|
#define SMB_ECHO_INTERVAL (60 * HZ)
|
||||||
|
|
||||||
#define CIFS_DEFAULT_IOSIZE (64 * 1024)
|
#define CIFS_DEFAULT_IOSIZE (64 * 1024)
|
||||||
#define MAX_CIFS_SMALL_BUFFER_SIZE 448 /* big enough for most */
|
#define MAX_CIFS_SMALL_BUFFER_SIZE 448 /* big enough for most */
|
||||||
|
@ -490,8 +490,6 @@ struct smb_version_cmds {
|
||||||
int (*proc)(struct ksmbd_work *swork);
|
int (*proc)(struct ksmbd_work *swork);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int ksmbd_min_protocol(void);
|
int ksmbd_min_protocol(void);
|
||||||
int ksmbd_max_protocol(void);
|
int ksmbd_max_protocol(void);
|
||||||
|
|
||||||
|
|
|
@ -68,13 +68,12 @@ static const struct smb_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
|
||||||
* if the two SIDs (roughly equivalent to a UUID for a user or group) are
|
* if the two SIDs (roughly equivalent to a UUID for a user or group) are
|
||||||
* the same returns zero, if they do not match returns non-zero.
|
* the same returns zero, if they do not match returns non-zero.
|
||||||
*/
|
*/
|
||||||
int
|
int compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid)
|
||||||
compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int num_subauth, num_sat, num_saw;
|
int num_subauth, num_sat, num_saw;
|
||||||
|
|
||||||
if ((!ctsid) || (!cwsid))
|
if (!ctsid || !cwsid)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* compare the revision */
|
/* compare the revision */
|
||||||
|
@ -103,7 +102,7 @@ compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid)
|
||||||
for (i = 0; i < num_subauth; ++i) {
|
for (i = 0; i < num_subauth; ++i) {
|
||||||
if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
|
if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
|
||||||
if (le32_to_cpu(ctsid->sub_auth[i]) >
|
if (le32_to_cpu(ctsid->sub_auth[i]) >
|
||||||
le32_to_cpu(cwsid->sub_auth[i]))
|
le32_to_cpu(cwsid->sub_auth[i]))
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -114,8 +113,7 @@ compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid)
|
||||||
return 0; /* sids compare/match */
|
return 0; /* sids compare/match */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void smb_copy_sid(struct smb_sid *dst, const struct smb_sid *src)
|
||||||
smb_copy_sid(struct smb_sid *dst, const struct smb_sid *src)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -144,21 +142,17 @@ static umode_t access_flags_to_mode(struct smb_fattr *fattr, __le32 ace_flags,
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & GENERIC_READ) ||
|
if ((flags & GENERIC_READ) || (flags & FILE_READ_RIGHTS))
|
||||||
(flags & FILE_READ_RIGHTS))
|
|
||||||
mode = 0444;
|
mode = 0444;
|
||||||
if ((flags & GENERIC_WRITE) ||
|
if ((flags & GENERIC_WRITE) || (flags & FILE_WRITE_RIGHTS)) {
|
||||||
(flags & FILE_WRITE_RIGHTS)) {
|
|
||||||
mode |= 0222;
|
mode |= 0222;
|
||||||
if (S_ISDIR(fattr->cf_mode))
|
if (S_ISDIR(fattr->cf_mode))
|
||||||
mode |= 0111;
|
mode |= 0111;
|
||||||
}
|
}
|
||||||
if ((flags & GENERIC_EXECUTE) ||
|
if ((flags & GENERIC_EXECUTE) || (flags & FILE_EXEC_RIGHTS))
|
||||||
(flags & FILE_EXEC_RIGHTS))
|
|
||||||
mode |= 0111;
|
mode |= 0111;
|
||||||
|
|
||||||
if (type == ACCESS_DENIED_ACE_TYPE ||
|
if (type == ACCESS_DENIED_ACE_TYPE || type == ACCESS_DENIED_OBJECT_ACE_TYPE)
|
||||||
type == ACCESS_DENIED_OBJECT_ACE_TYPE)
|
|
||||||
mode = ~mode;
|
mode = ~mode;
|
||||||
|
|
||||||
ksmbd_debug(SMB, "access flags 0x%x mode now %04o\n", flags, mode);
|
ksmbd_debug(SMB, "access flags 0x%x mode now %04o\n", flags, mode);
|
||||||
|
@ -282,8 +276,7 @@ static int sid_to_id(struct smb_sid *psid, uint sidtype,
|
||||||
id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
|
id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
|
||||||
if (id > 0) {
|
if (id > 0) {
|
||||||
uid = make_kuid(&init_user_ns, id);
|
uid = make_kuid(&init_user_ns, id);
|
||||||
if (uid_valid(uid) &&
|
if (uid_valid(uid) && kuid_has_mapping(&init_user_ns, uid)) {
|
||||||
kuid_has_mapping(&init_user_ns, uid)) {
|
|
||||||
fattr->cf_uid = uid;
|
fattr->cf_uid = uid;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
|
@ -295,8 +288,7 @@ static int sid_to_id(struct smb_sid *psid, uint sidtype,
|
||||||
id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
|
id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
|
||||||
if (id > 0) {
|
if (id > 0) {
|
||||||
gid = make_kgid(&init_user_ns, id);
|
gid = make_kgid(&init_user_ns, id);
|
||||||
if (gid_valid(gid) &&
|
if (gid_valid(gid) && kgid_has_mapping(&init_user_ns, gid)) {
|
||||||
kgid_has_mapping(&init_user_ns, gid)) {
|
|
||||||
fattr->cf_gid = gid;
|
fattr->cf_gid = gid;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
|
@ -353,7 +345,7 @@ int init_acl_state(struct posix_acl_state *state, int cnt)
|
||||||
* enough space for either:
|
* enough space for either:
|
||||||
*/
|
*/
|
||||||
alloc = sizeof(struct posix_ace_state_array)
|
alloc = sizeof(struct posix_ace_state_array)
|
||||||
+ cnt*sizeof(struct posix_user_ace_state);
|
+ cnt * sizeof(struct posix_user_ace_state);
|
||||||
state->users = kzalloc(alloc, GFP_KERNEL);
|
state->users = kzalloc(alloc, GFP_KERNEL);
|
||||||
if (!state->users)
|
if (!state->users)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -429,17 +421,17 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
|
||||||
* user/group/other have no permissions
|
* user/group/other have no permissions
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < num_aces; ++i) {
|
for (i = 0; i < num_aces; ++i) {
|
||||||
ppace[i] = (struct smb_ace *) (acl_base + acl_size);
|
ppace[i] = (struct smb_ace *)(acl_base + acl_size);
|
||||||
acl_base = (char *)ppace[i];
|
acl_base = (char *)ppace[i];
|
||||||
acl_size = le16_to_cpu(ppace[i]->size);
|
acl_size = le16_to_cpu(ppace[i]->size);
|
||||||
ppace[i]->access_req =
|
ppace[i]->access_req =
|
||||||
smb_map_generic_desired_access(ppace[i]->access_req);
|
smb_map_generic_desired_access(ppace[i]->access_req);
|
||||||
|
|
||||||
if (!(compare_sids(&(ppace[i]->sid), &sid_unix_NFS_mode))) {
|
if (!(compare_sids(&ppace[i]->sid, &sid_unix_NFS_mode))) {
|
||||||
fattr->cf_mode =
|
fattr->cf_mode =
|
||||||
le32_to_cpu(ppace[i]->sid.sub_auth[2]);
|
le32_to_cpu(ppace[i]->sid.sub_auth[2]);
|
||||||
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;
|
||||||
|
@ -449,9 +441,9 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
|
||||||
mode |= acl_mode;
|
mode |= acl_mode;
|
||||||
}
|
}
|
||||||
owner_found = true;
|
owner_found = true;
|
||||||
} else if (!compare_sids(&(ppace[i]->sid), pgrpsid) ||
|
} else if (!compare_sids(&ppace[i]->sid, pgrpsid) ||
|
||||||
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;
|
||||||
|
@ -460,7 +452,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
|
||||||
mode |= acl_mode;
|
mode |= acl_mode;
|
||||||
}
|
}
|
||||||
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;
|
||||||
|
@ -469,13 +461,13 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
|
||||||
mode |= acl_mode;
|
mode |= acl_mode;
|
||||||
}
|
}
|
||||||
others_found = true;
|
others_found = true;
|
||||||
} else if (!compare_sids(&(ppace[i]->sid), &creator_owner))
|
} else if (!compare_sids(&ppace[i]->sid, &creator_owner)) {
|
||||||
continue;
|
continue;
|
||||||
else if (!compare_sids(&(ppace[i]->sid), &creator_group))
|
} else if (!compare_sids(&ppace[i]->sid, &creator_group)) {
|
||||||
continue;
|
continue;
|
||||||
else if (!compare_sids(&(ppace[i]->sid), &sid_authusers))
|
} else if (!compare_sids(&ppace[i]->sid, &sid_authusers)) {
|
||||||
continue;
|
continue;
|
||||||
else {
|
} else {
|
||||||
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,
|
||||||
|
@ -610,7 +602,7 @@ static void set_posix_acl_entries_dacl(struct smb_ace *pndace,
|
||||||
if (S_ISDIR(fattr->cf_mode) && pace->e_tag == ACL_OTHER)
|
if (S_ISDIR(fattr->cf_mode) && pace->e_tag == ACL_OTHER)
|
||||||
flags = 0x03;
|
flags = 0x03;
|
||||||
|
|
||||||
ntace = (struct smb_ace *) ((char *)pndace + *size);
|
ntace = (struct smb_ace *)((char *)pndace + *size);
|
||||||
*size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED, flags,
|
*size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED, flags,
|
||||||
pace->e_perm, 0777);
|
pace->e_perm, 0777);
|
||||||
(*num_aces)++;
|
(*num_aces)++;
|
||||||
|
@ -619,8 +611,8 @@ static void set_posix_acl_entries_dacl(struct smb_ace *pndace,
|
||||||
FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
|
FILE_DELETE_LE | FILE_DELETE_CHILD_LE;
|
||||||
|
|
||||||
if (S_ISDIR(fattr->cf_mode) &&
|
if (S_ISDIR(fattr->cf_mode) &&
|
||||||
(pace->e_tag == ACL_USER || pace->e_tag == ACL_GROUP)) {
|
(pace->e_tag == ACL_USER || pace->e_tag == ACL_GROUP)) {
|
||||||
ntace = (struct smb_ace *) ((char *)pndace + *size);
|
ntace = (struct smb_ace *)((char *)pndace + *size);
|
||||||
*size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED,
|
*size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED,
|
||||||
0x03, pace->e_perm, 0777);
|
0x03, pace->e_perm, 0777);
|
||||||
(*num_aces)++;
|
(*num_aces)++;
|
||||||
|
@ -661,7 +653,7 @@ static void set_posix_acl_entries_dacl(struct smb_ace *pndace,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ntace = (struct smb_ace *) ((char *)pndace + *size);
|
ntace = (struct smb_ace *)((char *)pndace + *size);
|
||||||
*size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED, 0x0b,
|
*size += fill_ace_for_sid(ntace, sid, ACCESS_ALLOWED, 0x0b,
|
||||||
pace->e_perm, 0777);
|
pace->e_perm, 0777);
|
||||||
(*num_aces)++;
|
(*num_aces)++;
|
||||||
|
@ -786,7 +778,7 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len,
|
||||||
__u32 dacloffset;
|
__u32 dacloffset;
|
||||||
int pntsd_type;
|
int pntsd_type;
|
||||||
|
|
||||||
if (pntsd == NULL)
|
if (!pntsd)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
|
owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
|
||||||
|
@ -913,11 +905,11 @@ int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd,
|
||||||
dacl_ptr->size = cpu_to_le16(sizeof(struct smb_acl));
|
dacl_ptr->size = cpu_to_le16(sizeof(struct smb_acl));
|
||||||
dacl_ptr->num_aces = 0;
|
dacl_ptr->num_aces = 0;
|
||||||
|
|
||||||
if (!ppntsd)
|
if (!ppntsd) {
|
||||||
set_mode_dacl(dacl_ptr, fattr);
|
set_mode_dacl(dacl_ptr, fattr);
|
||||||
else if (!ppntsd->dacloffset)
|
} else if (!ppntsd->dacloffset) {
|
||||||
goto out;
|
goto out;
|
||||||
else {
|
} else {
|
||||||
struct smb_acl *ppdacl_ptr;
|
struct smb_acl *ppdacl_ptr;
|
||||||
|
|
||||||
ppdacl_ptr = (struct smb_acl *)((char *)ppntsd +
|
ppdacl_ptr = (struct smb_acl *)((char *)ppntsd +
|
||||||
|
@ -992,8 +984,9 @@ int smb_inherit_dacl(struct ksmbd_conn *conn, struct dentry *dentry,
|
||||||
flags |= INHERIT_ONLY_ACE;
|
flags |= INHERIT_ONLY_ACE;
|
||||||
if (flags & NO_PROPAGATE_INHERIT_ACE)
|
if (flags & NO_PROPAGATE_INHERIT_ACE)
|
||||||
flags = 0;
|
flags = 0;
|
||||||
} else
|
} else {
|
||||||
flags = 0;
|
flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!compare_sids(&creator_owner, &parent_aces->sid)) {
|
if (!compare_sids(&creator_owner, &parent_aces->sid)) {
|
||||||
creator = &creator_owner;
|
creator = &creator_owner;
|
||||||
|
@ -1016,8 +1009,9 @@ int smb_inherit_dacl(struct ksmbd_conn *conn, struct dentry *dentry,
|
||||||
aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size));
|
aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size));
|
||||||
flags |= INHERIT_ONLY_ACE;
|
flags |= INHERIT_ONLY_ACE;
|
||||||
psid = creator;
|
psid = creator;
|
||||||
} else if (is_dir && !(parent_aces->flags & NO_PROPAGATE_INHERIT_ACE))
|
} else if (is_dir && !(parent_aces->flags & NO_PROPAGATE_INHERIT_ACE)) {
|
||||||
psid = &parent_aces->sid;
|
psid = &parent_aces->sid;
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
@ -1166,7 +1160,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry,
|
||||||
ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
|
ace = (struct smb_ace *)((char *)pdacl + sizeof(struct smb_acl));
|
||||||
for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) {
|
for (i = 0; i < le32_to_cpu(pdacl->num_aces); i++) {
|
||||||
granted |= le32_to_cpu(ace->access_req);
|
granted |= le32_to_cpu(ace->access_req);
|
||||||
ace = (struct smb_ace *) ((char *)ace + le16_to_cpu(ace->size));
|
ace = (struct smb_ace *)((char *)ace + le16_to_cpu(ace->size));
|
||||||
if (end_of_acl < (char *)ace)
|
if (end_of_acl < (char *)ace)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
@ -1189,7 +1183,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry,
|
||||||
if (!compare_sids(&sid_everyone, &ace->sid))
|
if (!compare_sids(&sid_everyone, &ace->sid))
|
||||||
others_ace = ace;
|
others_ace = ace;
|
||||||
|
|
||||||
ace = (struct smb_ace *) ((char *)ace + le16_to_cpu(ace->size));
|
ace = (struct smb_ace *)((char *)ace + le16_to_cpu(ace->size));
|
||||||
if (end_of_acl < (char *)ace)
|
if (end_of_acl < (char *)ace)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
@ -1229,9 +1223,9 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry,
|
||||||
posix_acl_release(posix_acls);
|
posix_acl_release(posix_acls);
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
if (others_ace)
|
if (others_ace) {
|
||||||
ace = others_ace;
|
ace = others_ace;
|
||||||
else {
|
} else {
|
||||||
ksmbd_debug(SMB, "Can't find corresponding sid\n");
|
ksmbd_debug(SMB, "Can't find corresponding sid\n");
|
||||||
rc = -EACCES;
|
rc = -EACCES;
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
@ -1300,8 +1294,7 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
|
||||||
if (type_check && !(le16_to_cpu(pntsd->type) & DACL_PRESENT))
|
if (type_check && !(le16_to_cpu(pntsd->type) & DACL_PRESENT))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (test_share_config_flag(tcon->share_conf,
|
if (test_share_config_flag(tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) {
|
||||||
KSMBD_SHARE_FLAG_ACL_XATTR)) {
|
|
||||||
/* Update WinACL in xattr */
|
/* Update WinACL in xattr */
|
||||||
ksmbd_vfs_remove_sd_xattrs(dentry);
|
ksmbd_vfs_remove_sd_xattrs(dentry);
|
||||||
ksmbd_vfs_set_sd_xattr(conn, dentry, pntsd, ntsd_len);
|
ksmbd_vfs_set_sd_xattr(conn, dentry, pntsd, ntsd_len);
|
||||||
|
|
|
@ -11,13 +11,13 @@
|
||||||
* between different kernel versions.
|
* between different kernel versions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define NTFS_TIME_OFFSET ((u64)(369*365 + 89) * 24 * 3600 * 10000000)
|
#define NTFS_TIME_OFFSET ((u64)(369 * 365 + 89) * 24 * 3600 * 10000000)
|
||||||
|
|
||||||
/* Convert the Unix UTC into NT UTC. */
|
/* Convert the Unix UTC into NT UTC. */
|
||||||
static inline u64 ksmbd_UnixTimeToNT(struct timespec64 t)
|
static inline u64 ksmbd_UnixTimeToNT(struct timespec64 t)
|
||||||
{
|
{
|
||||||
/* Convert to 100ns intervals and then add the NTFS time offset. */
|
/* Convert to 100ns intervals and then add the NTFS time offset. */
|
||||||
return (u64) t.tv_sec * 10000000 + t.tv_nsec / 100 + NTFS_TIME_OFFSET;
|
return (u64)t.tv_sec * 10000000 + t.tv_nsec / 100 + NTFS_TIME_OFFSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct timespec64 ksmbd_NTtimeToUnix(__le64 ntutc);
|
struct timespec64 ksmbd_NTtimeToUnix(__le64 ntutc);
|
||||||
|
|
|
@ -75,8 +75,7 @@ struct ipc_msg_table_entry {
|
||||||
static struct delayed_work ipc_timer_work;
|
static struct delayed_work ipc_timer_work;
|
||||||
|
|
||||||
static int handle_startup_event(struct sk_buff *skb, struct genl_info *info);
|
static int handle_startup_event(struct sk_buff *skb, struct genl_info *info);
|
||||||
static int handle_unsupported_event(struct sk_buff *skb,
|
static int handle_unsupported_event(struct sk_buff *skb, struct genl_info *info);
|
||||||
struct genl_info *info);
|
|
||||||
static int handle_generic_event(struct sk_buff *skb, struct genl_info *info);
|
static int handle_generic_event(struct sk_buff *skb, struct genl_info *info);
|
||||||
static int ksmbd_ipc_heartbeat_request(void);
|
static int ksmbd_ipc_heartbeat_request(void);
|
||||||
|
|
||||||
|
@ -385,8 +384,7 @@ static int handle_startup_event(struct sk_buff *skb, struct genl_info *info)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_unsupported_event(struct sk_buff *skb,
|
static int handle_unsupported_event(struct sk_buff *skb, struct genl_info *info)
|
||||||
struct genl_info *info)
|
|
||||||
{
|
{
|
||||||
ksmbd_err("Unknown IPC event: %d, ignore.\n", info->genlhdr->cmd);
|
ksmbd_err("Unknown IPC event: %d, ignore.\n", info->genlhdr->cmd);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -453,8 +451,7 @@ static int ipc_msg_send(struct ksmbd_ipc_msg *msg)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *ipc_msg_send_request(struct ksmbd_ipc_msg *msg,
|
static void *ipc_msg_send_request(struct ksmbd_ipc_msg *msg, unsigned int handle)
|
||||||
unsigned int handle)
|
|
||||||
{
|
{
|
||||||
struct ipc_msg_table_entry entry;
|
struct ipc_msg_table_entry entry;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -550,9 +547,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;
|
||||||
|
@ -591,7 +588,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;
|
||||||
|
@ -658,8 +655,7 @@ ksmbd_ipc_share_config_request(const char *name)
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ksmbd_rpc_command *ksmbd_rpc_open(struct ksmbd_session *sess,
|
struct ksmbd_rpc_command *ksmbd_rpc_open(struct ksmbd_session *sess, int handle)
|
||||||
int handle)
|
|
||||||
{
|
{
|
||||||
struct ksmbd_ipc_msg *msg;
|
struct ksmbd_ipc_msg *msg;
|
||||||
struct ksmbd_rpc_command *req;
|
struct ksmbd_rpc_command *req;
|
||||||
|
@ -681,8 +677,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_open(struct ksmbd_session *sess,
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ksmbd_rpc_command *ksmbd_rpc_close(struct ksmbd_session *sess,
|
struct ksmbd_rpc_command *ksmbd_rpc_close(struct ksmbd_session *sess, int handle)
|
||||||
int handle)
|
|
||||||
{
|
{
|
||||||
struct ksmbd_ipc_msg *msg;
|
struct ksmbd_ipc_msg *msg;
|
||||||
struct ksmbd_rpc_command *req;
|
struct ksmbd_rpc_command *req;
|
||||||
|
@ -704,10 +699,8 @@ struct ksmbd_rpc_command *ksmbd_rpc_close(struct ksmbd_session *sess,
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess,
|
struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle,
|
||||||
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;
|
||||||
|
@ -731,8 +724,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess,
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess,
|
struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess, int handle)
|
||||||
int handle)
|
|
||||||
{
|
{
|
||||||
struct ksmbd_ipc_msg *msg;
|
struct ksmbd_ipc_msg *msg;
|
||||||
struct ksmbd_rpc_command *req;
|
struct ksmbd_rpc_command *req;
|
||||||
|
@ -755,10 +747,8 @@ struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess,
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess,
|
struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle,
|
||||||
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;
|
||||||
|
@ -782,9 +772,8 @@ struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess,
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ksmbd_rpc_command *ksmbd_rpc_rap(struct ksmbd_session *sess,
|
struct ksmbd_rpc_command *ksmbd_rpc_rap(struct ksmbd_session *sess, void *payload,
|
||||||
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;
|
||||||
|
@ -885,8 +874,7 @@ int ksmbd_ipc_init(void)
|
||||||
|
|
||||||
ret = genl_register_family(&ksmbd_genl_family);
|
ret = genl_register_family(&ksmbd_genl_family);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ksmbd_err("Failed to register KSMBD netlink interface %d\n",
|
ksmbd_err("Failed to register KSMBD netlink interface %d\n", ret);
|
||||||
ret);
|
|
||||||
goto cancel_work;
|
goto cancel_work;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,9 @@ struct sockaddr;
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
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);
|
||||||
|
@ -37,24 +37,16 @@ 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,
|
struct ksmbd_rpc_command *ksmbd_rpc_open(struct ksmbd_session *sess, int handle);
|
||||||
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,
|
struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle,
|
||||||
int handle,
|
void *payload, size_t payload_sz);
|
||||||
void *payload,
|
struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess, int handle);
|
||||||
size_t payload_sz);
|
struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle,
|
||||||
struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess,
|
void *payload, size_t payload_sz);
|
||||||
int handle);
|
struct ksmbd_rpc_command *ksmbd_rpc_rap(struct ksmbd_session *sess, void *payload,
|
||||||
struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess,
|
size_t payload_sz);
|
||||||
int handle,
|
|
||||||
void *payload,
|
|
||||||
size_t payload_sz);
|
|
||||||
struct ksmbd_rpc_command *ksmbd_rpc_rap(struct ksmbd_session *sess,
|
|
||||||
void *payload,
|
|
||||||
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);
|
||||||
|
|
|
@ -85,7 +85,6 @@ static struct smb_direct_listener {
|
||||||
struct rdma_cm_id *cm_id;
|
struct rdma_cm_id *cm_id;
|
||||||
} smb_direct_listener;
|
} smb_direct_listener;
|
||||||
|
|
||||||
|
|
||||||
static struct workqueue_struct *smb_direct_wq;
|
static struct workqueue_struct *smb_direct_wq;
|
||||||
|
|
||||||
enum smb_direct_status {
|
enum smb_direct_status {
|
||||||
|
@ -213,8 +212,8 @@ 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)
|
||||||
|
@ -223,7 +222,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);
|
||||||
|
@ -246,7 +245,7 @@ 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);
|
||||||
|
@ -254,7 +253,6 @@ static void put_recvmsg(struct smb_direct_transport *t,
|
||||||
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);
|
||||||
spin_unlock(&t->recvmsg_queue_lock);
|
spin_unlock(&t->recvmsg_queue_lock);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
|
@ -264,8 +262,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(
|
recvmsg = list_first_entry(&t->empty_recvmsg_queue,
|
||||||
&t->empty_recvmsg_queue,
|
|
||||||
struct smb_direct_recvmsg, list);
|
struct smb_direct_recvmsg, list);
|
||||||
list_del(&recvmsg->list);
|
list_del(&recvmsg->list);
|
||||||
}
|
}
|
||||||
|
@ -274,7 +271,7 @@ 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);
|
||||||
|
@ -285,8 +282,7 @@ 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,
|
struct smb_direct_recvmsg *recvmsg, int data_length)
|
||||||
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);
|
||||||
|
@ -300,11 +296,9 @@ static void enqueue_reassembly(struct smb_direct_transport *t,
|
||||||
virt_wmb();
|
virt_wmb();
|
||||||
t->reassembly_data_length += data_length;
|
t->reassembly_data_length += data_length;
|
||||||
spin_unlock(&t->reassembly_queue_lock);
|
spin_unlock(&t->reassembly_queue_lock);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct smb_direct_recvmsg *get_first_reassembly(
|
static struct smb_direct_recvmsg *get_first_reassembly(struct smb_direct_transport *t)
|
||||||
struct smb_direct_transport *t)
|
|
||||||
{
|
{
|
||||||
if (!list_empty(&t->reassembly_queue))
|
if (!list_empty(&t->reassembly_queue))
|
||||||
return list_first_entry(&t->reassembly_queue,
|
return list_first_entry(&t->reassembly_queue,
|
||||||
|
@ -423,11 +417,11 @@ static void free_transport(struct smb_direct_transport *t)
|
||||||
recvmsg = get_first_reassembly(t);
|
recvmsg = get_first_reassembly(t);
|
||||||
if (recvmsg) {
|
if (recvmsg) {
|
||||||
list_del(&recvmsg->list);
|
list_del(&recvmsg->list);
|
||||||
spin_unlock(
|
|
||||||
&t->reassembly_queue_lock);
|
|
||||||
put_recvmsg(t, recvmsg);
|
|
||||||
} else
|
|
||||||
spin_unlock(&t->reassembly_queue_lock);
|
spin_unlock(&t->reassembly_queue_lock);
|
||||||
|
put_recvmsg(t, recvmsg);
|
||||||
|
} else {
|
||||||
|
spin_unlock(&t->reassembly_queue_lock);
|
||||||
|
}
|
||||||
} while (recvmsg);
|
} while (recvmsg);
|
||||||
t->reassembly_data_length = 0;
|
t->reassembly_data_length = 0;
|
||||||
|
|
||||||
|
@ -460,7 +454,7 @@ 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;
|
||||||
|
|
||||||
|
@ -481,8 +475,8 @@ static int smb_direct_check_recvmsg(struct smb_direct_recvmsg *recvmsg)
|
||||||
switch (recvmsg->type) {
|
switch (recvmsg->type) {
|
||||||
case SMB_DIRECT_MSG_DATA_TRANSFER: {
|
case SMB_DIRECT_MSG_DATA_TRANSFER: {
|
||||||
struct smb_direct_data_transfer *req =
|
struct smb_direct_data_transfer *req =
|
||||||
(struct smb_direct_data_transfer *) recvmsg->packet;
|
(struct smb_direct_data_transfer *)recvmsg->packet;
|
||||||
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",
|
||||||
|
@ -504,12 +498,12 @@ static int smb_direct_check_recvmsg(struct smb_direct_recvmsg *recvmsg)
|
||||||
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;
|
||||||
if (le16_to_cpu(req->credits_requested) <= 0 ||
|
if (le16_to_cpu(req->credits_requested) <= 0 ||
|
||||||
le32_to_cpu(req->max_receive_size) <= 128 ||
|
le32_to_cpu(req->max_receive_size) <= 128 ||
|
||||||
le32_to_cpu(req->max_fragmented_size) <=
|
le32_to_cpu(req->max_fragmented_size) <=
|
||||||
128*1024)
|
128 * 1024)
|
||||||
return -ECONNABORTED;
|
return -ECONNABORTED;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -595,8 +589,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
||||||
if (atomic_read(&t->send_credits) > 0)
|
if (atomic_read(&t->send_credits) > 0)
|
||||||
wake_up_interruptible(&t->wait_send_credits);
|
wake_up_interruptible(&t->wait_send_credits);
|
||||||
|
|
||||||
if (is_receive_credit_post_required(receive_credits,
|
if (is_receive_credit_post_required(receive_credits, avail_recvmsg_count))
|
||||||
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;
|
||||||
|
@ -607,7 +600,7 @@ 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;
|
||||||
|
@ -681,8 +674,7 @@ static int smb_direct_read(struct ksmbd_transport *t, char *buf,
|
||||||
data_transfer = smb_direct_recvmsg_payload(recvmsg);
|
data_transfer = smb_direct_recvmsg_payload(recvmsg);
|
||||||
data_length = le32_to_cpu(data_transfer->data_length);
|
data_length = le32_to_cpu(data_transfer->data_length);
|
||||||
remaining_data_length =
|
remaining_data_length =
|
||||||
le32_to_cpu(
|
le32_to_cpu(data_transfer->remaining_data_length);
|
||||||
data_transfer->remaining_data_length);
|
|
||||||
data_offset = le32_to_cpu(data_transfer->data_offset);
|
data_offset = le32_to_cpu(data_transfer->data_offset);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -706,9 +698,7 @@ static int smb_direct_read(struct ksmbd_transport *t, char *buf,
|
||||||
}
|
}
|
||||||
|
|
||||||
to_copy = min_t(int, data_length - offset, to_read);
|
to_copy = min_t(int, data_length - offset, to_read);
|
||||||
memcpy(
|
memcpy(buf + data_read, (char *)data_transfer + data_offset + offset,
|
||||||
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? */
|
||||||
|
@ -718,20 +708,19 @@ static int smb_direct_read(struct ksmbd_transport *t, char *buf,
|
||||||
* No need to lock if we are not at the
|
* No need to lock if we are not at the
|
||||||
* end of the queue
|
* end of the queue
|
||||||
*/
|
*/
|
||||||
if (queue_length)
|
if (queue_length) {
|
||||||
list_del(&recvmsg->list);
|
list_del(&recvmsg->list);
|
||||||
else {
|
} else {
|
||||||
spin_lock_irq(
|
spin_lock_irq(&st->reassembly_queue_lock);
|
||||||
&st->reassembly_queue_lock);
|
|
||||||
list_del(&recvmsg->list);
|
list_del(&recvmsg->list);
|
||||||
spin_unlock_irq(
|
spin_unlock_irq(&st->reassembly_queue_lock);
|
||||||
&st->reassembly_queue_lock);
|
|
||||||
}
|
}
|
||||||
queue_removed++;
|
queue_removed++;
|
||||||
put_recvmsg(st, recvmsg);
|
put_recvmsg(st, recvmsg);
|
||||||
offset = 0;
|
offset = 0;
|
||||||
} else
|
} else {
|
||||||
offset += to_copy;
|
offset += to_copy;
|
||||||
|
}
|
||||||
|
|
||||||
to_read -= to_copy;
|
to_read -= to_copy;
|
||||||
data_read += to_copy;
|
data_read += to_copy;
|
||||||
|
@ -744,13 +733,13 @@ static int smb_direct_read(struct ksmbd_transport *t, char *buf,
|
||||||
|
|
||||||
spin_lock(&st->receive_credit_lock);
|
spin_lock(&st->receive_credit_lock);
|
||||||
st->count_avail_recvmsg += queue_removed;
|
st->count_avail_recvmsg += queue_removed;
|
||||||
if (is_receive_credit_post_required(st->recv_credits,
|
if (is_receive_credit_post_required(st->recv_credits, st->count_avail_recvmsg)) {
|
||||||
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,
|
||||||
|
@ -762,10 +751,8 @@ static int smb_direct_read(struct ksmbd_transport *t, char *buf,
|
||||||
}
|
}
|
||||||
|
|
||||||
ksmbd_debug(RDMA, "wait_event on more data\n");
|
ksmbd_debug(RDMA, "wait_event on more data\n");
|
||||||
rc = wait_event_interruptible(
|
rc = wait_event_interruptible(st->wait_reassembly_queue,
|
||||||
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;
|
||||||
|
|
||||||
|
@ -795,8 +782,9 @@ static void smb_direct_post_recv_credits(struct work_struct *work)
|
||||||
if (use_free) {
|
if (use_free) {
|
||||||
use_free = 0;
|
use_free = 0;
|
||||||
continue;
|
continue;
|
||||||
} else
|
} else {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
recvmsg->type = SMB_DIRECT_MSG_DATA_TRANSFER;
|
recvmsg->type = SMB_DIRECT_MSG_DATA_TRANSFER;
|
||||||
|
@ -904,8 +892,8 @@ 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;
|
||||||
|
@ -914,7 +902,7 @@ 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;
|
||||||
|
@ -973,12 +961,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 && (send_ctx->wr_cnt >= 16 ||
|
||||||
atomic_read(&t->send_credits) <= 1)) {
|
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;
|
||||||
|
@ -1048,8 +1036,7 @@ static int smb_direct_create_header(struct smb_direct_transport *t,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_sg_list(void *buf, int size,
|
static int get_sg_list(void *buf, int size, struct scatterlist *sg_list, int nentries)
|
||||||
struct scatterlist *sg_list, int nentries)
|
|
||||||
{
|
{
|
||||||
bool high = is_vmalloc_addr(buf);
|
bool high = is_vmalloc_addr(buf);
|
||||||
struct page *page;
|
struct page *page;
|
||||||
|
@ -1082,8 +1069,8 @@ static int get_sg_list(void *buf, int size,
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
@ -1094,8 +1081,8 @@ 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;
|
||||||
|
|
||||||
|
@ -1132,13 +1119,13 @@ 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;
|
||||||
int data_length;
|
int data_length;
|
||||||
struct scatterlist sg[SMB_DIRECT_MAX_SEND_SGES-1];
|
struct scatterlist sg[SMB_DIRECT_MAX_SEND_SGES - 1];
|
||||||
|
|
||||||
ret = wait_for_send_credits(t, send_ctx);
|
ret = wait_for_send_credits(t, send_ctx);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -1159,15 +1146,15 @@ static int smb_direct_post_send_data(struct smb_direct_transport *t,
|
||||||
struct ib_sge *sge;
|
struct ib_sge *sge;
|
||||||
int sg_cnt;
|
int sg_cnt;
|
||||||
|
|
||||||
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;
|
||||||
goto err;
|
goto err;
|
||||||
} else if (sg_cnt + msg->num_sge > SMB_DIRECT_MAX_SEND_SGES-1) {
|
} else if (sg_cnt + msg->num_sge > SMB_DIRECT_MAX_SEND_SGES - 1) {
|
||||||
ksmbd_err("buffer not fitted into sges\n");
|
ksmbd_err("buffer not fitted into sges\n");
|
||||||
ret = -E2BIG;
|
ret = -E2BIG;
|
||||||
ib_dma_unmap_sg(t->cm_id->device, sg, sg_cnt,
|
ib_dma_unmap_sg(t->cm_id->device, sg, sg_cnt,
|
||||||
|
@ -1195,8 +1182,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;
|
||||||
|
@ -1228,24 +1215,24 @@ static int smb_direct_writev(struct ksmbd_transport *t,
|
||||||
if (buflen > max_iov_size) {
|
if (buflen > max_iov_size) {
|
||||||
if (i > start) {
|
if (i > start) {
|
||||||
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 {
|
||||||
/* iov[start] is too big, break it */
|
/* iov[start] is too big, break it */
|
||||||
int nvec = (buflen+max_iov_size-1) /
|
int nvec = (buflen + max_iov_size - 1) /
|
||||||
max_iov_size;
|
max_iov_size;
|
||||||
|
|
||||||
for (j = 0; j < nvec; j++) {
|
for (j = 0; j < nvec; j++) {
|
||||||
vec.iov_base =
|
vec.iov_base =
|
||||||
(char *)iov[start].iov_base +
|
(char *)iov[start].iov_base +
|
||||||
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,
|
||||||
|
@ -1265,7 +1252,7 @@ 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;
|
||||||
|
@ -1290,7 +1277,7 @@ static int smb_direct_writev(struct ksmbd_transport *t,
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
@ -1323,8 +1310,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, u32 remote_len,
|
||||||
bool is_read)
|
bool is_read)
|
||||||
{
|
{
|
||||||
struct smb_direct_rdma_rw_msg *msg;
|
struct smb_direct_rdma_rw_msg *msg;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -1392,23 +1379,20 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, void *buf,
|
||||||
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,
|
static int smb_direct_rdma_write(struct ksmbd_transport *t, void *buf,
|
||||||
void *buf, unsigned int buflen,
|
unsigned int buflen, u32 remote_key, u64 remote_offset,
|
||||||
u32 remote_key, u64 remote_offset,
|
u32 remote_len)
|
||||||
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,
|
static int smb_direct_rdma_read(struct ksmbd_transport *t, void *buf,
|
||||||
void *buf, unsigned int buflen,
|
unsigned int buflen, u32 remote_key, u64 remote_offset,
|
||||||
u32 remote_key, u64 remote_offset,
|
u32 remote_len)
|
||||||
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,
|
||||||
|
@ -1428,7 +1412,7 @@ static void smb_direct_disconnect(struct ksmbd_transport *t)
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
@ -1505,8 +1489,7 @@ static int smb_direct_send_negotiate_response(struct smb_direct_transport *t,
|
||||||
resp->reserved = 0;
|
resp->reserved = 0;
|
||||||
resp->credits_requested =
|
resp->credits_requested =
|
||||||
cpu_to_le16(t->send_credit_target);
|
cpu_to_le16(t->send_credit_target);
|
||||||
resp->credits_granted = cpu_to_le16(
|
resp->credits_granted = cpu_to_le16(manage_credits_prior_sending(t));
|
||||||
manage_credits_prior_sending(t));
|
|
||||||
resp->max_readwrite_size = cpu_to_le32(t->max_rdma_rw_size);
|
resp->max_readwrite_size = cpu_to_le32(t->max_rdma_rw_size);
|
||||||
resp->preferred_send_size = cpu_to_le32(t->max_send_size);
|
resp->preferred_send_size = cpu_to_le32(t->max_send_size);
|
||||||
resp->max_receive_size = cpu_to_le32(t->max_recv_size);
|
resp->max_receive_size = cpu_to_le32(t->max_recv_size);
|
||||||
|
@ -1665,7 +1648,7 @@ static int smb_direct_init_params(struct smb_direct_transport *t,
|
||||||
|
|
||||||
max_send_wrs = smb_direct_send_credit_target + max_rw_wrs;
|
max_send_wrs = smb_direct_send_credit_target + max_rw_wrs;
|
||||||
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);
|
||||||
|
@ -1936,7 +1919,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: {
|
||||||
|
@ -2010,7 +1993,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;
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
#include "transport_tcp.h"
|
#include "transport_tcp.h"
|
||||||
|
|
||||||
#define IFACE_STATE_DOWN (1 << 0)
|
#define IFACE_STATE_DOWN BIT(0)
|
||||||
#define IFACE_STATE_CONFIGURED (1 << 1)
|
#define IFACE_STATE_CONFIGURED BIT(1)
|
||||||
|
|
||||||
struct interface {
|
struct interface {
|
||||||
struct task_struct *ksmbd_kthread;
|
struct task_struct *ksmbd_kthread;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -142,8 +142,7 @@ static unsigned int kvec_array_init(struct kvec *new, struct kvec *iov,
|
||||||
*
|
*
|
||||||
* Return: return existing or newly allocate iovec
|
* Return: return existing or newly allocate iovec
|
||||||
*/
|
*/
|
||||||
static struct kvec *get_conn_iovec(struct tcp_transport *t,
|
static struct kvec *get_conn_iovec(struct tcp_transport *t, unsigned int nr_segs)
|
||||||
unsigned int nr_segs)
|
|
||||||
{
|
{
|
||||||
struct kvec *new_iov;
|
struct kvec *new_iov;
|
||||||
|
|
||||||
|
@ -287,10 +286,8 @@ static int ksmbd_tcp_run_kthread(struct interface *iface)
|
||||||
* Return: on success return number of bytes read from socket,
|
* Return: on success return number of bytes read from socket,
|
||||||
* otherwise return error number
|
* otherwise return error number
|
||||||
*/
|
*/
|
||||||
static int ksmbd_tcp_readv(struct tcp_transport *t,
|
static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
|
||||||
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;
|
||||||
|
@ -345,9 +342,7 @@ static int ksmbd_tcp_readv(struct tcp_transport *t,
|
||||||
* Return: on success return number of bytes read from socket,
|
* Return: on success return number of bytes read from socket,
|
||||||
* otherwise return error number
|
* otherwise return error number
|
||||||
*/
|
*/
|
||||||
static int ksmbd_tcp_read(struct ksmbd_transport *t,
|
static int ksmbd_tcp_read(struct ksmbd_transport *t, char *buf, unsigned int to_read)
|
||||||
char *buf,
|
|
||||||
unsigned int to_read)
|
|
||||||
{
|
{
|
||||||
struct kvec iov;
|
struct kvec iov;
|
||||||
|
|
||||||
|
@ -357,9 +352,8 @@ static int ksmbd_tcp_read(struct ksmbd_transport *t,
|
||||||
return ksmbd_tcp_readv(TCP_TRANS(t), &iov, 1, to_read);
|
return ksmbd_tcp_readv(TCP_TRANS(t), &iov, 1, to_read);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ksmbd_tcp_writev(struct ksmbd_transport *t,
|
static int ksmbd_tcp_writev(struct ksmbd_transport *t, struct kvec *iov,
|
||||||
struct kvec *iov, int nvecs, int size,
|
int nvecs, int size, bool need_invalidate, unsigned int remote_key)
|
||||||
bool need_invalidate, unsigned int remote_key)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
struct msghdr smb_msg = {.msg_flags = MSG_NOSIGNAL};
|
struct msghdr smb_msg = {.msg_flags = MSG_NOSIGNAL};
|
||||||
|
@ -473,7 +467,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;
|
||||||
|
@ -523,7 +517,6 @@ static int ksmbd_netdev_event(struct notifier_block *nb, unsigned long event,
|
||||||
}
|
}
|
||||||
|
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct notifier_block ksmbd_netdev_notifier = {
|
static struct notifier_block ksmbd_netdev_notifier = {
|
||||||
|
|
|
@ -26,9 +26,8 @@
|
||||||
*
|
*
|
||||||
* Return: string length after conversion
|
* Return: string length after conversion
|
||||||
*/
|
*/
|
||||||
static int smb_utf16_bytes(const __le16 *from,
|
static int smb_utf16_bytes(const __le16 *from, int maxbytes,
|
||||||
int maxbytes,
|
const struct nls_table *codepage)
|
||||||
const struct nls_table *codepage)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int charlen, outlen = 0;
|
int charlen, outlen = 0;
|
||||||
|
@ -66,7 +65,7 @@ static int smb_utf16_bytes(const __le16 *from,
|
||||||
*/
|
*/
|
||||||
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;
|
||||||
|
|
||||||
|
@ -124,9 +123,9 @@ static inline int is_char_allowed(char *ch)
|
||||||
{
|
{
|
||||||
/* check for control chars, wildcards etc. */
|
/* check for control chars, wildcards etc. */
|
||||||
if (!(*ch & 0x80) &&
|
if (!(*ch & 0x80) &&
|
||||||
(*ch <= 0x1f ||
|
(*ch <= 0x1f ||
|
||||||
*ch == '?' || *ch == '"' || *ch == '<' ||
|
*ch == '?' || *ch == '"' || *ch == '<' ||
|
||||||
*ch == '>' || *ch == '|'))
|
*ch == '>' || *ch == '|'))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -156,12 +155,8 @@ 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,
|
static int smb_from_utf16(char *to, const __le16 *from, int tolen, int fromlen,
|
||||||
const __le16 *from,
|
const struct nls_table *codepage, bool mapchar)
|
||||||
int tolen,
|
|
||||||
int fromlen,
|
|
||||||
const struct nls_table *codepage,
|
|
||||||
bool mapchar)
|
|
||||||
{
|
{
|
||||||
int i, charlen, safelen;
|
int i, charlen, safelen;
|
||||||
int outlen = 0;
|
int outlen = 0;
|
||||||
|
@ -214,8 +209,7 @@ static int smb_from_utf16(char *to,
|
||||||
*
|
*
|
||||||
* Return: string length after conversion
|
* Return: string length after conversion
|
||||||
*/
|
*/
|
||||||
int
|
int smb_strtoUTF16(__le16 *to, const char *from, int len,
|
||||||
smb_strtoUTF16(__le16 *to, const char *from, int len,
|
|
||||||
const struct nls_table *codepage)
|
const struct nls_table *codepage)
|
||||||
{
|
{
|
||||||
int charlen;
|
int charlen;
|
||||||
|
@ -230,7 +224,7 @@ 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)
|
||||||
|
@ -272,20 +266,19 @@ smb_strtoUTF16(__le16 *to, const char *from, int len,
|
||||||
*
|
*
|
||||||
* Return: destination string buffer or error ptr
|
* Return: destination string buffer or error ptr
|
||||||
*/
|
*/
|
||||||
char *
|
char *smb_strndup_from_utf16(const char *src, const int maxlen,
|
||||||
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;
|
||||||
|
|
||||||
if (is_unicode) {
|
if (is_unicode) {
|
||||||
len = smb_utf16_bytes((__le16 *) src, maxlen, codepage);
|
len = smb_utf16_bytes((__le16 *)src, maxlen, codepage);
|
||||||
len += nls_nullsize(codepage);
|
len += nls_nullsize(codepage);
|
||||||
dst = kmalloc(len, GFP_KERNEL);
|
dst = kmalloc(len, GFP_KERNEL);
|
||||||
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);
|
||||||
|
@ -324,9 +317,8 @@ smb_strndup_from_utf16(const char *src, const int maxlen,
|
||||||
*
|
*
|
||||||
* Return: char length after conversion
|
* Return: char length after conversion
|
||||||
*/
|
*/
|
||||||
int
|
int smbConvertToUTF16(__le16 *target, const char *source, int srclen,
|
||||||
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;
|
||||||
|
|
|
@ -32,13 +32,13 @@
|
||||||
* reserved symbols (along with \ and /), otherwise illegal to store
|
* reserved symbols (along with \ and /), otherwise illegal to store
|
||||||
* in filenames in NTFS
|
* in filenames in NTFS
|
||||||
*/
|
*/
|
||||||
#define UNI_ASTERISK ((__u16) ('*' + 0xF000))
|
#define UNI_ASTERISK ((__u16)('*' + 0xF000))
|
||||||
#define UNI_QUESTION ((__u16) ('?' + 0xF000))
|
#define UNI_QUESTION ((__u16)('?' + 0xF000))
|
||||||
#define UNI_COLON ((__u16) (':' + 0xF000))
|
#define UNI_COLON ((__u16)(':' + 0xF000))
|
||||||
#define UNI_GRTRTHAN ((__u16) ('>' + 0xF000))
|
#define UNI_GRTRTHAN ((__u16)('>' + 0xF000))
|
||||||
#define UNI_LESSTHAN ((__u16) ('<' + 0xF000))
|
#define UNI_LESSTHAN ((__u16)('<' + 0xF000))
|
||||||
#define UNI_PIPE ((__u16) ('|' + 0xF000))
|
#define UNI_PIPE ((__u16)('|' + 0xF000))
|
||||||
#define UNI_SLASH ((__u16) ('\\' + 0xF000))
|
#define UNI_SLASH ((__u16)('\\' + 0xF000))
|
||||||
|
|
||||||
/* Just define what we want from uniupr.h. We don't want to define the tables
|
/* Just define what we want from uniupr.h. We don't want to define the tables
|
||||||
* in each source file.
|
* in each source file.
|
||||||
|
@ -63,13 +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);
|
|
||||||
char *smb_strndup_from_utf16(const char *src, const int maxlen,
|
|
||||||
const bool is_unicode,
|
|
||||||
const struct nls_table *codepage);
|
const struct nls_table *codepage);
|
||||||
extern int smbConvertToUTF16(__le16 *target, const char *source, int srclen,
|
char *smb_strndup_from_utf16(const char *src, const int maxlen,
|
||||||
|
const bool is_unicode, const struct nls_table *codepage);
|
||||||
|
int smbConvertToUTF16(__le16 *target, const char *source, int srclen,
|
||||||
const struct nls_table *cp, int mapchars);
|
const struct nls_table *cp, int mapchars);
|
||||||
extern char *ksmbd_extract_sharename(char *treename);
|
char *ksmbd_extract_sharename(char *treename);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wchar_t cifs_toupper(wchar_t in);
|
wchar_t cifs_toupper(wchar_t in);
|
||||||
|
@ -80,8 +79,7 @@ wchar_t cifs_toupper(wchar_t in);
|
||||||
* Returns:
|
* Returns:
|
||||||
* Address of the first string
|
* Address of the first string
|
||||||
*/
|
*/
|
||||||
static inline wchar_t *
|
static inline wchar_t *UniStrcat(wchar_t *ucs1, const wchar_t *ucs2)
|
||||||
UniStrcat(wchar_t *ucs1, const wchar_t *ucs2)
|
|
||||||
{
|
{
|
||||||
wchar_t *anchor = ucs1; /* save a pointer to start of ucs1 */
|
wchar_t *anchor = ucs1; /* save a pointer to start of ucs1 */
|
||||||
|
|
||||||
|
@ -100,14 +98,13 @@ UniStrcat(wchar_t *ucs1, const wchar_t *ucs2)
|
||||||
* Address of first occurrence of character in string
|
* Address of first occurrence of character in string
|
||||||
* or NULL if the character is not in the string
|
* or NULL if the character is not in the string
|
||||||
*/
|
*/
|
||||||
static inline wchar_t *
|
static inline wchar_t *UniStrchr(const wchar_t *ucs, wchar_t uc)
|
||||||
UniStrchr(const wchar_t *ucs, wchar_t uc)
|
|
||||||
{
|
{
|
||||||
while ((*ucs != uc) && *ucs)
|
while ((*ucs != uc) && *ucs)
|
||||||
ucs++;
|
ucs++;
|
||||||
|
|
||||||
if (*ucs == uc)
|
if (*ucs == uc)
|
||||||
return (wchar_t *) ucs;
|
return (wchar_t *)ucs;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,21 +116,19 @@ UniStrchr(const wchar_t *ucs, wchar_t uc)
|
||||||
* = 0: Strings are equal
|
* = 0: Strings are equal
|
||||||
* > 0: First string is greater than second
|
* > 0: First string is greater than second
|
||||||
*/
|
*/
|
||||||
static inline int
|
static inline int UniStrcmp(const wchar_t *ucs1, const wchar_t *ucs2)
|
||||||
UniStrcmp(const wchar_t *ucs1, const wchar_t *ucs2)
|
|
||||||
{
|
{
|
||||||
while ((*ucs1 == *ucs2) && *ucs1) {
|
while ((*ucs1 == *ucs2) && *ucs1) {
|
||||||
ucs1++;
|
ucs1++;
|
||||||
ucs2++;
|
ucs2++;
|
||||||
}
|
}
|
||||||
return (int) *ucs1 - (int) *ucs2;
|
return (int)*ucs1 - (int)*ucs2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UniStrcpy: Copy a string
|
* UniStrcpy: Copy a string
|
||||||
*/
|
*/
|
||||||
static inline wchar_t *
|
static inline wchar_t *UniStrcpy(wchar_t *ucs1, const wchar_t *ucs2)
|
||||||
UniStrcpy(wchar_t *ucs1, const wchar_t *ucs2)
|
|
||||||
{
|
{
|
||||||
wchar_t *anchor = ucs1; /* save the start of result string */
|
wchar_t *anchor = ucs1; /* save the start of result string */
|
||||||
|
|
||||||
|
@ -145,8 +140,7 @@ UniStrcpy(wchar_t *ucs1, const wchar_t *ucs2)
|
||||||
/*
|
/*
|
||||||
* UniStrlen: Return the length of a string (in 16 bit Unicode chars not bytes)
|
* UniStrlen: Return the length of a string (in 16 bit Unicode chars not bytes)
|
||||||
*/
|
*/
|
||||||
static inline size_t
|
static inline size_t UniStrlen(const wchar_t *ucs1)
|
||||||
UniStrlen(const wchar_t *ucs1)
|
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
@ -159,8 +153,7 @@ UniStrlen(const wchar_t *ucs1)
|
||||||
* UniStrnlen: Return the length (in 16 bit Unicode chars not bytes) of a
|
* UniStrnlen: Return the length (in 16 bit Unicode chars not bytes) of a
|
||||||
* string (length limited)
|
* string (length limited)
|
||||||
*/
|
*/
|
||||||
static inline size_t
|
static inline size_t UniStrnlen(const wchar_t *ucs1, int maxlen)
|
||||||
UniStrnlen(const wchar_t *ucs1, int maxlen)
|
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
@ -175,8 +168,7 @@ UniStrnlen(const wchar_t *ucs1, int maxlen)
|
||||||
/*
|
/*
|
||||||
* UniStrncat: Concatenate length limited string
|
* UniStrncat: Concatenate length limited string
|
||||||
*/
|
*/
|
||||||
static inline wchar_t *
|
static inline wchar_t *UniStrncat(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
|
||||||
UniStrncat(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
|
|
||||||
{
|
{
|
||||||
wchar_t *anchor = ucs1; /* save pointer to string 1 */
|
wchar_t *anchor = ucs1; /* save pointer to string 1 */
|
||||||
|
|
||||||
|
@ -194,8 +186,7 @@ UniStrncat(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
|
||||||
/*
|
/*
|
||||||
* UniStrncmp: Compare length limited string
|
* UniStrncmp: Compare length limited string
|
||||||
*/
|
*/
|
||||||
static inline int
|
static inline int UniStrncmp(const wchar_t *ucs1, const wchar_t *ucs2, size_t n)
|
||||||
UniStrncmp(const wchar_t *ucs1, const wchar_t *ucs2, size_t n)
|
|
||||||
{
|
{
|
||||||
if (!n)
|
if (!n)
|
||||||
return 0; /* Null strings are equal */
|
return 0; /* Null strings are equal */
|
||||||
|
@ -203,7 +194,7 @@ UniStrncmp(const wchar_t *ucs1, const wchar_t *ucs2, size_t n)
|
||||||
ucs1++;
|
ucs1++;
|
||||||
ucs2++;
|
ucs2++;
|
||||||
}
|
}
|
||||||
return (int) *ucs1 - (int) *ucs2;
|
return (int)*ucs1 - (int)*ucs2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -218,14 +209,13 @@ UniStrncmp_le(const wchar_t *ucs1, const wchar_t *ucs2, size_t n)
|
||||||
ucs1++;
|
ucs1++;
|
||||||
ucs2++;
|
ucs2++;
|
||||||
}
|
}
|
||||||
return (int) *ucs1 - (int) __le16_to_cpu(*ucs2);
|
return (int)*ucs1 - (int)__le16_to_cpu(*ucs2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UniStrncpy: Copy length limited string with pad
|
* UniStrncpy: Copy length limited string with pad
|
||||||
*/
|
*/
|
||||||
static inline wchar_t *
|
static inline wchar_t *UniStrncpy(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
|
||||||
UniStrncpy(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
|
|
||||||
{
|
{
|
||||||
wchar_t *anchor = ucs1;
|
wchar_t *anchor = ucs1;
|
||||||
|
|
||||||
|
@ -241,8 +231,7 @@ UniStrncpy(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
|
||||||
/*
|
/*
|
||||||
* UniStrncpy_le: Copy length limited string with pad to little-endian
|
* UniStrncpy_le: Copy length limited string with pad to little-endian
|
||||||
*/
|
*/
|
||||||
static inline wchar_t *
|
static inline wchar_t *UniStrncpy_le(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
|
||||||
UniStrncpy_le(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
|
|
||||||
{
|
{
|
||||||
wchar_t *anchor = ucs1;
|
wchar_t *anchor = ucs1;
|
||||||
|
|
||||||
|
@ -262,8 +251,7 @@ UniStrncpy_le(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
|
||||||
* Address of first match found
|
* Address of first match found
|
||||||
* NULL if no matching string is found
|
* NULL if no matching string is found
|
||||||
*/
|
*/
|
||||||
static inline wchar_t *
|
static inline wchar_t *UniStrstr(const wchar_t *ucs1, const wchar_t *ucs2)
|
||||||
UniStrstr(const wchar_t *ucs1, const wchar_t *ucs2)
|
|
||||||
{
|
{
|
||||||
const wchar_t *anchor1 = ucs1;
|
const wchar_t *anchor1 = ucs1;
|
||||||
const wchar_t *anchor2 = ucs2;
|
const wchar_t *anchor2 = ucs2;
|
||||||
|
@ -275,14 +263,14 @@ UniStrstr(const wchar_t *ucs1, const wchar_t *ucs2)
|
||||||
ucs2++;
|
ucs2++;
|
||||||
} else {
|
} else {
|
||||||
if (!*ucs2) /* Match found */
|
if (!*ucs2) /* Match found */
|
||||||
return (wchar_t *) anchor1;
|
return (wchar_t *)anchor1;
|
||||||
ucs1 = ++anchor1; /* No match */
|
ucs1 = ++anchor1; /* No match */
|
||||||
ucs2 = anchor2;
|
ucs2 = anchor2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!*ucs2) /* Both end together */
|
if (!*ucs2) /* Both end together */
|
||||||
return (wchar_t *) anchor1; /* Match found */
|
return (wchar_t *)anchor1; /* Match found */
|
||||||
return NULL; /* No match */
|
return NULL; /* No match */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,8 +278,7 @@ UniStrstr(const wchar_t *ucs1, const wchar_t *ucs2)
|
||||||
/*
|
/*
|
||||||
* UniToupper: Convert a unicode character to upper case
|
* UniToupper: Convert a unicode character to upper case
|
||||||
*/
|
*/
|
||||||
static inline wchar_t
|
static inline wchar_t UniToupper(register wchar_t uc)
|
||||||
UniToupper(register wchar_t uc)
|
|
||||||
{
|
{
|
||||||
register const struct UniCaseRange *rp;
|
register const struct UniCaseRange *rp;
|
||||||
|
|
||||||
|
@ -314,8 +301,7 @@ UniToupper(register wchar_t uc)
|
||||||
/*
|
/*
|
||||||
* UniStrupr: Upper case a unicode string
|
* UniStrupr: Upper case a unicode string
|
||||||
*/
|
*/
|
||||||
static inline __le16 *
|
static inline __le16 *UniStrupr(register __le16 *upin)
|
||||||
UniStrupr(register __le16 *upin)
|
|
||||||
{
|
{
|
||||||
register __le16 *up;
|
register __le16 *up;
|
||||||
|
|
||||||
|
@ -332,8 +318,7 @@ UniStrupr(register __le16 *upin)
|
||||||
/*
|
/*
|
||||||
* UniTolower: Convert a unicode character to lower case
|
* UniTolower: Convert a unicode character to lower case
|
||||||
*/
|
*/
|
||||||
static inline wchar_t
|
static inline wchar_t UniTolower(register wchar_t uc)
|
||||||
UniTolower(register wchar_t uc)
|
|
||||||
{
|
{
|
||||||
register const struct UniCaseRange *rp;
|
register const struct UniCaseRange *rp;
|
||||||
|
|
||||||
|
@ -356,8 +341,7 @@ UniTolower(register wchar_t uc)
|
||||||
/*
|
/*
|
||||||
* UniStrlwr: Lower case a unicode string
|
* UniStrlwr: Lower case a unicode string
|
||||||
*/
|
*/
|
||||||
static inline wchar_t *
|
static inline wchar_t *UniStrlwr(register wchar_t *upin)
|
||||||
UniStrlwr(register wchar_t *upin)
|
|
||||||
{
|
{
|
||||||
register wchar_t *up;
|
register wchar_t *up;
|
||||||
|
|
||||||
|
|
158
fs/cifsd/vfs.c
158
fs/cifsd/vfs.c
|
@ -61,19 +61,17 @@ static void rollback_path_modification(char *filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
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 *parent_inode, struct inode *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))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
i_uid_write(inode, i_uid_read(parent_inode));
|
i_uid_write(inode, i_uid_read(parent_inode));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ksmbd_vfs_inherit_smack(struct ksmbd_work *work,
|
static void ksmbd_vfs_inherit_smack(struct ksmbd_work *work,
|
||||||
struct dentry *dir_dentry,
|
struct dentry *dir_dentry, struct dentry *dentry)
|
||||||
struct dentry *dentry)
|
|
||||||
{
|
{
|
||||||
char *name, *xattr_list = NULL, *smack_buf;
|
char *name, *xattr_list = NULL, *smack_buf;
|
||||||
int value_len, xattr_list_len;
|
int value_len, xattr_list_len;
|
||||||
|
@ -173,7 +171,6 @@ int ksmbd_vfs_query_maximal_access(struct dentry *dentry, __le32 *daccess)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ksmbd_vfs_create() - vfs helper for smb create file
|
* ksmbd_vfs_create() - vfs helper for smb create file
|
||||||
* @work: work
|
* @work: work
|
||||||
|
@ -182,9 +179,7 @@ int ksmbd_vfs_query_maximal_access(struct dentry *dentry, __le32 *daccess)
|
||||||
*
|
*
|
||||||
* Return: 0 on success, otherwise error
|
* Return: 0 on success, otherwise error
|
||||||
*/
|
*/
|
||||||
int ksmbd_vfs_create(struct ksmbd_work *work,
|
int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode)
|
||||||
const char *name,
|
|
||||||
umode_t mode)
|
|
||||||
{
|
{
|
||||||
struct path path;
|
struct path path;
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
|
@ -220,9 +215,7 @@ int ksmbd_vfs_create(struct ksmbd_work *work,
|
||||||
*
|
*
|
||||||
* Return: 0 on success, otherwise error
|
* Return: 0 on success, otherwise error
|
||||||
*/
|
*/
|
||||||
int ksmbd_vfs_mkdir(struct ksmbd_work *work,
|
int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode)
|
||||||
const char *name,
|
|
||||||
umode_t mode)
|
|
||||||
{
|
{
|
||||||
struct path path;
|
struct path path;
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
|
@ -243,17 +236,16 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work,
|
||||||
ksmbd_vfs_inherit_owner(work, d_inode(path.dentry),
|
ksmbd_vfs_inherit_owner(work, d_inode(path.dentry),
|
||||||
d_inode(dentry));
|
d_inode(dentry));
|
||||||
ksmbd_vfs_inherit_smack(work, path.dentry, dentry);
|
ksmbd_vfs_inherit_smack(work, path.dentry, dentry);
|
||||||
} else
|
} else {
|
||||||
ksmbd_err("mkdir(%s): creation failed (err:%d)\n", name, err);
|
ksmbd_err("mkdir(%s): creation failed (err:%d)\n", name, err);
|
||||||
|
}
|
||||||
|
|
||||||
done_path_create(&path, dentry);
|
done_path_create(&path, dentry);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t ksmbd_vfs_getcasexattr(struct dentry *dentry,
|
static ssize_t ksmbd_vfs_getcasexattr(struct dentry *dentry, char *attr_name,
|
||||||
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;
|
||||||
|
@ -282,7 +274,7 @@ static ssize_t ksmbd_vfs_getcasexattr(struct dentry *dentry,
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
@ -314,10 +306,8 @@ 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,
|
static int check_lock_range(struct file *filp, loff_t start, loff_t end,
|
||||||
loff_t start,
|
unsigned char type)
|
||||||
loff_t end,
|
|
||||||
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;
|
||||||
|
@ -360,9 +350,7 @@ static int check_lock_range(struct file *filp,
|
||||||
*
|
*
|
||||||
* 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,
|
int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count,
|
||||||
struct ksmbd_file *fp,
|
|
||||||
size_t count,
|
|
||||||
loff_t *pos)
|
loff_t *pos)
|
||||||
{
|
{
|
||||||
struct file *filp;
|
struct file *filp;
|
||||||
|
@ -416,7 +404,7 @@ int ksmbd_vfs_read(struct ksmbd_work *work,
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
@ -483,7 +471,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, ssize_t *written)
|
char *buf, size_t count, loff_t *pos, bool sync,
|
||||||
|
ssize_t *written)
|
||||||
{
|
{
|
||||||
struct ksmbd_session *sess = work->sess;
|
struct ksmbd_session *sess = work->sess;
|
||||||
struct file *filp;
|
struct file *filp;
|
||||||
|
@ -564,7 +553,7 @@ int ksmbd_vfs_getattr(struct path *path, struct kstat *stat)
|
||||||
*
|
*
|
||||||
* Return: 0 on success, otherwise error
|
* Return: 0 on success, otherwise error
|
||||||
*/
|
*/
|
||||||
int ksmbd_vfs_fsync(struct ksmbd_work *work, uint64_t fid, uint64_t p_id)
|
int ksmbd_vfs_fsync(struct ksmbd_work *work, u64 fid, u64 p_id)
|
||||||
{
|
{
|
||||||
struct ksmbd_file *fp;
|
struct ksmbd_file *fp;
|
||||||
int err;
|
int err;
|
||||||
|
@ -656,8 +645,8 @@ 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,
|
int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname,
|
||||||
const char *oldname, const char *newname)
|
const char *newname)
|
||||||
{
|
{
|
||||||
struct path oldpath, newpath;
|
struct path oldpath, newpath;
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
|
@ -702,11 +691,9 @@ int ksmbd_vfs_link(struct ksmbd_work *work,
|
||||||
}
|
}
|
||||||
|
|
||||||
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_parent, struct dentry *src_dent,
|
||||||
struct dentry *src_dent,
|
struct dentry *dst_dent_parent, struct dentry *trap_dent,
|
||||||
struct dentry *dst_dent_parent,
|
char *dst_name)
|
||||||
struct dentry *trap_dent,
|
|
||||||
char *dst_name)
|
|
||||||
{
|
{
|
||||||
struct dentry *dst_dent;
|
struct dentry *dst_dent;
|
||||||
int err;
|
int err;
|
||||||
|
@ -823,7 +810,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;
|
||||||
|
@ -906,8 +893,7 @@ ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list)
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t ksmbd_vfs_xattr_len(struct dentry *dentry,
|
static ssize_t ksmbd_vfs_xattr_len(struct dentry *dentry, char *xattr_name)
|
||||||
char *xattr_name)
|
|
||||||
{
|
{
|
||||||
return vfs_getxattr(&init_user_ns, dentry, xattr_name, NULL, 0);
|
return vfs_getxattr(&init_user_ns, dentry, xattr_name, NULL, 0);
|
||||||
}
|
}
|
||||||
|
@ -920,9 +906,8 @@ static ssize_t ksmbd_vfs_xattr_len(struct dentry *dentry,
|
||||||
*
|
*
|
||||||
* 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,
|
ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name,
|
||||||
char *xattr_name,
|
char **xattr_buf)
|
||||||
char **xattr_buf)
|
|
||||||
{
|
{
|
||||||
ssize_t xattr_len;
|
ssize_t xattr_len;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
@ -955,11 +940,8 @@ ssize_t ksmbd_vfs_getxattr(struct dentry *dentry,
|
||||||
*
|
*
|
||||||
* Return: 0 on success, otherwise error
|
* Return: 0 on success, otherwise error
|
||||||
*/
|
*/
|
||||||
int ksmbd_vfs_setxattr(struct dentry *dentry,
|
int ksmbd_vfs_setxattr(struct dentry *dentry, const char *attr_name,
|
||||||
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;
|
||||||
|
|
||||||
|
@ -987,9 +969,9 @@ void ksmbd_vfs_set_fadvise(struct file *filp, __le32 option)
|
||||||
if (!option || !mapping)
|
if (!option || !mapping)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (option & FILE_WRITE_THROUGH_LE)
|
if (option & FILE_WRITE_THROUGH_LE) {
|
||||||
filp->f_flags |= O_SYNC;
|
filp->f_flags |= O_SYNC;
|
||||||
else if (option & FILE_SEQUENTIAL_ONLY_LE) {
|
} else if (option & FILE_SEQUENTIAL_ONLY_LE) {
|
||||||
filp->f_ra.ra_pages = inode_to_bdi(mapping->host)->ra_pages * 2;
|
filp->f_ra.ra_pages = inode_to_bdi(mapping->host)->ra_pages * 2;
|
||||||
spin_lock(&filp->f_lock);
|
spin_lock(&filp->f_lock);
|
||||||
filp->f_mode &= ~FMODE_RANDOM;
|
filp->f_mode &= ~FMODE_RANDOM;
|
||||||
|
@ -1021,18 +1003,15 @@ int ksmbd_vfs_readdir(struct file *file, struct ksmbd_readdir_data *rdata)
|
||||||
return iterate_dir(file, &rdata->ctx);
|
return iterate_dir(file, &rdata->ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksmbd_vfs_alloc_size(struct ksmbd_work *work,
|
int ksmbd_vfs_alloc_size(struct ksmbd_work *work, struct ksmbd_file *fp,
|
||||||
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,
|
int ksmbd_vfs_zero_data(struct ksmbd_work *work, struct ksmbd_file *fp,
|
||||||
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)
|
||||||
|
@ -1085,8 +1064,9 @@ int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length,
|
||||||
if (extent_end != -ENXIO)
|
if (extent_end != -ENXIO)
|
||||||
ret = (int)extent_end;
|
ret = (int)extent_end;
|
||||||
break;
|
break;
|
||||||
} else if (extent_start >= extent_end)
|
} else if (extent_start >= extent_end) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
ranges[*out_count].file_offset = cpu_to_le64(extent_start);
|
ranges[*out_count].file_offset = cpu_to_le64(extent_start);
|
||||||
ranges[(*out_count)++].length =
|
ranges[(*out_count)++].length =
|
||||||
|
@ -1161,7 +1141,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;
|
||||||
|
|
||||||
|
@ -1186,12 +1166,8 @@ void ksmbd_vfs_smb2_sector_size(struct inode *inode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __dir_empty(struct dir_context *ctx,
|
static int __dir_empty(struct dir_context *ctx, const char *name, int namlen,
|
||||||
const char *name,
|
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;
|
||||||
|
|
||||||
|
@ -1227,12 +1203,8 @@ int ksmbd_vfs_empty_dir(struct ksmbd_file *fp)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __caseless_lookup(struct dir_context *ctx,
|
static int __caseless_lookup(struct dir_context *ctx, const char *name,
|
||||||
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;
|
||||||
|
|
||||||
|
@ -1260,7 +1232,7 @@ static int ksmbd_vfs_lookup_in_dir(char *dirname, char *filename)
|
||||||
struct path dir_path;
|
struct path dir_path;
|
||||||
int ret;
|
int ret;
|
||||||
struct file *dfilp;
|
struct file *dfilp;
|
||||||
int flags = O_RDONLY|O_LARGEFILE;
|
int flags = O_RDONLY | O_LARGEFILE;
|
||||||
int dirnamelen = strlen(dirname);
|
int dirnamelen = strlen(dirname);
|
||||||
struct ksmbd_readdir_data readdir_data = {
|
struct ksmbd_readdir_data readdir_data = {
|
||||||
.ctx.actor = __caseless_lookup,
|
.ctx.actor = __caseless_lookup,
|
||||||
|
@ -1349,9 +1321,9 @@ int ksmbd_vfs_remove_acl_xattrs(struct dentry *dentry)
|
||||||
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,
|
||||||
sizeof(XATTR_NAME_POSIX_ACL_ACCESS)-1) ||
|
sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1) ||
|
||||||
!strncmp(name, XATTR_NAME_POSIX_ACL_DEFAULT,
|
!strncmp(name, XATTR_NAME_POSIX_ACL_DEFAULT,
|
||||||
sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)-1)) {
|
sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1)) {
|
||||||
err = ksmbd_vfs_remove_xattr(dentry, name);
|
err = ksmbd_vfs_remove_xattr(dentry, name);
|
||||||
if (err)
|
if (err)
|
||||||
ksmbd_debug(SMB,
|
ksmbd_debug(SMB,
|
||||||
|
@ -1621,8 +1593,9 @@ int ksmbd_vfs_get_dos_attrib_xattr(struct dentry *dentry,
|
||||||
if (ndr_decode_dos_attr(&n, da))
|
if (ndr_decode_dos_attr(&n, da))
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
ksmbd_free(n.data);
|
ksmbd_free(n.data);
|
||||||
} else
|
} else {
|
||||||
ksmbd_debug(SMB, "failed to load dos attribute in xattr\n");
|
ksmbd_debug(SMB, "failed to load dos attribute in xattr\n");
|
||||||
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -1687,9 +1660,8 @@ void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat)
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work,
|
int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, struct dentry *dentry,
|
||||||
struct dentry *dentry,
|
struct ksmbd_kstat *ksmbd_kstat)
|
||||||
struct ksmbd_kstat *ksmbd_kstat)
|
|
||||||
{
|
{
|
||||||
u64 time;
|
u64 time;
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -1709,23 +1681,23 @@ int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work,
|
||||||
ksmbd_kstat->file_attributes = ATTR_ARCHIVE_LE;
|
ksmbd_kstat->file_attributes = ATTR_ARCHIVE_LE;
|
||||||
|
|
||||||
if (test_share_config_flag(work->tcon->share_conf,
|
if (test_share_config_flag(work->tcon->share_conf,
|
||||||
KSMBD_SHARE_FLAG_STORE_DOS_ATTRS)) {
|
KSMBD_SHARE_FLAG_STORE_DOS_ATTRS)) {
|
||||||
struct xattr_dos_attrib da;
|
struct xattr_dos_attrib da;
|
||||||
|
|
||||||
rc = ksmbd_vfs_get_dos_attrib_xattr(dentry, &da);
|
rc = ksmbd_vfs_get_dos_attrib_xattr(dentry, &da);
|
||||||
if (rc > 0) {
|
if (rc > 0) {
|
||||||
ksmbd_kstat->file_attributes = cpu_to_le32(da.attr);
|
ksmbd_kstat->file_attributes = cpu_to_le32(da.attr);
|
||||||
ksmbd_kstat->create_time = da.create_time;
|
ksmbd_kstat->create_time = da.create_time;
|
||||||
} else
|
} else {
|
||||||
ksmbd_debug(VFS, "fail to load dos attribute.\n");
|
ksmbd_debug(VFS, "fail to load dos attribute.\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t ksmbd_vfs_casexattr_len(struct dentry *dentry,
|
ssize_t ksmbd_vfs_casexattr_len(struct dentry *dentry, char *attr_name,
|
||||||
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;
|
||||||
|
@ -1749,10 +1721,8 @@ ssize_t ksmbd_vfs_casexattr_len(struct dentry *dentry,
|
||||||
return value_len;
|
return value_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksmbd_vfs_xattr_stream_name(char *stream_name,
|
int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_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;
|
||||||
|
@ -1791,8 +1761,7 @@ int ksmbd_vfs_xattr_stream_name(char *stream_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ksmbd_vfs_copy_file_range(struct file *file_in, loff_t pos_in,
|
static int ksmbd_vfs_copy_file_range(struct file *file_in, loff_t pos_in,
|
||||||
struct file *file_out, loff_t pos_out,
|
struct file *file_out, loff_t pos_out, size_t len)
|
||||||
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);
|
||||||
|
@ -1838,13 +1807,10 @@ static 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 *src_fp, struct ksmbd_file *dst_fp,
|
||||||
struct ksmbd_file *dst_fp,
|
struct srv_copychunk *chunks, unsigned int chunk_count,
|
||||||
struct srv_copychunk *chunks,
|
unsigned int *chunk_count_written,
|
||||||
unsigned int chunk_count,
|
unsigned int *chunk_size_written, loff_t *total_size_written)
|
||||||
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;
|
||||||
|
@ -1876,10 +1842,10 @@ int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work,
|
||||||
len = le32_to_cpu(chunks[i].Length);
|
len = le32_to_cpu(chunks[i].Length);
|
||||||
|
|
||||||
if (check_lock_range(src_fp->filp, src_off,
|
if (check_lock_range(src_fp->filp, src_off,
|
||||||
src_off + len - 1, READ))
|
src_off + len - 1, READ))
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
if (check_lock_range(dst_fp->filp, dst_off,
|
if (check_lock_range(dst_fp->filp, dst_off,
|
||||||
dst_off + len - 1, WRITE))
|
dst_off + len - 1, WRITE))
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,6 @@ struct xattr_ntacl {
|
||||||
#define XATTR_NAME_SD_LEN \
|
#define XATTR_NAME_SD_LEN \
|
||||||
(sizeof(XATTR_SECURITY_PREFIX SD_PREFIX) - 1)
|
(sizeof(XATTR_SECURITY_PREFIX SD_PREFIX) - 1)
|
||||||
|
|
||||||
|
|
||||||
/* CreateOptions */
|
/* CreateOptions */
|
||||||
/* Flag is set, it must not be a file , valid for directory only */
|
/* Flag is set, it must not be a file , valid for directory only */
|
||||||
#define FILE_DIRECTORY_FILE_LE cpu_to_le32(0x00000001)
|
#define FILE_DIRECTORY_FILE_LE cpu_to_le32(0x00000001)
|
||||||
|
@ -197,10 +196,11 @@ 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, ssize_t *written);
|
char *buf, size_t count, loff_t *pos, bool sync,
|
||||||
int ksmbd_vfs_fsync(struct ksmbd_work *work, uint64_t fid, uint64_t p_id);
|
ssize_t *written);
|
||||||
|
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);
|
||||||
|
@ -210,90 +210,53 @@ int ksmbd_vfs_readlink(struct path *path, char *buf, int lenp);
|
||||||
|
|
||||||
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_rename_slowpath(struct ksmbd_work *work,
|
|
||||||
char *oldname, 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 *src_fp, struct ksmbd_file *dst_fp,
|
||||||
struct ksmbd_file *dst_fp,
|
struct srv_copychunk *chunks, unsigned int chunk_count,
|
||||||
struct srv_copychunk *chunks,
|
unsigned int *chunk_count_written,
|
||||||
unsigned int chunk_count,
|
unsigned int *chunk_size_written, loff_t *total_size_written);
|
||||||
unsigned int *chunk_count_written,
|
|
||||||
unsigned int *chunk_size_written,
|
|
||||||
loff_t *total_size_written);
|
|
||||||
|
|
||||||
struct ksmbd_file *ksmbd_vfs_dentry_open(struct ksmbd_work *work,
|
|
||||||
const struct path *path,
|
|
||||||
int flags,
|
|
||||||
__le32 option,
|
|
||||||
int fexist);
|
|
||||||
|
|
||||||
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,
|
ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name,
|
||||||
char *xattr_name,
|
char **xattr_buf);
|
||||||
char **xattr_buf);
|
ssize_t ksmbd_vfs_casexattr_len(struct dentry *dentry, char *attr_name,
|
||||||
|
int attr_name_len);
|
||||||
ssize_t ksmbd_vfs_casexattr_len(struct dentry *dentry,
|
int ksmbd_vfs_setxattr(struct dentry *dentry, const char *attr_name,
|
||||||
char *attr_name,
|
const void *attr_value, size_t attr_size, int flags);
|
||||||
int attr_name_len);
|
int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name,
|
||||||
|
size_t *xattr_stream_name_size, int s_type);
|
||||||
int ksmbd_vfs_setxattr(struct dentry *dentry,
|
|
||||||
const char *attr_name,
|
|
||||||
const void *attr_value,
|
|
||||||
size_t attr_size,
|
|
||||||
int flags);
|
|
||||||
|
|
||||||
int ksmbd_vfs_fsetxattr(const char *filename,
|
|
||||||
const char *attr_name,
|
|
||||||
const void *attr_value,
|
|
||||||
size_t attr_size,
|
|
||||||
int flags);
|
|
||||||
|
|
||||||
int ksmbd_vfs_xattr_stream_name(char *stream_name,
|
|
||||||
char **xattr_stream_name,
|
|
||||||
size_t *xattr_stream_name_size,
|
|
||||||
int s_type);
|
|
||||||
|
|
||||||
int ksmbd_vfs_truncate_xattr(struct dentry *dentry, int wo_streams);
|
int ksmbd_vfs_truncate_xattr(struct dentry *dentry, int wo_streams);
|
||||||
int ksmbd_vfs_remove_xattr(struct dentry *dentry, char *attr_name);
|
int ksmbd_vfs_remove_xattr(struct dentry *dentry, char *attr_name);
|
||||||
void ksmbd_vfs_xattr_free(char *xattr);
|
void ksmbd_vfs_xattr_free(char *xattr);
|
||||||
|
|
||||||
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,
|
int ksmbd_vfs_alloc_size(struct ksmbd_work *work, struct ksmbd_file *fp,
|
||||||
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,
|
loff_t off, loff_t len);
|
||||||
struct ksmbd_file *fp,
|
|
||||||
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 ksmbd_kstat *ksmbd_kstat);
|
||||||
struct dentry *dentry,
|
|
||||||
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,
|
||||||
|
|
|
@ -284,8 +284,7 @@ static void __ksmbd_remove_durable_fd(struct ksmbd_file *fp)
|
||||||
write_unlock(&global_ft.lock);
|
write_unlock(&global_ft.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __ksmbd_remove_fd(struct ksmbd_file_table *ft,
|
static void __ksmbd_remove_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp)
|
||||||
struct ksmbd_file *fp)
|
|
||||||
{
|
{
|
||||||
if (!HAS_FILE_ID(fp->volatile_id))
|
if (!HAS_FILE_ID(fp->volatile_id))
|
||||||
return;
|
return;
|
||||||
|
@ -299,8 +298,7 @@ static void __ksmbd_remove_fd(struct ksmbd_file_table *ft,
|
||||||
write_unlock(&ft->lock);
|
write_unlock(&ft->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __ksmbd_close_fd(struct ksmbd_file_table *ft,
|
static void __ksmbd_close_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp)
|
||||||
struct ksmbd_file *fp)
|
|
||||||
{
|
{
|
||||||
struct file *filp;
|
struct file *filp;
|
||||||
|
|
||||||
|
@ -328,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)
|
||||||
{
|
{
|
||||||
bool unclaimed = true;
|
bool unclaimed = true;
|
||||||
struct ksmbd_file *fp;
|
struct ksmbd_file *fp;
|
||||||
|
@ -352,8 +350,7 @@ static struct ksmbd_file *__ksmbd_lookup_fd(struct ksmbd_file_table *ft,
|
||||||
return fp;
|
return fp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __put_fd_final(struct ksmbd_work *work,
|
static void __put_fd_final(struct ksmbd_work *work, struct ksmbd_file *fp)
|
||||||
struct ksmbd_file *fp)
|
|
||||||
{
|
{
|
||||||
__ksmbd_close_fd(&work->sess->file_table, fp);
|
__ksmbd_close_fd(&work->sess->file_table, fp);
|
||||||
atomic_dec(&work->conn->stats.open_files_count);
|
atomic_dec(&work->conn->stats.open_files_count);
|
||||||
|
@ -399,8 +396,7 @@ int ksmbd_close_fd(struct ksmbd_work *work, unsigned int id)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ksmbd_fd_put(struct ksmbd_work *work,
|
void ksmbd_fd_put(struct ksmbd_work *work, struct ksmbd_file *fp)
|
||||||
struct ksmbd_file *fp)
|
|
||||||
{
|
{
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return;
|
return;
|
||||||
|
@ -410,8 +406,7 @@ void ksmbd_fd_put(struct ksmbd_work *work,
|
||||||
__put_fd_final(work, fp);
|
__put_fd_final(work, fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool __sanity_check(struct ksmbd_tree_connect *tcon,
|
static bool __sanity_check(struct ksmbd_tree_connect *tcon, struct ksmbd_file *fp)
|
||||||
struct ksmbd_file *fp)
|
|
||||||
{
|
{
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return false;
|
return false;
|
||||||
|
@ -420,14 +415,12 @@ static bool __sanity_check(struct ksmbd_tree_connect *tcon,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ksmbd_file *ksmbd_lookup_foreign_fd(struct ksmbd_work *work,
|
struct ksmbd_file *ksmbd_lookup_foreign_fd(struct ksmbd_work *work, unsigned int id)
|
||||||
unsigned int id)
|
|
||||||
{
|
{
|
||||||
return __ksmbd_lookup_fd(&work->sess->file_table, id);
|
return __ksmbd_lookup_fd(&work->sess->file_table, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ksmbd_file *ksmbd_lookup_fd_fast(struct ksmbd_work *work,
|
struct ksmbd_file *ksmbd_lookup_fd_fast(struct ksmbd_work *work, unsigned int id)
|
||||||
unsigned int id)
|
|
||||||
{
|
{
|
||||||
struct ksmbd_file *fp = __ksmbd_lookup_fd(&work->sess->file_table, id);
|
struct ksmbd_file *fp = __ksmbd_lookup_fd(&work->sess->file_table, id);
|
||||||
|
|
||||||
|
@ -438,9 +431,8 @@ struct ksmbd_file *ksmbd_lookup_fd_fast(struct ksmbd_work *work,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work,
|
struct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work, unsigned int id,
|
||||||
unsigned int id,
|
unsigned int pid)
|
||||||
unsigned int pid)
|
|
||||||
{
|
{
|
||||||
struct ksmbd_file *fp;
|
struct ksmbd_file *fp;
|
||||||
|
|
||||||
|
@ -469,8 +461,7 @@ struct ksmbd_file *ksmbd_lookup_durable_fd(unsigned long long id)
|
||||||
return __ksmbd_lookup_fd(&global_ft, id);
|
return __ksmbd_lookup_fd(&global_ft, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksmbd_close_fd_app_id(struct ksmbd_work *work,
|
int ksmbd_close_fd_app_id(struct ksmbd_work *work, char *app_id)
|
||||||
char *app_id)
|
|
||||||
{
|
{
|
||||||
struct ksmbd_file *fp = NULL;
|
struct ksmbd_file *fp = NULL;
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
|
@ -513,8 +504,7 @@ struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid)
|
||||||
return fp;
|
return fp;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ksmbd_file *ksmbd_lookup_fd_filename(struct ksmbd_work *work,
|
struct ksmbd_file *ksmbd_lookup_fd_filename(struct ksmbd_work *work, char *filename)
|
||||||
char *filename)
|
|
||||||
{
|
{
|
||||||
struct ksmbd_file *fp = NULL;
|
struct ksmbd_file *fp = NULL;
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
|
@ -566,8 +556,7 @@ static void __open_id_set(struct ksmbd_file *fp, unsigned int id, int type)
|
||||||
fp->persistent_id = id;
|
fp->persistent_id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __open_id(struct ksmbd_file_table *ft,
|
static int __open_id(struct ksmbd_file_table *ft, struct ksmbd_file *fp,
|
||||||
struct ksmbd_file *fp,
|
|
||||||
int type)
|
int type)
|
||||||
{
|
{
|
||||||
unsigned int id = 0;
|
unsigned int id = 0;
|
||||||
|
@ -601,8 +590,7 @@ unsigned int ksmbd_open_durable_fd(struct ksmbd_file *fp)
|
||||||
return fp->persistent_id;
|
return fp->persistent_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work,
|
struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp)
|
||||||
struct file *filp)
|
|
||||||
{
|
{
|
||||||
struct ksmbd_file *fp;
|
struct ksmbd_file *fp;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -657,7 +645,7 @@ static inline bool is_reconnectable(struct ksmbd_file *fp)
|
||||||
if (fp->is_resilient || fp->is_persistent)
|
if (fp->is_resilient || fp->is_persistent)
|
||||||
reconn = true;
|
reconn = true;
|
||||||
else if (fp->is_durable && opinfo->is_lease &&
|
else if (fp->is_durable && opinfo->is_lease &&
|
||||||
opinfo->o_lease->state & SMB2_LEASE_HANDLE_CACHING_LE)
|
opinfo->o_lease->state & SMB2_LEASE_HANDLE_CACHING_LE)
|
||||||
reconn = true;
|
reconn = true;
|
||||||
|
|
||||||
else if (fp->is_durable && opinfo->level == SMB2_OPLOCK_LEVEL_BATCH)
|
else if (fp->is_durable && opinfo->level == SMB2_OPLOCK_LEVEL_BATCH)
|
||||||
|
@ -668,10 +656,8 @@ static inline bool is_reconnectable(struct ksmbd_file *fp)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
__close_file_table_ids(struct ksmbd_file_table *ft,
|
__close_file_table_ids(struct ksmbd_file_table *ft, struct ksmbd_tree_connect *tcon,
|
||||||
struct ksmbd_tree_connect *tcon,
|
bool (*skip)(struct ksmbd_tree_connect *tcon, struct ksmbd_file *fp))
|
||||||
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;
|
||||||
|
@ -691,14 +677,12 @@ __close_file_table_ids(struct ksmbd_file_table *ft,
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool tree_conn_fd_check(struct ksmbd_tree_connect *tcon,
|
static bool tree_conn_fd_check(struct ksmbd_tree_connect *tcon, struct ksmbd_file *fp)
|
||||||
struct ksmbd_file *fp)
|
|
||||||
{
|
{
|
||||||
return fp->tcon != tcon;
|
return fp->tcon != tcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool session_fd_check(struct ksmbd_tree_connect *tcon,
|
static bool session_fd_check(struct ksmbd_tree_connect *tcon, struct ksmbd_file *fp)
|
||||||
struct ksmbd_file *fp)
|
|
||||||
{
|
{
|
||||||
if (!is_reconnectable(fp))
|
if (!is_reconnectable(fp))
|
||||||
return false;
|
return false;
|
||||||
|
@ -745,8 +729,7 @@ void ksmbd_free_global_file_table(void)
|
||||||
ksmbd_destroy_file_table(&global_ft);
|
ksmbd_destroy_file_table(&global_ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksmbd_reopen_durable_fd(struct ksmbd_work *work,
|
int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp)
|
||||||
struct ksmbd_file *fp)
|
|
||||||
{
|
{
|
||||||
if (!fp->is_durable || fp->conn || fp->tcon) {
|
if (!fp->is_durable || fp->conn || fp->tcon) {
|
||||||
ksmbd_err("Invalid durable fd [%p:%p]\n",
|
ksmbd_err("Invalid durable fd [%p:%p]\n",
|
||||||
|
|
|
@ -149,50 +149,31 @@ static inline bool ksmbd_stream_fd(struct ksmbd_file *fp)
|
||||||
|
|
||||||
int ksmbd_init_file_table(struct ksmbd_file_table *ft);
|
int ksmbd_init_file_table(struct ksmbd_file_table *ft);
|
||||||
void ksmbd_destroy_file_table(struct ksmbd_file_table *ft);
|
void ksmbd_destroy_file_table(struct ksmbd_file_table *ft);
|
||||||
|
|
||||||
int ksmbd_close_fd(struct ksmbd_work *work, unsigned int id);
|
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,
|
struct ksmbd_file *ksmbd_lookup_foreign_fd(struct ksmbd_work *work, unsigned int id);
|
||||||
unsigned int id);
|
struct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work, unsigned int id,
|
||||||
struct ksmbd_file *ksmbd_lookup_foreign_fd(struct ksmbd_work *work,
|
unsigned int pid);
|
||||||
unsigned int id);
|
|
||||||
struct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work,
|
|
||||||
unsigned int id,
|
|
||||||
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);
|
||||||
|
|
||||||
int ksmbd_close_fd_app_id(struct ksmbd_work *work, char *app_id);
|
int ksmbd_close_fd_app_id(struct ksmbd_work *work, char *app_id);
|
||||||
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);
|
||||||
struct ksmbd_file *ksmbd_lookup_fd_filename(struct ksmbd_work *work,
|
struct ksmbd_file *ksmbd_lookup_fd_filename(struct ksmbd_work *work, char *filename);
|
||||||
char *filename);
|
|
||||||
struct ksmbd_file *ksmbd_lookup_fd_inode(struct inode *inode);
|
struct ksmbd_file *ksmbd_lookup_fd_inode(struct inode *inode);
|
||||||
|
|
||||||
unsigned int ksmbd_open_durable_fd(struct ksmbd_file *fp);
|
unsigned int ksmbd_open_durable_fd(struct ksmbd_file *fp);
|
||||||
|
struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp);
|
||||||
struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work,
|
|
||||||
struct file *filp);
|
|
||||||
|
|
||||||
void ksmbd_close_tree_conn_fds(struct ksmbd_work *work);
|
void ksmbd_close_tree_conn_fds(struct ksmbd_work *work);
|
||||||
void ksmbd_close_session_fds(struct ksmbd_work *work);
|
void ksmbd_close_session_fds(struct ksmbd_work *work);
|
||||||
|
|
||||||
int ksmbd_close_inode_fds(struct ksmbd_work *work, struct inode *inode);
|
int ksmbd_close_inode_fds(struct ksmbd_work *work, struct inode *inode);
|
||||||
|
int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp);
|
||||||
int ksmbd_reopen_durable_fd(struct ksmbd_work *work,
|
|
||||||
struct ksmbd_file *fp);
|
|
||||||
|
|
||||||
int ksmbd_init_global_file_table(void);
|
int ksmbd_init_global_file_table(void);
|
||||||
void ksmbd_free_global_file_table(void);
|
void ksmbd_free_global_file_table(void);
|
||||||
|
|
||||||
int ksmbd_file_table_flush(struct ksmbd_work *work);
|
int ksmbd_file_table_flush(struct ksmbd_work *work);
|
||||||
|
|
||||||
void ksmbd_set_fd_limit(unsigned long limit);
|
void ksmbd_set_fd_limit(unsigned long limit);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* INODE hash
|
* INODE hash
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int __init ksmbd_inode_hash_init(void);
|
int __init ksmbd_inode_hash_init(void);
|
||||||
void ksmbd_release_inode_hash(void);
|
void ksmbd_release_inode_hash(void);
|
||||||
|
|
||||||
|
@ -203,11 +184,9 @@ enum KSMBD_INODE_STATUS {
|
||||||
};
|
};
|
||||||
|
|
||||||
int ksmbd_query_inode_status(struct inode *inode);
|
int ksmbd_query_inode_status(struct inode *inode);
|
||||||
|
|
||||||
bool ksmbd_inode_pending_delete(struct ksmbd_file *fp);
|
bool ksmbd_inode_pending_delete(struct ksmbd_file *fp);
|
||||||
void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp);
|
void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp);
|
||||||
void ksmbd_clear_inode_pending_delete(struct ksmbd_file *fp);
|
void ksmbd_clear_inode_pending_delete(struct ksmbd_file *fp);
|
||||||
|
|
||||||
void ksmbd_fd_set_delete_on_close(struct ksmbd_file *fp,
|
void ksmbd_fd_set_delete_on_close(struct ksmbd_file *fp,
|
||||||
int file_info);
|
int file_info);
|
||||||
#endif /* __VFS_CACHE_H__ */
|
#endif /* __VFS_CACHE_H__ */
|
||||||
|
|
Loading…
Reference in New Issue