提交 64b39f4a 编写于 作者: N Namjae Jeon 提交者: Steve French

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: NNamjae Jeon <namjae.jeon@samsung.com>
Signed-off-by: NSteve French <stfrench@microsoft.com>
上级 7cb82de3
...@@ -64,7 +64,6 @@ static char NEGOTIATE_GSS_HEADER[AUTH_GSS_LENGTH] = { ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 { ...@@ -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, ...@@ -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 { ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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 { ...@@ -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); ...@@ -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; ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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));
......
// 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); ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 @@ ...@@ -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 { ...@@ -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 { ...@@ -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); ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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", ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
} }
......
...@@ -58,7 +58,7 @@ static void __wbuf(struct ksmbd_work *work, void **req, void **rsp) ...@@ -58,7 +58,7 @@ static void __wbuf(struct ksmbd_work *work, void **req, void **rsp)
* *
* Return: 1 if valid session id, otherwise 0 * Return: 1 if valid session id, otherwise 0
*/ */
static inline int check_session_id(struct ksmbd_conn *conn, uint64_t id) static inline int check_session_id(struct ksmbd_conn *conn, u64 id)
{ {
struct ksmbd_session *sess; struct ksmbd_session *sess;
...@@ -98,9 +98,9 @@ int smb2_get_ksmbd_tcon(struct ksmbd_work *work) ...@@ -98,9 +98,9 @@ int smb2_get_ksmbd_tcon(struct ksmbd_work *work)
int tree_id; int tree_id;
work->tcon = NULL; work->tcon = NULL;
if ((work->conn->ops->get_cmd_val(work) == SMB2_TREE_CONNECT_HE) || if (work->conn->ops->get_cmd_val(work) == SMB2_TREE_CONNECT_HE ||
(work->conn->ops->get_cmd_val(work) == SMB2_CANCEL_HE) || work->conn->ops->get_cmd_val(work) == SMB2_CANCEL_HE ||
(work->conn->ops->get_cmd_val(work) == SMB2_LOGOFF_HE)) { work->conn->ops->get_cmd_val(work) == SMB2_LOGOFF_HE) {
ksmbd_debug(SMB, "skip to check tree connect request\n"); ksmbd_debug(SMB, "skip to check tree connect request\n");
return 0; return 0;
} }
...@@ -238,7 +238,7 @@ int init_smb2_neg_rsp(struct ksmbd_work *work) ...@@ -238,7 +238,7 @@ int init_smb2_neg_rsp(struct ksmbd_work *work)
if (conn->need_neg == false) if (conn->need_neg == false)
return -EINVAL; return -EINVAL;
if (!(conn->dialect >= SMB20_PROT_ID && if (!(conn->dialect >= SMB20_PROT_ID &&
conn->dialect <= SMB311_PROT_ID)) conn->dialect <= SMB311_PROT_ID))
return -EINVAL; return -EINVAL;
rsp_hdr = work->response_buf; rsp_hdr = work->response_buf;
...@@ -549,8 +549,8 @@ int smb2_allocate_rsp_buf(struct ksmbd_work *work) ...@@ -549,8 +549,8 @@ int smb2_allocate_rsp_buf(struct ksmbd_work *work)
req = work->request_buf; req = work->request_buf;
if (req->InfoType == SMB2_O_INFO_FILE && if (req->InfoType == SMB2_O_INFO_FILE &&
(req->FileInfoClass == FILE_FULL_EA_INFORMATION || (req->FileInfoClass == FILE_FULL_EA_INFORMATION ||
req->FileInfoClass == FILE_ALL_INFORMATION)) { req->FileInfoClass == FILE_ALL_INFORMATION)) {
sz = large_sz; sz = large_sz;
work->set_trans_buf = true; work->set_trans_buf = true;
} }
...@@ -595,7 +595,7 @@ int smb2_check_user_session(struct ksmbd_work *work) ...@@ -595,7 +595,7 @@ int smb2_check_user_session(struct ksmbd_work *work)
* these commands. * these commands.
*/ */
if (cmd == SMB2_ECHO_HE || cmd == SMB2_NEGOTIATE_HE || if (cmd == SMB2_ECHO_HE || cmd == SMB2_NEGOTIATE_HE ||
cmd == SMB2_SESSION_SETUP_HE) cmd == SMB2_SESSION_SETUP_HE)
return 0; return 0;
if (!ksmbd_conn_good(work)) if (!ksmbd_conn_good(work))
...@@ -610,7 +610,7 @@ int smb2_check_user_session(struct ksmbd_work *work) ...@@ -610,7 +610,7 @@ int smb2_check_user_session(struct ksmbd_work *work)
return -EINVAL; return -EINVAL;
} }
static void destroy_previous_session(struct ksmbd_user *user, uint64_t id) static void destroy_previous_session(struct ksmbd_user *user, u64 id)
{ {
struct ksmbd_session *prev_sess = ksmbd_session_lookup_slowpath(id); struct ksmbd_session *prev_sess = ksmbd_session_lookup_slowpath(id);
struct ksmbd_user *prev_user; struct ksmbd_user *prev_user;
...@@ -641,15 +641,12 @@ static void destroy_previous_session(struct ksmbd_user *user, uint64_t id) ...@@ -641,15 +641,12 @@ static void destroy_previous_session(struct ksmbd_user *user, uint64_t id)
* Return: matching converted filename on success, otherwise error ptr * Return: matching converted filename on success, otherwise error ptr
*/ */
static char * static char *
smb2_get_name(struct ksmbd_share_config *share, smb2_get_name(struct ksmbd_share_config *share, const char *src,
const char *src, const int maxlen, struct nls_table *local_nls)
const int maxlen,
struct nls_table *local_nls)
{ {
char *name, *unixname; char *name, *unixname;
name = smb_strndup_from_utf16(src, maxlen, 1, name = smb_strndup_from_utf16(src, maxlen, 1, local_nls);
local_nls);
if (IS_ERR(name)) { if (IS_ERR(name)) {
ksmbd_err("failed to get name %ld\n", PTR_ERR(name)); ksmbd_err("failed to get name %ld\n", PTR_ERR(name));
return name; return name;
...@@ -756,10 +753,10 @@ static int smb2_get_dos_mode(struct kstat *stat, int attribute) ...@@ -756,10 +753,10 @@ static int smb2_get_dos_mode(struct kstat *stat, int attribute)
{ {
int attr = 0; int attr = 0;
if (S_ISDIR(stat->mode)) if (S_ISDIR(stat->mode)) {
attr = ATTR_DIRECTORY | attr = ATTR_DIRECTORY |
(attribute & (ATTR_HIDDEN | ATTR_SYSTEM)); (attribute & (ATTR_HIDDEN | ATTR_SYSTEM));
else { } else {
attr = (attribute & 0x00005137) | ATTR_ARCHIVE; attr = (attribute & 0x00005137) | ATTR_ARCHIVE;
attr &= ~(ATTR_DIRECTORY); attr &= ~(ATTR_DIRECTORY);
if (S_ISREG(stat->mode) && (server_conf.share_fake_fscaps & if (S_ISREG(stat->mode) && (server_conf.share_fake_fscaps &
...@@ -774,7 +771,7 @@ static int smb2_get_dos_mode(struct kstat *stat, int attribute) ...@@ -774,7 +771,7 @@ static int smb2_get_dos_mode(struct kstat *stat, int attribute)
} }
static void build_preauth_ctxt(struct smb2_preauth_neg_context *pneg_ctxt, static void build_preauth_ctxt(struct smb2_preauth_neg_context *pneg_ctxt,
__le16 hash_id) __le16 hash_id)
{ {
pneg_ctxt->ContextType = SMB2_PREAUTH_INTEGRITY_CAPABILITIES; pneg_ctxt->ContextType = SMB2_PREAUTH_INTEGRITY_CAPABILITIES;
pneg_ctxt->DataLength = cpu_to_le16(38); pneg_ctxt->DataLength = cpu_to_le16(38);
...@@ -786,7 +783,7 @@ static void build_preauth_ctxt(struct smb2_preauth_neg_context *pneg_ctxt, ...@@ -786,7 +783,7 @@ static void build_preauth_ctxt(struct smb2_preauth_neg_context *pneg_ctxt,
} }
static void build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt, static void build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt,
__le16 cipher_type) __le16 cipher_type)
{ {
pneg_ctxt->ContextType = SMB2_ENCRYPTION_CAPABILITIES; pneg_ctxt->ContextType = SMB2_ENCRYPTION_CAPABILITIES;
pneg_ctxt->DataLength = cpu_to_le16(4); pneg_ctxt->DataLength = cpu_to_le16(4);
...@@ -796,7 +793,7 @@ static void build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt, ...@@ -796,7 +793,7 @@ static void build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt,
} }
static void build_compression_ctxt(struct smb2_compression_ctx *pneg_ctxt, static void build_compression_ctxt(struct smb2_compression_ctx *pneg_ctxt,
__le16 comp_algo) __le16 comp_algo)
{ {
pneg_ctxt->ContextType = SMB2_COMPRESSION_CAPABILITIES; pneg_ctxt->ContextType = SMB2_COMPRESSION_CAPABILITIES;
pneg_ctxt->DataLength = pneg_ctxt->DataLength =
...@@ -808,8 +805,7 @@ static void build_compression_ctxt(struct smb2_compression_ctx *pneg_ctxt, ...@@ -808,8 +805,7 @@ static void build_compression_ctxt(struct smb2_compression_ctx *pneg_ctxt,
pneg_ctxt->CompressionAlgorithms[0] = comp_algo; pneg_ctxt->CompressionAlgorithms[0] = comp_algo;
} }
static void static void build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
{ {
pneg_ctxt->ContextType = SMB2_POSIX_EXTENSIONS_AVAILABLE; pneg_ctxt->ContextType = SMB2_POSIX_EXTENSIONS_AVAILABLE;
pneg_ctxt->DataLength = cpu_to_le16(POSIX_CTXT_DATA_LEN); pneg_ctxt->DataLength = cpu_to_le16(POSIX_CTXT_DATA_LEN);
...@@ -832,9 +828,8 @@ build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt) ...@@ -832,9 +828,8 @@ build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
pneg_ctxt->Name[15] = 0x7C; pneg_ctxt->Name[15] = 0x7C;
} }
static void static void assemble_neg_contexts(struct ksmbd_conn *conn,
assemble_neg_contexts(struct ksmbd_conn *conn, struct smb2_negotiate_rsp *rsp)
struct smb2_negotiate_rsp *rsp)
{ {
/* +4 is to account for the RFC1001 len field */ /* +4 is to account for the RFC1001 len field */
char *pneg_ctxt = (char *)rsp + char *pneg_ctxt = (char *)rsp +
...@@ -856,8 +851,7 @@ assemble_neg_contexts(struct ksmbd_conn *conn, ...@@ -856,8 +851,7 @@ assemble_neg_contexts(struct ksmbd_conn *conn,
ctxt_size = round_up(ctxt_size, 8); ctxt_size = round_up(ctxt_size, 8);
ksmbd_debug(SMB, ksmbd_debug(SMB,
"assemble SMB2_ENCRYPTION_CAPABILITIES context\n"); "assemble SMB2_ENCRYPTION_CAPABILITIES context\n");
build_encrypt_ctxt( build_encrypt_ctxt((struct smb2_encryption_neg_context *)pneg_ctxt,
(struct smb2_encryption_neg_context *)pneg_ctxt,
conn->cipher_type); conn->cipher_type);
rsp->NegotiateContextCount = cpu_to_le16(++neg_ctxt_cnt); rsp->NegotiateContextCount = cpu_to_le16(++neg_ctxt_cnt);
ctxt_size += sizeof(struct smb2_encryption_neg_context); ctxt_size += sizeof(struct smb2_encryption_neg_context);
...@@ -892,9 +886,8 @@ assemble_neg_contexts(struct ksmbd_conn *conn, ...@@ -892,9 +886,8 @@ assemble_neg_contexts(struct ksmbd_conn *conn,
inc_rfc1001_len(rsp, ctxt_size); inc_rfc1001_len(rsp, ctxt_size);
} }
static __le32 static __le32 decode_preauth_ctxt(struct ksmbd_conn *conn,
decode_preauth_ctxt(struct ksmbd_conn *conn, struct smb2_preauth_neg_context *pneg_ctxt)
struct smb2_preauth_neg_context *pneg_ctxt)
{ {
__le32 err = STATUS_NO_PREAUTH_INTEGRITY_HASH_OVERLAP; __le32 err = STATUS_NO_PREAUTH_INTEGRITY_HASH_OVERLAP;
...@@ -909,7 +902,7 @@ decode_preauth_ctxt(struct ksmbd_conn *conn, ...@@ -909,7 +902,7 @@ decode_preauth_ctxt(struct ksmbd_conn *conn,
} }
static int decode_encrypt_ctxt(struct ksmbd_conn *conn, static int decode_encrypt_ctxt(struct ksmbd_conn *conn,
struct smb2_encryption_neg_context *pneg_ctxt) struct smb2_encryption_neg_context *pneg_ctxt)
{ {
int i; int i;
int cph_cnt = le16_to_cpu(pneg_ctxt->CipherCount); int cph_cnt = le16_to_cpu(pneg_ctxt->CipherCount);
...@@ -921,7 +914,7 @@ static int decode_encrypt_ctxt(struct ksmbd_conn *conn, ...@@ -921,7 +914,7 @@ static int decode_encrypt_ctxt(struct ksmbd_conn *conn,
for (i = 0; i < cph_cnt; i++) { for (i = 0; i < cph_cnt; i++) {
if (pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES128_GCM || if (pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES128_GCM ||
pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES128_CCM) { pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES128_CCM) {
ksmbd_debug(SMB, "Cipher ID = 0x%x\n", ksmbd_debug(SMB, "Cipher ID = 0x%x\n",
pneg_ctxt->Ciphers[i]); pneg_ctxt->Ciphers[i]);
conn->cipher_type = pneg_ctxt->Ciphers[i]; conn->cipher_type = pneg_ctxt->Ciphers[i];
...@@ -939,7 +932,7 @@ static int decode_encrypt_ctxt(struct ksmbd_conn *conn, ...@@ -939,7 +932,7 @@ static int decode_encrypt_ctxt(struct ksmbd_conn *conn,
} }
static int decode_compress_ctxt(struct ksmbd_conn *conn, static int decode_compress_ctxt(struct ksmbd_conn *conn,
struct smb2_compression_ctx *pneg_ctxt) struct smb2_compression_ctx *pneg_ctxt)
{ {
int algo_cnt = le16_to_cpu(pneg_ctxt->CompressionAlgorithmCount); int algo_cnt = le16_to_cpu(pneg_ctxt->CompressionAlgorithmCount);
...@@ -954,7 +947,7 @@ static int decode_compress_ctxt(struct ksmbd_conn *conn, ...@@ -954,7 +947,7 @@ static int decode_compress_ctxt(struct ksmbd_conn *conn,
} }
static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn, static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
struct smb2_negotiate_req *req) struct smb2_negotiate_req *req)
{ {
int i = 0; int i = 0;
__le32 status = 0; __le32 status = 0;
...@@ -976,8 +969,7 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn, ...@@ -976,8 +969,7 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
status = decode_preauth_ctxt(conn, status = decode_preauth_ctxt(conn,
(struct smb2_preauth_neg_context *)pneg_ctxt); (struct smb2_preauth_neg_context *)pneg_ctxt);
pneg_ctxt += DIV_ROUND_UP( pneg_ctxt += DIV_ROUND_UP(sizeof(struct smb2_preauth_neg_context), 8) * 8;
sizeof(struct smb2_preauth_neg_context), 8) * 8;
} else if (*ContextType == SMB2_ENCRYPTION_CAPABILITIES) { } else if (*ContextType == SMB2_ENCRYPTION_CAPABILITIES) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"deassemble SMB2_ENCRYPTION_CAPABILITIES context\n"); "deassemble SMB2_ENCRYPTION_CAPABILITIES context\n");
...@@ -985,8 +977,7 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn, ...@@ -985,8 +977,7 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
break; break;
ctxt_size = decode_encrypt_ctxt(conn, ctxt_size = decode_encrypt_ctxt(conn,
(struct smb2_encryption_neg_context *) (struct smb2_encryption_neg_context *)pneg_ctxt);
pneg_ctxt);
pneg_ctxt += DIV_ROUND_UP(ctxt_size, 8) * 8; pneg_ctxt += DIV_ROUND_UP(ctxt_size, 8) * 8;
} else if (*ContextType == SMB2_COMPRESSION_CAPABILITIES) { } else if (*ContextType == SMB2_COMPRESSION_CAPABILITIES) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
...@@ -995,23 +986,20 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn, ...@@ -995,23 +986,20 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
break; break;
ctxt_size = decode_compress_ctxt(conn, ctxt_size = decode_compress_ctxt(conn,
(struct smb2_compression_ctx *) (struct smb2_compression_ctx *) pneg_ctxt);
pneg_ctxt);
pneg_ctxt += DIV_ROUND_UP(ctxt_size, 8) * 8; pneg_ctxt += DIV_ROUND_UP(ctxt_size, 8) * 8;
} else if (*ContextType == SMB2_NETNAME_NEGOTIATE_CONTEXT_ID) { } else if (*ContextType == SMB2_NETNAME_NEGOTIATE_CONTEXT_ID) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"deassemble SMB2_NETNAME_NEGOTIATE_CONTEXT_ID context\n"); "deassemble SMB2_NETNAME_NEGOTIATE_CONTEXT_ID context\n");
ctxt_size = sizeof(struct smb2_netname_neg_context); ctxt_size = sizeof(struct smb2_netname_neg_context);
ctxt_size += DIV_ROUND_UP( ctxt_size += DIV_ROUND_UP(le16_to_cpu(((struct smb2_netname_neg_context *)
le16_to_cpu(((struct smb2_netname_neg_context *)
pneg_ctxt)->DataLength), 8) * 8; pneg_ctxt)->DataLength), 8) * 8;
pneg_ctxt += ctxt_size; pneg_ctxt += ctxt_size;
} else if (*ContextType == SMB2_POSIX_EXTENSIONS_AVAILABLE) { } else if (*ContextType == SMB2_POSIX_EXTENSIONS_AVAILABLE) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"deassemble SMB2_POSIX_EXTENSIONS_AVAILABLE context\n"); "deassemble SMB2_POSIX_EXTENSIONS_AVAILABLE context\n");
conn->posix_ext_supported = true; conn->posix_ext_supported = true;
pneg_ctxt += DIV_ROUND_UP( pneg_ctxt += DIV_ROUND_UP(sizeof(struct smb2_posix_neg_context), 8) * 8;
sizeof(struct smb2_posix_neg_context), 8) * 8;
} }
ContextType = (__le16 *)pneg_ctxt; ContextType = (__le16 *)pneg_ctxt;
...@@ -1149,8 +1137,8 @@ int smb2_handle_negotiate(struct ksmbd_work *work) ...@@ -1149,8 +1137,8 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
conn->use_spnego = true; conn->use_spnego = true;
if ((server_conf.signing == KSMBD_CONFIG_OPT_AUTO || if ((server_conf.signing == KSMBD_CONFIG_OPT_AUTO ||
server_conf.signing == KSMBD_CONFIG_OPT_DISABLED) && server_conf.signing == KSMBD_CONFIG_OPT_DISABLED) &&
req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED_LE) req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED_LE)
conn->sign = true; conn->sign = true;
else if (server_conf.signing == KSMBD_CONFIG_OPT_MANDATORY) { else if (server_conf.signing == KSMBD_CONFIG_OPT_MANDATORY) {
server_conf.enforced_signing = true; server_conf.enforced_signing = true;
...@@ -1169,7 +1157,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work) ...@@ -1169,7 +1157,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
} }
static int alloc_preauth_hash(struct ksmbd_session *sess, static int alloc_preauth_hash(struct ksmbd_session *sess,
struct ksmbd_conn *conn) struct ksmbd_conn *conn)
{ {
if (sess->Preauth_HashValue) if (sess->Preauth_HashValue)
return 0; return 0;
...@@ -1204,7 +1192,7 @@ static int generate_preauth_hash(struct ksmbd_work *work) ...@@ -1204,7 +1192,7 @@ static int generate_preauth_hash(struct ksmbd_work *work)
} }
static int decode_negotiation_token(struct ksmbd_work *work, static int decode_negotiation_token(struct ksmbd_work *work,
struct negotiate_message *negblob) struct negotiate_message *negblob)
{ {
struct ksmbd_conn *conn = work->conn; struct ksmbd_conn *conn = work->conn;
struct smb2_sess_setup_req *req; struct smb2_sess_setup_req *req;
...@@ -1227,7 +1215,7 @@ static int decode_negotiation_token(struct ksmbd_work *work, ...@@ -1227,7 +1215,7 @@ static int decode_negotiation_token(struct ksmbd_work *work,
} }
static int ntlm_negotiate(struct ksmbd_work *work, static int ntlm_negotiate(struct ksmbd_work *work,
struct negotiate_message *negblob) struct negotiate_message *negblob)
{ {
struct smb2_sess_setup_req *req = work->request_buf; struct smb2_sess_setup_req *req = work->request_buf;
struct smb2_sess_setup_rsp *rsp = work->response_buf; struct smb2_sess_setup_rsp *rsp = work->response_buf;
...@@ -1291,7 +1279,7 @@ static int ntlm_negotiate(struct ksmbd_work *work, ...@@ -1291,7 +1279,7 @@ static int ntlm_negotiate(struct ksmbd_work *work,
} }
static struct authenticate_message *user_authblob(struct ksmbd_conn *conn, static struct authenticate_message *user_authblob(struct ksmbd_conn *conn,
struct smb2_sess_setup_req *req) struct smb2_sess_setup_req *req)
{ {
int sz; int sz;
...@@ -1304,7 +1292,7 @@ static struct authenticate_message *user_authblob(struct ksmbd_conn *conn, ...@@ -1304,7 +1292,7 @@ static struct authenticate_message *user_authblob(struct ksmbd_conn *conn,
} }
static struct ksmbd_user *session_user(struct ksmbd_conn *conn, static struct ksmbd_user *session_user(struct ksmbd_conn *conn,
struct smb2_sess_setup_req *req) struct smb2_sess_setup_req *req)
{ {
struct authenticate_message *authblob; struct authenticate_message *authblob;
struct ksmbd_user *user; struct ksmbd_user *user;
...@@ -1336,7 +1324,7 @@ static int ntlm_authenticate(struct ksmbd_work *work) ...@@ -1336,7 +1324,7 @@ static int ntlm_authenticate(struct ksmbd_work *work)
struct ksmbd_session *sess = work->sess; struct ksmbd_session *sess = work->sess;
struct channel *chann = NULL; struct channel *chann = NULL;
struct ksmbd_user *user; struct ksmbd_user *user;
uint64_t prev_id; u64 prev_id;
int sz, rc; int sz, rc;
ksmbd_debug(SMB, "authenticate phase\n"); ksmbd_debug(SMB, "authenticate phase\n");
...@@ -1351,9 +1339,7 @@ static int ntlm_authenticate(struct ksmbd_work *work) ...@@ -1351,9 +1339,7 @@ static int ntlm_authenticate(struct ksmbd_work *work)
return -ENOMEM; return -ENOMEM;
sz = le16_to_cpu(rsp->SecurityBufferOffset); sz = le16_to_cpu(rsp->SecurityBufferOffset);
memcpy((char *)&rsp->hdr.ProtocolId + sz, memcpy((char *)&rsp->hdr.ProtocolId + sz, spnego_blob, spnego_blob_len);
spnego_blob,
spnego_blob_len);
rsp->SecurityBufferLength = cpu_to_le16(spnego_blob_len); rsp->SecurityBufferLength = cpu_to_le16(spnego_blob_len);
kfree(spnego_blob); kfree(spnego_blob);
inc_rfc1001_len(rsp, spnego_blob_len - 1); inc_rfc1001_len(rsp, spnego_blob_len - 1);
...@@ -1386,8 +1372,7 @@ static int ntlm_authenticate(struct ksmbd_work *work) ...@@ -1386,8 +1372,7 @@ static int ntlm_authenticate(struct ksmbd_work *work)
sess->user = user; sess->user = user;
if (user_guest(sess->user)) { if (user_guest(sess->user)) {
if (conn->sign) { if (conn->sign) {
ksmbd_debug(SMB, ksmbd_debug(SMB, "Guest login not allowed when signing enabled\n");
"Guest login not allowed when signing enabled\n");
rsp->hdr.Status = STATUS_LOGON_FAILURE; rsp->hdr.Status = STATUS_LOGON_FAILURE;
return -EACCES; return -EACCES;
} }
...@@ -1415,11 +1400,11 @@ static int ntlm_authenticate(struct ksmbd_work *work) ...@@ -1415,11 +1400,11 @@ static int ntlm_authenticate(struct ksmbd_work *work)
return 0; return 0;
if ((conn->sign || server_conf.enforced_signing) || if ((conn->sign || server_conf.enforced_signing) ||
(req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED)) (req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
sess->sign = true; sess->sign = true;
if (conn->vals->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION && if (conn->vals->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION &&
conn->ops->generate_encryptionkey) { conn->ops->generate_encryptionkey) {
rc = conn->ops->generate_encryptionkey(sess); rc = conn->ops->generate_encryptionkey(sess);
if (rc) { if (rc) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
...@@ -1453,8 +1438,7 @@ static int ntlm_authenticate(struct ksmbd_work *work) ...@@ -1453,8 +1438,7 @@ static int ntlm_authenticate(struct ksmbd_work *work)
if (conn->ops->generate_signingkey) { if (conn->ops->generate_signingkey) {
rc = conn->ops->generate_signingkey(sess); rc = conn->ops->generate_signingkey(sess);
if (rc) { if (rc) {
ksmbd_debug(SMB, ksmbd_debug(SMB, "SMB3 signing key generation failed\n");
"SMB3 signing key generation failed\n");
rsp->hdr.Status = STATUS_LOGON_FAILURE; rsp->hdr.Status = STATUS_LOGON_FAILURE;
return rc; return rc;
} }
...@@ -1479,7 +1463,7 @@ static int krb5_authenticate(struct ksmbd_work *work) ...@@ -1479,7 +1463,7 @@ static int krb5_authenticate(struct ksmbd_work *work)
struct ksmbd_session *sess = work->sess; struct ksmbd_session *sess = work->sess;
char *in_blob, *out_blob; char *in_blob, *out_blob;
struct channel *chann = NULL; struct channel *chann = NULL;
uint64_t prev_sess_id; u64 prev_sess_id;
int in_len, out_len; int in_len, out_len;
int retval; int retval;
...@@ -1511,11 +1495,11 @@ static int krb5_authenticate(struct ksmbd_work *work) ...@@ -1511,11 +1495,11 @@ static int krb5_authenticate(struct ksmbd_work *work)
inc_rfc1001_len(rsp, out_len - 1); inc_rfc1001_len(rsp, out_len - 1);
if ((conn->sign || server_conf.enforced_signing) || if ((conn->sign || server_conf.enforced_signing) ||
(req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED)) (req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
sess->sign = true; sess->sign = true;
if ((conn->vals->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) && if ((conn->vals->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) &&
conn->ops->generate_encryptionkey) { conn->ops->generate_encryptionkey) {
retval = conn->ops->generate_encryptionkey(sess); retval = conn->ops->generate_encryptionkey(sess);
if (retval) { if (retval) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
...@@ -1544,8 +1528,7 @@ static int krb5_authenticate(struct ksmbd_work *work) ...@@ -1544,8 +1528,7 @@ static int krb5_authenticate(struct ksmbd_work *work)
if (conn->ops->generate_signingkey) { if (conn->ops->generate_signingkey) {
retval = conn->ops->generate_signingkey(sess); retval = conn->ops->generate_signingkey(sess);
if (retval) { if (retval) {
ksmbd_debug(SMB, ksmbd_debug(SMB, "SMB3 signing key generation failed\n");
"SMB3 signing key generation failed\n");
rsp->hdr.Status = STATUS_LOGON_FAILURE; rsp->hdr.Status = STATUS_LOGON_FAILURE;
return retval; return retval;
} }
...@@ -1646,9 +1629,7 @@ int smb2_sess_setup(struct ksmbd_work *work) ...@@ -1646,9 +1629,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
* Note: here total size -1 is done as an * Note: here total size -1 is done as an
* adjustment for 0 size blob * adjustment for 0 size blob
*/ */
inc_rfc1001_len(rsp, inc_rfc1001_len(rsp, le16_to_cpu(rsp->SecurityBufferLength) - 1);
le16_to_cpu(rsp->SecurityBufferLength)
- 1);
} else if (negblob->MessageType == NtLmAuthenticate) { } else if (negblob->MessageType == NtLmAuthenticate) {
rc = ntlm_authenticate(work); rc = ntlm_authenticate(work);
...@@ -1704,7 +1685,7 @@ int smb2_tree_connect(struct ksmbd_work *work) ...@@ -1704,7 +1685,7 @@ int smb2_tree_connect(struct ksmbd_work *work)
int rc = -EINVAL; int rc = -EINVAL;
treename = smb_strndup_from_utf16(req->Buffer, treename = smb_strndup_from_utf16(req->Buffer,
le16_to_cpu(req->PathLength), true, conn->local_nls); le16_to_cpu(req->PathLength), true, conn->local_nls);
if (IS_ERR(treename)) { if (IS_ERR(treename)) {
ksmbd_err("treename is NULL\n"); ksmbd_err("treename is NULL\n");
status.ret = KSMBD_TREE_CONN_STATUS_ERROR; status.ret = KSMBD_TREE_CONN_STATUS_ERROR;
...@@ -1808,7 +1789,7 @@ static int smb2_create_open_flags(bool file_present, __le32 access, ...@@ -1808,7 +1789,7 @@ static int smb2_create_open_flags(bool file_present, __le32 access,
int oflags = O_NONBLOCK | O_LARGEFILE; int oflags = O_NONBLOCK | O_LARGEFILE;
if (access & FILE_READ_DESIRED_ACCESS_LE && if (access & FILE_READ_DESIRED_ACCESS_LE &&
access & FILE_WRITE_DESIRE_ACCESS_LE) access & FILE_WRITE_DESIRE_ACCESS_LE)
oflags |= O_RDWR; oflags |= O_RDWR;
else if (access & FILE_WRITE_DESIRE_ACCESS_LE) else if (access & FILE_WRITE_DESIRE_ACCESS_LE)
oflags |= O_WRONLY; oflags |= O_WRONLY;
...@@ -1995,13 +1976,13 @@ struct durable_info { ...@@ -1995,13 +1976,13 @@ struct durable_info {
}; };
static int parse_durable_handle_context(struct ksmbd_work *work, static int parse_durable_handle_context(struct ksmbd_work *work,
struct smb2_create_req *req, struct lease_ctx_info *lc, struct smb2_create_req *req, struct lease_ctx_info *lc,
struct durable_info *d_info) struct durable_info *d_info)
{ {
struct ksmbd_conn *conn = work->conn; struct ksmbd_conn *conn = work->conn;
struct create_context *context; struct create_context *context;
int i, err = 0; int i, err = 0;
uint64_t persistent_id = 0; u64 persistent_id = 0;
int req_op_level; int req_op_level;
static const char * const durable_arr[] = {"DH2C", "DHnC", "DH2Q", static const char * const durable_arr[] = {"DH2C", "DHnC", "DH2Q",
"DHnQ", SMB2_CREATE_APP_INSTANCE_ID}; "DHnQ", SMB2_CREATE_APP_INSTANCE_ID};
...@@ -2026,8 +2007,7 @@ static int parse_durable_handle_context(struct ksmbd_work *work, ...@@ -2026,8 +2007,7 @@ static int parse_durable_handle_context(struct ksmbd_work *work,
recon_v2 = recon_v2 =
(struct create_durable_reconn_v2_req *)context; (struct create_durable_reconn_v2_req *)context;
persistent_id = le64_to_cpu( persistent_id = le64_to_cpu(recon_v2->Fid.PersistentFileId);
recon_v2->Fid.PersistentFileId);
d_info->fp = ksmbd_lookup_durable_fd(persistent_id); d_info->fp = ksmbd_lookup_durable_fd(persistent_id);
if (!d_info->fp) { if (!d_info->fp) {
ksmbd_err("Failed to get Durable handle state\n"); ksmbd_err("Failed to get Durable handle state\n");
...@@ -2035,9 +2015,8 @@ static int parse_durable_handle_context(struct ksmbd_work *work, ...@@ -2035,9 +2015,8 @@ static int parse_durable_handle_context(struct ksmbd_work *work,
goto out; goto out;
} }
if (memcmp(d_info->fp->create_guid, if (memcmp(d_info->fp->create_guid, recon_v2->CreateGuid,
recon_v2->CreateGuid, SMB2_CREATE_GUID_SIZE)) {
SMB2_CREATE_GUID_SIZE)) {
err = -EBADF; err = -EBADF;
goto out; goto out;
} }
...@@ -2053,15 +2032,14 @@ static int parse_durable_handle_context(struct ksmbd_work *work, ...@@ -2053,15 +2032,14 @@ static int parse_durable_handle_context(struct ksmbd_work *work,
struct create_durable_reconn_req *recon; struct create_durable_reconn_req *recon;
if (d_info->type == DURABLE_RECONN_V2 || if (d_info->type == DURABLE_RECONN_V2 ||
d_info->type == DURABLE_REQ_V2) { d_info->type == DURABLE_REQ_V2) {
err = -EINVAL; err = -EINVAL;
goto out; goto out;
} }
recon = recon =
(struct create_durable_reconn_req *)context; (struct create_durable_reconn_req *)context;
persistent_id = le64_to_cpu( persistent_id = le64_to_cpu(recon->Data.Fid.PersistentFileId);
recon->Data.Fid.PersistentFileId);
d_info->fp = ksmbd_lookup_durable_fd(persistent_id); d_info->fp = ksmbd_lookup_durable_fd(persistent_id);
if (!d_info->fp) { if (!d_info->fp) {
ksmbd_err("Failed to get Durable handle state\n"); ksmbd_err("Failed to get Durable handle state\n");
...@@ -2080,7 +2058,7 @@ static int parse_durable_handle_context(struct ksmbd_work *work, ...@@ -2080,7 +2058,7 @@ static int parse_durable_handle_context(struct ksmbd_work *work,
struct create_durable_req_v2 *durable_v2_blob; struct create_durable_req_v2 *durable_v2_blob;
if (d_info->type == DURABLE_RECONN || if (d_info->type == DURABLE_RECONN ||
d_info->type == DURABLE_RECONN_V2) { d_info->type == DURABLE_RECONN_V2) {
err = -EINVAL; err = -EINVAL;
goto out; goto out;
} }
...@@ -2088,14 +2066,11 @@ static int parse_durable_handle_context(struct ksmbd_work *work, ...@@ -2088,14 +2066,11 @@ static int parse_durable_handle_context(struct ksmbd_work *work,
durable_v2_blob = durable_v2_blob =
(struct create_durable_req_v2 *)context; (struct create_durable_req_v2 *)context;
ksmbd_debug(SMB, "Request for durable v2 open\n"); ksmbd_debug(SMB, "Request for durable v2 open\n");
d_info->fp = ksmbd_lookup_fd_cguid( d_info->fp = ksmbd_lookup_fd_cguid(durable_v2_blob->CreateGuid);
durable_v2_blob->CreateGuid);
if (d_info->fp) { if (d_info->fp) {
if (!memcmp(conn->ClientGUID, if (!memcmp(conn->ClientGUID, d_info->fp->client_guid,
d_info->fp->client_guid, SMB2_CLIENT_GUID_SIZE)) {
SMB2_CLIENT_GUID_SIZE)) { if (!(req->hdr.Flags & SMB2_FLAGS_REPLAY_OPERATIONS)) {
if (!(req->hdr.Flags &
SMB2_FLAGS_REPLAY_OPERATIONS)) {
err = -ENOEXEC; err = -ENOEXEC;
goto out; goto out;
} }
...@@ -2105,10 +2080,8 @@ static int parse_durable_handle_context(struct ksmbd_work *work, ...@@ -2105,10 +2080,8 @@ static int parse_durable_handle_context(struct ksmbd_work *work,
goto out; goto out;
} }
} }
if (((lc && if (((lc && (lc->req_state & SMB2_LEASE_HANDLE_CACHING_LE)) ||
(lc->req_state & req_op_level == SMB2_OPLOCK_LEVEL_BATCH)) {
SMB2_LEASE_HANDLE_CACHING_LE)) ||
(req_op_level == SMB2_OPLOCK_LEVEL_BATCH))) {
d_info->CreateGuid = d_info->CreateGuid =
durable_v2_blob->CreateGuid; durable_v2_blob->CreateGuid;
d_info->persistent = d_info->persistent =
...@@ -2123,15 +2096,13 @@ static int parse_durable_handle_context(struct ksmbd_work *work, ...@@ -2123,15 +2096,13 @@ static int parse_durable_handle_context(struct ksmbd_work *work,
if (d_info->type == DURABLE_RECONN) if (d_info->type == DURABLE_RECONN)
goto out; goto out;
if (d_info->type == DURABLE_RECONN_V2 || if (d_info->type == DURABLE_RECONN_V2 ||
d_info->type == DURABLE_REQ_V2) { d_info->type == DURABLE_REQ_V2) {
err = -EINVAL; err = -EINVAL;
goto out; goto out;
} }
if (((lc && if (((lc && (lc->req_state & SMB2_LEASE_HANDLE_CACHING_LE)) ||
(lc->req_state & req_op_level == SMB2_OPLOCK_LEVEL_BATCH)) {
SMB2_LEASE_HANDLE_CACHING_LE)) ||
(req_op_level == SMB2_OPLOCK_LEVEL_BATCH))) {
ksmbd_debug(SMB, "Request for durable open\n"); ksmbd_debug(SMB, "Request for durable open\n");
d_info->type = i; d_info->type = i;
} }
...@@ -2252,9 +2223,7 @@ static inline int check_context_err(void *ctx, char *str) ...@@ -2252,9 +2223,7 @@ static inline int check_context_err(void *ctx, char *str)
} }
static noinline int smb2_set_stream_name_xattr(struct path *path, static noinline int smb2_set_stream_name_xattr(struct path *path,
struct ksmbd_file *fp, struct ksmbd_file *fp, char *stream_name, int s_type)
char *stream_name,
int s_type)
{ {
size_t xattr_stream_size; size_t xattr_stream_size;
char *xattr_stream_name; char *xattr_stream_name;
...@@ -2307,12 +2276,9 @@ static int smb2_remove_smb_xattrs(struct dentry *dentry) ...@@ -2307,12 +2276,9 @@ static int smb2_remove_smb_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_USER_PREFIX, XATTR_USER_PREFIX_LEN) && if (strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) &&
strncmp(&name[XATTR_USER_PREFIX_LEN], strncmp(&name[XATTR_USER_PREFIX_LEN], DOS_ATTRIBUTE_PREFIX,
DOS_ATTRIBUTE_PREFIX, DOS_ATTRIBUTE_PREFIX_LEN) &&
DOS_ATTRIBUTE_PREFIX_LEN) && strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX, STREAM_PREFIX_LEN))
strncmp(&name[XATTR_USER_PREFIX_LEN],
STREAM_PREFIX,
STREAM_PREFIX_LEN))
continue; continue;
err = ksmbd_vfs_remove_xattr(dentry, name); err = ksmbd_vfs_remove_xattr(dentry, name);
...@@ -2343,9 +2309,8 @@ static int smb2_create_truncate(struct path *path) ...@@ -2343,9 +2309,8 @@ static int smb2_create_truncate(struct path *path)
return rc; return rc;
} }
static void smb2_new_xattrs(struct ksmbd_tree_connect *tcon, static void smb2_new_xattrs(struct ksmbd_tree_connect *tcon, struct path *path,
struct path *path, struct ksmbd_file *fp)
struct ksmbd_file *fp)
{ {
struct xattr_dos_attrib da = {0}; struct xattr_dos_attrib da = {0};
int rc; int rc;
...@@ -2366,8 +2331,7 @@ static void smb2_new_xattrs(struct ksmbd_tree_connect *tcon, ...@@ -2366,8 +2331,7 @@ static void smb2_new_xattrs(struct ksmbd_tree_connect *tcon,
} }
static void smb2_update_xattrs(struct ksmbd_tree_connect *tcon, static void smb2_update_xattrs(struct ksmbd_tree_connect *tcon,
struct path *path, struct path *path, struct ksmbd_file *fp)
struct ksmbd_file *fp)
{ {
struct xattr_dos_attrib da; struct xattr_dos_attrib da;
int rc; int rc;
...@@ -2376,7 +2340,7 @@ static void smb2_update_xattrs(struct ksmbd_tree_connect *tcon, ...@@ -2376,7 +2340,7 @@ static void smb2_update_xattrs(struct ksmbd_tree_connect *tcon,
/* get FileAttributes from XATTR_NAME_DOS_ATTRIBUTE */ /* get FileAttributes from XATTR_NAME_DOS_ATTRIBUTE */
if (!test_share_config_flag(tcon->share_conf, if (!test_share_config_flag(tcon->share_conf,
KSMBD_SHARE_FLAG_STORE_DOS_ATTRS)) KSMBD_SHARE_FLAG_STORE_DOS_ATTRS))
return; return;
rc = ksmbd_vfs_get_dos_attrib_xattr(path->dentry, &da); rc = ksmbd_vfs_get_dos_attrib_xattr(path->dentry, &da);
...@@ -2387,12 +2351,8 @@ static void smb2_update_xattrs(struct ksmbd_tree_connect *tcon, ...@@ -2387,12 +2351,8 @@ static void smb2_update_xattrs(struct ksmbd_tree_connect *tcon,
} }
} }
static int smb2_creat(struct ksmbd_work *work, static int smb2_creat(struct ksmbd_work *work, struct path *path, char *name,
struct path *path, int open_flags, umode_t posix_mode, bool is_dir)
char *name,
int open_flags,
umode_t posix_mode,
bool is_dir)
{ {
struct ksmbd_tree_connect *tcon = work->tcon; struct ksmbd_tree_connect *tcon = work->tcon;
struct ksmbd_share_config *share = tcon->share_conf; struct ksmbd_share_config *share = tcon->share_conf;
...@@ -2494,7 +2454,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2494,7 +2454,7 @@ int smb2_open(struct ksmbd_work *work)
WORK_BUFFERS(work, req, rsp); WORK_BUFFERS(work, req, rsp);
if (req->hdr.NextCommand && !work->next_smb2_rcv_hdr_off && if (req->hdr.NextCommand && !work->next_smb2_rcv_hdr_off &&
(req->hdr.Flags & SMB2_FLAGS_RELATED_OPERATIONS)) { (req->hdr.Flags & SMB2_FLAGS_RELATED_OPERATIONS)) {
ksmbd_debug(SMB, "invalid flag in chained command\n"); ksmbd_debug(SMB, "invalid flag in chained command\n");
rsp->hdr.Status = STATUS_INVALID_PARAMETER; rsp->hdr.Status = STATUS_INVALID_PARAMETER;
smb2_set_err_rsp(work); smb2_set_err_rsp(work);
...@@ -2508,7 +2468,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2508,7 +2468,7 @@ int smb2_open(struct ksmbd_work *work)
if (req->NameLength) { if (req->NameLength) {
if ((req->CreateOptions & FILE_DIRECTORY_FILE_LE) && if ((req->CreateOptions & FILE_DIRECTORY_FILE_LE) &&
*(char *)req->Buffer == '\\') { *(char *)req->Buffer == '\\') {
ksmbd_err("not allow directory name included leading slash\n"); ksmbd_err("not allow directory name included leading slash\n");
rc = -EINVAL; rc = -EINVAL;
goto err_out1; goto err_out1;
...@@ -2528,7 +2488,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2528,7 +2488,7 @@ int smb2_open(struct ksmbd_work *work)
ksmbd_debug(SMB, "converted name = %s\n", name); ksmbd_debug(SMB, "converted name = %s\n", name);
if (strchr(name, ':')) { if (strchr(name, ':')) {
if (!test_share_config_flag(work->tcon->share_conf, if (!test_share_config_flag(work->tcon->share_conf,
KSMBD_SHARE_FLAG_STREAMS)) { KSMBD_SHARE_FLAG_STREAMS)) {
rc = -EBADF; rc = -EBADF;
goto err_out1; goto err_out1;
} }
...@@ -2564,7 +2524,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2564,7 +2524,7 @@ int smb2_open(struct ksmbd_work *work)
req_op_level = req->RequestedOplockLevel; req_op_level = req->RequestedOplockLevel;
memset(&d_info, 0, sizeof(struct durable_info)); memset(&d_info, 0, sizeof(struct durable_info));
if (server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE && if (server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE &&
req->CreateContextsOffset) { req->CreateContextsOffset) {
lc = parse_lease_state(req); lc = parse_lease_state(req);
rc = parse_durable_handle_context(work, req, lc, &d_info); rc = parse_durable_handle_context(work, req, lc, &d_info);
if (rc) { if (rc) {
...@@ -2593,8 +2553,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2593,8 +2553,7 @@ int smb2_open(struct ksmbd_work *work)
lc = parse_lease_state(req); lc = parse_lease_state(req);
} }
if (le32_to_cpu(req->ImpersonationLevel) > if (le32_to_cpu(req->ImpersonationLevel) > le32_to_cpu(IL_DELEGATE_LE)) {
le32_to_cpu(IL_DELEGATE_LE)) {
ksmbd_err("Invalid impersonationlevel : 0x%x\n", ksmbd_err("Invalid impersonationlevel : 0x%x\n",
le32_to_cpu(req->ImpersonationLevel)); le32_to_cpu(req->ImpersonationLevel));
rc = -EIO; rc = -EIO;
...@@ -2610,7 +2569,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2610,7 +2569,7 @@ int smb2_open(struct ksmbd_work *work)
} else { } else {
if (req->CreateOptions & FILE_SEQUENTIAL_ONLY_LE && if (req->CreateOptions & FILE_SEQUENTIAL_ONLY_LE &&
req->CreateOptions & FILE_RANDOM_ACCESS_LE) req->CreateOptions & FILE_RANDOM_ACCESS_LE)
req->CreateOptions = ~(FILE_SEQUENTIAL_ONLY_LE); req->CreateOptions = ~(FILE_SEQUENTIAL_ONLY_LE);
if (req->CreateOptions & (FILE_OPEN_BY_FILE_ID_LE | if (req->CreateOptions & (FILE_OPEN_BY_FILE_ID_LE |
...@@ -2623,8 +2582,9 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2623,8 +2582,9 @@ int smb2_open(struct ksmbd_work *work)
if (req->CreateOptions & FILE_NON_DIRECTORY_FILE_LE) { if (req->CreateOptions & FILE_NON_DIRECTORY_FILE_LE) {
rc = -EINVAL; rc = -EINVAL;
goto err_out1; goto err_out1;
} else if (req->CreateOptions & FILE_NO_COMPRESSION_LE) } else if (req->CreateOptions & FILE_NO_COMPRESSION_LE) {
req->CreateOptions = ~(FILE_NO_COMPRESSION_LE); req->CreateOptions = ~(FILE_NO_COMPRESSION_LE);
}
} }
} }
...@@ -2643,8 +2603,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2643,8 +2603,7 @@ int smb2_open(struct ksmbd_work *work)
goto err_out1; goto err_out1;
} }
if (req->FileAttributes && if (req->FileAttributes && !(req->FileAttributes & ATTR_MASK_LE)) {
!(req->FileAttributes & ATTR_MASK_LE)) {
ksmbd_err("Invalid file attribute : 0x%x\n", ksmbd_err("Invalid file attribute : 0x%x\n",
le32_to_cpu(req->FileAttributes)); le32_to_cpu(req->FileAttributes));
rc = -EINVAL; rc = -EINVAL;
...@@ -2729,14 +2688,13 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2729,14 +2688,13 @@ int smb2_open(struct ksmbd_work *work)
* denied error. * denied error.
*/ */
if (req->CreateDisposition == FILE_OVERWRITE_IF_LE || if (req->CreateDisposition == FILE_OVERWRITE_IF_LE ||
req->CreateDisposition == FILE_OPEN_IF_LE) { req->CreateDisposition == FILE_OPEN_IF_LE) {
rc = -EACCES; rc = -EACCES;
path_put(&path); path_put(&path);
goto err_out; goto err_out;
} }
if (!test_tree_conn_flag(tcon, if (!test_tree_conn_flag(tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
KSMBD_TREE_CONN_FLAG_WRITABLE)) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"User does not have write permission\n"); "User does not have write permission\n");
rc = -EACCES; rc = -EACCES;
...@@ -2746,7 +2704,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2746,7 +2704,7 @@ int smb2_open(struct ksmbd_work *work)
} }
} else { } else {
if (test_share_config_flag(work->tcon->share_conf, if (test_share_config_flag(work->tcon->share_conf,
KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS)) { KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS)) {
/* /*
* Use LOOKUP_FOLLOW to follow the path of * Use LOOKUP_FOLLOW to follow the path of
* symlink in path buildup * symlink in path buildup
...@@ -2792,7 +2750,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2792,7 +2750,7 @@ int smb2_open(struct ksmbd_work *work)
} }
if (req->CreateOptions & FILE_DIRECTORY_FILE_LE && if (req->CreateOptions & FILE_DIRECTORY_FILE_LE &&
req->FileAttributes & ATTR_NORMAL_LE) { req->FileAttributes & ATTR_NORMAL_LE) {
rsp->hdr.Status = STATUS_NOT_A_DIRECTORY; rsp->hdr.Status = STATUS_NOT_A_DIRECTORY;
rc = -EIO; rc = -EIO;
} }
...@@ -2801,9 +2759,8 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2801,9 +2759,8 @@ int smb2_open(struct ksmbd_work *work)
goto err_out; goto err_out;
} }
if (file_present && req->CreateOptions & FILE_NON_DIRECTORY_FILE_LE if (file_present && req->CreateOptions & FILE_NON_DIRECTORY_FILE_LE &&
&& S_ISDIR(stat.mode) && S_ISDIR(stat.mode) && !(req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) {
!(req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) {
ksmbd_debug(SMB, "open() argument is a directory: %s, %x\n", ksmbd_debug(SMB, "open() argument is a directory: %s, %x\n",
name, req->CreateOptions); name, req->CreateOptions);
rsp->hdr.Status = STATUS_FILE_IS_A_DIRECTORY; rsp->hdr.Status = STATUS_FILE_IS_A_DIRECTORY;
...@@ -2812,21 +2769,21 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2812,21 +2769,21 @@ int smb2_open(struct ksmbd_work *work)
} }
if (file_present && (req->CreateOptions & FILE_DIRECTORY_FILE_LE) && if (file_present && (req->CreateOptions & FILE_DIRECTORY_FILE_LE) &&
!(req->CreateDisposition == FILE_CREATE_LE) && !(req->CreateDisposition == FILE_CREATE_LE) &&
!S_ISDIR(stat.mode)) { !S_ISDIR(stat.mode)) {
rsp->hdr.Status = STATUS_NOT_A_DIRECTORY; rsp->hdr.Status = STATUS_NOT_A_DIRECTORY;
rc = -EIO; rc = -EIO;
goto err_out; goto err_out;
} }
if (!stream_name && file_present && if (!stream_name && file_present &&
(req->CreateDisposition == FILE_CREATE_LE)) { req->CreateDisposition == FILE_CREATE_LE) {
rc = -EEXIST; rc = -EEXIST;
goto err_out; goto err_out;
} }
if (server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE && if (server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE &&
file_present) file_present)
file_present = ksmbd_close_inode_fds(work, file_present = ksmbd_close_inode_fds(work,
d_inode(path.dentry)); d_inode(path.dentry));
...@@ -2889,10 +2846,10 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2889,10 +2846,10 @@ int smb2_open(struct ksmbd_work *work)
* because execute(search) permission on a parent directory, * because execute(search) permission on a parent directory,
* is already granted. * is already granted.
*/ */
if (daccess & ~(FILE_READ_ATTRIBUTES_LE | if (daccess & ~(FILE_READ_ATTRIBUTES_LE | FILE_READ_CONTROL_LE)) {
FILE_READ_CONTROL_LE)) {
if (ksmbd_vfs_inode_permission(path.dentry, if (ksmbd_vfs_inode_permission(path.dentry,
open_flags & O_ACCMODE, may_delete)) { open_flags & O_ACCMODE,
may_delete)) {
rc = -EACCES; rc = -EACCES;
goto err_out; goto err_out;
} }
...@@ -2922,8 +2879,9 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2922,8 +2879,9 @@ int smb2_open(struct ksmbd_work *work)
if ((req->CreateDisposition & FILE_CREATE_MASK_LE) if ((req->CreateDisposition & FILE_CREATE_MASK_LE)
== FILE_SUPERSEDE_LE) == FILE_SUPERSEDE_LE)
file_info = FILE_SUPERSEDED; file_info = FILE_SUPERSEDED;
} else if (open_flags & O_CREAT) } else if (open_flags & O_CREAT) {
file_info = FILE_CREATED; file_info = FILE_CREATED;
}
ksmbd_vfs_set_fadvise(filp, req->CreateOptions); ksmbd_vfs_set_fadvise(filp, req->CreateOptions);
...@@ -2959,7 +2917,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2959,7 +2917,7 @@ int smb2_open(struct ksmbd_work *work)
ksmbd_debug(SMB, "inherit posix acl failed : %d\n", posix_acl_rc); ksmbd_debug(SMB, "inherit posix acl failed : %d\n", posix_acl_rc);
if (test_share_config_flag(work->tcon->share_conf, if (test_share_config_flag(work->tcon->share_conf,
KSMBD_SHARE_FLAG_ACL_XATTR)) { KSMBD_SHARE_FLAG_ACL_XATTR)) {
rc = smb_inherit_dacl(conn, path.dentry, sess->user->uid, rc = smb_inherit_dacl(conn, path.dentry, sess->user->uid,
sess->user->gid); sess->user->gid);
} }
...@@ -2971,7 +2929,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2971,7 +2929,7 @@ int smb2_open(struct ksmbd_work *work)
ksmbd_vfs_set_init_posix_acl(inode); ksmbd_vfs_set_init_posix_acl(inode);
if (test_share_config_flag(work->tcon->share_conf, if (test_share_config_flag(work->tcon->share_conf,
KSMBD_SHARE_FLAG_ACL_XATTR)) { KSMBD_SHARE_FLAG_ACL_XATTR)) {
struct smb_fattr fattr; struct smb_fattr fattr;
struct smb_ntsd *pntsd; struct smb_ntsd *pntsd;
int pntsd_size, ace_num; int pntsd_size, ace_num;
...@@ -2990,9 +2948,9 @@ int smb2_open(struct ksmbd_work *work) ...@@ -2990,9 +2948,9 @@ int smb2_open(struct ksmbd_work *work)
} }
pntsd = kmalloc(sizeof(struct smb_ntsd) + pntsd = kmalloc(sizeof(struct smb_ntsd) +
sizeof(struct smb_sid)*3 + sizeof(struct smb_sid) * 3 +
sizeof(struct smb_acl) + sizeof(struct smb_acl) +
sizeof(struct smb_ace)*ace_num*2, sizeof(struct smb_ace) * ace_num * 2,
GFP_KERNEL); GFP_KERNEL);
if (!pntsd) if (!pntsd)
goto err_out; goto err_out;
...@@ -3026,8 +2984,8 @@ int smb2_open(struct ksmbd_work *work) ...@@ -3026,8 +2984,8 @@ int smb2_open(struct ksmbd_work *work)
fp->attrib_only = !(req->DesiredAccess & ~(FILE_READ_ATTRIBUTES_LE | fp->attrib_only = !(req->DesiredAccess & ~(FILE_READ_ATTRIBUTES_LE |
FILE_WRITE_ATTRIBUTES_LE | FILE_SYNCHRONIZE_LE)); FILE_WRITE_ATTRIBUTES_LE | FILE_SYNCHRONIZE_LE));
if (!S_ISDIR(file_inode(filp)->i_mode) && open_flags & O_TRUNC if (!S_ISDIR(file_inode(filp)->i_mode) && open_flags & O_TRUNC &&
&& !fp->attrib_only && !stream_name) { !fp->attrib_only && !stream_name) {
smb_break_all_oplock(work, fp); smb_break_all_oplock(work, fp);
need_truncate = 1; need_truncate = 1;
} }
...@@ -3053,10 +3011,9 @@ int smb2_open(struct ksmbd_work *work) ...@@ -3053,10 +3011,9 @@ int smb2_open(struct ksmbd_work *work)
} }
share_ret = ksmbd_smb_check_shared_mode(fp->filp, fp); share_ret = ksmbd_smb_check_shared_mode(fp->filp, 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) || (req_op_level == SMB2_OPLOCK_LEVEL_LEASE &&
(req_op_level == SMB2_OPLOCK_LEVEL_LEASE && !(conn->vals->capabilities & SMB2_GLOBAL_CAP_LEASING))) {
!(conn->vals->capabilities & SMB2_GLOBAL_CAP_LEASING))) {
if (share_ret < 0 && !S_ISDIR(FP_INODE(fp)->i_mode)) { if (share_ret < 0 && !S_ISDIR(FP_INODE(fp)->i_mode)) {
rc = share_ret; rc = share_ret;
goto err_out; goto err_out;
...@@ -3071,8 +3028,8 @@ int smb2_open(struct ksmbd_work *work) ...@@ -3071,8 +3028,8 @@ int smb2_open(struct ksmbd_work *work)
if (rc) if (rc)
goto err_out; goto err_out;
} else if (open_flags == O_RDONLY && } else if (open_flags == O_RDONLY &&
(req_op_level == SMB2_OPLOCK_LEVEL_BATCH || (req_op_level == SMB2_OPLOCK_LEVEL_BATCH ||
req_op_level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)) req_op_level == SMB2_OPLOCK_LEVEL_EXCLUSIVE))
req_op_level = SMB2_OPLOCK_LEVEL_II; req_op_level = SMB2_OPLOCK_LEVEL_II;
rc = smb_grant_oplock(work, req_op_level, rc = smb_grant_oplock(work, req_op_level,
...@@ -3117,11 +3074,9 @@ int smb2_open(struct ksmbd_work *work) ...@@ -3117,11 +3074,9 @@ int smb2_open(struct ksmbd_work *work)
err); err);
} }
context = smb2_find_context_vals(req, context = smb2_find_context_vals(req, SMB2_CREATE_QUERY_ON_DISK_ID);
SMB2_CREATE_QUERY_ON_DISK_ID);
if (IS_ERR(context)) { if (IS_ERR(context)) {
rc = check_context_err(context, rc = check_context_err(context, SMB2_CREATE_QUERY_ON_DISK_ID);
SMB2_CREATE_QUERY_ON_DISK_ID);
if (rc < 0) if (rc < 0)
goto err_out; goto err_out;
} else { } else {
...@@ -3146,8 +3101,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -3146,8 +3101,7 @@ int smb2_open(struct ksmbd_work *work)
memcpy(fp->client_guid, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE); memcpy(fp->client_guid, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE);
if (d_info.type) { if (d_info.type) {
if (d_info.type == DURABLE_REQ_V2 && if (d_info.type == DURABLE_REQ_V2 && d_info.persistent)
d_info.persistent)
fp->is_persistent = 1; fp->is_persistent = 1;
else else
fp->is_durable = 1; fp->is_durable = 1;
...@@ -3160,8 +3114,7 @@ int smb2_open(struct ksmbd_work *work) ...@@ -3160,8 +3114,7 @@ int smb2_open(struct ksmbd_work *work)
else else
fp->durable_timeout = 1600; fp->durable_timeout = 1600;
if (d_info.app_id) if (d_info.app_id)
memcpy(fp->app_instance_id, memcpy(fp->app_instance_id, d_info.app_id, 16);
d_info.app_id, 16);
} }
} }
...@@ -3457,10 +3410,8 @@ static int dentry_name(struct ksmbd_dir_info *d_info, int info_level) ...@@ -3457,10 +3410,8 @@ static int dentry_name(struct ksmbd_dir_info *d_info, int info_level)
* *
* Return: 0 on success, otherwise error * Return: 0 on success, otherwise error
*/ */
static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
int info_level, struct ksmbd_dir_info *d_info, struct ksmbd_kstat *ksmbd_kstat)
struct ksmbd_dir_info *d_info,
struct ksmbd_kstat *ksmbd_kstat)
{ {
int next_entry_offset = 0; int next_entry_offset = 0;
char *conv_name; char *conv_name;
...@@ -3710,7 +3661,7 @@ static int process_query_dir_entries(struct smb2_query_dir_private *priv) ...@@ -3710,7 +3661,7 @@ static int process_query_dir_entries(struct smb2_query_dir_private *priv)
} }
static int reserve_populate_dentry(struct ksmbd_dir_info *d_info, static int reserve_populate_dentry(struct ksmbd_dir_info *d_info,
int info_level) int info_level)
{ {
int struct_sz; int struct_sz;
int conv_len; int conv_len;
...@@ -3816,12 +3767,8 @@ static int reserve_populate_dentry(struct ksmbd_dir_info *d_info, ...@@ -3816,12 +3767,8 @@ static int reserve_populate_dentry(struct ksmbd_dir_info *d_info,
return 0; return 0;
} }
static int __query_dir(struct dir_context *ctx, static int __query_dir(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;
struct smb2_query_dir_private *priv; struct smb2_query_dir_private *priv;
...@@ -3913,8 +3860,7 @@ int smb2_query_dir(struct ksmbd_work *work) ...@@ -3913,8 +3860,7 @@ int smb2_query_dir(struct ksmbd_work *work)
} }
if (!(dir_fp->daccess & FILE_LIST_DIRECTORY_LE) || if (!(dir_fp->daccess & FILE_LIST_DIRECTORY_LE) ||
inode_permission(&init_user_ns, file_inode(dir_fp->filp), inode_permission(&init_user_ns, file_inode(dir_fp->filp), MAY_READ | MAY_EXEC)) {
MAY_READ | MAY_EXEC)) {
ksmbd_err("no right to enumerate directory (%s)\n", ksmbd_err("no right to enumerate directory (%s)\n",
FP_FILENAME(dir_fp)); FP_FILENAME(dir_fp));
rc = -EACCES; rc = -EACCES;
...@@ -3935,8 +3881,9 @@ int smb2_query_dir(struct ksmbd_work *work) ...@@ -3935,8 +3881,9 @@ int smb2_query_dir(struct ksmbd_work *work)
ksmbd_debug(SMB, "Search Pattern not found\n"); ksmbd_debug(SMB, "Search Pattern not found\n");
rc = -EINVAL; rc = -EINVAL;
goto err_out2; goto err_out2;
} else } else {
ksmbd_debug(SMB, "Search pattern is %s\n", srch_ptr); ksmbd_debug(SMB, "Search pattern is %s\n", srch_ptr);
}
ksmbd_debug(SMB, "Directory name is %s\n", dir_fp->filename); ksmbd_debug(SMB, "Directory name is %s\n", dir_fp->filename);
...@@ -3949,11 +3896,9 @@ int smb2_query_dir(struct ksmbd_work *work) ...@@ -3949,11 +3896,9 @@ int smb2_query_dir(struct ksmbd_work *work)
memset(&d_info, 0, sizeof(struct ksmbd_dir_info)); memset(&d_info, 0, sizeof(struct ksmbd_dir_info));
d_info.wptr = (char *)rsp->Buffer; d_info.wptr = (char *)rsp->Buffer;
d_info.rptr = (char *)rsp->Buffer; d_info.rptr = (char *)rsp->Buffer;
d_info.out_buf_len = (work->response_sz - d_info.out_buf_len = (work->response_sz - (get_rfc1002_len(rsp_org) + 4));
(get_rfc1002_len(rsp_org) + 4));
d_info.out_buf_len = min_t(int, d_info.out_buf_len, d_info.out_buf_len = min_t(int, d_info.out_buf_len,
le32_to_cpu(req->OutputBufferLength)) - le32_to_cpu(req->OutputBufferLength)) - sizeof(struct smb2_query_directory_rsp);
sizeof(struct smb2_query_directory_rsp);
d_info.flags = srch_flag; d_info.flags = srch_flag;
/* /*
...@@ -3995,9 +3940,9 @@ int smb2_query_dir(struct ksmbd_work *work) ...@@ -3995,9 +3940,9 @@ int smb2_query_dir(struct ksmbd_work *work)
goto err_out; goto err_out;
if (!d_info.data_count && d_info.out_buf_len >= 0) { if (!d_info.data_count && d_info.out_buf_len >= 0) {
if (srch_flag & SMB2_RETURN_SINGLE_ENTRY && !is_asterisk(srch_ptr)) if (srch_flag & SMB2_RETURN_SINGLE_ENTRY && !is_asterisk(srch_ptr)) {
rsp->hdr.Status = STATUS_NO_SUCH_FILE; rsp->hdr.Status = STATUS_NO_SUCH_FILE;
else { } else {
dir_fp->dot_dotdot[0] = dir_fp->dot_dotdot[1] = 0; dir_fp->dot_dotdot[0] = dir_fp->dot_dotdot[1] = 0;
rsp->hdr.Status = STATUS_NO_MORE_FILES; rsp->hdr.Status = STATUS_NO_MORE_FILES;
} }
...@@ -4057,24 +4002,21 @@ int smb2_query_dir(struct ksmbd_work *work) ...@@ -4057,24 +4002,21 @@ int smb2_query_dir(struct ksmbd_work *work)
* Return: 0 on success, otherwise error * Return: 0 on success, otherwise error
*/ */
static int buffer_check_err(int reqOutputBufferLength, static int buffer_check_err(int reqOutputBufferLength,
struct smb2_query_info_rsp *rsp, int infoclass_size) struct smb2_query_info_rsp *rsp, int infoclass_size)
{ {
if (reqOutputBufferLength < le32_to_cpu(rsp->OutputBufferLength)) { if (reqOutputBufferLength < le32_to_cpu(rsp->OutputBufferLength)) {
if (reqOutputBufferLength < infoclass_size) { if (reqOutputBufferLength < infoclass_size) {
ksmbd_err("Invalid Buffer Size Requested\n"); ksmbd_err("Invalid Buffer Size Requested\n");
rsp->hdr.Status = STATUS_INFO_LENGTH_MISMATCH; rsp->hdr.Status = STATUS_INFO_LENGTH_MISMATCH;
rsp->hdr.smb2_buf_length = cpu_to_be32( rsp->hdr.smb2_buf_length = cpu_to_be32(sizeof(struct smb2_hdr) - 4);
sizeof(struct smb2_hdr) - 4);
return -EINVAL; return -EINVAL;
} }
ksmbd_debug(SMB, "Buffer Overflow\n"); ksmbd_debug(SMB, "Buffer Overflow\n");
rsp->hdr.Status = STATUS_BUFFER_OVERFLOW; rsp->hdr.Status = STATUS_BUFFER_OVERFLOW;
rsp->hdr.smb2_buf_length = cpu_to_be32( rsp->hdr.smb2_buf_length = cpu_to_be32(sizeof(struct smb2_hdr) - 4 +
sizeof(struct smb2_hdr) - 4 reqOutputBufferLength);
+ reqOutputBufferLength); rsp->OutputBufferLength = cpu_to_le32(reqOutputBufferLength);
rsp->OutputBufferLength = cpu_to_le32(
reqOutputBufferLength);
} }
return 0; return 0;
} }
...@@ -4096,7 +4038,7 @@ static void get_standard_info_pipe(struct smb2_query_info_rsp *rsp) ...@@ -4096,7 +4038,7 @@ static void get_standard_info_pipe(struct smb2_query_info_rsp *rsp)
} }
static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp, static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp,
uint64_t num) u64 num)
{ {
struct smb2_file_internal_info *file_info; struct smb2_file_internal_info *file_info;
...@@ -4110,9 +4052,10 @@ static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp, ...@@ -4110,9 +4052,10 @@ static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp,
} }
static int smb2_get_info_file_pipe(struct ksmbd_session *sess, static int smb2_get_info_file_pipe(struct ksmbd_session *sess,
struct smb2_query_info_req *req, struct smb2_query_info_rsp *rsp) struct smb2_query_info_req *req,
struct smb2_query_info_rsp *rsp)
{ {
uint64_t id; u64 id;
int rc; int rc;
/* /*
...@@ -4155,11 +4098,9 @@ static int smb2_get_info_file_pipe(struct ksmbd_session *sess, ...@@ -4155,11 +4098,9 @@ static int smb2_get_info_file_pipe(struct ksmbd_session *sess,
* *
* Return: 0 on success, otherwise error * Return: 0 on success, otherwise error
*/ */
static int smb2_get_ea(struct ksmbd_work *work, static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp,
struct ksmbd_file *fp, struct smb2_query_info_req *req,
struct smb2_query_info_req *req, struct smb2_query_info_rsp *rsp, void *rsp_org)
struct smb2_query_info_rsp *rsp,
void *rsp_org)
{ {
struct smb2_ea_info *eainfo, *prev_eainfo; struct smb2_ea_info *eainfo, *prev_eainfo;
char *name, *ptr, *xattr_list = NULL, *buf; char *name, *ptr, *xattr_list = NULL, *buf;
...@@ -4176,9 +4117,9 @@ static int smb2_get_ea(struct ksmbd_work *work, ...@@ -4176,9 +4117,9 @@ static int smb2_get_ea(struct ksmbd_work *work,
path = &fp->filp->f_path; path = &fp->filp->f_path;
/* single EA entry is requested with given user.* name */ /* single EA entry is requested with given user.* name */
if (req->InputBufferLength) if (req->InputBufferLength) {
ea_req = (struct smb2_ea_info_req *)req->Buffer; ea_req = (struct smb2_ea_info_req *)req->Buffer;
else { } else {
/* need to send all EAs, if no specific EA is requested*/ /* need to send all EAs, if no specific EA is requested*/
if (le32_to_cpu(req->Flags) & SL_RETURN_SINGLE_ENTRY) if (le32_to_cpu(req->Flags) & SL_RETURN_SINGLE_ENTRY)
ksmbd_debug(SMB, ksmbd_debug(SMB,
...@@ -4224,16 +4165,16 @@ static int smb2_get_ea(struct ksmbd_work *work, ...@@ -4224,16 +4165,16 @@ static int smb2_get_ea(struct ksmbd_work *work,
continue; continue;
if (!strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX, if (!strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX,
STREAM_PREFIX_LEN)) STREAM_PREFIX_LEN))
continue; continue;
if (req->InputBufferLength && if (req->InputBufferLength &&
(strncmp(&name[XATTR_USER_PREFIX_LEN], strncmp(&name[XATTR_USER_PREFIX_LEN], ea_req->name,
ea_req->name, ea_req->EaNameLength))) ea_req->EaNameLength))
continue; continue;
if (!strncmp(&name[XATTR_USER_PREFIX_LEN], if (!strncmp(&name[XATTR_USER_PREFIX_LEN],
DOS_ATTRIBUTE_PREFIX, DOS_ATTRIBUTE_PREFIX_LEN)) DOS_ATTRIBUTE_PREFIX, DOS_ATTRIBUTE_PREFIX_LEN))
continue; continue;
if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
...@@ -4263,8 +4204,7 @@ static int smb2_get_ea(struct ksmbd_work *work, ...@@ -4263,8 +4204,7 @@ static int smb2_get_ea(struct ksmbd_work *work,
eainfo->Flags = 0; eainfo->Flags = 0;
eainfo->EaNameLength = name_len; eainfo->EaNameLength = name_len;
if (!strncmp(name, XATTR_USER_PREFIX, if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
XATTR_USER_PREFIX_LEN))
memcpy(eainfo->name, &name[XATTR_USER_PREFIX_LEN], memcpy(eainfo->name, &name[XATTR_USER_PREFIX_LEN],
name_len); name_len);
else else
...@@ -4308,8 +4248,7 @@ static int smb2_get_ea(struct ksmbd_work *work, ...@@ -4308,8 +4248,7 @@ static int smb2_get_ea(struct ksmbd_work *work,
} }
static void get_file_access_info(struct smb2_query_info_rsp *rsp, static void get_file_access_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, struct ksmbd_file *fp, void *rsp_org)
void *rsp_org)
{ {
struct smb2_file_access_info *file_info; struct smb2_file_access_info *file_info;
...@@ -4321,8 +4260,7 @@ static void get_file_access_info(struct smb2_query_info_rsp *rsp, ...@@ -4321,8 +4260,7 @@ static void get_file_access_info(struct smb2_query_info_rsp *rsp,
} }
static int get_file_basic_info(struct smb2_query_info_rsp *rsp, static int get_file_basic_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, struct ksmbd_file *fp, void *rsp_org)
void *rsp_org)
{ {
struct smb2_file_all_info *basic_info; struct smb2_file_all_info *basic_info;
struct kstat stat; struct kstat stat;
...@@ -4346,8 +4284,7 @@ static int get_file_basic_info(struct smb2_query_info_rsp *rsp, ...@@ -4346,8 +4284,7 @@ static int get_file_basic_info(struct smb2_query_info_rsp *rsp,
basic_info->Attributes = fp->f_ci->m_fattr; basic_info->Attributes = fp->f_ci->m_fattr;
basic_info->Pad1 = 0; basic_info->Pad1 = 0;
rsp->OutputBufferLength = rsp->OutputBufferLength =
cpu_to_le32(offsetof(struct smb2_file_all_info, cpu_to_le32(offsetof(struct smb2_file_all_info, AllocationSize));
AllocationSize));
inc_rfc1001_len(rsp_org, offsetof(struct smb2_file_all_info, inc_rfc1001_len(rsp_org, offsetof(struct smb2_file_all_info,
AllocationSize)); AllocationSize));
return 0; return 0;
...@@ -4363,15 +4300,13 @@ static unsigned long long get_allocation_size(struct inode *inode, ...@@ -4363,15 +4300,13 @@ static unsigned long long get_allocation_size(struct inode *inode,
alloc_size = stat->size; alloc_size = stat->size;
else else
alloc_size = inode->i_blocks << 9; alloc_size = inode->i_blocks << 9;
} }
return alloc_size; return alloc_size;
} }
static void get_file_standard_info(struct smb2_query_info_rsp *rsp, static void get_file_standard_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, struct ksmbd_file *fp, void *rsp_org)
void *rsp_org)
{ {
struct smb2_file_standard_info *sinfo; struct smb2_file_standard_info *sinfo;
unsigned int delete_pending; unsigned int delete_pending;
...@@ -4396,7 +4331,7 @@ static void get_file_standard_info(struct smb2_query_info_rsp *rsp, ...@@ -4396,7 +4331,7 @@ static void get_file_standard_info(struct smb2_query_info_rsp *rsp,
} }
static void get_file_alignment_info(struct smb2_query_info_rsp *rsp, static void get_file_alignment_info(struct smb2_query_info_rsp *rsp,
void *rsp_org) void *rsp_org)
{ {
struct smb2_file_alignment_info *file_info; struct smb2_file_alignment_info *file_info;
...@@ -4409,9 +4344,8 @@ static void get_file_alignment_info(struct smb2_query_info_rsp *rsp, ...@@ -4409,9 +4344,8 @@ static void get_file_alignment_info(struct smb2_query_info_rsp *rsp,
} }
static int get_file_all_info(struct ksmbd_work *work, static int get_file_all_info(struct ksmbd_work *work,
struct smb2_query_info_rsp *rsp, struct smb2_query_info_rsp *rsp, struct ksmbd_file *fp,
struct ksmbd_file *fp, void *rsp_org)
void *rsp_org)
{ {
struct ksmbd_conn *conn = work->conn; struct ksmbd_conn *conn = work->conn;
struct smb2_file_all_info *file_info; struct smb2_file_all_info *file_info;
...@@ -4478,9 +4412,8 @@ static int get_file_all_info(struct ksmbd_work *work, ...@@ -4478,9 +4412,8 @@ static int get_file_all_info(struct ksmbd_work *work,
} }
static void get_file_alternate_info(struct ksmbd_work *work, static void get_file_alternate_info(struct ksmbd_work *work,
struct smb2_query_info_rsp *rsp, struct smb2_query_info_rsp *rsp, struct ksmbd_file *fp,
struct ksmbd_file *fp, void *rsp_org)
void *rsp_org)
{ {
struct ksmbd_conn *conn = work->conn; struct ksmbd_conn *conn = work->conn;
struct smb2_file_alt_name_info *file_info; struct smb2_file_alt_name_info *file_info;
...@@ -4499,9 +4432,8 @@ static void get_file_alternate_info(struct ksmbd_work *work, ...@@ -4499,9 +4432,8 @@ static void get_file_alternate_info(struct ksmbd_work *work,
} }
static void get_file_stream_info(struct ksmbd_work *work, static void get_file_stream_info(struct ksmbd_work *work,
struct smb2_query_info_rsp *rsp, struct smb2_query_info_rsp *rsp, struct ksmbd_file *fp,
struct ksmbd_file *fp, void *rsp_org)
void *rsp_org)
{ {
struct ksmbd_conn *conn = work->conn; struct ksmbd_conn *conn = work->conn;
struct smb2_file_stream_info *file_info; struct smb2_file_stream_info *file_info;
...@@ -4530,7 +4462,7 @@ static void get_file_stream_info(struct ksmbd_work *work, ...@@ -4530,7 +4462,7 @@ static void get_file_stream_info(struct ksmbd_work *work,
ksmbd_debug(SMB, "%s, len %d\n", stream_name, streamlen); ksmbd_debug(SMB, "%s, len %d\n", stream_name, streamlen);
if (strncmp(&stream_name[XATTR_USER_PREFIX_LEN], if (strncmp(&stream_name[XATTR_USER_PREFIX_LEN],
STREAM_PREFIX, STREAM_PREFIX_LEN)) STREAM_PREFIX, STREAM_PREFIX_LEN))
continue; continue;
stream_name_len = streamlen - (XATTR_USER_PREFIX_LEN + stream_name_len = streamlen - (XATTR_USER_PREFIX_LEN +
...@@ -4588,8 +4520,7 @@ static void get_file_stream_info(struct ksmbd_work *work, ...@@ -4588,8 +4520,7 @@ static void get_file_stream_info(struct ksmbd_work *work,
} }
static void get_file_internal_info(struct smb2_query_info_rsp *rsp, static void get_file_internal_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, struct ksmbd_file *fp, void *rsp_org)
void *rsp_org)
{ {
struct smb2_file_internal_info *file_info; struct smb2_file_internal_info *file_info;
struct kstat stat; struct kstat stat;
...@@ -4603,8 +4534,7 @@ static void get_file_internal_info(struct smb2_query_info_rsp *rsp, ...@@ -4603,8 +4534,7 @@ static void get_file_internal_info(struct smb2_query_info_rsp *rsp,
} }
static int get_file_network_open_info(struct smb2_query_info_rsp *rsp, static int get_file_network_open_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, struct ksmbd_file *fp, void *rsp_org)
void *rsp_org)
{ {
struct smb2_file_ntwrk_info *file_info; struct smb2_file_ntwrk_info *file_info;
struct inode *inode; struct inode *inode;
...@@ -4640,8 +4570,7 @@ static int get_file_network_open_info(struct smb2_query_info_rsp *rsp, ...@@ -4640,8 +4570,7 @@ static int get_file_network_open_info(struct smb2_query_info_rsp *rsp,
return 0; return 0;
} }
static void get_file_ea_info(struct smb2_query_info_rsp *rsp, static void get_file_ea_info(struct smb2_query_info_rsp *rsp, void *rsp_org)
void *rsp_org)
{ {
struct smb2_file_ea_info *file_info; struct smb2_file_ea_info *file_info;
...@@ -4653,8 +4582,7 @@ static void get_file_ea_info(struct smb2_query_info_rsp *rsp, ...@@ -4653,8 +4582,7 @@ static void get_file_ea_info(struct smb2_query_info_rsp *rsp,
} }
static void get_file_position_info(struct smb2_query_info_rsp *rsp, static void get_file_position_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, struct ksmbd_file *fp, void *rsp_org)
void *rsp_org)
{ {
struct smb2_file_pos_info *file_info; struct smb2_file_pos_info *file_info;
...@@ -4666,8 +4594,7 @@ static void get_file_position_info(struct smb2_query_info_rsp *rsp, ...@@ -4666,8 +4594,7 @@ static void get_file_position_info(struct smb2_query_info_rsp *rsp,
} }
static void get_file_mode_info(struct smb2_query_info_rsp *rsp, static void get_file_mode_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, struct ksmbd_file *fp, void *rsp_org)
void *rsp_org)
{ {
struct smb2_file_mode_info *file_info; struct smb2_file_mode_info *file_info;
...@@ -4679,8 +4606,7 @@ static void get_file_mode_info(struct smb2_query_info_rsp *rsp, ...@@ -4679,8 +4606,7 @@ static void get_file_mode_info(struct smb2_query_info_rsp *rsp,
} }
static void get_file_compression_info(struct smb2_query_info_rsp *rsp, static void get_file_compression_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, struct ksmbd_file *fp, void *rsp_org)
void *rsp_org)
{ {
struct smb2_file_comp_info *file_info; struct smb2_file_comp_info *file_info;
struct kstat stat; struct kstat stat;
...@@ -4701,8 +4627,7 @@ static void get_file_compression_info(struct smb2_query_info_rsp *rsp, ...@@ -4701,8 +4627,7 @@ static void get_file_compression_info(struct smb2_query_info_rsp *rsp,
} }
static int get_file_attribute_tag_info(struct smb2_query_info_rsp *rsp, static int get_file_attribute_tag_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, struct ksmbd_file *fp, void *rsp_org)
void *rsp_org)
{ {
struct smb2_file_attr_tag_info *file_info; struct smb2_file_attr_tag_info *file_info;
...@@ -4723,8 +4648,7 @@ static int get_file_attribute_tag_info(struct smb2_query_info_rsp *rsp, ...@@ -4723,8 +4648,7 @@ static int get_file_attribute_tag_info(struct smb2_query_info_rsp *rsp,
} }
static int find_file_posix_info(struct smb2_query_info_rsp *rsp, static int find_file_posix_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, struct ksmbd_file *fp, void *rsp_org)
void *rsp_org)
{ {
struct smb311_posix_qinfo *file_info; struct smb311_posix_qinfo *file_info;
struct inode *inode = FP_INODE(fp); struct inode *inode = FP_INODE(fp);
...@@ -4747,15 +4671,13 @@ static int find_file_posix_info(struct smb2_query_info_rsp *rsp, ...@@ -4747,15 +4671,13 @@ static int find_file_posix_info(struct smb2_query_info_rsp *rsp,
file_info->DeviceId = cpu_to_le32(inode->i_rdev); file_info->DeviceId = cpu_to_le32(inode->i_rdev);
rsp->OutputBufferLength = rsp->OutputBufferLength =
cpu_to_le32(sizeof(struct smb311_posix_qinfo)); cpu_to_le32(sizeof(struct smb311_posix_qinfo));
inc_rfc1001_len(rsp_org, inc_rfc1001_len(rsp_org, sizeof(struct smb311_posix_qinfo));
sizeof(struct smb311_posix_qinfo));
return 0; return 0;
} }
static int smb2_get_info_file(struct ksmbd_work *work, static int smb2_get_info_file(struct ksmbd_work *work,
struct smb2_query_info_req *req, struct smb2_query_info_req *req,
struct smb2_query_info_rsp *rsp, struct smb2_query_info_rsp *rsp, void *rsp_org)
void *rsp_org)
{ {
struct ksmbd_file *fp; struct ksmbd_file *fp;
int fileinfoclass = 0; int fileinfoclass = 0;
...@@ -4764,7 +4686,7 @@ static int smb2_get_info_file(struct ksmbd_work *work, ...@@ -4764,7 +4686,7 @@ static int smb2_get_info_file(struct ksmbd_work *work,
unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID; unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID;
if (test_share_config_flag(work->tcon->share_conf, if (test_share_config_flag(work->tcon->share_conf,
KSMBD_SHARE_FLAG_PIPE)) { KSMBD_SHARE_FLAG_PIPE)) {
/* smb2 info file called for pipe */ /* smb2 info file called for pipe */
return smb2_get_info_file_pipe(work->sess, req, rsp); return smb2_get_info_file_pipe(work->sess, req, rsp);
} }
...@@ -4887,9 +4809,8 @@ static int smb2_get_info_file(struct ksmbd_work *work, ...@@ -4887,9 +4809,8 @@ static int smb2_get_info_file(struct ksmbd_work *work,
} }
static int smb2_get_info_filesystem(struct ksmbd_work *work, static int smb2_get_info_filesystem(struct ksmbd_work *work,
struct smb2_query_info_req *req, struct smb2_query_info_req *req,
struct smb2_query_info_rsp *rsp, struct smb2_query_info_rsp *rsp, void *rsp_org)
void *rsp_org)
{ {
struct ksmbd_session *sess = work->sess; struct ksmbd_session *sess = work->sess;
struct ksmbd_conn *conn = sess->conn; struct ksmbd_conn *conn = sess->conn;
...@@ -5029,9 +4950,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, ...@@ -5029,9 +4950,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
info->extended_info.version = cpu_to_le32(1); info->extended_info.version = cpu_to_le32(1);
info->extended_info.release = cpu_to_le32(1); info->extended_info.release = cpu_to_le32(1);
info->extended_info.rel_date = 0; info->extended_info.rel_date = 0;
memcpy(info->extended_info.version_string, memcpy(info->extended_info.version_string, "1.1.0", strlen("1.1.0"));
"1.1.0",
strlen("1.1.0"));
rsp->OutputBufferLength = cpu_to_le32(64); rsp->OutputBufferLength = cpu_to_le32(64);
inc_rfc1001_len(rsp_org, 64); inc_rfc1001_len(rsp_org, 64);
fs_infoclass_size = FS_OBJECT_ID_INFORMATION_SIZE; fs_infoclass_size = FS_OBJECT_ID_INFORMATION_SIZE;
...@@ -5121,8 +5040,8 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, ...@@ -5121,8 +5040,8 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
} }
static int smb2_get_info_sec(struct ksmbd_work *work, static int smb2_get_info_sec(struct ksmbd_work *work,
struct smb2_query_info_req *req, struct smb2_query_info_rsp *rsp, struct smb2_query_info_req *req,
void *rsp_org) struct smb2_query_info_rsp *rsp, void *rsp_org)
{ {
struct ksmbd_file *fp; struct ksmbd_file *fp;
struct smb_ntsd *pntsd = (struct smb_ntsd *)rsp->Buffer, *ppntsd = NULL; struct smb_ntsd *pntsd = (struct smb_ntsd *)rsp->Buffer, *ppntsd = NULL;
...@@ -5162,7 +5081,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work, ...@@ -5162,7 +5081,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
fattr.cf_dacls = ksmbd_vfs_get_acl(inode, ACL_TYPE_DEFAULT); fattr.cf_dacls = ksmbd_vfs_get_acl(inode, ACL_TYPE_DEFAULT);
if (test_share_config_flag(work->tcon->share_conf, if (test_share_config_flag(work->tcon->share_conf,
KSMBD_SHARE_FLAG_ACL_XATTR)) KSMBD_SHARE_FLAG_ACL_XATTR))
ksmbd_vfs_get_sd_xattr(work->conn, fp->filp->f_path.dentry, &ppntsd); ksmbd_vfs_get_sd_xattr(work->conn, fp->filp->f_path.dentry, &ppntsd);
rc = build_sec_desc(pntsd, ppntsd, addition_info, &secdesclen, &fattr); rc = build_sec_desc(pntsd, ppntsd, addition_info, &secdesclen, &fattr);
...@@ -5243,7 +5162,7 @@ int smb2_query_info(struct ksmbd_work *work) ...@@ -5243,7 +5162,7 @@ int smb2_query_info(struct ksmbd_work *work)
*/ */
static noinline int smb2_close_pipe(struct ksmbd_work *work) static noinline int smb2_close_pipe(struct ksmbd_work *work)
{ {
uint64_t id; u64 id;
struct smb2_close_req *req = work->request_buf; struct smb2_close_req *req = work->request_buf;
struct smb2_close_rsp *rsp = work->response_buf; struct smb2_close_rsp *rsp = work->response_buf;
...@@ -5273,7 +5192,7 @@ static noinline int smb2_close_pipe(struct ksmbd_work *work) ...@@ -5273,7 +5192,7 @@ static noinline int smb2_close_pipe(struct ksmbd_work *work)
int smb2_close(struct ksmbd_work *work) int smb2_close(struct ksmbd_work *work)
{ {
unsigned int volatile_id = KSMBD_NO_FID; unsigned int volatile_id = KSMBD_NO_FID;
uint64_t sess_id; u64 sess_id;
struct smb2_close_req *req; struct smb2_close_req *req;
struct smb2_close_rsp *rsp; struct smb2_close_rsp *rsp;
struct smb2_close_rsp *rsp_org; struct smb2_close_rsp *rsp_org;
...@@ -5297,9 +5216,9 @@ int smb2_close(struct ksmbd_work *work) ...@@ -5297,9 +5216,9 @@ int smb2_close(struct ksmbd_work *work)
sess_id = work->compound_sid; sess_id = work->compound_sid;
work->compound_sid = 0; work->compound_sid = 0;
if (check_session_id(conn, sess_id)) if (check_session_id(conn, sess_id)) {
work->compound_sid = sess_id; work->compound_sid = sess_id;
else { } else {
rsp->hdr.Status = STATUS_USER_SESSION_DELETED; rsp->hdr.Status = STATUS_USER_SESSION_DELETED;
if (req->hdr.Flags & SMB2_FLAGS_RELATED_OPERATIONS) if (req->hdr.Flags & SMB2_FLAGS_RELATED_OPERATIONS)
rsp->hdr.Status = STATUS_INVALID_PARAMETER; rsp->hdr.Status = STATUS_INVALID_PARAMETER;
...@@ -5308,7 +5227,7 @@ int smb2_close(struct ksmbd_work *work) ...@@ -5308,7 +5227,7 @@ int smb2_close(struct ksmbd_work *work)
} }
if (work->next_smb2_rcv_hdr_off && if (work->next_smb2_rcv_hdr_off &&
!HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) { !HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) {
if (!HAS_FILE_ID(work->compound_fid)) { if (!HAS_FILE_ID(work->compound_fid)) {
/* file already closed, return FILE_CLOSED */ /* file already closed, return FILE_CLOSED */
ksmbd_debug(SMB, "file already closed\n"); ksmbd_debug(SMB, "file already closed\n");
...@@ -5395,8 +5314,8 @@ int smb2_echo(struct ksmbd_work *work) ...@@ -5395,8 +5314,8 @@ int smb2_echo(struct ksmbd_work *work)
} }
static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp, static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
struct smb2_file_rename_info *file_info, struct smb2_file_rename_info *file_info,
struct nls_table *local_nls) struct nls_table *local_nls)
{ {
struct ksmbd_share_config *share = fp->tcon->share_conf; struct ksmbd_share_config *share = fp->tcon->share_conf;
char *new_name = NULL, *abs_oldname = NULL, *old_name = NULL; char *new_name = NULL, *abs_oldname = NULL, *old_name = NULL;
...@@ -5416,9 +5335,9 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -5416,9 +5335,9 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
goto out; goto out;
} }
old_name = strrchr(abs_oldname, '/'); old_name = strrchr(abs_oldname, '/');
if (old_name && old_name[1] != '\0') if (old_name && old_name[1] != '\0') {
old_name++; old_name++;
else { } else {
ksmbd_debug(SMB, "can't get last component in path %s\n", ksmbd_debug(SMB, "can't get last component in path %s\n",
abs_oldname); abs_oldname);
rc = -ENOENT; rc = -ENOENT;
...@@ -5497,8 +5416,7 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -5497,8 +5416,7 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
} }
} else { } else {
if (file_present && if (file_present &&
strncmp(old_name, path.dentry->d_name.name, strncmp(old_name, path.dentry->d_name.name, strlen(old_name))) {
strlen(old_name))) {
rc = -EEXIST; rc = -EEXIST;
ksmbd_debug(SMB, ksmbd_debug(SMB,
"cannot rename already existing file\n"); "cannot rename already existing file\n");
...@@ -5515,10 +5433,9 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp, ...@@ -5515,10 +5433,9 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
} }
static int smb2_create_link(struct ksmbd_work *work, static int smb2_create_link(struct ksmbd_work *work,
struct ksmbd_share_config *share, struct ksmbd_share_config *share,
struct smb2_file_link_info *file_info, struct smb2_file_link_info *file_info, struct file *filp,
struct file *filp, struct nls_table *local_nls)
struct nls_table *local_nls)
{ {
char *link_name = NULL, *target_name = NULL, *pathname = NULL; char *link_name = NULL, *target_name = NULL, *pathname = NULL;
struct path path; struct path path;
...@@ -5586,9 +5503,8 @@ static bool is_attributes_write_allowed(struct ksmbd_file *fp) ...@@ -5586,9 +5503,8 @@ static bool is_attributes_write_allowed(struct ksmbd_file *fp)
return fp->daccess & FILE_WRITE_ATTRIBUTES_LE; return fp->daccess & FILE_WRITE_ATTRIBUTES_LE;
} }
static int set_file_basic_info(struct ksmbd_file *fp, static int set_file_basic_info(struct ksmbd_file *fp, char *buf,
char *buf, struct ksmbd_share_config *share)
struct ksmbd_share_config *share)
{ {
struct smb2_file_all_info *file_info; struct smb2_file_all_info *file_info;
struct iattr attrs; struct iattr attrs;
...@@ -5617,8 +5533,9 @@ static int set_file_basic_info(struct ksmbd_file *fp, ...@@ -5617,8 +5533,9 @@ static int set_file_basic_info(struct ksmbd_file *fp,
temp_attrs.ia_ctime = ksmbd_NTtimeToUnix(file_info->ChangeTime); temp_attrs.ia_ctime = ksmbd_NTtimeToUnix(file_info->ChangeTime);
attrs.ia_ctime = temp_attrs.ia_ctime; attrs.ia_ctime = temp_attrs.ia_ctime;
attrs.ia_valid |= ATTR_CTIME; attrs.ia_valid |= ATTR_CTIME;
} else } else {
temp_attrs.ia_ctime = inode->i_ctime; temp_attrs.ia_ctime = inode->i_ctime;
}
if (file_info->LastWriteTime) { if (file_info->LastWriteTime) {
attrs.ia_mtime = ksmbd_NTtimeToUnix(file_info->LastWriteTime); attrs.ia_mtime = ksmbd_NTtimeToUnix(file_info->LastWriteTime);
...@@ -5627,7 +5544,7 @@ static int set_file_basic_info(struct ksmbd_file *fp, ...@@ -5627,7 +5544,7 @@ static int set_file_basic_info(struct ksmbd_file *fp,
if (file_info->Attributes) { if (file_info->Attributes) {
if (!S_ISDIR(inode->i_mode) && if (!S_ISDIR(inode->i_mode) &&
file_info->Attributes & ATTR_DIRECTORY_LE) { file_info->Attributes & ATTR_DIRECTORY_LE) {
ksmbd_err("can't change a file to a directory\n"); ksmbd_err("can't change a file to a directory\n");
return -EINVAL; return -EINVAL;
} }
...@@ -5683,8 +5600,7 @@ static int set_file_basic_info(struct ksmbd_file *fp, ...@@ -5683,8 +5600,7 @@ static int set_file_basic_info(struct ksmbd_file *fp,
} }
static int set_file_allocation_info(struct ksmbd_work *work, static int set_file_allocation_info(struct ksmbd_work *work,
struct ksmbd_file *fp, struct ksmbd_file *fp, char *buf)
char *buf)
{ {
/* /*
* TODO : It's working fine only when store dos attributes * TODO : It's working fine only when store dos attributes
...@@ -5733,9 +5649,8 @@ static int set_file_allocation_info(struct ksmbd_work *work, ...@@ -5733,9 +5649,8 @@ static int set_file_allocation_info(struct ksmbd_work *work,
return 0; return 0;
} }
static int set_end_of_file_info(struct ksmbd_work *work, static int set_end_of_file_info(struct ksmbd_work *work, struct ksmbd_file *fp,
struct ksmbd_file *fp, char *buf)
char *buf)
{ {
struct smb2_file_eof_info *file_eof_info; struct smb2_file_eof_info *file_eof_info;
loff_t newsize; loff_t newsize;
...@@ -5761,8 +5676,7 @@ static int set_end_of_file_info(struct ksmbd_work *work, ...@@ -5761,8 +5676,7 @@ static int set_end_of_file_info(struct ksmbd_work *work,
fp->filename, newsize); fp->filename, newsize);
rc = ksmbd_vfs_truncate(work, NULL, fp, newsize); rc = ksmbd_vfs_truncate(work, NULL, fp, newsize);
if (rc) { if (rc) {
ksmbd_debug(SMB, ksmbd_debug(SMB, "truncate failed! filename : %s err %d\n",
"truncate failed! filename : %s err %d\n",
fp->filename, rc); fp->filename, rc);
if (rc != -EAGAIN) if (rc != -EAGAIN)
rc = -EBADF; rc = -EBADF;
...@@ -5772,9 +5686,8 @@ static int set_end_of_file_info(struct ksmbd_work *work, ...@@ -5772,9 +5686,8 @@ static int set_end_of_file_info(struct ksmbd_work *work,
return 0; return 0;
} }
static int set_rename_info(struct ksmbd_work *work, static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp,
struct ksmbd_file *fp, char *buf)
char *buf)
{ {
struct ksmbd_file *parent_fp; struct ksmbd_file *parent_fp;
...@@ -5799,8 +5712,7 @@ static int set_rename_info(struct ksmbd_work *work, ...@@ -5799,8 +5712,7 @@ static int set_rename_info(struct ksmbd_work *work,
work->sess->conn->local_nls); work->sess->conn->local_nls);
} }
static int set_file_disposition_info(struct ksmbd_file *fp, static int set_file_disposition_info(struct ksmbd_file *fp, char *buf)
char *buf)
{ {
struct smb2_file_disposition_info *file_info; struct smb2_file_disposition_info *file_info;
struct inode *inode; struct inode *inode;
...@@ -5814,7 +5726,7 @@ static int set_file_disposition_info(struct ksmbd_file *fp, ...@@ -5814,7 +5726,7 @@ static int set_file_disposition_info(struct ksmbd_file *fp,
file_info = (struct smb2_file_disposition_info *)buf; file_info = (struct smb2_file_disposition_info *)buf;
if (file_info->DeletePending) { if (file_info->DeletePending) {
if (S_ISDIR(inode->i_mode) && if (S_ISDIR(inode->i_mode) &&
ksmbd_vfs_empty_dir(fp) == -ENOTEMPTY) ksmbd_vfs_empty_dir(fp) == -ENOTEMPTY)
return -EBUSY; return -EBUSY;
ksmbd_set_inode_pending_delete(fp); ksmbd_set_inode_pending_delete(fp);
} else { } else {
...@@ -5823,8 +5735,7 @@ static int set_file_disposition_info(struct ksmbd_file *fp, ...@@ -5823,8 +5735,7 @@ static int set_file_disposition_info(struct ksmbd_file *fp,
return 0; return 0;
} }
static int set_file_position_info(struct ksmbd_file *fp, static int set_file_position_info(struct ksmbd_file *fp, char *buf)
char *buf)
{ {
struct smb2_file_pos_info *file_info; struct smb2_file_pos_info *file_info;
loff_t current_byte_offset; loff_t current_byte_offset;
...@@ -5837,8 +5748,8 @@ static int set_file_position_info(struct ksmbd_file *fp, ...@@ -5837,8 +5748,8 @@ static int set_file_position_info(struct ksmbd_file *fp,
sector_size = ksmbd_vfs_logical_sector_size(inode); sector_size = ksmbd_vfs_logical_sector_size(inode);
if (current_byte_offset < 0 || if (current_byte_offset < 0 ||
(fp->coption == FILE_NO_INTERMEDIATE_BUFFERING_LE && (fp->coption == FILE_NO_INTERMEDIATE_BUFFERING_LE &&
current_byte_offset & (sector_size-1))) { current_byte_offset & (sector_size - 1))) {
ksmbd_err("CurrentByteOffset is not valid : %llu\n", ksmbd_err("CurrentByteOffset is not valid : %llu\n",
current_byte_offset); current_byte_offset);
return -EINVAL; return -EINVAL;
...@@ -5848,8 +5759,7 @@ static int set_file_position_info(struct ksmbd_file *fp, ...@@ -5848,8 +5759,7 @@ static int set_file_position_info(struct ksmbd_file *fp,
return 0; return 0;
} }
static int set_file_mode_info(struct ksmbd_file *fp, static int set_file_mode_info(struct ksmbd_file *fp, char *buf)
char *buf)
{ {
struct smb2_file_mode_info *file_info; struct smb2_file_mode_info *file_info;
__le32 mode; __le32 mode;
...@@ -5857,9 +5767,9 @@ static int set_file_mode_info(struct ksmbd_file *fp, ...@@ -5857,9 +5767,9 @@ static int set_file_mode_info(struct ksmbd_file *fp,
file_info = (struct smb2_file_mode_info *)buf; file_info = (struct smb2_file_mode_info *)buf;
mode = file_info->Mode; mode = file_info->Mode;
if ((mode & (~FILE_MODE_INFO_MASK)) || if ((mode & ~FILE_MODE_INFO_MASK) ||
(mode & FILE_SYNCHRONOUS_IO_ALERT_LE && (mode & FILE_SYNCHRONOUS_IO_ALERT_LE &&
mode & FILE_SYNCHRONOUS_IO_NONALERT_LE)) { mode & FILE_SYNCHRONOUS_IO_NONALERT_LE)) {
ksmbd_err("Mode is not valid : 0x%x\n", le32_to_cpu(mode)); ksmbd_err("Mode is not valid : 0x%x\n", le32_to_cpu(mode));
return -EINVAL; return -EINVAL;
} }
...@@ -5883,11 +5793,8 @@ static int set_file_mode_info(struct ksmbd_file *fp, ...@@ -5883,11 +5793,8 @@ static int set_file_mode_info(struct ksmbd_file *fp,
* Return: 0 on success, otherwise error * Return: 0 on success, otherwise error
* TODO: need to implement an error handling for STATUS_INFO_LENGTH_MISMATCH * TODO: need to implement an error handling for STATUS_INFO_LENGTH_MISMATCH
*/ */
static int smb2_set_info_file(struct ksmbd_work *work, static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
struct ksmbd_file *fp, int info_class, char *buf, struct ksmbd_share_config *share)
int info_class,
char *buf,
struct ksmbd_share_config *share)
{ {
switch (info_class) { switch (info_class) {
case FILE_BASIC_INFORMATION: case FILE_BASIC_INFORMATION:
...@@ -5900,8 +5807,7 @@ static int smb2_set_info_file(struct ksmbd_work *work, ...@@ -5900,8 +5807,7 @@ static int smb2_set_info_file(struct ksmbd_work *work,
return set_end_of_file_info(work, fp, buf); return set_end_of_file_info(work, fp, buf);
case FILE_RENAME_INFORMATION: case FILE_RENAME_INFORMATION:
if (!test_tree_conn_flag(work->tcon, if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
KSMBD_TREE_CONN_FLAG_WRITABLE)) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"User does not have write permission\n"); "User does not have write permission\n");
return -EACCES; return -EACCES;
...@@ -5914,8 +5820,7 @@ static int smb2_set_info_file(struct ksmbd_work *work, ...@@ -5914,8 +5820,7 @@ static int smb2_set_info_file(struct ksmbd_work *work,
work->sess->conn->local_nls); work->sess->conn->local_nls);
case FILE_DISPOSITION_INFORMATION: case FILE_DISPOSITION_INFORMATION:
if (!test_tree_conn_flag(work->tcon, if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
KSMBD_TREE_CONN_FLAG_WRITABLE)) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"User does not have write permission\n"); "User does not have write permission\n");
return -EACCES; return -EACCES;
...@@ -5945,10 +5850,8 @@ static int smb2_set_info_file(struct ksmbd_work *work, ...@@ -5945,10 +5850,8 @@ static int smb2_set_info_file(struct ksmbd_work *work,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static int smb2_set_info_sec(struct ksmbd_file *fp, static int smb2_set_info_sec(struct ksmbd_file *fp, int addition_info,
int addition_info, char *buffer, int buf_len)
char *buffer,
int buf_len)
{ {
struct smb_ntsd *pntsd = (struct smb_ntsd *)buffer; struct smb_ntsd *pntsd = (struct smb_ntsd *)buffer;
...@@ -6060,7 +5963,7 @@ int smb2_set_info(struct ksmbd_work *work) ...@@ -6060,7 +5963,7 @@ int smb2_set_info(struct ksmbd_work *work)
static noinline int smb2_read_pipe(struct ksmbd_work *work) static noinline int smb2_read_pipe(struct ksmbd_work *work)
{ {
int nbytes = 0, err; int nbytes = 0, err;
uint64_t id; u64 id;
struct ksmbd_rpc_command *rpc_resp; struct ksmbd_rpc_command *rpc_resp;
struct smb2_read_req *req = work->request_buf; struct smb2_read_req *req = work->request_buf;
struct smb2_read_rsp *rsp = work->response_buf; struct smb2_read_rsp *rsp = work->response_buf;
...@@ -6108,30 +6011,27 @@ static noinline int smb2_read_pipe(struct ksmbd_work *work) ...@@ -6108,30 +6011,27 @@ static noinline int smb2_read_pipe(struct ksmbd_work *work)
} }
static ssize_t smb2_read_rdma_channel(struct ksmbd_work *work, static ssize_t smb2_read_rdma_channel(struct ksmbd_work *work,
struct smb2_read_req *req, struct smb2_read_req *req, void *data_buf, size_t length)
void *data_buf, size_t length)
{ {
struct smb2_buffer_desc_v1 *desc = struct smb2_buffer_desc_v1 *desc =
(struct smb2_buffer_desc_v1 *)&req->Buffer[0]; (struct smb2_buffer_desc_v1 *)&req->Buffer[0];
int err; int err;
if (work->conn->dialect == SMB30_PROT_ID if (work->conn->dialect == SMB30_PROT_ID &&
&& req->Channel != SMB2_CHANNEL_RDMA_V1) req->Channel != SMB2_CHANNEL_RDMA_V1)
return -EINVAL; return -EINVAL;
if (req->ReadChannelInfoOffset == 0 if (req->ReadChannelInfoOffset == 0 ||
|| le16_to_cpu(req->ReadChannelInfoLength) < sizeof(*desc)) le16_to_cpu(req->ReadChannelInfoLength) < sizeof(*desc))
return -EINVAL; return -EINVAL;
work->need_invalidate_rkey = work->need_invalidate_rkey =
(req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE); (req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE);
work->remote_key = le32_to_cpu(desc->token); work->remote_key = le32_to_cpu(desc->token);
err = ksmbd_conn_rdma_write(work->conn, err = ksmbd_conn_rdma_write(work->conn, data_buf, length,
data_buf, length, le32_to_cpu(desc->token), le64_to_cpu(desc->offset),
le32_to_cpu(desc->token), le32_to_cpu(desc->length));
le64_to_cpu(desc->offset),
le32_to_cpu(desc->length));
if (err) if (err)
return err; return err;
...@@ -6226,7 +6126,7 @@ int smb2_read(struct ksmbd_work *work) ...@@ -6226,7 +6126,7 @@ int smb2_read(struct ksmbd_work *work)
nbytes, offset, mincount); nbytes, offset, mincount);
if (req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE || if (req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE ||
req->Channel == SMB2_CHANNEL_RDMA_V1) { req->Channel == SMB2_CHANNEL_RDMA_V1) {
/* write data to the client using rdma channel */ /* write data to the client using rdma channel */
remain_bytes = smb2_read_rdma_channel(work, req, remain_bytes = smb2_read_rdma_channel(work, req,
work->aux_payload_buf, nbytes); work->aux_payload_buf, nbytes);
...@@ -6290,7 +6190,7 @@ static noinline int smb2_write_pipe(struct ksmbd_work *work) ...@@ -6290,7 +6190,7 @@ static noinline int smb2_write_pipe(struct ksmbd_work *work)
struct smb2_write_req *req = work->request_buf; struct smb2_write_req *req = work->request_buf;
struct smb2_write_rsp *rsp = work->response_buf; struct smb2_write_rsp *rsp = work->response_buf;
struct ksmbd_rpc_command *rpc_resp; struct ksmbd_rpc_command *rpc_resp;
uint64_t id = 0; u64 id = 0;
int err = 0, ret = 0; int err = 0, ret = 0;
char *data_buf; char *data_buf;
size_t length; size_t length;
...@@ -6299,15 +6199,13 @@ static noinline int smb2_write_pipe(struct ksmbd_work *work) ...@@ -6299,15 +6199,13 @@ static noinline int smb2_write_pipe(struct ksmbd_work *work)
id = le64_to_cpu(req->VolatileFileId); id = le64_to_cpu(req->VolatileFileId);
if (le16_to_cpu(req->DataOffset) == if (le16_to_cpu(req->DataOffset) ==
(offsetof(struct smb2_write_req, Buffer) - 4)) { (offsetof(struct smb2_write_req, Buffer) - 4)) {
data_buf = (char *)&req->Buffer[0]; data_buf = (char *)&req->Buffer[0];
} else { } else {
if ((le16_to_cpu(req->DataOffset) > get_rfc1002_len(req)) || if ((le16_to_cpu(req->DataOffset) > get_rfc1002_len(req)) ||
(le16_to_cpu(req->DataOffset) + (le16_to_cpu(req->DataOffset) + length > get_rfc1002_len(req))) {
length > get_rfc1002_len(req))) {
ksmbd_err("invalid write data offset %u, smb_len %u\n", ksmbd_err("invalid write data offset %u, smb_len %u\n",
le16_to_cpu(req->DataOffset), le16_to_cpu(req->DataOffset), get_rfc1002_len(req));
get_rfc1002_len(req));
err = -EINVAL; err = -EINVAL;
goto out; goto out;
} }
...@@ -6351,8 +6249,8 @@ static noinline int smb2_write_pipe(struct ksmbd_work *work) ...@@ -6351,8 +6249,8 @@ static noinline int smb2_write_pipe(struct ksmbd_work *work)
} }
static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work, static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work,
struct smb2_write_req *req, struct ksmbd_file *fp, struct smb2_write_req *req, struct ksmbd_file *fp,
loff_t offset, size_t length, bool sync) loff_t offset, size_t length, bool sync)
{ {
struct smb2_buffer_desc_v1 *desc; struct smb2_buffer_desc_v1 *desc;
char *data_buf; char *data_buf;
...@@ -6362,14 +6260,14 @@ static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work, ...@@ -6362,14 +6260,14 @@ static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work,
desc = (struct smb2_buffer_desc_v1 *)&req->Buffer[0]; desc = (struct smb2_buffer_desc_v1 *)&req->Buffer[0];
if (work->conn->dialect == SMB30_PROT_ID && if (work->conn->dialect == SMB30_PROT_ID &&
req->Channel != SMB2_CHANNEL_RDMA_V1) req->Channel != SMB2_CHANNEL_RDMA_V1)
return -EINVAL; return -EINVAL;
if (req->Length != 0 || req->DataOffset != 0) if (req->Length != 0 || req->DataOffset != 0)
return -EINVAL; return -EINVAL;
if (req->WriteChannelInfoOffset == 0 if (req->WriteChannelInfoOffset == 0 ||
|| le16_to_cpu(req->WriteChannelInfoLength) < sizeof(*desc)) le16_to_cpu(req->WriteChannelInfoLength) < sizeof(*desc))
return -EINVAL; return -EINVAL;
work->need_invalidate_rkey = work->need_invalidate_rkey =
...@@ -6384,15 +6282,12 @@ static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work, ...@@ -6384,15 +6282,12 @@ static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work,
le32_to_cpu(desc->token), le32_to_cpu(desc->token),
le64_to_cpu(desc->offset), le64_to_cpu(desc->offset),
le32_to_cpu(desc->length)); le32_to_cpu(desc->length));
if (ret < 0) { if (ret < 0) {
ksmbd_free_response(data_buf); ksmbd_free_response(data_buf);
return ret; return ret;
} }
ret = ksmbd_vfs_write(work, fp, data_buf, length, &offset, ret = ksmbd_vfs_write(work, fp, data_buf, length, &offset, sync, &nbytes);
sync, &nbytes);
ksmbd_free_response(data_buf); ksmbd_free_response(data_buf);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -6421,8 +6316,7 @@ int smb2_write(struct ksmbd_work *work) ...@@ -6421,8 +6316,7 @@ int smb2_write(struct ksmbd_work *work)
rsp_org = work->response_buf; rsp_org = work->response_buf;
WORK_BUFFERS(work, req, rsp); WORK_BUFFERS(work, req, rsp);
if (test_share_config_flag(work->tcon->share_conf, if (test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_PIPE)) {
KSMBD_SHARE_FLAG_PIPE)) {
ksmbd_debug(SMB, "IPC pipe write request\n"); ksmbd_debug(SMB, "IPC pipe write request\n");
return smb2_write_pipe(work); return smb2_write_pipe(work);
} }
...@@ -6433,9 +6327,8 @@ int smb2_write(struct ksmbd_work *work) ...@@ -6433,9 +6327,8 @@ int smb2_write(struct ksmbd_work *work)
goto out; goto out;
} }
fp = ksmbd_lookup_fd_slow(work, fp = ksmbd_lookup_fd_slow(work, le64_to_cpu(req->VolatileFileId),
le64_to_cpu(req->VolatileFileId), le64_to_cpu(req->PersistentFileId));
le64_to_cpu(req->PersistentFileId));
if (!fp) { if (!fp) {
rsp->hdr.Status = STATUS_FILE_CLOSED; rsp->hdr.Status = STATUS_FILE_CLOSED;
return -ENOENT; return -ENOENT;
...@@ -6461,16 +6354,13 @@ int smb2_write(struct ksmbd_work *work) ...@@ -6461,16 +6354,13 @@ int smb2_write(struct ksmbd_work *work)
writethrough = true; writethrough = true;
if (req->Channel != SMB2_CHANNEL_RDMA_V1 && if (req->Channel != SMB2_CHANNEL_RDMA_V1 &&
req->Channel != SMB2_CHANNEL_RDMA_V1_INVALIDATE) { req->Channel != SMB2_CHANNEL_RDMA_V1_INVALIDATE) {
if (le16_to_cpu(req->DataOffset) == if (le16_to_cpu(req->DataOffset) ==
(offsetof(struct smb2_write_req, Buffer) - 4)) { (offsetof(struct smb2_write_req, Buffer) - 4)) {
data_buf = (char *)&req->Buffer[0]; data_buf = (char *)&req->Buffer[0];
} else { } else {
if ((le16_to_cpu(req->DataOffset) > if ((le16_to_cpu(req->DataOffset) > get_rfc1002_len(req)) ||
get_rfc1002_len(req)) || (le16_to_cpu(req->DataOffset) + length > get_rfc1002_len(req))) {
(le16_to_cpu(req->DataOffset) +
length > get_rfc1002_len(req))) {
ksmbd_err("invalid write data offset %u, smb_len %u\n", ksmbd_err("invalid write data offset %u, smb_len %u\n",
le16_to_cpu(req->DataOffset), le16_to_cpu(req->DataOffset),
get_rfc1002_len(req)); get_rfc1002_len(req));
...@@ -6603,7 +6493,7 @@ int smb2_cancel(struct ksmbd_work *work) ...@@ -6603,7 +6493,7 @@ int smb2_cancel(struct ksmbd_work *work)
chdr = cancel_work->request_buf; chdr = cancel_work->request_buf;
if (cancel_work->async_id != if (cancel_work->async_id !=
le64_to_cpu(hdr->Id.AsyncId)) le64_to_cpu(hdr->Id.AsyncId))
continue; continue;
ksmbd_debug(SMB, ksmbd_debug(SMB,
...@@ -6624,7 +6514,7 @@ int smb2_cancel(struct ksmbd_work *work) ...@@ -6624,7 +6514,7 @@ int smb2_cancel(struct ksmbd_work *work)
chdr = cancel_work->request_buf; chdr = cancel_work->request_buf;
if (chdr->MessageId != hdr->MessageId || if (chdr->MessageId != hdr->MessageId ||
cancel_work == work) cancel_work == work)
continue; continue;
ksmbd_debug(SMB, ksmbd_debug(SMB,
...@@ -6687,13 +6577,13 @@ static int smb2_set_flock_flags(struct file_lock *flock, int flags) ...@@ -6687,13 +6577,13 @@ static int smb2_set_flock_flags(struct file_lock *flock, int flags)
flock->fl_type = F_WRLCK; flock->fl_type = F_WRLCK;
flock->fl_flags |= FL_SLEEP; flock->fl_flags |= FL_SLEEP;
break; break;
case SMB2_LOCKFLAG_SHARED|SMB2_LOCKFLAG_FAIL_IMMEDIATELY: case SMB2_LOCKFLAG_SHARED | SMB2_LOCKFLAG_FAIL_IMMEDIATELY:
ksmbd_debug(SMB, ksmbd_debug(SMB,
"received shared & fail immediately request\n"); "received shared & fail immediately request\n");
cmd = F_SETLK; cmd = F_SETLK;
flock->fl_type = F_RDLCK; flock->fl_type = F_RDLCK;
break; break;
case SMB2_LOCKFLAG_EXCLUSIVE|SMB2_LOCKFLAG_FAIL_IMMEDIATELY: case SMB2_LOCKFLAG_EXCLUSIVE | SMB2_LOCKFLAG_FAIL_IMMEDIATELY:
ksmbd_debug(SMB, ksmbd_debug(SMB,
"received exclusive & fail immediately request\n"); "received exclusive & fail immediately request\n");
cmd = F_SETLK; cmd = F_SETLK;
...@@ -6710,7 +6600,7 @@ static int smb2_set_flock_flags(struct file_lock *flock, int flags) ...@@ -6710,7 +6600,7 @@ static int smb2_set_flock_flags(struct file_lock *flock, int flags)
} }
static struct ksmbd_lock *smb2_lock_init(struct file_lock *flock, static struct ksmbd_lock *smb2_lock_init(struct file_lock *flock,
unsigned int cmd, int flags, struct list_head *lock_list) unsigned int cmd, int flags, struct list_head *lock_list)
{ {
struct ksmbd_lock *lock; struct ksmbd_lock *lock;
...@@ -6764,7 +6654,7 @@ int smb2_lock(struct ksmbd_work *work) ...@@ -6764,7 +6654,7 @@ int smb2_lock(struct ksmbd_work *work)
int flags = 0; int flags = 0;
int cmd = 0; int cmd = 0;
int err = 0, i; int err = 0, i;
uint64_t lock_length; u64 lock_length;
struct ksmbd_lock *smb_lock = NULL, *cmp_lock, *tmp; struct ksmbd_lock *smb_lock = NULL, *cmp_lock, *tmp;
int nolock = 0; int nolock = 0;
LIST_HEAD(lock_list); LIST_HEAD(lock_list);
...@@ -6773,8 +6663,8 @@ int smb2_lock(struct ksmbd_work *work) ...@@ -6773,8 +6663,8 @@ int smb2_lock(struct ksmbd_work *work)
ksmbd_debug(SMB, "Received lock request\n"); ksmbd_debug(SMB, "Received lock request\n");
fp = ksmbd_lookup_fd_slow(work, fp = ksmbd_lookup_fd_slow(work,
le64_to_cpu(req->VolatileFileId), le64_to_cpu(req->VolatileFileId),
le64_to_cpu(req->PersistentFileId)); le64_to_cpu(req->PersistentFileId));
if (!fp) { if (!fp) {
ksmbd_debug(SMB, "Invalid file id for lock : %llu\n", ksmbd_debug(SMB, "Invalid file id for lock : %llu\n",
le64_to_cpu(req->VolatileFileId)); le64_to_cpu(req->VolatileFileId));
...@@ -6812,16 +6702,16 @@ int smb2_lock(struct ksmbd_work *work) ...@@ -6812,16 +6702,16 @@ int smb2_lock(struct ksmbd_work *work)
lock_length = le64_to_cpu(lock_ele[i].Length); lock_length = le64_to_cpu(lock_ele[i].Length);
if (lock_length > 0) { if (lock_length > 0) {
if (lock_length > if (lock_length > OFFSET_MAX - flock->fl_start) {
OFFSET_MAX - flock->fl_start) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"Invalid lock range requested\n"); "Invalid lock range requested\n");
lock_length = OFFSET_MAX - flock->fl_start; lock_length = OFFSET_MAX - flock->fl_start;
rsp->hdr.Status = STATUS_INVALID_LOCK_RANGE; rsp->hdr.Status = STATUS_INVALID_LOCK_RANGE;
goto out; goto out;
} }
} else } else {
lock_length = 0; lock_length = 0;
}
flock->fl_end = flock->fl_start + lock_length; flock->fl_end = flock->fl_start + lock_length;
...@@ -6836,9 +6726,9 @@ int smb2_lock(struct ksmbd_work *work) ...@@ -6836,9 +6726,9 @@ int smb2_lock(struct ksmbd_work *work)
/* Check conflict locks in one request */ /* Check conflict locks in one request */
list_for_each_entry(cmp_lock, &lock_list, llist) { list_for_each_entry(cmp_lock, &lock_list, llist) {
if (cmp_lock->fl->fl_start <= flock->fl_start && if (cmp_lock->fl->fl_start <= flock->fl_start &&
cmp_lock->fl->fl_end >= flock->fl_end) { cmp_lock->fl->fl_end >= flock->fl_end) {
if (cmp_lock->fl->fl_type != F_UNLCK && if (cmp_lock->fl->fl_type != F_UNLCK &&
flock->fl_type != F_UNLCK) { flock->fl_type != F_UNLCK) {
ksmbd_err("conflict two locks in one request\n"); ksmbd_err("conflict two locks in one request\n");
rsp->hdr.Status = rsp->hdr.Status =
STATUS_INVALID_PARAMETER; STATUS_INVALID_PARAMETER;
...@@ -6865,11 +6755,10 @@ int smb2_lock(struct ksmbd_work *work) ...@@ -6865,11 +6755,10 @@ int smb2_lock(struct ksmbd_work *work)
goto out; goto out;
} }
if ((prior_lock & (SMB2_LOCKFLAG_EXCLUSIVE | if ((prior_lock & (SMB2_LOCKFLAG_EXCLUSIVE | SMB2_LOCKFLAG_SHARED) &&
SMB2_LOCKFLAG_SHARED) && smb_lock->flags & SMB2_LOCKFLAG_UNLOCK) ||
smb_lock->flags & SMB2_LOCKFLAG_UNLOCK) || (prior_lock == SMB2_LOCKFLAG_UNLOCK &&
(prior_lock == SMB2_LOCKFLAG_UNLOCK && !(smb_lock->flags & SMB2_LOCKFLAG_UNLOCK))) {
!(smb_lock->flags & SMB2_LOCKFLAG_UNLOCK))) {
rsp->hdr.Status = STATUS_INVALID_PARAMETER; rsp->hdr.Status = STATUS_INVALID_PARAMETER;
goto out; goto out;
} }
...@@ -6877,22 +6766,21 @@ int smb2_lock(struct ksmbd_work *work) ...@@ -6877,22 +6766,21 @@ int smb2_lock(struct ksmbd_work *work)
prior_lock = smb_lock->flags; prior_lock = smb_lock->flags;
if (!(smb_lock->flags & SMB2_LOCKFLAG_UNLOCK) && if (!(smb_lock->flags & SMB2_LOCKFLAG_UNLOCK) &&
!(smb_lock->flags & SMB2_LOCKFLAG_FAIL_IMMEDIATELY)) !(smb_lock->flags & SMB2_LOCKFLAG_FAIL_IMMEDIATELY))
goto no_check_gl; goto no_check_gl;
nolock = 1; nolock = 1;
/* check locks in global list */ /* check locks in global list */
list_for_each_entry(cmp_lock, &global_lock_list, glist) { list_for_each_entry(cmp_lock, &global_lock_list, glist) {
if (file_inode(cmp_lock->fl->fl_file) != if (file_inode(cmp_lock->fl->fl_file) !=
file_inode(smb_lock->fl->fl_file)) file_inode(smb_lock->fl->fl_file))
continue; continue;
if (smb_lock->fl->fl_type == F_UNLCK) { if (smb_lock->fl->fl_type == F_UNLCK) {
if (cmp_lock->fl->fl_file == if (cmp_lock->fl->fl_file == smb_lock->fl->fl_file &&
smb_lock->fl->fl_file && cmp_lock->start == smb_lock->start &&
cmp_lock->start == smb_lock->start && cmp_lock->end == smb_lock->end &&
cmp_lock->end == smb_lock->end && !lock_defer_pending(cmp_lock->fl)) {
!lock_defer_pending(cmp_lock->fl)) {
nolock = 0; nolock = 0;
locks_free_lock(cmp_lock->fl); locks_free_lock(cmp_lock->fl);
list_del(&cmp_lock->glist); list_del(&cmp_lock->glist);
...@@ -6912,26 +6800,25 @@ int smb2_lock(struct ksmbd_work *work) ...@@ -6912,26 +6800,25 @@ int smb2_lock(struct ksmbd_work *work)
/* check zero byte lock range */ /* check zero byte lock range */
if (cmp_lock->zero_len && !smb_lock->zero_len && if (cmp_lock->zero_len && !smb_lock->zero_len &&
cmp_lock->start > smb_lock->start && cmp_lock->start > smb_lock->start &&
cmp_lock->start < smb_lock->end) { cmp_lock->start < smb_lock->end) {
ksmbd_err("previous lock conflict with zero byte lock range\n"); ksmbd_err("previous lock conflict with zero byte lock range\n");
rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED;
goto out; goto out;
} }
if (smb_lock->zero_len && !cmp_lock->zero_len && if (smb_lock->zero_len && !cmp_lock->zero_len &&
smb_lock->start > cmp_lock->start && smb_lock->start > cmp_lock->start &&
smb_lock->start < cmp_lock->end) { smb_lock->start < cmp_lock->end) {
ksmbd_err("current lock conflict with zero byte lock range\n"); ksmbd_err("current lock conflict with zero byte lock range\n");
rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED;
goto out; goto out;
} }
if (((cmp_lock->start <= smb_lock->start && if (((cmp_lock->start <= smb_lock->start &&
cmp_lock->end > smb_lock->start) || cmp_lock->end > smb_lock->start) ||
(cmp_lock->start < smb_lock->end && (cmp_lock->start < smb_lock->end && cmp_lock->end >= smb_lock->end)) &&
cmp_lock->end >= smb_lock->end)) && !cmp_lock->zero_len && !smb_lock->zero_len) {
!cmp_lock->zero_len && !smb_lock->zero_len) {
ksmbd_err("Not allow lock operation on exclusive lock range\n"); ksmbd_err("Not allow lock operation on exclusive lock range\n");
rsp->hdr.Status = rsp->hdr.Status =
STATUS_LOCK_NOT_GRANTED; STATUS_LOCK_NOT_GRANTED;
...@@ -6957,9 +6844,9 @@ int smb2_lock(struct ksmbd_work *work) ...@@ -6957,9 +6844,9 @@ int smb2_lock(struct ksmbd_work *work)
err = ksmbd_vfs_lock(filp, smb_lock->cmd, flock); err = ksmbd_vfs_lock(filp, smb_lock->cmd, flock);
skip: skip:
if (flags & SMB2_LOCKFLAG_UNLOCK) { if (flags & SMB2_LOCKFLAG_UNLOCK) {
if (!err) if (!err) {
ksmbd_debug(SMB, "File unlocked\n"); ksmbd_debug(SMB, "File unlocked\n");
else if (err == -ENOENT) { } else if (err == -ENOENT) {
rsp->hdr.Status = STATUS_NOT_LOCKED; rsp->hdr.Status = STATUS_NOT_LOCKED;
goto out; goto out;
} }
...@@ -7082,9 +6969,8 @@ int smb2_lock(struct ksmbd_work *work) ...@@ -7082,9 +6969,8 @@ int smb2_lock(struct ksmbd_work *work)
return 0; return 0;
} }
static int fsctl_copychunk(struct ksmbd_work *work, static int fsctl_copychunk(struct ksmbd_work *work, struct smb2_ioctl_req *req,
struct smb2_ioctl_req *req, struct smb2_ioctl_rsp *rsp)
struct smb2_ioctl_rsp *rsp)
{ {
struct copychunk_ioctl_req *ci_req; struct copychunk_ioctl_req *ci_req;
struct copychunk_ioctl_rsp *ci_rsp; struct copychunk_ioctl_rsp *ci_rsp;
...@@ -7101,12 +6987,12 @@ static int fsctl_copychunk(struct ksmbd_work *work, ...@@ -7101,12 +6987,12 @@ static int fsctl_copychunk(struct ksmbd_work *work,
rsp->VolatileFileId = req->VolatileFileId; rsp->VolatileFileId = req->VolatileFileId;
rsp->PersistentFileId = req->PersistentFileId; rsp->PersistentFileId = req->PersistentFileId;
ci_rsp->ChunksWritten = cpu_to_le32( ci_rsp->ChunksWritten =
ksmbd_server_side_copy_max_chunk_count()); cpu_to_le32(ksmbd_server_side_copy_max_chunk_count());
ci_rsp->ChunkBytesWritten = cpu_to_le32( ci_rsp->ChunkBytesWritten =
ksmbd_server_side_copy_max_chunk_size()); cpu_to_le32(ksmbd_server_side_copy_max_chunk_size());
ci_rsp->TotalBytesWritten = cpu_to_le32( ci_rsp->TotalBytesWritten =
ksmbd_server_side_copy_max_total_size()); cpu_to_le32(ksmbd_server_side_copy_max_total_size());
chunks = (struct srv_copychunk *)&ci_req->Chunks[0]; chunks = (struct srv_copychunk *)&ci_req->Chunks[0];
chunk_count = le32_to_cpu(ci_req->ChunkCount); chunk_count = le32_to_cpu(ci_req->ChunkCount);
...@@ -7114,22 +7000,22 @@ static int fsctl_copychunk(struct ksmbd_work *work, ...@@ -7114,22 +7000,22 @@ static int fsctl_copychunk(struct ksmbd_work *work,
/* verify the SRV_COPYCHUNK_COPY packet */ /* verify the SRV_COPYCHUNK_COPY packet */
if (chunk_count > ksmbd_server_side_copy_max_chunk_count() || if (chunk_count > ksmbd_server_side_copy_max_chunk_count() ||
le32_to_cpu(req->InputCount) < le32_to_cpu(req->InputCount) <
offsetof(struct copychunk_ioctl_req, Chunks) + offsetof(struct copychunk_ioctl_req, Chunks) +
chunk_count * sizeof(struct srv_copychunk)) { chunk_count * sizeof(struct srv_copychunk)) {
rsp->hdr.Status = STATUS_INVALID_PARAMETER; rsp->hdr.Status = STATUS_INVALID_PARAMETER;
return -EINVAL; return -EINVAL;
} }
for (i = 0; i < chunk_count; i++) { for (i = 0; i < chunk_count; i++) {
if (le32_to_cpu(chunks[i].Length) == 0 || if (le32_to_cpu(chunks[i].Length) == 0 ||
le32_to_cpu(chunks[i].Length) > le32_to_cpu(chunks[i].Length) > ksmbd_server_side_copy_max_chunk_size())
ksmbd_server_side_copy_max_chunk_size())
break; break;
total_size_written += le32_to_cpu(chunks[i].Length); total_size_written += le32_to_cpu(chunks[i].Length);
} }
if (i < chunk_count || total_size_written >
ksmbd_server_side_copy_max_total_size()) { if (i < chunk_count ||
total_size_written > ksmbd_server_side_copy_max_total_size()) {
rsp->hdr.Status = STATUS_INVALID_PARAMETER; rsp->hdr.Status = STATUS_INVALID_PARAMETER;
return -EINVAL; return -EINVAL;
} }
...@@ -7139,13 +7025,13 @@ static int fsctl_copychunk(struct ksmbd_work *work, ...@@ -7139,13 +7025,13 @@ static int fsctl_copychunk(struct ksmbd_work *work,
dst_fp = ksmbd_lookup_fd_slow(work, dst_fp = ksmbd_lookup_fd_slow(work,
le64_to_cpu(req->VolatileFileId), le64_to_cpu(req->VolatileFileId),
le64_to_cpu(req->PersistentFileId)); le64_to_cpu(req->PersistentFileId));
ret = -EINVAL; ret = -EINVAL;
if (!src_fp || src_fp->persistent_id != if (!src_fp ||
le64_to_cpu(ci_req->ResumeKey[1])) { src_fp->persistent_id != le64_to_cpu(ci_req->ResumeKey[1])) {
rsp->hdr.Status = STATUS_OBJECT_NAME_NOT_FOUND; rsp->hdr.Status = STATUS_OBJECT_NAME_NOT_FOUND;
goto out; goto out;
} }
if (!dst_fp) { if (!dst_fp) {
rsp->hdr.Status = STATUS_FILE_CLOSED; rsp->hdr.Status = STATUS_FILE_CLOSED;
goto out; goto out;
...@@ -7212,8 +7098,7 @@ static __be32 idev_ipv4_address(struct in_device *idev) ...@@ -7212,8 +7098,7 @@ static __be32 idev_ipv4_address(struct in_device *idev)
} }
static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn, static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn,
struct smb2_ioctl_req *req, struct smb2_ioctl_req *req, struct smb2_ioctl_rsp *rsp)
struct smb2_ioctl_rsp *rsp)
{ {
struct network_interface_info_ioctl_rsp *nii_rsp = NULL; struct network_interface_info_ioctl_rsp *nii_rsp = NULL;
int nbytes = 0; int nbytes = 0;
...@@ -7255,10 +7140,8 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn, ...@@ -7255,10 +7140,8 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn,
netdev->ethtool_ops->get_link_ksettings(netdev, &cmd); netdev->ethtool_ops->get_link_ksettings(netdev, &cmd);
speed = cmd.base.speed; speed = cmd.base.speed;
} else { } else {
ksmbd_err("%s %s %s\n", ksmbd_err("%s %s\n", netdev->name,
netdev->name, "speed is unknown, defaulting to 1Gb/sec");
"speed is unknown,",
"defaulting to 1Gb/sec");
speed = SPEED_1000; speed = SPEED_1000;
} }
...@@ -7321,10 +7204,9 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn, ...@@ -7321,10 +7204,9 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn,
return nbytes; return nbytes;
} }
static int fsctl_validate_negotiate_info(struct ksmbd_conn *conn, static int fsctl_validate_negotiate_info(struct ksmbd_conn *conn,
struct validate_negotiate_info_req *neg_req, struct validate_negotiate_info_req *neg_req,
struct validate_negotiate_info_rsp *neg_rsp) struct validate_negotiate_info_rsp *neg_rsp)
{ {
int ret = 0; int ret = 0;
int dialect; int dialect;
...@@ -7359,10 +7241,10 @@ static int fsctl_validate_negotiate_info(struct ksmbd_conn *conn, ...@@ -7359,10 +7241,10 @@ static int fsctl_validate_negotiate_info(struct ksmbd_conn *conn,
return ret; return ret;
} }
static int fsctl_query_allocated_ranges(struct ksmbd_work *work, uint64_t id, static int fsctl_query_allocated_ranges(struct ksmbd_work *work, u64 id,
struct file_allocated_range_buffer *qar_req, struct file_allocated_range_buffer *qar_req,
struct file_allocated_range_buffer *qar_rsp, struct file_allocated_range_buffer *qar_rsp,
int in_count, int *out_count) int in_count, int *out_count)
{ {
struct ksmbd_file *fp; struct ksmbd_file *fp;
loff_t start, length; loff_t start, length;
...@@ -7388,15 +7270,15 @@ static int fsctl_query_allocated_ranges(struct ksmbd_work *work, uint64_t id, ...@@ -7388,15 +7270,15 @@ static int fsctl_query_allocated_ranges(struct ksmbd_work *work, uint64_t id,
return ret; return ret;
} }
static int fsctl_pipe_transceive(struct ksmbd_work *work, uint64_t id, static int fsctl_pipe_transceive(struct ksmbd_work *work, u64 id,
int out_buf_len, struct smb2_ioctl_req *req, struct smb2_ioctl_rsp *rsp) int out_buf_len, struct smb2_ioctl_req *req,
struct smb2_ioctl_rsp *rsp)
{ {
struct ksmbd_rpc_command *rpc_resp; struct ksmbd_rpc_command *rpc_resp;
char *data_buf = (char *)&req->Buffer[0]; char *data_buf = (char *)&req->Buffer[0];
int nbytes = 0; int nbytes = 0;
rpc_resp = ksmbd_rpc_ioctl(work->sess, id, rpc_resp = ksmbd_rpc_ioctl(work->sess, id, data_buf,
data_buf,
le32_to_cpu(req->InputCount)); le32_to_cpu(req->InputCount));
if (rpc_resp) { if (rpc_resp) {
if (rpc_resp->flags == KSMBD_RPC_SOME_NOT_MAPPED) { if (rpc_resp->flags == KSMBD_RPC_SOME_NOT_MAPPED) {
...@@ -7432,8 +7314,8 @@ static int fsctl_pipe_transceive(struct ksmbd_work *work, uint64_t id, ...@@ -7432,8 +7314,8 @@ static int fsctl_pipe_transceive(struct ksmbd_work *work, uint64_t id,
return nbytes; return nbytes;
} }
static inline int fsctl_set_sparse(struct ksmbd_work *work, uint64_t id, static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id,
struct file_sparse *sparse) struct file_sparse *sparse)
{ {
struct ksmbd_file *fp; struct ksmbd_file *fp;
int ret = 0; int ret = 0;
...@@ -7450,8 +7332,8 @@ static inline int fsctl_set_sparse(struct ksmbd_work *work, uint64_t id, ...@@ -7450,8 +7332,8 @@ static inline int fsctl_set_sparse(struct ksmbd_work *work, uint64_t id,
fp->f_ci->m_fattr &= ~ATTR_SPARSE_FILE_LE; fp->f_ci->m_fattr &= ~ATTR_SPARSE_FILE_LE;
if (fp->f_ci->m_fattr != old_fattr && if (fp->f_ci->m_fattr != old_fattr &&
test_share_config_flag(work->tcon->share_conf, 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;
ret = ksmbd_vfs_get_dos_attrib_xattr(fp->filp->f_path.dentry, &da); ret = ksmbd_vfs_get_dos_attrib_xattr(fp->filp->f_path.dentry, &da);
...@@ -7470,7 +7352,8 @@ static inline int fsctl_set_sparse(struct ksmbd_work *work, uint64_t id, ...@@ -7470,7 +7352,8 @@ static inline int fsctl_set_sparse(struct ksmbd_work *work, uint64_t id,
} }
static int fsctl_request_resume_key(struct ksmbd_work *work, static int fsctl_request_resume_key(struct ksmbd_work *work,
struct smb2_ioctl_req *req, struct resume_key_ioctl_rsp *key_rsp) struct smb2_ioctl_req *req,
struct resume_key_ioctl_rsp *key_rsp)
{ {
struct ksmbd_file *fp; struct ksmbd_file *fp;
...@@ -7500,7 +7383,7 @@ int smb2_ioctl(struct ksmbd_work *work) ...@@ -7500,7 +7383,7 @@ int smb2_ioctl(struct ksmbd_work *work)
struct smb2_ioctl_rsp *rsp, *rsp_org; struct smb2_ioctl_rsp *rsp, *rsp_org;
int cnt_code, nbytes = 0; int cnt_code, nbytes = 0;
int out_buf_len; int out_buf_len;
uint64_t id = KSMBD_NO_FID; u64 id = KSMBD_NO_FID;
struct ksmbd_conn *conn = work->conn; struct ksmbd_conn *conn = work->conn;
int ret = 0; int ret = 0;
...@@ -7595,8 +7478,7 @@ int smb2_ioctl(struct ksmbd_work *work) ...@@ -7595,8 +7478,7 @@ int smb2_ioctl(struct ksmbd_work *work)
break; break;
case FSCTL_COPYCHUNK: case FSCTL_COPYCHUNK:
case FSCTL_COPYCHUNK_WRITE: case FSCTL_COPYCHUNK_WRITE:
if (!test_tree_conn_flag(work->tcon, if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
KSMBD_TREE_CONN_FLAG_WRITABLE)) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"User does not have write permission\n"); "User does not have write permission\n");
ret = -EACCES; ret = -EACCES;
...@@ -7623,8 +7505,7 @@ int smb2_ioctl(struct ksmbd_work *work) ...@@ -7623,8 +7505,7 @@ int smb2_ioctl(struct ksmbd_work *work)
struct ksmbd_file *fp; struct ksmbd_file *fp;
loff_t off, len; loff_t off, len;
if (!test_tree_conn_flag(work->tcon, if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
KSMBD_TREE_CONN_FLAG_WRITABLE)) {
ksmbd_debug(SMB, ksmbd_debug(SMB,
"User does not have write permission\n"); "User does not have write permission\n");
ret = -EACCES; ret = -EACCES;
...@@ -7731,7 +7612,7 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work) ...@@ -7731,7 +7612,7 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work)
struct oplock_info *opinfo = NULL; struct oplock_info *opinfo = NULL;
__le32 err = 0; __le32 err = 0;
int ret = 0; int ret = 0;
uint64_t volatile_id, persistent_id; u64 volatile_id, persistent_id;
char req_oplevel = 0, rsp_oplevel = 0; char req_oplevel = 0, rsp_oplevel = 0;
unsigned int oplock_change_type; unsigned int oplock_change_type;
...@@ -7768,34 +7649,36 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work) ...@@ -7768,34 +7649,36 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work)
goto err_out; goto err_out;
} }
if (((opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE) || if ((opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE ||
(opinfo->level == SMB2_OPLOCK_LEVEL_BATCH)) && opinfo->level == SMB2_OPLOCK_LEVEL_BATCH) &&
((req_oplevel != SMB2_OPLOCK_LEVEL_II) && (req_oplevel != SMB2_OPLOCK_LEVEL_II &&
(req_oplevel != SMB2_OPLOCK_LEVEL_NONE))) { req_oplevel != SMB2_OPLOCK_LEVEL_NONE)) {
err = STATUS_INVALID_OPLOCK_PROTOCOL; err = STATUS_INVALID_OPLOCK_PROTOCOL;
oplock_change_type = OPLOCK_WRITE_TO_NONE; oplock_change_type = OPLOCK_WRITE_TO_NONE;
} else if ((opinfo->level == SMB2_OPLOCK_LEVEL_II) && } else if (opinfo->level == SMB2_OPLOCK_LEVEL_II &&
(req_oplevel != SMB2_OPLOCK_LEVEL_NONE)) { req_oplevel != SMB2_OPLOCK_LEVEL_NONE) {
err = STATUS_INVALID_OPLOCK_PROTOCOL; err = STATUS_INVALID_OPLOCK_PROTOCOL;
oplock_change_type = OPLOCK_READ_TO_NONE; oplock_change_type = OPLOCK_READ_TO_NONE;
} else if ((req_oplevel == SMB2_OPLOCK_LEVEL_II) || } else if (req_oplevel == SMB2_OPLOCK_LEVEL_II ||
(req_oplevel == SMB2_OPLOCK_LEVEL_NONE)) { req_oplevel == SMB2_OPLOCK_LEVEL_NONE) {
err = STATUS_INVALID_DEVICE_STATE; err = STATUS_INVALID_DEVICE_STATE;
if (((opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE) || if ((opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE ||
(opinfo->level == SMB2_OPLOCK_LEVEL_BATCH)) && opinfo->level == SMB2_OPLOCK_LEVEL_BATCH) &&
(req_oplevel == SMB2_OPLOCK_LEVEL_II)) { req_oplevel == SMB2_OPLOCK_LEVEL_II) {
oplock_change_type = OPLOCK_WRITE_TO_READ; oplock_change_type = OPLOCK_WRITE_TO_READ;
} else if (((opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE) } else if ((opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE ||
|| (opinfo->level == SMB2_OPLOCK_LEVEL_BATCH)) && opinfo->level == SMB2_OPLOCK_LEVEL_BATCH) &&
(req_oplevel == SMB2_OPLOCK_LEVEL_NONE)) { req_oplevel == SMB2_OPLOCK_LEVEL_NONE) {
oplock_change_type = OPLOCK_WRITE_TO_NONE; oplock_change_type = OPLOCK_WRITE_TO_NONE;
} else if ((opinfo->level == SMB2_OPLOCK_LEVEL_II) && } else if (opinfo->level == SMB2_OPLOCK_LEVEL_II &&
(req_oplevel == SMB2_OPLOCK_LEVEL_NONE)) { req_oplevel == SMB2_OPLOCK_LEVEL_NONE) {
oplock_change_type = OPLOCK_READ_TO_NONE; oplock_change_type = OPLOCK_READ_TO_NONE;
} else } else {
oplock_change_type = 0; oplock_change_type = 0;
} else }
} else {
oplock_change_type = 0; oplock_change_type = 0;
}
switch (oplock_change_type) { switch (oplock_change_type) {
case OPLOCK_WRITE_TO_READ: case OPLOCK_WRITE_TO_READ:
...@@ -7846,8 +7729,8 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work) ...@@ -7846,8 +7729,8 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work)
static int check_lease_state(struct lease *lease, __le32 req_state) static int check_lease_state(struct lease *lease, __le32 req_state)
{ {
if ((lease->new_state == if ((lease->new_state ==
(SMB2_LEASE_READ_CACHING_LE | SMB2_LEASE_HANDLE_CACHING_LE)) (SMB2_LEASE_READ_CACHING_LE | SMB2_LEASE_HANDLE_CACHING_LE)) &&
&& !(req_state & SMB2_LEASE_WRITE_CACHING_LE)) { !(req_state & SMB2_LEASE_WRITE_CACHING_LE)) {
lease->new_state = req_state; lease->new_state = req_state;
return 0; return 0;
} }
...@@ -7909,7 +7792,7 @@ static void smb21_lease_break_ack(struct ksmbd_work *work) ...@@ -7909,7 +7792,7 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
/* check for bad lease state */ /* check for bad lease state */
if (req->LeaseState & (~(SMB2_LEASE_READ_CACHING_LE | if (req->LeaseState & (~(SMB2_LEASE_READ_CACHING_LE |
SMB2_LEASE_HANDLE_CACHING_LE))) { SMB2_LEASE_HANDLE_CACHING_LE))) {
err = STATUS_INVALID_OPLOCK_PROTOCOL; err = STATUS_INVALID_OPLOCK_PROTOCOL;
if (lease->state & SMB2_LEASE_WRITE_CACHING_LE) if (lease->state & SMB2_LEASE_WRITE_CACHING_LE)
lease_change_type = OPLOCK_WRITE_TO_NONE; lease_change_type = OPLOCK_WRITE_TO_NONE;
...@@ -7918,8 +7801,8 @@ static void smb21_lease_break_ack(struct ksmbd_work *work) ...@@ -7918,8 +7801,8 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
ksmbd_debug(OPLOCK, "handle bad lease state 0x%x -> 0x%x\n", ksmbd_debug(OPLOCK, "handle bad lease state 0x%x -> 0x%x\n",
le32_to_cpu(lease->state), le32_to_cpu(lease->state),
le32_to_cpu(req->LeaseState)); le32_to_cpu(req->LeaseState));
} else if ((lease->state == SMB2_LEASE_READ_CACHING_LE) && } else if (lease->state == SMB2_LEASE_READ_CACHING_LE &&
(req->LeaseState != SMB2_LEASE_NONE_LE)) { req->LeaseState != SMB2_LEASE_NONE_LE) {
err = STATUS_INVALID_OPLOCK_PROTOCOL; err = STATUS_INVALID_OPLOCK_PROTOCOL;
lease_change_type = OPLOCK_READ_TO_NONE; lease_change_type = OPLOCK_READ_TO_NONE;
ksmbd_debug(OPLOCK, "handle bad lease state 0x%x -> 0x%x\n", ksmbd_debug(OPLOCK, "handle bad lease state 0x%x -> 0x%x\n",
...@@ -7938,8 +7821,9 @@ static void smb21_lease_break_ack(struct ksmbd_work *work) ...@@ -7938,8 +7821,9 @@ static void smb21_lease_break_ack(struct ksmbd_work *work)
lease_change_type = OPLOCK_WRITE_TO_READ; lease_change_type = OPLOCK_WRITE_TO_READ;
else else
lease_change_type = OPLOCK_READ_HANDLE_TO_READ; lease_change_type = OPLOCK_READ_HANDLE_TO_READ;
} else } else {
lease_change_type = 0; lease_change_type = 0;
}
} }
switch (lease_change_type) { switch (lease_change_type) {
...@@ -8056,9 +7940,9 @@ bool smb2_is_sign_req(struct ksmbd_work *work, unsigned int command) ...@@ -8056,9 +7940,9 @@ bool smb2_is_sign_req(struct ksmbd_work *work, unsigned int command)
struct smb2_hdr *rcv_hdr2 = work->request_buf; struct smb2_hdr *rcv_hdr2 = work->request_buf;
if ((rcv_hdr2->Flags & SMB2_FLAGS_SIGNED) && if ((rcv_hdr2->Flags & SMB2_FLAGS_SIGNED) &&
command != SMB2_NEGOTIATE_HE && command != SMB2_NEGOTIATE_HE &&
command != SMB2_SESSION_SETUP_HE && command != SMB2_SESSION_SETUP_HE &&
command != SMB2_OPLOCK_BREAK_HE) command != SMB2_OPLOCK_BREAK_HE)
return true; return true;
return 0; return 0;
...@@ -8097,7 +7981,7 @@ int smb2_check_sign_req(struct ksmbd_work *work) ...@@ -8097,7 +7981,7 @@ int smb2_check_sign_req(struct ksmbd_work *work)
iov[0].iov_len = len; iov[0].iov_len = len;
if (ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, 1, if (ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, 1,
signature)) signature))
return 0; return 0;
if (memcmp(signature, signature_req, SMB2_SIGNATURE_SIZE)) { if (memcmp(signature, signature_req, SMB2_SIGNATURE_SIZE)) {
...@@ -8155,7 +8039,7 @@ void smb2_set_sign_rsp(struct ksmbd_work *work) ...@@ -8155,7 +8039,7 @@ void smb2_set_sign_rsp(struct ksmbd_work *work)
} }
if (!ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, n_vec, if (!ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, n_vec,
signature)) signature))
memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE); memcpy(hdr->Signature, signature, SMB2_SIGNATURE_SIZE);
} }
...@@ -8305,7 +8189,7 @@ void smb3_preauth_hash_rsp(struct ksmbd_work *work) ...@@ -8305,7 +8189,7 @@ void smb3_preauth_hash_rsp(struct ksmbd_work *work)
conn->preauth_info->Preauth_HashValue); conn->preauth_info->Preauth_HashValue);
if (le16_to_cpu(rsp->Command) == SMB2_SESSION_SETUP_HE && if (le16_to_cpu(rsp->Command) == SMB2_SESSION_SETUP_HE &&
sess && sess->state == SMB2_SESSION_IN_PROGRESS) { sess && sess->state == SMB2_SESSION_IN_PROGRESS) {
__u8 *hash_value; __u8 *hash_value;
hash_value = sess->Preauth_HashValue; hash_value = sess->Preauth_HashValue;
...@@ -8314,9 +8198,8 @@ void smb3_preauth_hash_rsp(struct ksmbd_work *work) ...@@ -8314,9 +8198,8 @@ void smb3_preauth_hash_rsp(struct ksmbd_work *work)
} }
} }
static void fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, static void fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, char *old_buf,
char *old_buf, __le16 cipher_type)
__le16 cipher_type)
{ {
struct smb2_hdr *hdr = (struct smb2_hdr *)old_buf; struct smb2_hdr *hdr = (struct smb2_hdr *)old_buf;
unsigned int orig_len = get_rfc1002_len(old_buf); unsigned int orig_len = get_rfc1002_len(old_buf);
...@@ -8403,7 +8286,7 @@ int smb3_decrypt_req(struct ksmbd_work *work) ...@@ -8403,7 +8286,7 @@ int smb3_decrypt_req(struct ksmbd_work *work)
sess = ksmbd_session_lookup(conn, le64_to_cpu(tr_hdr->SessionId)); sess = ksmbd_session_lookup(conn, le64_to_cpu(tr_hdr->SessionId));
if (!sess) { if (!sess) {
ksmbd_err("invalid session id(%llx) in transform header\n", ksmbd_err("invalid session id(%llx) in transform header\n",
le64_to_cpu(tr_hdr->SessionId)); le64_to_cpu(tr_hdr->SessionId));
return -ECONNABORTED; return -ECONNABORTED;
} }
...@@ -8446,7 +8329,7 @@ bool smb3_11_final_sess_setup_resp(struct ksmbd_work *work) ...@@ -8446,7 +8329,7 @@ bool smb3_11_final_sess_setup_resp(struct ksmbd_work *work)
rsp = RESPONSE_BUF_NEXT(work); rsp = RESPONSE_BUF_NEXT(work);
if (le16_to_cpu(rsp->Command) == SMB2_SESSION_SETUP_HE && if (le16_to_cpu(rsp->Command) == SMB2_SESSION_SETUP_HE &&
rsp->Status == STATUS_SUCCESS) rsp->Status == STATUS_SUCCESS)
return true; return true;
return false; return false;
} }
...@@ -346,8 +346,8 @@ struct smb2_negotiate_rsp { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -1579,71 +1577,70 @@ struct smb2_posix_info {
} __packed; } __packed;
/* functions */ /* functions */
int init_smb2_0_server(struct ksmbd_conn *conn);
extern int init_smb2_0_server(struct ksmbd_conn *conn); void init_smb2_1_server(struct ksmbd_conn *conn);
extern void init_smb2_1_server(struct ksmbd_conn *conn); void init_smb3_0_server(struct ksmbd_conn *conn);
extern void init_smb3_0_server(struct ksmbd_conn *conn); void init_smb3_02_server(struct ksmbd_conn *conn);
extern void init_smb3_02_server(struct ksmbd_conn *conn); int init_smb3_11_server(struct ksmbd_conn *conn);
extern int init_smb3_11_server(struct ksmbd_conn *conn);
void init_smb2_max_read_size(unsigned int sz);
extern void init_smb2_max_read_size(unsigned int sz); void init_smb2_max_write_size(unsigned int sz);
extern void init_smb2_max_write_size(unsigned int sz); void init_smb2_max_trans_size(unsigned int sz);
extern void init_smb2_max_trans_size(unsigned int sz);
int is_smb2_neg_cmd(struct ksmbd_work *work);
extern int is_smb2_neg_cmd(struct ksmbd_work *work); int is_smb2_rsp(struct ksmbd_work *work);
extern int is_smb2_rsp(struct ksmbd_work *work);
u16 get_smb2_cmd_val(struct ksmbd_work *work);
extern uint16_t get_smb2_cmd_val(struct ksmbd_work *work); void set_smb2_rsp_status(struct ksmbd_work *work, __le32 err);
extern void set_smb2_rsp_status(struct ksmbd_work *work, __le32 err); int init_smb2_rsp_hdr(struct ksmbd_work *work);
extern int init_smb2_rsp_hdr(struct ksmbd_work *work); int smb2_allocate_rsp_buf(struct ksmbd_work *work);
extern int smb2_allocate_rsp_buf(struct ksmbd_work *work); bool is_chained_smb2_message(struct ksmbd_work *work);
extern bool is_chained_smb2_message(struct ksmbd_work *work); int init_smb2_neg_rsp(struct ksmbd_work *work);
extern int init_smb2_neg_rsp(struct ksmbd_work *work); void smb2_set_err_rsp(struct ksmbd_work *work);
extern void smb2_set_err_rsp(struct ksmbd_work *work); int smb2_check_user_session(struct ksmbd_work *work);
extern int smb2_check_user_session(struct ksmbd_work *work); int smb2_get_ksmbd_tcon(struct ksmbd_work *work);
extern int smb2_get_ksmbd_tcon(struct ksmbd_work *work); bool smb2_is_sign_req(struct ksmbd_work *work, unsigned int command);
extern bool smb2_is_sign_req(struct ksmbd_work *work, unsigned int command); int smb2_check_sign_req(struct ksmbd_work *work);
extern int smb2_check_sign_req(struct ksmbd_work *work); void smb2_set_sign_rsp(struct ksmbd_work *work);
extern void smb2_set_sign_rsp(struct ksmbd_work *work); int smb3_check_sign_req(struct ksmbd_work *work);
extern int smb3_check_sign_req(struct ksmbd_work *work); void smb3_set_sign_rsp(struct ksmbd_work *work);
extern void smb3_set_sign_rsp(struct ksmbd_work *work); int find_matching_smb2_dialect(int start_index, __le16 *cli_dialects,
extern int find_matching_smb2_dialect(int start_index, __le16 *cli_dialects, __le16 dialects_count);
__le16 dialects_count); struct file_lock *smb_flock_init(struct file *f);
extern struct file_lock *smb_flock_init(struct file *f); int setup_async_work(struct ksmbd_work *work, void (*fn)(void **),
extern int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg);
void **arg); void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status);
extern void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status); struct channel *lookup_chann_list(struct ksmbd_session *sess);
extern struct channel *lookup_chann_list(struct ksmbd_session *sess); void smb3_preauth_hash_rsp(struct ksmbd_work *work);
extern void smb3_preauth_hash_rsp(struct ksmbd_work *work); int smb3_is_transform_hdr(void *buf);
extern int smb3_is_transform_hdr(void *buf); int smb3_decrypt_req(struct ksmbd_work *work);
extern int smb3_decrypt_req(struct ksmbd_work *work); int smb3_encrypt_resp(struct ksmbd_work *work);
extern int smb3_encrypt_resp(struct ksmbd_work *work); bool smb3_11_final_sess_setup_resp(struct ksmbd_work *work);
extern bool smb3_11_final_sess_setup_resp(struct ksmbd_work *work); int smb2_set_rsp_credits(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 @@ ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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[] = { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 @@ ...@@ -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 { ...@@ -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}, ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 @@ ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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; ...@@ -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); ...@@ -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, int handle,
void *payload, size_t payload_sz);
struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess, int handle);
int handle, struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle,
void *payload, void *payload, size_t payload_sz);
size_t payload_sz); struct ksmbd_rpc_command *ksmbd_rpc_rap(struct ksmbd_session *sess, void *payload,
struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess, size_t payload_sz);
int handle);
struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess,
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 { ...@@ -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 { ...@@ -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 ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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( spin_unlock(&t->reassembly_queue_lock);
&t->reassembly_queue_lock);
put_recvmsg(t, recvmsg); put_recvmsg(t, recvmsg);
} else } else {
spin_unlock(&t->reassembly_queue_lock); 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 ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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 @@ ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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 @@ ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 @@ ...@@ -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[]; ...@@ -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); ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
......
...@@ -61,19 +61,17 @@ static void rollback_path_modification(char *filename) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 { ...@@ -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); ...@@ -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); ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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 { ...@@ -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__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册