From 5fb68864674faa3e0a4fc767c4a87f51ece218c6 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 18 Jun 2021 09:54:53 +0900 Subject: [PATCH 01/45] ksmbd: fix kfree of uninitialized pointer oid Currently function ksmbd_neg_token_init_mech_type can kfree an uninitialized pointer oid when the call to asn1_oid_decode fails when vlen is out of range. All the other failure cases in function asn1_oid_decode set *oid to NULL on an error, so fix the issue by ensuring the vlen out of range error also nullifies the pointer. Addresses-Coverity: ("Uninitialized pointer read") Signed-off-by: Colin Ian King Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/cifsd/asn1.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/cifsd/asn1.c b/fs/cifsd/asn1.c index 2c63a3e5618b..b014f4638610 100644 --- a/fs/cifsd/asn1.c +++ b/fs/cifsd/asn1.c @@ -66,7 +66,7 @@ static bool asn1_oid_decode(const unsigned char *value, size_t vlen, vlen += 1; if (vlen < 2 || vlen > UINT_MAX / sizeof(unsigned long)) - return false; + goto fail_nullify; *oid = kmalloc(vlen * sizeof(unsigned long), GFP_KERNEL); if (!*oid) @@ -102,6 +102,7 @@ static bool asn1_oid_decode(const unsigned char *value, size_t vlen, fail: kfree(*oid); +fail_nullify: *oid = NULL; return false; } From f5a544e3bab78142207e0242d22442db85ba1eff Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Fri, 18 Jun 2021 10:04:19 +0900 Subject: [PATCH 02/45] ksmbd: add support for SMB3 multichannel Add support for SMB3 multichannel. It will be enable by setting 'server multi channel support = yes' in smb.conf. Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/cifsd/auth.c | 32 ++++--- fs/cifsd/auth.h | 6 +- fs/cifsd/connection.h | 1 + fs/cifsd/ksmbd_server.h | 1 + fs/cifsd/mgmt/user_session.c | 49 ++++++++++- fs/cifsd/mgmt/user_session.h | 11 ++- fs/cifsd/smb2ops.c | 9 ++ fs/cifsd/smb2pdu.c | 165 ++++++++++++++++++++++++++--------- fs/cifsd/smb2pdu.h | 3 +- fs/cifsd/smb_common.h | 2 +- 10 files changed, 221 insertions(+), 58 deletions(-) diff --git a/fs/cifsd/auth.c b/fs/cifsd/auth.c index 5f47de49c05d..1ba03a7c3201 100644 --- a/fs/cifsd/auth.c +++ b/fs/cifsd/auth.c @@ -921,13 +921,14 @@ smb3signkey_ret: } static int generate_smb3signingkey(struct ksmbd_session *sess, + struct ksmbd_conn *conn, const struct derivation *signing) { int rc; struct channel *chann; char *key; - chann = lookup_chann_list(sess); + chann = lookup_chann_list(sess, conn); if (!chann) return 0; @@ -953,7 +954,8 @@ static int generate_smb3signingkey(struct ksmbd_session *sess, return 0; } -int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess) +int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess, + struct ksmbd_conn *conn) { struct derivation d; @@ -961,22 +963,32 @@ int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess) d.label.iov_len = 12; d.context.iov_base = "SmbSign"; d.context.iov_len = 8; - d.binding = false; + d.binding = conn->binding; - return generate_smb3signingkey(sess, &d); + return generate_smb3signingkey(sess, conn, &d); } -int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess) +int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess, + struct ksmbd_conn *conn) { struct derivation d; d.label.iov_base = "SMBSigningKey"; d.label.iov_len = 14; - d.context.iov_base = sess->Preauth_HashValue; - d.context.iov_len = 64; - d.binding = false; + if (conn->binding) { + struct preauth_session *preauth_sess; - return generate_smb3signingkey(sess, &d); + preauth_sess = ksmbd_preauth_session_lookup(conn, sess->id); + if (!preauth_sess) + return -ENOENT; + d.context.iov_base = preauth_sess->Preauth_HashValue; + } else { + d.context.iov_base = sess->Preauth_HashValue; + } + d.context.iov_len = 64; + d.binding = conn->binding; + + return generate_smb3signingkey(sess, conn, &d); } struct derivation_twin { @@ -1148,7 +1160,7 @@ static int ksmbd_get_encryption_key(struct ksmbd_conn *conn, __u64 ses_id, struct ksmbd_session *sess; u8 *ses_enc_key; - sess = ksmbd_session_lookup(conn, ses_id); + sess = ksmbd_session_lookup_all(conn, ses_id); if (!sess) return -EINVAL; diff --git a/fs/cifsd/auth.h b/fs/cifsd/auth.h index 650bd7dd6750..9c2d4badd05d 100644 --- a/fs/cifsd/auth.h +++ b/fs/cifsd/auth.h @@ -54,8 +54,10 @@ int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov, int n_vec, char *sig); int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov, int n_vec, char *sig); -int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess); -int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess); +int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess, + struct ksmbd_conn *conn); +int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess, + struct ksmbd_conn *conn); int ksmbd_gen_smb30_encryptionkey(struct ksmbd_session *sess); int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess); int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf, diff --git a/fs/cifsd/connection.h b/fs/cifsd/connection.h index 1658442b27b0..98108b41f739 100644 --- a/fs/cifsd/connection.h +++ b/fs/cifsd/connection.h @@ -106,6 +106,7 @@ struct ksmbd_conn { __le16 cipher_type; __le16 compress_algorithm; bool posix_ext_supported; + bool binding; }; struct ksmbd_conn_ops { diff --git a/fs/cifsd/ksmbd_server.h b/fs/cifsd/ksmbd_server.h index 442077a1e77b..5ae3fe91bfb4 100644 --- a/fs/cifsd/ksmbd_server.h +++ b/fs/cifsd/ksmbd_server.h @@ -33,6 +33,7 @@ struct ksmbd_heartbeat { #define KSMBD_GLOBAL_FLAG_CACHE_TBUF BIT(1) #define KSMBD_GLOBAL_FLAG_CACHE_RBUF BIT(2) #define KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION BIT(3) +#define KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL BIT(4) struct ksmbd_startup_request { __u32 flags; diff --git a/fs/cifsd/mgmt/user_session.c b/fs/cifsd/mgmt/user_session.c index 739588a6c96a..c3487b1a004c 100644 --- a/fs/cifsd/mgmt/user_session.c +++ b/fs/cifsd/mgmt/user_session.c @@ -207,7 +207,8 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn) } } -bool ksmbd_session_id_match(struct ksmbd_session *sess, unsigned long long id) +static bool ksmbd_session_id_match(struct ksmbd_session *sess, + unsigned long long id) { return sess->id == id; } @@ -250,6 +251,52 @@ struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id) return sess; } +struct ksmbd_session *ksmbd_session_lookup_all(struct ksmbd_conn *conn, + unsigned long long id) +{ + struct ksmbd_session *sess; + + sess = ksmbd_session_lookup(conn, id); + if (!sess && conn->binding) + sess = ksmbd_session_lookup_slowpath(id); + return sess; +} + +struct preauth_session *ksmbd_preauth_session_alloc(struct ksmbd_conn *conn, + u64 sess_id) +{ + struct preauth_session *sess; + + sess = kmalloc(sizeof(struct preauth_session), GFP_KERNEL); + if (!sess) + return NULL; + + sess->id = sess_id; + memcpy(sess->Preauth_HashValue, conn->preauth_info->Preauth_HashValue, + PREAUTH_HASHVALUE_SIZE); + list_add(&sess->preauth_entry, &conn->preauth_sess_table); + + return sess; +} + +static bool ksmbd_preauth_session_id_match(struct preauth_session *sess, + unsigned long long id) +{ + return sess->id == id; +} + +struct preauth_session *ksmbd_preauth_session_lookup(struct ksmbd_conn *conn, + unsigned long long id) +{ + struct preauth_session *sess = NULL; + + list_for_each_entry(sess, &conn->preauth_sess_table, preauth_entry) { + if (ksmbd_preauth_session_id_match(sess, id)) + return sess; + } + return NULL; +} + static int __init_smb2_session(struct ksmbd_session *sess) { int id = ksmbd_acquire_smb2_uid(&session_ida); diff --git a/fs/cifsd/mgmt/user_session.h b/fs/cifsd/mgmt/user_session.h index 761bf4776cf1..82289c3cbd2b 100644 --- a/fs/cifsd/mgmt/user_session.h +++ b/fs/cifsd/mgmt/user_session.h @@ -26,8 +26,8 @@ struct channel { struct preauth_session { __u8 Preauth_HashValue[PREAUTH_HASHVALUE_SIZE]; - u64 sess_id; - struct list_head list_entry; + u64 id; + struct list_head preauth_entry; }; struct ksmbd_session { @@ -82,13 +82,18 @@ struct ksmbd_session *ksmbd_smb2_session_create(void); void ksmbd_session_destroy(struct ksmbd_session *sess); -bool ksmbd_session_id_match(struct ksmbd_session *sess, unsigned long long id); struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id); struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn, unsigned long long id); void ksmbd_session_register(struct ksmbd_conn *conn, struct ksmbd_session *sess); void ksmbd_sessions_deregister(struct ksmbd_conn *conn); +struct ksmbd_session *ksmbd_session_lookup_all(struct ksmbd_conn *conn, + unsigned long long id); +struct preauth_session *ksmbd_preauth_session_alloc(struct ksmbd_conn *conn, + u64 sess_id); +struct preauth_session *ksmbd_preauth_session_lookup(struct ksmbd_conn *conn, + unsigned long long id); int ksmbd_acquire_tree_conn_id(struct ksmbd_session *sess); void ksmbd_release_tree_conn_id(struct ksmbd_session *sess, int id); diff --git a/fs/cifsd/smb2ops.c b/fs/cifsd/smb2ops.c index 8999c3faf4fc..f7e5f21d4ae2 100644 --- a/fs/cifsd/smb2ops.c +++ b/fs/cifsd/smb2ops.c @@ -229,6 +229,9 @@ void init_smb3_0_server(struct ksmbd_conn *conn) if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION && conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION) conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION; + + if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) + conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL; } /** @@ -250,6 +253,9 @@ void init_smb3_02_server(struct ksmbd_conn *conn) if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION && conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION) conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION; + + if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) + conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL; } /** @@ -271,6 +277,9 @@ int init_smb3_11_server(struct ksmbd_conn *conn) if (conn->cipher_type) conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION; + if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) + conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL; + INIT_LIST_HEAD(&conn->preauth_sess_table); return 0; } diff --git a/fs/cifsd/smb2pdu.c b/fs/cifsd/smb2pdu.c index ac15a9287310..12c954dac51a 100644 --- a/fs/cifsd/smb2pdu.c +++ b/fs/cifsd/smb2pdu.c @@ -64,21 +64,21 @@ static inline int check_session_id(struct ksmbd_conn *conn, u64 id) if (id == 0 || id == -1) return 0; - sess = ksmbd_session_lookup(conn, id); + sess = ksmbd_session_lookup_all(conn, id); if (sess) return 1; ksmbd_err("Invalid user session id: %llu\n", id); return 0; } -struct channel *lookup_chann_list(struct ksmbd_session *sess) +struct channel *lookup_chann_list(struct ksmbd_session *sess, struct ksmbd_conn *conn) { struct channel *chann; struct list_head *t; list_for_each(t, &sess->ksmbd_chann_list) { chann = list_entry(t, struct channel, chann_list); - if (chann && chann->conn == sess->conn) + if (chann && chann->conn == conn) return chann; } @@ -600,7 +600,7 @@ int smb2_check_user_session(struct ksmbd_work *work) sess_id = le64_to_cpu(req_hdr->SessionId); /* Check for validity of user session */ - work->sess = ksmbd_session_lookup(conn, sess_id); + work->sess = ksmbd_session_lookup_all(conn, sess_id); if (work->sess) return 1; ksmbd_debug(SMB, "Invalid user session, Uid %llu\n", sess_id); @@ -1165,18 +1165,30 @@ static int generate_preauth_hash(struct ksmbd_work *work) { struct ksmbd_conn *conn = work->conn; struct ksmbd_session *sess = work->sess; + u8 *preauth_hash; if (conn->dialect != SMB311_PROT_ID) return 0; - if (!sess->Preauth_HashValue) { - if (alloc_preauth_hash(sess, conn)) - return -ENOMEM; + if (conn->binding) { + struct preauth_session *preauth_sess; + + preauth_sess = ksmbd_preauth_session_lookup(conn, sess->id); + if (!preauth_sess) { + preauth_sess = ksmbd_preauth_session_alloc(conn, sess->id); + if (!preauth_sess) + return -ENOMEM; + } + + preauth_hash = preauth_sess->Preauth_HashValue; + } else { + if (!sess->Preauth_HashValue) + if (alloc_preauth_hash(sess, conn)) + return -ENOMEM; + preauth_hash = sess->Preauth_HashValue; } - ksmbd_gen_preauth_integrity_hash(conn, - work->request_buf, - sess->Preauth_HashValue); + ksmbd_gen_preauth_integrity_hash(conn, work->request_buf, preauth_hash); return 0; } @@ -1383,15 +1395,19 @@ static int ntlm_authenticate(struct ksmbd_work *work) * that it is reauthentication. And the user/password * has been verified, so return it here. */ - if (sess->state == SMB2_SESSION_VALID) + if (sess->state == SMB2_SESSION_VALID) { + if (conn->binding) + goto binding_session; return 0; + } if ((conn->sign || server_conf.enforced_signing) || (req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED)) sess->sign = true; if (conn->vals->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION && - conn->ops->generate_encryptionkey) { + conn->ops->generate_encryptionkey && + !(req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) { rc = conn->ops->generate_encryptionkey(sess); if (rc) { ksmbd_debug(SMB, @@ -1409,8 +1425,9 @@ static int ntlm_authenticate(struct ksmbd_work *work) } } +binding_session: if (conn->dialect >= SMB30_PROT_ID) { - chann = lookup_chann_list(sess); + chann = lookup_chann_list(sess, conn); if (!chann) { chann = kmalloc(sizeof(struct channel), GFP_KERNEL); if (!chann) @@ -1423,7 +1440,7 @@ static int ntlm_authenticate(struct ksmbd_work *work) } if (conn->ops->generate_signingkey) { - rc = conn->ops->generate_signingkey(sess); + rc = conn->ops->generate_signingkey(sess, conn); if (rc) { ksmbd_debug(SMB, "SMB3 signing key generation failed\n"); rsp->hdr.Status = STATUS_LOGON_FAILURE; @@ -1500,7 +1517,7 @@ static int krb5_authenticate(struct ksmbd_work *work) } if (conn->dialect >= SMB30_PROT_ID) { - chann = lookup_chann_list(sess); + chann = lookup_chann_list(sess, conn); if (!chann) { chann = kmalloc(sizeof(struct channel), GFP_KERNEL); if (!chann) @@ -1513,7 +1530,7 @@ static int krb5_authenticate(struct ksmbd_work *work) } if (conn->ops->generate_signingkey) { - retval = conn->ops->generate_signingkey(sess); + retval = conn->ops->generate_signingkey(sess, conn); if (retval) { ksmbd_debug(SMB, "SMB3 signing key generation failed\n"); rsp->hdr.Status = STATUS_LOGON_FAILURE; @@ -1562,12 +1579,59 @@ int smb2_sess_setup(struct ksmbd_work *work) } rsp->hdr.SessionId = cpu_to_le64(sess->id); ksmbd_session_register(conn, sess); + } else if (conn->dialect >= SMB30_PROT_ID && + (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) && + req->Flags & SMB2_SESSION_REQ_FLAG_BINDING) { + u64 sess_id = le64_to_cpu(req->hdr.SessionId); + + sess = ksmbd_session_lookup_slowpath(sess_id); + if (!sess) { + rc = -ENOENT; + goto out_err; + } + + if (conn->dialect != sess->conn->dialect) { + rc = -EINVAL; + goto out_err; + } + + if (!(req->hdr.Flags & SMB2_FLAGS_SIGNED)) { + rc = -EINVAL; + goto out_err; + } + + if (strncmp(conn->ClientGUID, sess->conn->ClientGUID, + SMB2_CLIENT_GUID_SIZE)) { + rc = -ENOENT; + goto out_err; + } + + if (sess->state == SMB2_SESSION_IN_PROGRESS) { + rc = -EACCES; + goto out_err; + } + + if (sess->state == SMB2_SESSION_EXPIRED) { + rc = -EFAULT; + goto out_err; + } + + if (ksmbd_session_lookup(conn, sess_id)) { + rc = -EACCES; + goto out_err; + } + + conn->binding = true; + } else if ((conn->dialect < SMB30_PROT_ID || + server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) && + (req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) { + rc = -EACCES; + goto out_err; } else { sess = ksmbd_session_lookup(conn, le64_to_cpu(req->hdr.SessionId)); if (!sess) { rc = -ENOENT; - rsp->hdr.Status = STATUS_USER_SESSION_DELETED; goto out_err; } } @@ -1585,15 +1649,15 @@ int smb2_sess_setup(struct ksmbd_work *work) } if (server_conf.auth_mechs & conn->auth_mechs) { + rc = generate_preauth_hash(work); + if (rc) + goto out_err; + if (conn->preferred_auth_mech & (KSMBD_AUTH_KRB5 | KSMBD_AUTH_MSKRB5)) { - rc = generate_preauth_hash(work); - if (rc) - goto out_err; - rc = krb5_authenticate(work); if (rc) { - rsp->hdr.Status = STATUS_INVALID_PARAMETER; + rc = -EINVAL; goto out_err; } @@ -1602,10 +1666,6 @@ int smb2_sess_setup(struct ksmbd_work *work) kfree(sess->Preauth_HashValue); sess->Preauth_HashValue = NULL; } else if (conn->preferred_auth_mech == KSMBD_AUTH_NTLMSSP) { - rc = generate_preauth_hash(work); - if (rc) - goto out_err; - if (negblob->MessageType == NtLmNegotiate) { rc = ntlm_negotiate(work, negblob); if (rc) @@ -1625,6 +1685,16 @@ int smb2_sess_setup(struct ksmbd_work *work) ksmbd_conn_set_good(work); sess->state = SMB2_SESSION_VALID; + if (conn->binding) { + struct preauth_session *preauth_sess; + + preauth_sess = + ksmbd_preauth_session_lookup(conn, sess->id); + if (preauth_sess) { + list_del(&preauth_sess->preauth_entry); + kfree(preauth_sess); + } + } kfree(sess->Preauth_HashValue); sess->Preauth_HashValue = NULL; } @@ -1632,15 +1702,24 @@ int smb2_sess_setup(struct ksmbd_work *work) /* TODO: need one more negotiation */ ksmbd_err("Not support the preferred authentication\n"); rc = -EINVAL; - rsp->hdr.Status = STATUS_INVALID_PARAMETER; } } else { ksmbd_err("Not support authentication\n"); rc = -EINVAL; - rsp->hdr.Status = STATUS_INVALID_PARAMETER; } out_err: + if (rc == -EINVAL) + rsp->hdr.Status = STATUS_INVALID_PARAMETER; + else if (rc == -ENOENT) + rsp->hdr.Status = STATUS_USER_SESSION_DELETED; + else if (rc == -EACCES) + rsp->hdr.Status = STATUS_REQUEST_NOT_ACCEPTED; + else if (rc == -EFAULT) + rsp->hdr.Status = STATUS_NETWORK_SESSION_EXPIRED; + else if (rc) + rsp->hdr.Status = STATUS_LOGON_FAILURE; + if (conn->use_spnego && conn->mechToken) { kfree(conn->mechToken); conn->mechToken = NULL; @@ -7883,7 +7962,7 @@ void smb2_set_sign_rsp(struct ksmbd_work *work) */ int smb3_check_sign_req(struct ksmbd_work *work) { - struct ksmbd_conn *conn; + struct ksmbd_conn *conn = work->conn; char *signing_key; struct smb2_hdr *hdr, *hdr_org; struct channel *chann; @@ -7906,13 +7985,11 @@ int smb3_check_sign_req(struct ksmbd_work *work) if (le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) { signing_key = work->sess->smb3signingkey; - conn = work->sess->conn; } else { - chann = lookup_chann_list(work->sess); + chann = lookup_chann_list(work->sess, conn); if (!chann) return 0; signing_key = chann->smb3signingkey; - conn = chann->conn; } if (!signing_key) { @@ -7943,7 +8020,7 @@ int smb3_check_sign_req(struct ksmbd_work *work) */ void smb3_set_sign_rsp(struct ksmbd_work *work) { - struct ksmbd_conn *conn; + struct ksmbd_conn *conn = work->conn; struct smb2_hdr *req_hdr; struct smb2_hdr *hdr, *hdr_org; struct channel *chann; @@ -7970,13 +8047,11 @@ void smb3_set_sign_rsp(struct ksmbd_work *work) if (le16_to_cpu(hdr->Command) == SMB2_SESSION_SETUP_HE) { signing_key = work->sess->smb3signingkey; - conn = work->sess->conn; } else { - chann = lookup_chann_list(work->sess); + chann = lookup_chann_list(work->sess, work->conn); if (!chann) return; signing_key = chann->smb3signingkey; - conn = chann->conn; } if (!signing_key) @@ -8020,11 +8095,21 @@ void smb3_preauth_hash_rsp(struct ksmbd_work *work) ksmbd_gen_preauth_integrity_hash(conn, (char *)rsp, conn->preauth_info->Preauth_HashValue); - if (le16_to_cpu(rsp->Command) == SMB2_SESSION_SETUP_HE && - sess && sess->state == SMB2_SESSION_IN_PROGRESS) { + if (le16_to_cpu(rsp->Command) == SMB2_SESSION_SETUP_HE && sess) { __u8 *hash_value; - hash_value = sess->Preauth_HashValue; + if (conn->binding) { + struct preauth_session *preauth_sess; + + preauth_sess = ksmbd_preauth_session_lookup(conn, sess->id); + if (!preauth_sess) + return; + hash_value = preauth_sess->Preauth_HashValue; + } else { + hash_value = sess->Preauth_HashValue; + if (!hash_value) + return; + } ksmbd_gen_preauth_integrity_hash(conn, (char *)rsp, hash_value); } @@ -8116,7 +8201,7 @@ int smb3_decrypt_req(struct ksmbd_work *work) unsigned int orig_len = le32_to_cpu(tr_hdr->OriginalMessageSize); int rc = 0; - sess = ksmbd_session_lookup(conn, le64_to_cpu(tr_hdr->SessionId)); + sess = ksmbd_session_lookup_all(conn, le64_to_cpu(tr_hdr->SessionId)); if (!sess) { ksmbd_err("invalid session id(%llx) in transform header\n", le64_to_cpu(tr_hdr->SessionId)); diff --git a/fs/cifsd/smb2pdu.h b/fs/cifsd/smb2pdu.h index 0d5349e75dd9..0eac40e1ba65 100644 --- a/fs/cifsd/smb2pdu.h +++ b/fs/cifsd/smb2pdu.h @@ -1647,7 +1647,8 @@ struct file_lock *smb_flock_init(struct file *f); int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg); void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status); -struct channel *lookup_chann_list(struct ksmbd_session *sess); +struct channel *lookup_chann_list(struct ksmbd_session *sess, + struct ksmbd_conn *conn); void smb3_preauth_hash_rsp(struct ksmbd_work *work); int smb3_is_transform_hdr(void *buf); int smb3_decrypt_req(struct ksmbd_work *work); diff --git a/fs/cifsd/smb_common.h b/fs/cifsd/smb_common.h index 6e7404b8db96..084166ba7654 100644 --- a/fs/cifsd/smb_common.h +++ b/fs/cifsd/smb_common.h @@ -479,7 +479,7 @@ struct smb_version_ops { bool (*is_sign_req)(struct ksmbd_work *work, unsigned int command); int (*check_sign_req)(struct ksmbd_work *work); void (*set_sign_rsp)(struct ksmbd_work *work); - int (*generate_signingkey)(struct ksmbd_session *sess); + int (*generate_signingkey)(struct ksmbd_session *sess, struct ksmbd_conn *conn); int (*generate_encryptionkey)(struct ksmbd_session *sess); int (*is_transform_hdr)(void *buf); int (*decrypt_req)(struct ksmbd_work *work); From c30f4eb84badf7476824c38f874542a2e653b46b Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Fri, 18 Jun 2021 10:17:37 +0900 Subject: [PATCH 03/45] ksmbd: remove cache read/trans buffer support As vmalloc performance improvement patch for big allocation is merged into linux kernel, This feature is no longer not needed. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/cifsd/Makefile | 4 +- fs/cifsd/auth.c | 1 - fs/cifsd/buffer_pool.c | 265 ----------------------------------- fs/cifsd/buffer_pool.h | 17 --- fs/cifsd/connection.c | 1 - fs/cifsd/crypto_ctx.c | 1 - fs/cifsd/ksmbd_server.h | 6 +- fs/cifsd/ksmbd_work.c | 14 +- fs/cifsd/ksmbd_work.h | 2 - fs/cifsd/mgmt/share_config.c | 1 - fs/cifsd/mgmt/tree_connect.c | 1 - fs/cifsd/mgmt/user_config.c | 1 - fs/cifsd/mgmt/user_session.c | 1 - fs/cifsd/oplock.c | 1 - fs/cifsd/server.c | 18 ++- fs/cifsd/smb2pdu.c | 34 +---- fs/cifsd/transport_ipc.c | 1 - fs/cifsd/transport_rdma.c | 1 - fs/cifsd/transport_tcp.c | 1 - fs/cifsd/vfs.c | 1 - fs/cifsd/vfs_cache.c | 34 ++++- fs/cifsd/vfs_cache.h | 2 + 22 files changed, 53 insertions(+), 355 deletions(-) delete mode 100644 fs/cifsd/buffer_pool.c delete mode 100644 fs/cifsd/buffer_pool.h diff --git a/fs/cifsd/Makefile b/fs/cifsd/Makefile index 30f64b87cf61..7d6337a7dee4 100644 --- a/fs/cifsd/Makefile +++ b/fs/cifsd/Makefile @@ -4,13 +4,13 @@ # obj-$(CONFIG_SMB_SERVER) += ksmbd.o -ksmbd-y := unicode.o auth.o vfs.o vfs_cache.o server.o buffer_pool.o \ +ksmbd-y := unicode.o auth.o vfs.o vfs_cache.o server.o ndr.o \ misc.o oplock.o connection.o ksmbd_work.o crypto_ctx.o \ mgmt/ksmbd_ida.o mgmt/user_config.o mgmt/share_config.o \ mgmt/tree_connect.o mgmt/user_session.o smb_common.o \ transport_tcp.o transport_ipc.o smbacl.o smb2pdu.o \ smb2ops.o smb2misc.o ksmbd_spnego_negtokeninit.asn1.o \ - ksmbd_spnego_negtokentarg.asn1.o asn1.o ndr.o + ksmbd_spnego_negtokentarg.asn1.o asn1.o $(obj)/asn1.o: $(obj)/ksmbd_spnego_negtokeninit.asn1.h $(obj)/ksmbd_spnego_negtokentarg.asn1.h diff --git a/fs/cifsd/auth.c b/fs/cifsd/auth.c index 1ba03a7c3201..daf31c9f0880 100644 --- a/fs/cifsd/auth.c +++ b/fs/cifsd/auth.c @@ -29,7 +29,6 @@ #include "mgmt/user_config.h" #include "crypto_ctx.h" #include "transport_ipc.h" -#include "buffer_pool.h" /* * Fixed format data defining GSS header and fixed string diff --git a/fs/cifsd/buffer_pool.c b/fs/cifsd/buffer_pool.c deleted file mode 100644 index ea7d2d1a056a..000000000000 --- a/fs/cifsd/buffer_pool.c +++ /dev/null @@ -1,265 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2018 Samsung Electronics Co., Ltd. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "glob.h" -#include "buffer_pool.h" -#include "connection.h" -#include "mgmt/ksmbd_ida.h" - -static struct kmem_cache *filp_cache; - -struct wm { - struct list_head list; - unsigned int sz; - char buffer[0]; -}; - -struct wm_list { - struct list_head list; - unsigned int sz; - - spinlock_t wm_lock; - int avail_wm; - struct list_head idle_wm; - wait_queue_head_t wm_wait; -}; - -static LIST_HEAD(wm_lists); -static DEFINE_RWLOCK(wm_lists_lock); - -static struct wm *wm_alloc(size_t sz, gfp_t flags) -{ - struct wm *wm; - size_t alloc_sz = sz + sizeof(struct wm); - - if (sz > SIZE_MAX - sizeof(struct wm)) - return NULL; - - wm = kvmalloc(alloc_sz, flags); - if (!wm) - return NULL; - wm->sz = sz; - return wm; -} - -static int register_wm_size_class(size_t sz) -{ - struct wm_list *l, *nl; - - nl = kmalloc(sizeof(struct wm_list), GFP_KERNEL); - if (!nl) - return -ENOMEM; - - nl->sz = sz; - spin_lock_init(&nl->wm_lock); - INIT_LIST_HEAD(&nl->idle_wm); - INIT_LIST_HEAD(&nl->list); - init_waitqueue_head(&nl->wm_wait); - nl->avail_wm = 0; - - write_lock(&wm_lists_lock); - list_for_each_entry(l, &wm_lists, list) { - if (l->sz == sz) { - write_unlock(&wm_lists_lock); - kfree(nl); - return 0; - } - } - - list_add(&nl->list, &wm_lists); - write_unlock(&wm_lists_lock); - return 0; -} - -static struct wm_list *match_wm_list(size_t size) -{ - struct wm_list *l, *rl = NULL; - - read_lock(&wm_lists_lock); - list_for_each_entry(l, &wm_lists, list) { - if (l->sz == size) { - rl = l; - break; - } - } - read_unlock(&wm_lists_lock); - return rl; -} - -static struct wm *find_wm(size_t size) -{ - struct wm_list *wm_list; - struct wm *wm; - - wm_list = match_wm_list(size); - if (!wm_list) { - if (register_wm_size_class(size)) - return NULL; - wm_list = match_wm_list(size); - } - - if (!wm_list) - return NULL; - - while (1) { - spin_lock(&wm_list->wm_lock); - if (!list_empty(&wm_list->idle_wm)) { - wm = list_entry(wm_list->idle_wm.next, - struct wm, - list); - list_del(&wm->list); - spin_unlock(&wm_list->wm_lock); - return wm; - } - - if (wm_list->avail_wm > num_online_cpus()) { - spin_unlock(&wm_list->wm_lock); - wait_event(wm_list->wm_wait, - !list_empty(&wm_list->idle_wm)); - continue; - } - - wm_list->avail_wm++; - spin_unlock(&wm_list->wm_lock); - - wm = wm_alloc(size, GFP_KERNEL); - if (!wm) { - spin_lock(&wm_list->wm_lock); - wm_list->avail_wm--; - spin_unlock(&wm_list->wm_lock); - wait_event(wm_list->wm_wait, - !list_empty(&wm_list->idle_wm)); - continue; - } - break; - } - - return wm; -} - -static void release_wm(struct wm *wm, struct wm_list *wm_list) -{ - if (!wm) - return; - - spin_lock(&wm_list->wm_lock); - if (wm_list->avail_wm <= num_online_cpus()) { - list_add(&wm->list, &wm_list->idle_wm); - spin_unlock(&wm_list->wm_lock); - wake_up(&wm_list->wm_wait); - return; - } - - wm_list->avail_wm--; - spin_unlock(&wm_list->wm_lock); - kvfree(wm); -} - -static void wm_list_free(struct wm_list *l) -{ - struct wm *wm; - - while (!list_empty(&l->idle_wm)) { - wm = list_entry(l->idle_wm.next, struct wm, list); - list_del(&wm->list); - kvfree(wm); - } - kfree(l); -} - -static void wm_lists_destroy(void) -{ - struct wm_list *l; - - while (!list_empty(&wm_lists)) { - l = list_entry(wm_lists.next, struct wm_list, list); - list_del(&l->list); - wm_list_free(l); - } -} - -void *ksmbd_find_buffer(size_t size) -{ - struct wm *wm; - - wm = find_wm(size); - - WARN_ON(!wm); - if (wm) - return wm->buffer; - return NULL; -} - -void ksmbd_release_buffer(void *buffer) -{ - struct wm_list *wm_list; - struct wm *wm; - - if (!buffer) - return; - - wm = container_of(buffer, struct wm, buffer); - wm_list = match_wm_list(wm->sz); - WARN_ON(!wm_list); - if (wm_list) - release_wm(wm, wm_list); -} - -void *ksmbd_realloc_response(void *ptr, size_t old_sz, size_t new_sz) -{ - size_t sz = min(old_sz, new_sz); - void *nptr; - - nptr = kvmalloc(new_sz, GFP_KERNEL | __GFP_ZERO); - if (!nptr) - return ptr; - memcpy(nptr, ptr, sz); - kvfree(ptr); - return nptr; -} - -void ksmbd_free_file_struct(void *filp) -{ - kmem_cache_free(filp_cache, filp); -} - -void *ksmbd_alloc_file_struct(void) -{ - return kmem_cache_zalloc(filp_cache, GFP_KERNEL); -} - -void ksmbd_destroy_buffer_pools(void) -{ - wm_lists_destroy(); - ksmbd_work_pool_destroy(); - kmem_cache_destroy(filp_cache); -} - -int ksmbd_init_buffer_pools(void) -{ - if (ksmbd_work_pool_init()) - goto out; - - filp_cache = kmem_cache_create("ksmbd_file_cache", - sizeof(struct ksmbd_file), 0, - SLAB_HWCACHE_ALIGN, NULL); - if (!filp_cache) - goto out; - - return 0; - -out: - ksmbd_err("failed to allocate memory\n"); - ksmbd_destroy_buffer_pools(); - return -ENOMEM; -} diff --git a/fs/cifsd/buffer_pool.h b/fs/cifsd/buffer_pool.h deleted file mode 100644 index 088aa07ba09b..000000000000 --- a/fs/cifsd/buffer_pool.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2018 Samsung Electronics Co., Ltd. - */ - -#ifndef __KSMBD_BUFFER_POOL_H__ -#define __KSMBD_BUFFER_POOL_H__ - -void *ksmbd_find_buffer(size_t size); -void ksmbd_release_buffer(void *buffer); -void *ksmbd_realloc_response(void *ptr, size_t old_sz, size_t new_sz); -void ksmbd_free_file_struct(void *filp); -void *ksmbd_alloc_file_struct(void); -void ksmbd_destroy_buffer_pools(void); -int ksmbd_init_buffer_pools(void); - -#endif /* __KSMBD_BUFFER_POOL_H__ */ diff --git a/fs/cifsd/connection.c b/fs/cifsd/connection.c index 06c42309be72..a0d15093dd6f 100644 --- a/fs/cifsd/connection.c +++ b/fs/cifsd/connection.c @@ -9,7 +9,6 @@ #include #include "server.h" -#include "buffer_pool.h" #include "smb_common.h" #include "mgmt/ksmbd_ida.h" #include "connection.h" diff --git a/fs/cifsd/crypto_ctx.c b/fs/cifsd/crypto_ctx.c index cfea4c4db30f..7b727fe141a6 100644 --- a/fs/cifsd/crypto_ctx.c +++ b/fs/cifsd/crypto_ctx.c @@ -12,7 +12,6 @@ #include "glob.h" #include "crypto_ctx.h" -#include "buffer_pool.h" struct crypto_ctx_list { spinlock_t ctx_lock; diff --git a/fs/cifsd/ksmbd_server.h b/fs/cifsd/ksmbd_server.h index 5ae3fe91bfb4..c2467a709144 100644 --- a/fs/cifsd/ksmbd_server.h +++ b/fs/cifsd/ksmbd_server.h @@ -30,10 +30,8 @@ struct ksmbd_heartbeat { */ #define KSMBD_GLOBAL_FLAG_INVALID (0) #define KSMBD_GLOBAL_FLAG_SMB2_LEASES BIT(0) -#define KSMBD_GLOBAL_FLAG_CACHE_TBUF BIT(1) -#define KSMBD_GLOBAL_FLAG_CACHE_RBUF BIT(2) -#define KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION BIT(3) -#define KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL BIT(4) +#define KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION BIT(1) +#define KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL BIT(2) struct ksmbd_startup_request { __u32 flags; diff --git a/fs/cifsd/ksmbd_work.c b/fs/cifsd/ksmbd_work.c index f284a2a803d6..a88c25965012 100644 --- a/fs/cifsd/ksmbd_work.c +++ b/fs/cifsd/ksmbd_work.c @@ -11,7 +11,6 @@ #include "server.h" #include "connection.h" #include "ksmbd_work.h" -#include "buffer_pool.h" #include "mgmt/ksmbd_ida.h" /* @FIXME */ @@ -38,18 +37,9 @@ struct ksmbd_work *ksmbd_alloc_work_struct(void) void ksmbd_free_work_struct(struct ksmbd_work *work) { WARN_ON(work->saved_cred != NULL); - if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_TBUF && - work->set_trans_buf) - ksmbd_release_buffer(work->response_buf); - else - kvfree(work->response_buf); - - if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_RBUF && - work->set_read_buf) - ksmbd_release_buffer(work->aux_payload_buf); - else - kvfree(work->aux_payload_buf); + kvfree(work->response_buf); + kvfree(work->aux_payload_buf); kfree(work->tr_buf); kvfree(work->request_buf); if (work->async_id) diff --git a/fs/cifsd/ksmbd_work.h b/fs/cifsd/ksmbd_work.h index 28a1692ed37f..0e2d4f3fc49f 100644 --- a/fs/cifsd/ksmbd_work.h +++ b/fs/cifsd/ksmbd_work.h @@ -70,8 +70,6 @@ struct ksmbd_work { /* Is this SYNC or ASYNC ksmbd_work */ bool syncronous:1; bool need_invalidate_rkey:1; - bool set_trans_buf:1; - bool set_read_buf:1; unsigned int remote_key; /* cancel works */ diff --git a/fs/cifsd/mgmt/share_config.c b/fs/cifsd/mgmt/share_config.c index bcc4ae4381b9..fac6034b97a9 100644 --- a/fs/cifsd/mgmt/share_config.c +++ b/fs/cifsd/mgmt/share_config.c @@ -15,7 +15,6 @@ #include "share_config.h" #include "user_config.h" #include "user_session.h" -#include "../buffer_pool.h" #include "../transport_ipc.h" #define SHARE_HASH_BITS 3 diff --git a/fs/cifsd/mgmt/tree_connect.c b/fs/cifsd/mgmt/tree_connect.c index 029a9e81e844..0d28e723a28c 100644 --- a/fs/cifsd/mgmt/tree_connect.c +++ b/fs/cifsd/mgmt/tree_connect.c @@ -7,7 +7,6 @@ #include #include -#include "../buffer_pool.h" #include "../transport_ipc.h" #include "../connection.h" diff --git a/fs/cifsd/mgmt/user_config.c b/fs/cifsd/mgmt/user_config.c index 7f898c5bda25..d21629ae5c89 100644 --- a/fs/cifsd/mgmt/user_config.c +++ b/fs/cifsd/mgmt/user_config.c @@ -7,7 +7,6 @@ #include #include "user_config.h" -#include "../buffer_pool.h" #include "../transport_ipc.h" struct ksmbd_user *ksmbd_login_user(const char *account) diff --git a/fs/cifsd/mgmt/user_session.c b/fs/cifsd/mgmt/user_session.c index c3487b1a004c..77bdf3642f72 100644 --- a/fs/cifsd/mgmt/user_session.c +++ b/fs/cifsd/mgmt/user_session.c @@ -14,7 +14,6 @@ #include "tree_connect.h" #include "../transport_ipc.h" #include "../connection.h" -#include "../buffer_pool.h" #include "../vfs_cache.h" static DEFINE_IDA(session_ida); diff --git a/fs/cifsd/oplock.c b/fs/cifsd/oplock.c index 5868cdca7187..1ef2acbea2bb 100644 --- a/fs/cifsd/oplock.c +++ b/fs/cifsd/oplock.c @@ -11,7 +11,6 @@ #include "smb_common.h" #include "smbstatus.h" -#include "buffer_pool.h" #include "connection.h" #include "mgmt/user_session.h" #include "mgmt/share_config.h" diff --git a/fs/cifsd/server.c b/fs/cifsd/server.c index a99963b849d5..6d14daae1b07 100644 --- a/fs/cifsd/server.c +++ b/fs/cifsd/server.c @@ -16,7 +16,6 @@ #include "server.h" #include "smb_common.h" #include "smbstatus.h" -#include "buffer_pool.h" #include "connection.h" #include "transport_ipc.h" #include "mgmt/user_session.h" @@ -536,7 +535,8 @@ static int ksmbd_server_shutdown(void) ksmbd_crypto_destroy(); ksmbd_free_global_file_table(); destroy_lease_table(NULL); - ksmbd_destroy_buffer_pools(); + ksmbd_work_pool_destroy(); + ksmbd_exit_file_cache(); server_conf_free(); return 0; } @@ -557,13 +557,17 @@ static int __init ksmbd_server_init(void) if (ret) goto err_unregister; - ret = ksmbd_init_buffer_pools(); + ret = ksmbd_work_pool_init(); if (ret) goto err_unregister; + ret = ksmbd_init_file_cache(); + if (ret) + goto err_destroy_work_pools; + ret = ksmbd_ipc_init(); if (ret) - goto err_free_session_table; + goto err_exit_file_cache; ret = ksmbd_init_global_file_table(); if (ret) @@ -590,8 +594,10 @@ err_destroy_file_table: ksmbd_free_global_file_table(); err_ipc_release: ksmbd_ipc_release(); -err_free_session_table: - ksmbd_destroy_buffer_pools(); +err_exit_file_cache: + ksmbd_exit_file_cache(); +err_destroy_work_pools: + ksmbd_work_pool_destroy(); err_unregister: class_unregister(&ksmbd_control_class); diff --git a/fs/cifsd/smb2pdu.c b/fs/cifsd/smb2pdu.c index 12c954dac51a..345c4c75da9a 100644 --- a/fs/cifsd/smb2pdu.c +++ b/fs/cifsd/smb2pdu.c @@ -19,7 +19,6 @@ #include "auth.h" #include "asn1.h" -#include "buffer_pool.h" #include "connection.h" #include "transport_ipc.h" #include "vfs.h" @@ -538,10 +537,8 @@ int smb2_allocate_rsp_buf(struct ksmbd_work *work) size_t sz = small_sz; int cmd = le16_to_cpu(hdr->Command); - if (cmd == SMB2_IOCTL_HE || cmd == SMB2_QUERY_DIRECTORY_HE) { + if (cmd == SMB2_IOCTL_HE || cmd == SMB2_QUERY_DIRECTORY_HE) sz = large_sz; - work->set_trans_buf = true; - } if (cmd == SMB2_QUERY_INFO_HE) { struct smb2_query_info_req *req; @@ -549,22 +546,15 @@ int smb2_allocate_rsp_buf(struct ksmbd_work *work) req = work->request_buf; if (req->InfoType == SMB2_O_INFO_FILE && (req->FileInfoClass == FILE_FULL_EA_INFORMATION || - req->FileInfoClass == FILE_ALL_INFORMATION)) { + req->FileInfoClass == FILE_ALL_INFORMATION)) sz = large_sz; - work->set_trans_buf = true; - } } /* allocate large response buf for chained commands */ if (le32_to_cpu(hdr->NextCommand) > 0) sz = large_sz; - if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_TBUF && - work->set_trans_buf) - work->response_buf = ksmbd_find_buffer(sz); - else - work->response_buf = kvmalloc(sz, GFP_KERNEL | __GFP_ZERO); - + work->response_buf = kvmalloc(sz, GFP_KERNEL | __GFP_ZERO); if (!work->response_buf) return -ENOMEM; @@ -5950,13 +5940,7 @@ int smb2_read(struct ksmbd_work *work) ksmbd_debug(SMB, "filename %s, offset %lld, len %zu\n", FP_FILENAME(fp), offset, length); - if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_RBUF) { - work->aux_payload_buf = - ksmbd_find_buffer(conn->vals->max_read_size); - work->set_read_buf = true; - } else { - work->aux_payload_buf = kvmalloc(length, GFP_KERNEL | __GFP_ZERO); - } + work->aux_payload_buf = kvmalloc(length, GFP_KERNEL | __GFP_ZERO); if (!work->aux_payload_buf) { err = -ENOMEM; goto out; @@ -5969,10 +5953,7 @@ int smb2_read(struct ksmbd_work *work) } if ((nbytes == 0 && length != 0) || nbytes < mincount) { - if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_RBUF) - ksmbd_release_buffer(work->aux_payload_buf); - else - kvfree(work->aux_payload_buf); + kvfree(work->aux_payload_buf); work->aux_payload_buf = NULL; rsp->hdr.Status = STATUS_END_OF_FILE; smb2_set_err_rsp(work); @@ -5989,10 +5970,7 @@ int smb2_read(struct ksmbd_work *work) remain_bytes = smb2_read_rdma_channel(work, req, work->aux_payload_buf, nbytes); - if (server_conf.flags & KSMBD_GLOBAL_FLAG_CACHE_RBUF) - ksmbd_release_buffer(work->aux_payload_buf); - else - kvfree(work->aux_payload_buf); + kvfree(work->aux_payload_buf); work->aux_payload_buf = NULL; nbytes = 0; diff --git a/fs/cifsd/transport_ipc.c b/fs/cifsd/transport_ipc.c index b09df832431f..2bcc1cad6037 100644 --- a/fs/cifsd/transport_ipc.c +++ b/fs/cifsd/transport_ipc.c @@ -16,7 +16,6 @@ #include "vfs_cache.h" #include "transport_ipc.h" -#include "buffer_pool.h" #include "server.h" #include "smb_common.h" diff --git a/fs/cifsd/transport_rdma.c b/fs/cifsd/transport_rdma.c index efaa9776841f..52237f023b66 100644 --- a/fs/cifsd/transport_rdma.c +++ b/fs/cifsd/transport_rdma.c @@ -33,7 +33,6 @@ #include "connection.h" #include "smb_common.h" #include "smbstatus.h" -#include "buffer_pool.h" #include "transport_rdma.h" #define SMB_DIRECT_PORT 5445 diff --git a/fs/cifsd/transport_tcp.c b/fs/cifsd/transport_tcp.c index d6d5c0038dea..16702b7874f4 100644 --- a/fs/cifsd/transport_tcp.c +++ b/fs/cifsd/transport_tcp.c @@ -9,7 +9,6 @@ #include "smb_common.h" #include "server.h" #include "auth.h" -#include "buffer_pool.h" #include "connection.h" #include "transport_tcp.h" diff --git a/fs/cifsd/vfs.c b/fs/cifsd/vfs.c index 9111b485d611..fb31c1ccb1bd 100644 --- a/fs/cifsd/vfs.c +++ b/fs/cifsd/vfs.c @@ -23,7 +23,6 @@ #include "glob.h" #include "oplock.h" #include "connection.h" -#include "buffer_pool.h" #include "vfs.h" #include "vfs_cache.h" #include "smbacl.h" diff --git a/fs/cifsd/vfs_cache.c b/fs/cifsd/vfs_cache.c index 6ea09fe82814..dcac1f0a29e4 100644 --- a/fs/cifsd/vfs_cache.c +++ b/fs/cifsd/vfs_cache.c @@ -10,7 +10,6 @@ #include "glob.h" #include "vfs_cache.h" -#include "buffer_pool.h" #include "oplock.h" #include "vfs.h" #include "connection.h" @@ -29,6 +28,7 @@ static DEFINE_RWLOCK(inode_hash_lock); static struct ksmbd_file_table global_ft; static atomic_long_t fd_limit; +static struct kmem_cache *filp_cache; void ksmbd_set_fd_limit(unsigned long limit) { @@ -315,7 +315,7 @@ static void __ksmbd_close_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp) kfree(fp->filename); if (ksmbd_stream_fd(fp)) kfree(fp->stream.name); - ksmbd_free_file_struct(fp); + kmem_cache_free(filp_cache, fp); } static struct ksmbd_file *ksmbd_fp_get(struct ksmbd_file *fp) @@ -539,10 +539,10 @@ 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 *fp; + struct ksmbd_file *fp; int ret; - fp = ksmbd_alloc_file_struct(); + fp = kmem_cache_zalloc(filp_cache, GFP_KERNEL); if (!fp) { ksmbd_err("Failed to allocate memory\n"); return ERR_PTR(-ENOMEM); @@ -561,14 +561,14 @@ struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp) fp->f_ci = ksmbd_inode_get(fp); if (!fp->f_ci) { - ksmbd_free_file_struct(fp); + kmem_cache_free(filp_cache, fp); return ERR_PTR(-ENOMEM); } ret = __open_id(&work->sess->file_table, fp, OPEN_ID_TYPE_VOLATILE_ID); if (ret) { ksmbd_inode_put(fp->f_ci); - ksmbd_free_file_struct(fp); + kmem_cache_free(filp_cache, fp); return ERR_PTR(ret); } @@ -640,7 +640,7 @@ void ksmbd_free_global_file_table(void) idr_for_each_entry(global_ft.idr, fp, id) { __ksmbd_remove_durable_fd(fp); - ksmbd_free_file_struct(fp); + kmem_cache_free(filp_cache, fp); } ksmbd_destroy_file_table(&global_ft); @@ -683,3 +683,23 @@ void ksmbd_destroy_file_table(struct ksmbd_file_table *ft) kfree(ft->idr); ft->idr = NULL; } + +int ksmbd_init_file_cache(void) +{ + filp_cache = kmem_cache_create("ksmbd_file_cache", + sizeof(struct ksmbd_file), 0, + SLAB_HWCACHE_ALIGN, NULL); + if (!filp_cache) + goto out; + + return 0; + +out: + ksmbd_err("failed to allocate file cache\n"); + return -ENOMEM; +} + +void ksmbd_exit_file_cache(void) +{ + kmem_cache_destroy(filp_cache); +} diff --git a/fs/cifsd/vfs_cache.h b/fs/cifsd/vfs_cache.h index 635eedbd497c..745855367106 100644 --- a/fs/cifsd/vfs_cache.h +++ b/fs/cifsd/vfs_cache.h @@ -182,4 +182,6 @@ void ksmbd_set_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, int file_info); +int ksmbd_init_file_cache(void); +void ksmbd_exit_file_cache(void); #endif /* __VFS_CACHE_H__ */ From afa8f016c5a527bd004042ea47ca8b8007e4185f Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Fri, 18 Jun 2021 10:18:34 +0900 Subject: [PATCH 04/45] ksmbd: initialize variables on the declaration Initialize variables on the declaration. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/cifsd/vfs.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/fs/cifsd/vfs.c b/fs/cifsd/vfs.c index fb31c1ccb1bd..4e0cf1b95419 100644 --- a/fs/cifsd/vfs.c +++ b/fs/cifsd/vfs.c @@ -355,14 +355,11 @@ out: int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count, loff_t *pos) { - struct file *filp; + struct file *filp = fp->filp; ssize_t nbytes = 0; - char *rbuf; - struct inode *inode; + char *rbuf = work->aux_payload_buf; + struct inode *inode = file_inode(filp); - rbuf = work->aux_payload_buf; - filp = fp->filp; - inode = file_inode(filp); if (S_ISDIR(inode->i_mode)) return -EISDIR; From f8524776f1bbf2895de757438b41915a9b3d9bbc Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Fri, 18 Jun 2021 10:28:00 +0900 Subject: [PATCH 05/45] ksmbd: remove ksmbd_vfs_copy_file_range vfs_copy_file_range and cifs client already does this type of fallback, so this is dead code. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/cifsd/smb2pdu.c | 4 ++-- fs/cifsd/vfs.c | 50 ++-------------------------------------------- fs/cifsd/vfs.h | 3 --- 3 files changed, 4 insertions(+), 53 deletions(-) diff --git a/fs/cifsd/smb2pdu.c b/fs/cifsd/smb2pdu.c index 345c4c75da9a..2df8217c7395 100644 --- a/fs/cifsd/smb2pdu.c +++ b/fs/cifsd/smb2pdu.c @@ -7437,8 +7437,8 @@ int smb2_ioctl(struct ksmbd_work *work) ret = -EOPNOTSUPP; goto dup_ext_out; } else if (cloned != length) { - cloned = ksmbd_vfs_copy_file_range(fp_in->filp, src_off, - fp_out->filp, dst_off, length); + cloned = vfs_copy_file_range(fp_in->filp, src_off, + fp_out->filp, dst_off, length, 0); if (cloned != length) { if (cloned < 0) ret = cloned; diff --git a/fs/cifsd/vfs.c b/fs/cifsd/vfs.c index 4e0cf1b95419..ef74e56cd05f 100644 --- a/fs/cifsd/vfs.c +++ b/fs/cifsd/vfs.c @@ -1802,52 +1802,6 @@ int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name, return 0; } -int ksmbd_vfs_copy_file_range(struct file *file_in, loff_t pos_in, - struct file *file_out, loff_t pos_out, size_t len) -{ - struct inode *inode_in = file_inode(file_in); - struct inode *inode_out = file_inode(file_out); - int ret; - - ret = vfs_copy_file_range(file_in, pos_in, file_out, pos_out, len, 0); - /* do splice for the copy between different file systems */ - if (ret != -EXDEV) - return ret; - - if (S_ISDIR(inode_in->i_mode) || S_ISDIR(inode_out->i_mode)) - return -EISDIR; - if (!S_ISREG(inode_in->i_mode) || !S_ISREG(inode_out->i_mode)) - return -EINVAL; - - if (!(file_in->f_mode & FMODE_READ) || - !(file_out->f_mode & FMODE_WRITE)) - return -EBADF; - - if (len == 0) - return 0; - - file_start_write(file_out); - - /* - * skip the verification of the range of data. it will be done - * in do_splice_direct - */ - ret = do_splice_direct(file_in, &pos_in, file_out, &pos_out, - len > MAX_RW_COUNT ? MAX_RW_COUNT : len, 0); - if (ret > 0) { - fsnotify_access(file_in); - add_rchar(current, ret); - fsnotify_modify(file_out); - add_wchar(current, ret); - } - - inc_syscr(current); - inc_syscw(current); - - file_end_write(file_out); - return ret; -} - int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work, struct ksmbd_file *src_fp, struct ksmbd_file *dst_fp, @@ -1905,8 +1859,8 @@ int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work, if (src_off + len > src_file_size) return -E2BIG; - ret = ksmbd_vfs_copy_file_range(src_fp->filp, src_off, - dst_fp->filp, dst_off, len); + ret = vfs_copy_file_range(src_fp->filp, src_off, + dst_fp->filp, dst_off, len, 0); if (ret < 0) return ret; diff --git a/fs/cifsd/vfs.h b/fs/cifsd/vfs.h index 5db1e9e2a754..03b877e6520b 100644 --- a/fs/cifsd/vfs.h +++ b/fs/cifsd/vfs.h @@ -218,9 +218,6 @@ int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work, unsigned int *chunk_count_written, unsigned int *chunk_size_written, loff_t *total_size_written); -int ksmbd_vfs_copy_file_range(struct file *file_in, loff_t pos_in, - struct file *file_out, loff_t pos_out, - size_t len); ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list); ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name, char **xattr_buf); From 6f3d5eeec744727bf017be3bb12e7fbf1c4438ed Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Fri, 18 Jun 2021 10:28:52 +0900 Subject: [PATCH 06/45] ksmbd: use list_for_each_entry instead of list_for_each Use list_for_each_entry instead of list_for_each. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/cifsd/smb2pdu.c | 14 ++++---------- fs/cifsd/smb_common.c | 4 +--- fs/cifsd/vfs_cache.c | 4 +--- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/fs/cifsd/smb2pdu.c b/fs/cifsd/smb2pdu.c index 2df8217c7395..f1642fffe4e1 100644 --- a/fs/cifsd/smb2pdu.c +++ b/fs/cifsd/smb2pdu.c @@ -73,10 +73,8 @@ static inline int check_session_id(struct ksmbd_conn *conn, u64 id) struct channel *lookup_chann_list(struct ksmbd_session *sess, struct ksmbd_conn *conn) { struct channel *chann; - struct list_head *t; - list_for_each(t, &sess->ksmbd_chann_list) { - chann = list_entry(t, struct channel, chann_list); + list_for_each_entry(chann, &sess->ksmbd_chann_list, chann_list) { if (chann && chann->conn == conn) return chann; } @@ -6315,7 +6313,6 @@ int smb2_cancel(struct ksmbd_work *work) struct smb2_hdr *hdr = work->request_buf; struct smb2_hdr *chdr; struct ksmbd_work *cancel_work = NULL; - struct list_head *tmp; int canceled = 0; struct list_head *command_list; @@ -6326,9 +6323,8 @@ int smb2_cancel(struct ksmbd_work *work) command_list = &conn->async_requests; spin_lock(&conn->request_lock); - list_for_each(tmp, command_list) { - cancel_work = list_entry(tmp, struct ksmbd_work, - async_request_entry); + list_for_each_entry(cancel_work, command_list, + async_request_entry) { chdr = cancel_work->request_buf; if (cancel_work->async_id != @@ -6347,9 +6343,7 @@ int smb2_cancel(struct ksmbd_work *work) command_list = &conn->requests; spin_lock(&conn->request_lock); - list_for_each(tmp, command_list) { - cancel_work = list_entry(tmp, struct ksmbd_work, - request_entry); + list_for_each_entry(cancel_work, command_list, request_entry) { chdr = cancel_work->request_buf; if (chdr->MessageId != hdr->MessageId || diff --git a/fs/cifsd/smb_common.c b/fs/cifsd/smb_common.c index 039030968b50..d74b2ce08187 100644 --- a/fs/cifsd/smb_common.c +++ b/fs/cifsd/smb_common.c @@ -481,15 +481,13 @@ int ksmbd_smb_check_shared_mode(struct file *filp, struct ksmbd_file *curr_fp) { int rc = 0; struct ksmbd_file *prev_fp; - struct list_head *cur; /* * Lookup fp in master fp list, and check desired access and * shared mode between previous open and current open. */ read_lock(&curr_fp->f_ci->m_lock); - list_for_each(cur, &curr_fp->f_ci->m_fp_list) { - prev_fp = list_entry(cur, struct ksmbd_file, node); + list_for_each_entry(prev_fp, &curr_fp->f_ci->m_fp_list, node) { if (file_inode(filp) != FP_INODE(prev_fp)) continue; diff --git a/fs/cifsd/vfs_cache.c b/fs/cifsd/vfs_cache.c index dcac1f0a29e4..3f18018668b6 100644 --- a/fs/cifsd/vfs_cache.c +++ b/fs/cifsd/vfs_cache.c @@ -472,15 +472,13 @@ struct ksmbd_file *ksmbd_lookup_fd_inode(struct inode *inode) { struct ksmbd_file *lfp; struct ksmbd_inode *ci; - struct list_head *cur; ci = ksmbd_inode_lookup_by_vfsinode(inode); if (!ci) return NULL; read_lock(&ci->m_lock); - list_for_each(cur, &ci->m_fp_list) { - lfp = list_entry(cur, struct ksmbd_file, node); + list_for_each_entry(lfp, &ci->m_fp_list, node) { if (inode == FP_INODE(lfp)) { atomic_dec(&ci->m_count); read_unlock(&ci->m_lock); From 1dfb8242e8d982d036399766c4af62ddc221e38d Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Fri, 18 Jun 2021 10:29:56 +0900 Subject: [PATCH 07/45] ksmbd: use goto instead of duplicating the resoure cleanup in ksmbd_open_fd Use goto instead of duplicating the resoure cleanup in ksmbd_open_fd. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/cifsd/vfs_cache.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/fs/cifsd/vfs_cache.c b/fs/cifsd/vfs_cache.c index 3f18018668b6..71a11128d908 100644 --- a/fs/cifsd/vfs_cache.c +++ b/fs/cifsd/vfs_cache.c @@ -559,19 +559,22 @@ struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp) fp->f_ci = ksmbd_inode_get(fp); if (!fp->f_ci) { - kmem_cache_free(filp_cache, fp); - return ERR_PTR(-ENOMEM); + ret = -ENOMEM; + goto err_out; } ret = __open_id(&work->sess->file_table, fp, OPEN_ID_TYPE_VOLATILE_ID); if (ret) { ksmbd_inode_put(fp->f_ci); - kmem_cache_free(filp_cache, fp); - return ERR_PTR(ret); + goto err_out; } atomic_inc(&work->conn->stats.open_files_count); return fp; + +err_out: + kmem_cache_free(filp_cache, fp); + return ERR_PTR(ret); } static int From 79a8a71db4084d7536fc45ed2a33ce7b451ba127 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Fri, 18 Jun 2021 10:30:46 +0900 Subject: [PATCH 08/45] ksmbd: fix overly long line Fix overly long line. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/cifsd/vfs_cache.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/cifsd/vfs_cache.c b/fs/cifsd/vfs_cache.c index 71a11128d908..4cf14c247e9e 100644 --- a/fs/cifsd/vfs_cache.c +++ b/fs/cifsd/vfs_cache.c @@ -601,12 +601,14 @@ __close_file_table_ids(struct ksmbd_file_table *ft, return num; } -static bool tree_conn_fd_check(struct ksmbd_tree_connect *tcon, struct ksmbd_file *fp) +static bool tree_conn_fd_check(struct ksmbd_tree_connect *tcon, + struct ksmbd_file *fp) { return fp->tcon != tcon; } -static bool session_fd_check(struct ksmbd_tree_connect *tcon, struct ksmbd_file *fp) +static bool session_fd_check(struct ksmbd_tree_connect *tcon, + struct ksmbd_file *fp) { return false; } From 9c78ad067faf605e0cd16d557859310e5f5312be Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Fri, 18 Jun 2021 10:40:56 +0900 Subject: [PATCH 09/45] ksmbd: remove unneeded FIXME comment Remove unneeded FIXME comment. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/cifsd/glob.h | 2 -- fs/cifsd/ksmbd_work.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/fs/cifsd/glob.h b/fs/cifsd/glob.h index ffeaf8aa5595..da8f804a3ee2 100644 --- a/fs/cifsd/glob.h +++ b/fs/cifsd/glob.h @@ -14,8 +14,6 @@ #define KSMBD_VERSION "3.1.9" -/* @FIXME clean up this code */ - extern int ksmbd_debug_types; #define DATA_STREAM 1 diff --git a/fs/cifsd/ksmbd_work.c b/fs/cifsd/ksmbd_work.c index a88c25965012..7c914451bbe1 100644 --- a/fs/cifsd/ksmbd_work.c +++ b/fs/cifsd/ksmbd_work.c @@ -12,8 +12,6 @@ #include "connection.h" #include "ksmbd_work.h" #include "mgmt/ksmbd_ida.h" - -/* @FIXME */ #include "ksmbd_server.h" static struct kmem_cache *work_cache; From 9f88af04f03d585b8257740745d19897b48a9795 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Fri, 18 Jun 2021 10:41:42 +0900 Subject: [PATCH 10/45] ksmbd: remove ____ksmbd_align in ksmbd_server.h None of structures needs the attribute. So remove ____ksmbd_align in ksmbd_server.h. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/cifsd/ksmbd_server.h | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/fs/cifsd/ksmbd_server.h b/fs/cifsd/ksmbd_server.h index c2467a709144..a915ca5596dc 100644 --- a/fs/cifsd/ksmbd_server.h +++ b/fs/cifsd/ksmbd_server.h @@ -13,10 +13,6 @@ #define KSMBD_GENL_NAME "SMBD_GENL" #define KSMBD_GENL_VERSION 0x01 -#ifndef ____ksmbd_align -#define ____ksmbd_align __aligned(4) -#endif - #define KSMBD_REQ_MAX_ACCOUNT_NAME_SZ 48 #define KSMBD_REQ_MAX_HASH_SZ 18 #define KSMBD_REQ_MAX_SHARE_NAME 64 @@ -51,19 +47,19 @@ struct ksmbd_startup_request { __u32 share_fake_fscaps; __u32 sub_auth[3]; __u32 ifc_list_sz; - __s8 ____payload[0]; -} ____ksmbd_align; + __s8 ____payload[]; +}; #define KSMBD_STARTUP_CONFIG_INTERFACES(s) ((s)->____payload) struct ksmbd_shutdown_request { __s32 reserved; -} ____ksmbd_align; +}; struct ksmbd_login_request { __u32 handle; __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; -} ____ksmbd_align; +}; struct ksmbd_login_response { __u32 handle; @@ -73,12 +69,12 @@ struct ksmbd_login_response { __u16 status; __u16 hash_sz; __s8 hash[KSMBD_REQ_MAX_HASH_SZ]; -} ____ksmbd_align; +}; struct ksmbd_share_config_request { __u32 handle; __s8 share_name[KSMBD_REQ_MAX_SHARE_NAME]; -} ____ksmbd_align; +}; struct ksmbd_share_config_response { __u32 handle; @@ -90,8 +86,8 @@ struct ksmbd_share_config_response { __u16 force_uid; __u16 force_gid; __u32 veto_list_sz; - __s8 ____payload[0]; -} ____ksmbd_align; + __s8 ____payload[]; +}; #define KSMBD_SHARE_CONFIG_VETO_LIST(s) ((s)->____payload) #define KSMBD_SHARE_CONFIG_PATH(s) \ @@ -111,43 +107,43 @@ struct ksmbd_tree_connect_request { __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; __s8 share[KSMBD_REQ_MAX_SHARE_NAME]; __s8 peer_addr[64]; -} ____ksmbd_align; +}; struct ksmbd_tree_connect_response { __u32 handle; __u16 status; __u16 connection_flags; -} ____ksmbd_align; +}; struct ksmbd_tree_disconnect_request { __u64 session_id; __u64 connect_id; -} ____ksmbd_align; +}; struct ksmbd_logout_request { __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; -} ____ksmbd_align; +}; struct ksmbd_rpc_command { __u32 handle; __u32 flags; __u32 payload_sz; - __u8 payload[0]; -} ____ksmbd_align; + __u8 payload[]; +}; struct ksmbd_spnego_authen_request { __u32 handle; __u16 spnego_blob_len; __u8 spnego_blob[0]; -} ____ksmbd_align; +}; struct ksmbd_spnego_authen_response { __u32 handle; struct ksmbd_login_response login_response; __u16 session_key_len; __u16 spnego_blob_len; - __u8 payload[0]; /* session key + AP_REP */ -} ____ksmbd_align; + __u8 payload[]; /* session key + AP_REP */ +}; /* * This also used as NETLINK attribute type value. From 3fbe43c9f577cadd6b5136fda2e6a6c0b4e0651e Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Fri, 18 Jun 2021 10:42:32 +0900 Subject: [PATCH 11/45] ksmbd: replace KSMBD_SHARE_CONFIG_PATH with inline function replace KSMBD_SHARE_CONFIG_PATH with inline function. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/cifsd/ksmbd_server.h | 18 +++++++++++------- fs/cifsd/mgmt/share_config.c | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/fs/cifsd/ksmbd_server.h b/fs/cifsd/ksmbd_server.h index a915ca5596dc..55b7602b79bd 100644 --- a/fs/cifsd/ksmbd_server.h +++ b/fs/cifsd/ksmbd_server.h @@ -90,13 +90,17 @@ struct ksmbd_share_config_response { }; #define KSMBD_SHARE_CONFIG_VETO_LIST(s) ((s)->____payload) -#define KSMBD_SHARE_CONFIG_PATH(s) \ - ({ \ - char *p = (s)->____payload; \ - if ((s)->veto_list_sz) \ - p += (s)->veto_list_sz + 1; \ - p; \ - }) + +static inline char * +ksmbd_share_config_path(struct ksmbd_share_config_response *sc) +{ + char *p = sc->____payload; + + if (sc->veto_list_sz) + p += sc->veto_list_sz + 1; + + return p; +} struct ksmbd_tree_connect_request { __u32 handle; diff --git a/fs/cifsd/mgmt/share_config.c b/fs/cifsd/mgmt/share_config.c index fac6034b97a9..cb72d30f5b71 100644 --- a/fs/cifsd/mgmt/share_config.c +++ b/fs/cifsd/mgmt/share_config.c @@ -139,7 +139,7 @@ static struct ksmbd_share_config *share_config_request(char *name) share->name = kstrdup(name, GFP_KERNEL); if (!test_share_config_flag(share, KSMBD_SHARE_FLAG_PIPE)) { - share->path = kstrdup(KSMBD_SHARE_CONFIG_PATH(resp), + share->path = kstrdup(ksmbd_share_config_path(resp), GFP_KERNEL); if (share->path) share->path_sz = strlen(share->path); From bde1694aecdb535970787b4f1d07ddb317e191e3 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Mon, 28 Jun 2021 15:23:19 +0900 Subject: [PATCH 12/45] ksmbd: remove ksmbd_err/info Use the pr_fmt built into pr_*. and use pr_err/info after removing wrapper ksmbd_err/info. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/cifsd/auth.c | 18 ++-- fs/cifsd/connection.c | 15 ++- fs/cifsd/crypto_ctx.c | 4 +- fs/cifsd/glob.h | 26 ++--- fs/cifsd/mgmt/user_session.c | 4 +- fs/cifsd/misc.c | 2 +- fs/cifsd/ndr.c | 14 +-- fs/cifsd/oplock.c | 20 ++-- fs/cifsd/server.c | 6 +- fs/cifsd/smb2misc.c | 8 +- fs/cifsd/smb2pdu.c | 204 +++++++++++++++++------------------ fs/cifsd/smb_common.c | 2 +- fs/cifsd/smbacl.c | 26 ++--- fs/cifsd/transport_ipc.c | 30 +++--- fs/cifsd/transport_rdma.c | 106 +++++++++--------- fs/cifsd/transport_tcp.c | 20 ++-- fs/cifsd/vfs.c | 88 +++++++-------- fs/cifsd/vfs_cache.c | 10 +- 18 files changed, 295 insertions(+), 308 deletions(-) diff --git a/fs/cifsd/auth.c b/fs/cifsd/auth.c index daf31c9f0880..de36f12070bf 100644 --- a/fs/cifsd/auth.c +++ b/fs/cifsd/auth.c @@ -342,7 +342,7 @@ int ksmbd_auth_ntlm(struct ksmbd_session *sess, char *pw_buf) memcpy(p21, user_passkey(sess->user), CIFS_NTHASH_SIZE); rc = ksmbd_enc_p24(p21, sess->ntlmssp.cryptkey, key); if (rc) { - ksmbd_err("password processing failed\n"); + pr_err("password processing failed\n"); return rc; } @@ -461,7 +461,7 @@ static int __ksmbd_auth_ntlmv2(struct ksmbd_session *sess, char *client_nonce, client_nonce, (char *)sess->ntlmssp.cryptkey, 8); if (rc) { - ksmbd_err("password processing failed\n"); + pr_err("password processing failed\n"); goto out; } @@ -469,7 +469,7 @@ static int __ksmbd_auth_ntlmv2(struct ksmbd_session *sess, char *client_nonce, memcpy(p21, user_passkey(sess->user), CIFS_NTHASH_SIZE); rc = ksmbd_enc_p24(p21, sess_key, key); if (rc) { - ksmbd_err("password processing failed\n"); + pr_err("password processing failed\n"); goto out; } @@ -1269,7 +1269,7 @@ int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov, enc, key); if (rc) { - ksmbd_err("Could not get %scryption key\n", enc ? "en" : "de"); + pr_err("Could not get %scryption key\n", enc ? "en" : "de"); return rc; } @@ -1279,7 +1279,7 @@ int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov, else ctx = ksmbd_crypto_ctx_find_ccm(); if (!ctx) { - ksmbd_err("crypto alloc failed\n"); + pr_err("crypto alloc failed\n"); return -ENOMEM; } @@ -1295,19 +1295,18 @@ int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov, else rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE); if (rc) { - ksmbd_err("Failed to set aead key %d\n", rc); + pr_err("Failed to set aead key %d\n", rc); goto free_ctx; } rc = crypto_aead_setauthsize(tfm, SMB2_SIGNATURE_SIZE); if (rc) { - ksmbd_err("Failed to set authsize %d\n", rc); + pr_err("Failed to set authsize %d\n", rc); goto free_ctx; } req = aead_request_alloc(tfm, GFP_KERNEL); if (!req) { - ksmbd_err("Failed to alloc aead request\n"); rc = -ENOMEM; goto free_ctx; } @@ -1319,7 +1318,7 @@ int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov, sg = ksmbd_init_sg(iov, nvec, sign); if (!sg) { - ksmbd_err("Failed to init sg\n"); + pr_err("Failed to init sg\n"); rc = -ENOMEM; goto free_req; } @@ -1327,7 +1326,6 @@ int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov, iv_len = crypto_aead_ivsize(tfm); iv = kzalloc(iv_len, GFP_KERNEL); if (!iv) { - ksmbd_err("Failed to alloc IV\n"); rc = -ENOMEM; goto free_sg; } diff --git a/fs/cifsd/connection.c b/fs/cifsd/connection.c index a0d15093dd6f..928e22e19def 100644 --- a/fs/cifsd/connection.c +++ b/fs/cifsd/connection.c @@ -160,7 +160,7 @@ int ksmbd_conn_write(struct ksmbd_work *work) ksmbd_conn_try_dequeue_request(work); if (!rsp_hdr) { - ksmbd_err("NULL response header\n"); + pr_err("NULL response header\n"); return -EINVAL; } @@ -192,7 +192,7 @@ int ksmbd_conn_write(struct ksmbd_work *work) ksmbd_conn_unlock(conn); if (sent < 0) { - ksmbd_err("Failed to send message: %d\n", sent); + pr_err("Failed to send message: %d\n", sent); return sent; } @@ -315,24 +315,23 @@ int ksmbd_conn_handler_loop(void *p) */ size = t->ops->read(t, conn->request_buf + 4, pdu_size); if (size < 0) { - ksmbd_err("sock_read failed: %d\n", size); + pr_err("sock_read failed: %d\n", size); break; } if (size != pdu_size) { - ksmbd_err("PDU error. Read: %d, Expected: %d\n", - size, - pdu_size); + pr_err("PDU error. Read: %d, Expected: %d\n", + size, pdu_size); continue; } if (!default_conn_ops.process_fn) { - ksmbd_err("No connection request callback\n"); + pr_err("No connection request callback\n"); break; } if (default_conn_ops.process_fn(conn)) { - ksmbd_err("Cannot handle request\n"); + pr_err("Cannot handle request\n"); break; } } diff --git a/fs/cifsd/crypto_ctx.c b/fs/cifsd/crypto_ctx.c index 7b727fe141a6..5f4b1008d17e 100644 --- a/fs/cifsd/crypto_ctx.c +++ b/fs/cifsd/crypto_ctx.c @@ -48,12 +48,12 @@ static struct crypto_aead *alloc_aead(int id) tfm = crypto_alloc_aead("ccm(aes)", 0, 0); break; default: - ksmbd_err("Does not support encrypt ahead(id : %d)\n", id); + pr_err("Does not support encrypt ahead(id : %d)\n", id); return NULL; } if (IS_ERR(tfm)) { - ksmbd_err("Failed to alloc encrypt aead : %ld\n", PTR_ERR(tfm)); + pr_err("Failed to alloc encrypt aead : %ld\n", PTR_ERR(tfm)); return NULL; } diff --git a/fs/cifsd/glob.h b/fs/cifsd/glob.h index da8f804a3ee2..8119cb7ddbed 100644 --- a/fs/cifsd/glob.h +++ b/fs/cifsd/glob.h @@ -31,32 +31,22 @@ extern int ksmbd_debug_types; KSMBD_DEBUG_IPC | KSMBD_DEBUG_CONN | \ KSMBD_DEBUG_RDMA) -#ifndef ksmbd_pr_fmt -#ifdef SUBMOD_NAME -#define ksmbd_pr_fmt(fmt) "ksmbd: " SUBMOD_NAME ": " fmt -#else -#define ksmbd_pr_fmt(fmt) "ksmbd: " fmt +#ifdef pr_fmt +#undef pr_fmt #endif + +#ifdef SUBMOD_NAME +#define pr_fmt(fmt) "ksmbd: " SUBMOD_NAME ": " fmt +#else +#define pr_fmt(fmt) "ksmbd: " fmt #endif #define ksmbd_debug(type, fmt, ...) \ do { \ if (ksmbd_debug_types & KSMBD_DEBUG_##type) \ - pr_info(ksmbd_pr_fmt("%s:%d: " fmt), \ - __func__, \ - __LINE__, \ - ##__VA_ARGS__); \ + pr_info(fmt, ##__VA_ARGS__); \ } while (0) -#define ksmbd_info(fmt, ...) \ - pr_info(ksmbd_pr_fmt(fmt), ##__VA_ARGS__) - -#define ksmbd_err(fmt, ...) \ - pr_err(ksmbd_pr_fmt("%s:%d: " fmt), \ - __func__, \ - __LINE__, \ - ##__VA_ARGS__) - #define UNICODE_LEN(x) ((x) * 2) #endif /* __KSMBD_GLOB_H */ diff --git a/fs/cifsd/mgmt/user_session.c b/fs/cifsd/mgmt/user_session.c index 77bdf3642f72..615b46f0762b 100644 --- a/fs/cifsd/mgmt/user_session.c +++ b/fs/cifsd/mgmt/user_session.c @@ -87,7 +87,7 @@ static int __rpc_method(char *rpc_name) if (!strcmp(rpc_name, "\\lsarpc") || !strcmp(rpc_name, "lsarpc")) return KSMBD_RPC_LSARPC_METHOD_INVOKE; - ksmbd_err("Unsupported RPC: %s\n", rpc_name); + pr_err("Unsupported RPC: %s\n", rpc_name); return 0; } @@ -232,7 +232,7 @@ int get_session(struct ksmbd_session *sess) void put_session(struct ksmbd_session *sess) { if (atomic_dec_and_test(&sess->refcnt)) - ksmbd_err("get/%s seems to be mismatched.", __func__); + pr_err("get/%s seems to be mismatched.", __func__); } struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id) diff --git a/fs/cifsd/misc.c b/fs/cifsd/misc.c index 1c6ed20f4a18..0b307ca28a19 100644 --- a/fs/cifsd/misc.c +++ b/fs/cifsd/misc.c @@ -107,7 +107,7 @@ static int ksmbd_validate_stream_name(char *stream_name) stream_name++; if (c == '/' || c == ':' || c == '\\') { - ksmbd_err("Stream name validation failed: %c\n", c); + pr_err("Stream name validation failed: %c\n", c); return -ENOENT; } } diff --git a/fs/cifsd/ndr.c b/fs/cifsd/ndr.c index 14189832c65e..46cc01475d38 100644 --- a/fs/cifsd/ndr.c +++ b/fs/cifsd/ndr.c @@ -178,14 +178,14 @@ int ndr_decode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da) da->version = ndr_read_int16(n); if (da->version != 3 && da->version != 4) { - ksmbd_err("v%d version is not supported\n", da->version); + pr_err("v%d version is not supported\n", da->version); return -EINVAL; } version2 = ndr_read_int32(n); if (da->version != version2) { - ksmbd_err("ndr version mismatched(version: %d, version2: %d)\n", - da->version, version2); + pr_err("ndr version mismatched(version: %d, version2: %d)\n", + da->version, version2); return -EINVAL; } @@ -309,14 +309,14 @@ int ndr_decode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl) n->offset = 0; acl->version = ndr_read_int16(n); if (acl->version != 4) { - ksmbd_err("v%d version is not supported\n", acl->version); + pr_err("v%d version is not supported\n", acl->version); return -EINVAL; } version2 = ndr_read_int32(n); if (acl->version != version2) { - ksmbd_err("ndr version mismatched(version: %d, version2: %d)\n", - acl->version, version2); + pr_err("ndr version mismatched(version: %d, version2: %d)\n", + acl->version, version2); return -EINVAL; } @@ -329,7 +329,7 @@ int ndr_decode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl) ndr_read_bytes(n, acl->desc, 10); if (strncmp(acl->desc, "posix_acl", 9)) { - ksmbd_err("Invalid acl description : %s\n", acl->desc); + pr_err("Invalid acl description : %s\n", acl->desc); return -EINVAL; } diff --git a/fs/cifsd/oplock.c b/fs/cifsd/oplock.c index 1ef2acbea2bb..9027cb7d970f 100644 --- a/fs/cifsd/oplock.c +++ b/fs/cifsd/oplock.c @@ -230,9 +230,9 @@ int opinfo_write_to_read(struct oplock_info *opinfo) if (!(opinfo->level == SMB2_OPLOCK_LEVEL_BATCH || opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)) { - ksmbd_err("bad oplock(0x%x)\n", opinfo->level); + pr_err("bad oplock(0x%x)\n", opinfo->level); if (opinfo->is_lease) - ksmbd_err("lease state(0x%x)\n", lease->state); + pr_err("lease state(0x%x)\n", lease->state); return -EINVAL; } opinfo->level = SMB2_OPLOCK_LEVEL_II; @@ -269,9 +269,9 @@ int opinfo_write_to_none(struct oplock_info *opinfo) if (!(opinfo->level == SMB2_OPLOCK_LEVEL_BATCH || opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)) { - ksmbd_err("bad oplock(0x%x)\n", opinfo->level); + pr_err("bad oplock(0x%x)\n", opinfo->level); if (opinfo->is_lease) - ksmbd_err("lease state(0x%x)\n", lease->state); + pr_err("lease state(0x%x)\n", lease->state); return -EINVAL; } opinfo->level = SMB2_OPLOCK_LEVEL_NONE; @@ -291,9 +291,9 @@ int opinfo_read_to_none(struct oplock_info *opinfo) struct lease *lease = opinfo->o_lease; if (opinfo->level != SMB2_OPLOCK_LEVEL_II) { - ksmbd_err("bad oplock(0x%x)\n", opinfo->level); + pr_err("bad oplock(0x%x)\n", opinfo->level); if (opinfo->is_lease) - ksmbd_err("lease state(0x%x)\n", lease->state); + pr_err("lease state(0x%x)\n", lease->state); return -EINVAL; } opinfo->level = SMB2_OPLOCK_LEVEL_NONE; @@ -622,7 +622,7 @@ static void __smb2_oplock_break_noti(struct work_struct *wk) } if (allocate_oplock_break_buf(work)) { - ksmbd_err("smb2_allocate_rsp_buf failed! "); + pr_err("smb2_allocate_rsp_buf failed! "); atomic_dec(&conn->r_count); ksmbd_fd_put(work, fp); ksmbd_free_work_struct(work); @@ -1680,18 +1680,18 @@ int smb2_check_durable_oplock(struct ksmbd_file *fp, if (opinfo && opinfo->is_lease) { if (!lctx) { - ksmbd_err("open does not include lease\n"); + pr_err("open does not include lease\n"); ret = -EBADF; goto out; } if (memcmp(opinfo->o_lease->lease_key, lctx->lease_key, SMB2_LEASE_KEY_SIZE)) { - ksmbd_err("invalid lease key\n"); + pr_err("invalid lease key\n"); ret = -EBADF; goto out; } if (name && strcmp(fp->filename, name)) { - ksmbd_err("invalid name reconnect %s\n", name); + pr_err("invalid name reconnect %s\n", name); ret = -EINVAL; goto out; } diff --git a/fs/cifsd/server.c b/fs/cifsd/server.c index 6d14daae1b07..a8c59e96a2f7 100644 --- a/fs/cifsd/server.c +++ b/fs/cifsd/server.c @@ -277,7 +277,7 @@ static int queue_ksmbd_work(struct ksmbd_conn *conn) work = ksmbd_alloc_work_struct(); if (!work) { - ksmbd_err("allocation for work failed\n"); + pr_err("allocation for work failed\n"); return -ENOMEM; } @@ -442,7 +442,7 @@ static ssize_t kill_server_store(struct class *class, if (!sysfs_streq(buf, "hard")) return len; - ksmbd_info("kill command received\n"); + pr_info("kill command received\n"); mutex_lock(&ctrl_lock); WRITE_ONCE(server_conf.state, SERVER_STATE_RESETTING); __module_get(THIS_MODULE); @@ -547,7 +547,7 @@ static int __init ksmbd_server_init(void) ret = class_register(&ksmbd_control_class); if (ret) { - ksmbd_err("Unable to register ksmbd-control class\n"); + pr_err("Unable to register ksmbd-control class\n"); return ret; } diff --git a/fs/cifsd/smb2misc.c b/fs/cifsd/smb2misc.c index c4b870dbf683..e412d69690ed 100644 --- a/fs/cifsd/smb2misc.c +++ b/fs/cifsd/smb2misc.c @@ -320,12 +320,12 @@ static int smb2_validate_credit_charge(struct smb2_hdr *hdr) max_len = max(req_len, expect_resp_len); calc_credit_num = DIV_ROUND_UP(max_len, SMB2_MAX_BUFFER_SIZE); if (!credit_charge && max_len > SMB2_MAX_BUFFER_SIZE) { - ksmbd_err("credit charge is zero and payload size(%d) is bigger than 64K\n", - max_len); + pr_err("credit charge is zero and payload size(%d) is bigger than 64K\n", + max_len); return 1; } else if (credit_charge < calc_credit_num) { - ksmbd_err("credit charge : %d, calc_credit_num : %d\n", - credit_charge, calc_credit_num); + pr_err("credit charge : %d, calc_credit_num : %d\n", + credit_charge, calc_credit_num); return 1; } diff --git a/fs/cifsd/smb2pdu.c b/fs/cifsd/smb2pdu.c index f1642fffe4e1..84f4cd7f545f 100644 --- a/fs/cifsd/smb2pdu.c +++ b/fs/cifsd/smb2pdu.c @@ -66,7 +66,7 @@ static inline int check_session_id(struct ksmbd_conn *conn, u64 id) sess = ksmbd_session_lookup_all(conn, id); if (sess) return 1; - ksmbd_err("Invalid user session id: %llu\n", id); + pr_err("Invalid user session id: %llu\n", id); return 0; } @@ -109,7 +109,7 @@ int smb2_get_ksmbd_tcon(struct ksmbd_work *work) tree_id = le32_to_cpu(req_hdr->Id.SyncId.TreeId); work->tcon = ksmbd_tree_conn_lookup(work->sess, tree_id); if (!work->tcon) { - ksmbd_err("Invalid tid %d\n", tree_id); + pr_err("Invalid tid %d\n", tree_id); return -1; } @@ -329,7 +329,7 @@ int smb2_set_rsp_credits(struct ksmbd_work *work) min_credits = conn->max_credits >> 4; if (conn->total_credits >= conn->max_credits) { - ksmbd_err("Total credits overflow: %d\n", conn->total_credits); + pr_err("Total credits overflow: %d\n", conn->total_credits); conn->total_credits = min_credits; } @@ -634,7 +634,7 @@ smb2_get_name(struct ksmbd_share_config *share, const char *src, name = smb_strndup_from_utf16(src, maxlen, 1, local_nls); if (IS_ERR(name)) { - ksmbd_err("failed to get name %ld\n", PTR_ERR(name)); + pr_err("failed to get name %ld\n", PTR_ERR(name)); return name; } @@ -645,7 +645,7 @@ smb2_get_name(struct ksmbd_share_config *share, const char *src, unixname = convert_to_unix_name(share, name); kfree(name); if (!unixname) { - ksmbd_err("can not convert absolute name\n"); + pr_err("can not convert absolute name\n"); return ERR_PTR(-ENOMEM); } @@ -664,7 +664,7 @@ int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg) id = ksmbd_acquire_async_msg_id(&conn->async_ida); if (id < 0) { - ksmbd_err("Failed to alloc async message id\n"); + pr_err("Failed to alloc async message id\n"); return id; } work->syncronous = false; @@ -1005,13 +1005,13 @@ int smb2_handle_negotiate(struct ksmbd_work *work) ksmbd_debug(SMB, "Received negotiate request\n"); conn->need_neg = false; if (ksmbd_conn_good(work)) { - ksmbd_err("conn->tcp_status is already in CifsGood State\n"); + pr_err("conn->tcp_status is already in CifsGood State\n"); work->send_no_response = 1; return rc; } if (req->DialectCount == 0) { - ksmbd_err("malformed packet\n"); + pr_err("malformed packet\n"); rsp->hdr.Status = STATUS_INVALID_PARAMETER; rc = -EINVAL; goto err_out; @@ -1031,8 +1031,8 @@ int smb2_handle_negotiate(struct ksmbd_work *work) status = deassemble_neg_contexts(conn, req); if (status != STATUS_SUCCESS) { - ksmbd_err("deassemble_neg_contexts error(0x%x)\n", - status); + pr_err("deassemble_neg_contexts error(0x%x)\n", + status); rsp->hdr.Status = status; rc = -EINVAL; goto err_out; @@ -1293,7 +1293,7 @@ static struct ksmbd_user *session_user(struct ksmbd_conn *conn, true, conn->local_nls); if (IS_ERR(name)) { - ksmbd_err("cannot allocate memory\n"); + pr_err("cannot allocate memory\n"); return NULL; } @@ -1438,7 +1438,7 @@ binding_session: if (conn->dialect > SMB20_PROT_ID) { if (!ksmbd_conn_lookup_dialect(conn)) { - ksmbd_err("fail to verify the dialect\n"); + pr_err("fail to verify the dialect\n"); rsp->hdr.Status = STATUS_USER_SESSION_DELETED; return -EPERM; } @@ -1528,7 +1528,7 @@ static int krb5_authenticate(struct ksmbd_work *work) if (conn->dialect > SMB20_PROT_ID) { if (!ksmbd_conn_lookup_dialect(conn)) { - ksmbd_err("fail to verify the dialect\n"); + pr_err("fail to verify the dialect\n"); rsp->hdr.Status = STATUS_USER_SESSION_DELETED; return -EPERM; } @@ -1688,11 +1688,11 @@ int smb2_sess_setup(struct ksmbd_work *work) } } else { /* TODO: need one more negotiation */ - ksmbd_err("Not support the preferred authentication\n"); + pr_err("Not support the preferred authentication\n"); rc = -EINVAL; } } else { - ksmbd_err("Not support authentication\n"); + pr_err("Not support authentication\n"); rc = -EINVAL; } @@ -1742,7 +1742,7 @@ int smb2_tree_connect(struct ksmbd_work *work) le16_to_cpu(req->PathLength), true, conn->local_nls); if (IS_ERR(treename)) { - ksmbd_err("treename is NULL\n"); + pr_err("treename is NULL\n"); status.ret = KSMBD_TREE_CONN_STATUS_ERROR; goto out_err1; } @@ -1986,7 +1986,7 @@ static noinline int create_smb2_pipe(struct ksmbd_work *work) id = ksmbd_session_rpc_open(work->sess, name); if (id < 0) { - ksmbd_err("Unable to open RPC pipe: %d\n", id); + pr_err("Unable to open RPC pipe: %d\n", id); err = id; goto out; } @@ -2120,7 +2120,7 @@ static inline int check_context_err(void *ctx, char *str) ksmbd_debug(SMB, "find context %s err %d\n", str, err); if (err == -EINVAL) { - ksmbd_err("bad name length\n"); + pr_err("bad name length\n"); return err; } @@ -2159,7 +2159,7 @@ static noinline int smb2_set_stream_name_xattr(struct path *path, rc = ksmbd_vfs_setxattr(path->dentry, xattr_stream_name, NULL, 0, 0); if (rc < 0) - ksmbd_err("Failed to store XATTR stream name :%d\n", rc); + pr_err("Failed to store XATTR stream name :%d\n", rc); return 0; } @@ -2201,7 +2201,7 @@ static int smb2_create_truncate(struct path *path) int rc = vfs_truncate(path, 0); if (rc) { - ksmbd_err("vfs_truncate failed, rc %d\n", rc); + pr_err("vfs_truncate failed, rc %d\n", rc); return rc; } @@ -2287,8 +2287,8 @@ static int smb2_creat(struct ksmbd_work *work, struct path *path, char *name, rc = ksmbd_vfs_kern_path(name, 0, path, 0); if (rc) { - ksmbd_err("cannot get linux path (%s), err = %d\n", - name, rc); + pr_err("cannot get linux path (%s), err = %d\n", + name, rc); return rc; } return 0; @@ -2387,7 +2387,7 @@ int smb2_open(struct ksmbd_work *work) if (req->NameLength) { if ((req->CreateOptions & FILE_DIRECTORY_FILE_LE) && *(char *)req->Buffer == '\\') { - ksmbd_err("not allow directory name included leading slash\n"); + pr_err("not allow directory name included leading slash\n"); rc = -EINVAL; goto err_out1; } @@ -2444,16 +2444,16 @@ int smb2_open(struct ksmbd_work *work) lc = parse_lease_state(req); if (le32_to_cpu(req->ImpersonationLevel) > le32_to_cpu(IL_DELEGATE_LE)) { - ksmbd_err("Invalid impersonationlevel : 0x%x\n", - le32_to_cpu(req->ImpersonationLevel)); + pr_err("Invalid impersonationlevel : 0x%x\n", + le32_to_cpu(req->ImpersonationLevel)); rc = -EIO; rsp->hdr.Status = STATUS_BAD_IMPERSONATION_LEVEL; goto err_out1; } if (req->CreateOptions && !(req->CreateOptions & CREATE_OPTIONS_MASK)) { - ksmbd_err("Invalid create options : 0x%x\n", - le32_to_cpu(req->CreateOptions)); + pr_err("Invalid create options : 0x%x\n", + le32_to_cpu(req->CreateOptions)); rc = -EINVAL; goto err_out1; } else { @@ -2480,22 +2480,22 @@ int smb2_open(struct ksmbd_work *work) if (le32_to_cpu(req->CreateDisposition) > le32_to_cpu(FILE_OVERWRITE_IF_LE)) { - ksmbd_err("Invalid create disposition : 0x%x\n", - le32_to_cpu(req->CreateDisposition)); + pr_err("Invalid create disposition : 0x%x\n", + le32_to_cpu(req->CreateDisposition)); rc = -EINVAL; goto err_out1; } if (!(req->DesiredAccess & DESIRED_ACCESS_MASK)) { - ksmbd_err("Invalid desired access : 0x%x\n", - le32_to_cpu(req->DesiredAccess)); + pr_err("Invalid desired access : 0x%x\n", + le32_to_cpu(req->DesiredAccess)); rc = -EACCES; goto err_out1; } if (req->FileAttributes && !(req->FileAttributes & ATTR_MASK_LE)) { - ksmbd_err("Invalid file attribute : 0x%x\n", - le32_to_cpu(req->FileAttributes)); + pr_err("Invalid file attribute : 0x%x\n", + le32_to_cpu(req->FileAttributes)); rc = -EINVAL; goto err_out1; } @@ -2750,7 +2750,7 @@ int smb2_open(struct ksmbd_work *work) filp = dentry_open(&path, open_flags, current_cred()); if (IS_ERR(filp)) { rc = PTR_ERR(filp); - ksmbd_err("dentry open for dir failed, rc %d\n", rc); + pr_err("dentry open for dir failed, rc %d\n", rc); goto err_out; } @@ -2846,8 +2846,8 @@ int smb2_open(struct ksmbd_work *work) pntsd_size); kfree(pntsd); if (rc) - ksmbd_err("failed to store ntacl in xattr : %d\n", - rc); + pr_err("failed to store ntacl in xattr : %d\n", + rc); } } } @@ -3697,14 +3697,14 @@ int smb2_query_dir(struct ksmbd_work *work) if (!(dir_fp->daccess & FILE_LIST_DIRECTORY_LE) || inode_permission(&init_user_ns, file_inode(dir_fp->filp), MAY_READ | MAY_EXEC)) { - ksmbd_err("no right to enumerate directory (%s)\n", - FP_FILENAME(dir_fp)); + pr_err("no right to enumerate directory (%s)\n", + FP_FILENAME(dir_fp)); rc = -EACCES; goto err_out2; } if (!S_ISDIR(file_inode(dir_fp->filp)->i_mode)) { - ksmbd_err("can't do query dir for a file\n"); + pr_err("can't do query dir for a file\n"); rc = -EINVAL; goto err_out2; } @@ -3805,7 +3805,7 @@ int smb2_query_dir(struct ksmbd_work *work) return 0; err_out: - ksmbd_err("error while processing smb2 query dir rc = %d\n", rc); + pr_err("error while processing smb2 query dir rc = %d\n", rc); kfree(srch_ptr); err_out2: @@ -3843,7 +3843,7 @@ static int buffer_check_err(int reqOutputBufferLength, { if (reqOutputBufferLength < le32_to_cpu(rsp->OutputBufferLength)) { if (reqOutputBufferLength < infoclass_size) { - ksmbd_err("Invalid Buffer Size Requested\n"); + pr_err("Invalid Buffer Size Requested\n"); rsp->hdr.Status = STATUS_INFO_LENGTH_MISMATCH; rsp->hdr.smb2_buf_length = cpu_to_be32(sizeof(struct smb2_hdr) - 4); return -EINVAL; @@ -3946,8 +3946,8 @@ static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp, struct path *path; if (!(fp->daccess & FILE_READ_EA_LE)) { - ksmbd_err("Not permitted to read ext attr : 0x%x\n", - fp->daccess); + pr_err("Not permitted to read ext attr : 0x%x\n", + fp->daccess); return -EACCES; } @@ -4103,8 +4103,8 @@ static int get_file_basic_info(struct smb2_query_info_rsp *rsp, u64 time; if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) { - ksmbd_err("no right to read the attributes : 0x%x\n", - fp->daccess); + pr_err("no right to read the attributes : 0x%x\n", + fp->daccess); return -EACCES; } @@ -4375,8 +4375,8 @@ static int get_file_network_open_info(struct smb2_query_info_rsp *rsp, u64 time; if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) { - ksmbd_err("no right to read the attributes : 0x%x\n", - fp->daccess); + pr_err("no right to read the attributes : 0x%x\n", + fp->daccess); return -EACCES; } @@ -4465,8 +4465,8 @@ static int get_file_attribute_tag_info(struct smb2_query_info_rsp *rsp, struct smb2_file_attr_tag_info *file_info; if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) { - ksmbd_err("no right to read the attributes : 0x%x\n", - fp->daccess); + pr_err("no right to read the attributes : 0x%x\n", + fp->daccess); return -EACCES; } @@ -4620,7 +4620,7 @@ static int smb2_get_info_file(struct ksmbd_work *work, break; case SMB_FIND_FILE_POSIX_INFO: if (!work->tcon->posix_extensions) { - ksmbd_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n"); + pr_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n"); rc = -EOPNOTSUPP; } else { rc = find_file_posix_info(rsp, fp, rsp_org); @@ -4659,13 +4659,13 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, rc = ksmbd_vfs_kern_path(share->path, lookup_flags, &path, 0); if (rc) { - ksmbd_err("cannot create vfs path\n"); + pr_err("cannot create vfs path\n"); return -EIO; } rc = vfs_statfs(&path, &stfs); if (rc) { - ksmbd_err("cannot do stat of path %s\n", share->path); + pr_err("cannot do stat of path %s\n", share->path); path_put(&path); return -EIO; } @@ -4846,7 +4846,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, unsigned short logical_sector_size; if (!work->tcon->posix_extensions) { - ksmbd_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n"); + pr_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n"); rc = -EOPNOTSUPP; } else { info = (struct filesystem_posix_info *)(rsp->Buffer); @@ -5213,7 +5213,7 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp, len = strlen(new_name); if (new_name[len - 1] != '/') { - ksmbd_err("not allow base filename in rename\n"); + pr_err("not allow base filename in rename\n"); rc = -ESHARE; goto out; } @@ -5229,8 +5229,8 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp, xattr_stream_name, NULL, 0, 0); if (rc < 0) { - ksmbd_err("failed to store stream name in xattr: %d\n", - rc); + pr_err("failed to store stream name in xattr: %d\n", + rc); rc = -EINVAL; goto out; } @@ -5389,7 +5389,7 @@ static int set_file_basic_info(struct ksmbd_file *fp, char *buf, if (file_info->Attributes) { if (!S_ISDIR(inode->i_mode) && file_info->Attributes & ATTR_DIRECTORY_LE) { - ksmbd_err("can't change a file to a directory\n"); + pr_err("can't change a file to a directory\n"); return -EINVAL; } @@ -5467,7 +5467,7 @@ static int set_file_allocation_info(struct ksmbd_work *work, if (alloc_blks > inode->i_blocks) { rc = ksmbd_vfs_alloc_size(work, fp, alloc_blks * 512); if (rc && rc != -EOPNOTSUPP) { - ksmbd_err("ksmbd_vfs_alloc_size is failed : %d\n", rc); + pr_err("ksmbd_vfs_alloc_size is failed : %d\n", rc); return rc; } } else if (alloc_blks < inode->i_blocks) { @@ -5483,8 +5483,8 @@ static int set_file_allocation_info(struct ksmbd_work *work, size = i_size_read(inode); rc = ksmbd_vfs_truncate(work, NULL, fp, alloc_blks * 512); if (rc) { - ksmbd_err("truncate failed! filename : %s, err %d\n", - fp->filename, rc); + pr_err("truncate failed! filename : %s, err %d\n", + fp->filename, rc); return rc; } if (size < alloc_blks * 512) @@ -5536,7 +5536,7 @@ static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp, struct ksmbd_file *parent_fp; if (!(fp->daccess & FILE_DELETE_LE)) { - ksmbd_err("no right to delete : 0x%x\n", fp->daccess); + pr_err("no right to delete : 0x%x\n", fp->daccess); return -EACCES; } @@ -5546,7 +5546,7 @@ static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp, parent_fp = ksmbd_lookup_fd_inode(PARENT_INODE(fp)); if (parent_fp) { if (parent_fp->daccess & FILE_DELETE_LE) { - ksmbd_err("parent dir is opened with delete access\n"); + pr_err("parent dir is opened with delete access\n"); return -ESHARE; } } @@ -5562,7 +5562,7 @@ static int set_file_disposition_info(struct ksmbd_file *fp, char *buf) struct inode *inode; if (!(fp->daccess & FILE_DELETE_LE)) { - ksmbd_err("no right to delete : 0x%x\n", fp->daccess); + pr_err("no right to delete : 0x%x\n", fp->daccess); return -EACCES; } @@ -5594,8 +5594,8 @@ static int set_file_position_info(struct ksmbd_file *fp, char *buf) if (current_byte_offset < 0 || (fp->coption == FILE_NO_INTERMEDIATE_BUFFERING_LE && current_byte_offset & (sector_size - 1))) { - ksmbd_err("CurrentByteOffset is not valid : %llu\n", - current_byte_offset); + pr_err("CurrentByteOffset is not valid : %llu\n", + current_byte_offset); return -EINVAL; } @@ -5614,7 +5614,7 @@ static int set_file_mode_info(struct ksmbd_file *fp, char *buf) if ((mode & ~FILE_MODE_INFO_MASK) || (mode & FILE_SYNCHRONOUS_IO_ALERT_LE && mode & FILE_SYNCHRONOUS_IO_NONALERT_LE)) { - ksmbd_err("Mode is not valid : 0x%x\n", le32_to_cpu(mode)); + pr_err("Mode is not valid : 0x%x\n", le32_to_cpu(mode)); return -EINVAL; } @@ -5675,8 +5675,8 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, case FILE_FULL_EA_INFORMATION: { if (!(fp->daccess & FILE_WRITE_EA_LE)) { - ksmbd_err("Not permitted to write ext attr: 0x%x\n", - fp->daccess); + pr_err("Not permitted to write ext attr: 0x%x\n", + fp->daccess); return -EACCES; } @@ -5691,7 +5691,7 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, return set_file_mode_info(fp, buf); } - ksmbd_err("Unimplemented Fileinfoclass :%d\n", info_class); + pr_err("Unimplemented Fileinfoclass :%d\n", info_class); return -EOPNOTSUPP; } @@ -5919,7 +5919,7 @@ int smb2_read(struct ksmbd_work *work) } if (!(fp->daccess & (FILE_READ_DATA_LE | FILE_READ_ATTRIBUTES_LE))) { - ksmbd_err("Not permitted to read : 0x%x\n", fp->daccess); + pr_err("Not permitted to read : 0x%x\n", fp->daccess); err = -EACCES; goto out; } @@ -6039,9 +6039,9 @@ static noinline int smb2_write_pipe(struct ksmbd_work *work) } else { if ((le16_to_cpu(req->DataOffset) > 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", - le16_to_cpu(req->DataOffset), - get_rfc1002_len(req)); + pr_err("invalid write data offset %u, smb_len %u\n", + le16_to_cpu(req->DataOffset), + get_rfc1002_len(req)); err = -EINVAL; goto out; } @@ -6172,7 +6172,7 @@ int smb2_write(struct ksmbd_work *work) } if (!(fp->daccess & (FILE_WRITE_DATA_LE | FILE_READ_ATTRIBUTES_LE))) { - ksmbd_err("Not permitted to write : 0x%x\n", fp->daccess); + pr_err("Not permitted to write : 0x%x\n", fp->daccess); err = -EACCES; goto out; } @@ -6198,9 +6198,9 @@ int smb2_write(struct ksmbd_work *work) } else { if ((le16_to_cpu(req->DataOffset) > 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", - le16_to_cpu(req->DataOffset), - get_rfc1002_len(req)); + pr_err("invalid write data offset %u, smb_len %u\n", + le16_to_cpu(req->DataOffset), + get_rfc1002_len(req)); err = -EINVAL; goto out; } @@ -6530,7 +6530,7 @@ int smb2_lock(struct ksmbd_work *work) lock_start = le64_to_cpu(lock_ele[i].Offset); lock_length = le64_to_cpu(lock_ele[i].Length); if (lock_start > U64_MAX - lock_length) { - ksmbd_err("Invalid lock range requested\n"); + pr_err("Invalid lock range requested\n"); rsp->hdr.Status = STATUS_INVALID_LOCK_RANGE; goto out; } @@ -6560,7 +6560,7 @@ int smb2_lock(struct ksmbd_work *work) cmp_lock->fl->fl_end >= flock->fl_end) { if (cmp_lock->fl->fl_type != F_UNLCK && flock->fl_type != F_UNLCK) { - ksmbd_err("conflict two locks in one request\n"); + pr_err("conflict two locks in one request\n"); rsp->hdr.Status = STATUS_INVALID_PARAMETER; goto out; @@ -6633,7 +6633,7 @@ int smb2_lock(struct ksmbd_work *work) if (cmp_lock->zero_len && !smb_lock->zero_len && cmp_lock->start > smb_lock->start && cmp_lock->start < smb_lock->end) { - ksmbd_err("previous lock conflict with zero byte lock range\n"); + pr_err("previous lock conflict with zero byte lock range\n"); rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; goto out; } @@ -6641,7 +6641,7 @@ int smb2_lock(struct ksmbd_work *work) if (smb_lock->zero_len && !cmp_lock->zero_len && smb_lock->start > cmp_lock->start && smb_lock->start < cmp_lock->end) { - ksmbd_err("current lock conflict with zero byte lock range\n"); + pr_err("current lock conflict with zero byte lock range\n"); rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; goto out; } @@ -6650,7 +6650,7 @@ int smb2_lock(struct ksmbd_work *work) cmp_lock->end > smb_lock->start) || (cmp_lock->start < smb_lock->end && cmp_lock->end >= smb_lock->end)) && !cmp_lock->zero_len && !smb_lock->zero_len) { - ksmbd_err("Not allow lock operation on exclusive lock range\n"); + pr_err("Not allow lock operation on exclusive lock range\n"); rsp->hdr.Status = STATUS_LOCK_NOT_GRANTED; goto out; @@ -6658,7 +6658,7 @@ int smb2_lock(struct ksmbd_work *work) } if (smb_lock->fl->fl_type == F_UNLCK && nolock) { - ksmbd_err("Try to unlock nolocked range\n"); + pr_err("Try to unlock nolocked range\n"); rsp->hdr.Status = STATUS_RANGE_NOT_LOCKED; goto out; } @@ -6787,7 +6787,7 @@ out: err = ksmbd_vfs_lock(filp, 0, rlock); if (err) - ksmbd_err("rollback unlock fail : %d\n", err); + pr_err("rollback unlock fail : %d\n", err); list_del(&smb_lock->llist); list_del(&smb_lock->glist); locks_free_lock(smb_lock->fl); @@ -6974,8 +6974,8 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn, netdev->ethtool_ops->get_link_ksettings(netdev, &cmd); speed = cmd.base.speed; } else { - ksmbd_err("%s %s\n", netdev->name, - "speed is unknown, defaulting to 1Gb/sec"); + pr_err("%s %s\n", netdev->name, + "speed is unknown, defaulting to 1Gb/sec"); speed = SPEED_1000; } @@ -7387,7 +7387,7 @@ int smb2_ioctl(struct ksmbd_work *work) reparse_ptr = (struct reparse_data_buffer *)&rsp->Buffer[0]; fp = ksmbd_lookup_fd_fast(work, id); if (!fp) { - ksmbd_err("not found fp!!\n"); + pr_err("not found fp!!\n"); ret = -ENOENT; goto out; } @@ -7410,14 +7410,14 @@ int smb2_ioctl(struct ksmbd_work *work) fp_in = ksmbd_lookup_fd_slow(work, dup_ext->VolatileFileHandle, dup_ext->PersistentFileHandle); if (!fp_in) { - ksmbd_err("not found file handle in duplicate extent to file\n"); + pr_err("not found file handle in duplicate extent to file\n"); ret = -ENOENT; goto out; } fp_out = ksmbd_lookup_fd_fast(work, id); if (!fp_out) { - ksmbd_err("not found fp\n"); + pr_err("not found fp\n"); ret = -ENOENT; goto dup_ext_out; } @@ -7514,7 +7514,7 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work) opinfo = opinfo_get(fp); if (!opinfo) { - ksmbd_err("unexpected null oplock_info\n"); + pr_err("unexpected null oplock_info\n"); rsp->hdr.Status = STATUS_INVALID_OPLOCK_PROTOCOL; smb2_set_err_rsp(work); ksmbd_fd_put(work, fp); @@ -7577,8 +7577,8 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work) rsp_oplevel = SMB2_OPLOCK_LEVEL_NONE; break; default: - ksmbd_err("unknown oplock change 0x%x -> 0x%x\n", - opinfo->level, rsp_oplevel); + pr_err("unknown oplock change 0x%x -> 0x%x\n", + opinfo->level, rsp_oplevel); } if (ret < 0) { @@ -7654,8 +7654,8 @@ static void smb21_lease_break_ack(struct ksmbd_work *work) lease = opinfo->o_lease; if (opinfo->op_state == OPLOCK_STATE_NONE) { - ksmbd_err("unexpected lease break state 0x%x\n", - opinfo->op_state); + pr_err("unexpected lease break state 0x%x\n", + opinfo->op_state); rsp->hdr.Status = STATUS_UNSUCCESSFUL; goto err_out; } @@ -7868,7 +7868,7 @@ int smb2_check_sign_req(struct ksmbd_work *work) return 0; if (memcmp(signature, signature_req, SMB2_SIGNATURE_SIZE)) { - ksmbd_err("bad smb2 signature\n"); + pr_err("bad smb2 signature\n"); return 0; } @@ -7965,7 +7965,7 @@ int smb3_check_sign_req(struct ksmbd_work *work) } if (!signing_key) { - ksmbd_err("SMB3 signing key is not generated\n"); + pr_err("SMB3 signing key is not generated\n"); return 0; } @@ -7978,7 +7978,7 @@ int smb3_check_sign_req(struct ksmbd_work *work) return 0; if (memcmp(signature, signature_req, SMB2_SIGNATURE_SIZE)) { - ksmbd_err("bad smb2 signature\n"); + pr_err("bad smb2 signature\n"); return 0; } @@ -8175,20 +8175,20 @@ int smb3_decrypt_req(struct ksmbd_work *work) sess = ksmbd_session_lookup_all(conn, le64_to_cpu(tr_hdr->SessionId)); if (!sess) { - ksmbd_err("invalid session id(%llx) in transform header\n", - le64_to_cpu(tr_hdr->SessionId)); + pr_err("invalid session id(%llx) in transform header\n", + le64_to_cpu(tr_hdr->SessionId)); return -ECONNABORTED; } if (pdu_length + 4 < sizeof(struct smb2_transform_hdr) + sizeof(struct smb2_hdr)) { - ksmbd_err("Transform message is too small (%u)\n", - pdu_length); + pr_err("Transform message is too small (%u)\n", + pdu_length); return -ECONNABORTED; } if (pdu_length + 4 < orig_len + sizeof(struct smb2_transform_hdr)) { - ksmbd_err("Transform message is broken\n"); + pr_err("Transform message is broken\n"); return -ECONNABORTED; } diff --git a/fs/cifsd/smb_common.c b/fs/cifsd/smb_common.c index d74b2ce08187..5bf644d7e321 100644 --- a/fs/cifsd/smb_common.c +++ b/fs/cifsd/smb_common.c @@ -447,7 +447,7 @@ int ksmbd_smb_negotiate_common(struct ksmbd_work *work, unsigned int command) return smb_handle_negotiate(work); } - ksmbd_err("Unknown SMB negotiation command: %u\n", command); + pr_err("Unknown SMB negotiation command: %u\n", command); return -EINVAL; } diff --git a/fs/cifsd/smbacl.c b/fs/cifsd/smbacl.c index 63db8c015f9d..23c952612db4 100644 --- a/fs/cifsd/smbacl.c +++ b/fs/cifsd/smbacl.c @@ -264,8 +264,8 @@ static int sid_to_id(struct smb_sid *psid, uint sidtype, * Just return an error. */ if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) { - ksmbd_err("%s: %u subauthorities is too many!\n", - __func__, psid->num_subauth); + pr_err("%s: %u subauthorities is too many!\n", + __func__, psid->num_subauth); return -EIO; } @@ -383,7 +383,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, /* validate that we do not go past end of acl */ if (end_of_acl <= (char *)pdacl || end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) { - ksmbd_err("ACL too small to parse DACL\n"); + pr_err("ACL too small to parse DACL\n"); return; } @@ -477,8 +477,8 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, temp_fattr.cf_uid = INVALID_UID; ret = sid_to_id(&ppace[i]->sid, SIDOWNER, &temp_fattr); if (ret || uid_eq(temp_fattr.cf_uid, INVALID_UID)) { - ksmbd_err("%s: Error %d mapping Owner SID to uid\n", - __func__, ret); + pr_err("%s: Error %d mapping Owner SID to uid\n", + __func__, ret); continue; } @@ -764,7 +764,7 @@ static int parse_sid(struct smb_sid *psid, char *end_of_acl) * bytes long (assuming no sub-auths - e.g. the null SID */ if (end_of_acl < (char *)psid + 8) { - ksmbd_err("ACL too small to parse SID %p\n", psid); + pr_err("ACL too small to parse SID %p\n", psid); return -EINVAL; } @@ -808,14 +808,14 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len, if (pntsd->osidoffset) { rc = parse_sid(owner_sid_ptr, end_of_acl); if (rc) { - ksmbd_err("%s: Error %d parsing Owner SID\n", __func__, rc); + pr_err("%s: Error %d parsing Owner SID\n", __func__, rc); return rc; } rc = sid_to_id(owner_sid_ptr, SIDOWNER, fattr); if (rc) { - ksmbd_err("%s: Error %d mapping Owner SID to uid\n", - __func__, rc); + pr_err("%s: Error %d mapping Owner SID to uid\n", + __func__, rc); owner_sid_ptr = NULL; } } @@ -823,14 +823,14 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len, if (pntsd->gsidoffset) { rc = parse_sid(group_sid_ptr, end_of_acl); if (rc) { - ksmbd_err("%s: Error %d mapping Owner SID to gid\n", - __func__, rc); + pr_err("%s: Error %d mapping Owner SID to gid\n", + __func__, rc); return rc; } rc = sid_to_id(group_sid_ptr, SIDUNIX_GROUP, fattr); if (rc) { - ksmbd_err("%s: Error %d mapping Group SID to gid\n", - __func__, rc); + pr_err("%s: Error %d mapping Group SID to gid\n", + __func__, rc); group_sid_ptr = NULL; } } diff --git a/fs/cifsd/transport_ipc.c b/fs/cifsd/transport_ipc.c index 2bcc1cad6037..13eacfda64ac 100644 --- a/fs/cifsd/transport_ipc.c +++ b/fs/cifsd/transport_ipc.c @@ -43,11 +43,11 @@ static unsigned int ksmbd_tools_pid; static bool ksmbd_ipc_validate_version(struct genl_info *m) { if (m->genlhdr->version != KSMBD_GENL_VERSION) { - ksmbd_err("%s. ksmbd: %d, kernel module: %d. %s.\n", - "Daemon and kernel module version mismatch", - m->genlhdr->version, - KSMBD_GENL_VERSION, - "User-space ksmbd should terminate"); + pr_err("%s. ksmbd: %d, kernel module: %d. %s.\n", + "Daemon and kernel module version mismatch", + m->genlhdr->version, + KSMBD_GENL_VERSION, + "User-space ksmbd should terminate"); return false; } return true; @@ -267,8 +267,8 @@ static int handle_response(int type, void *payload, size_t sz) * request message type + 1. */ if (entry->type + 1 != type) { - ksmbd_err("Waiting for IPC type %d, got %d. Ignore.\n", - entry->type + 1, type); + pr_err("Waiting for IPC type %d, got %d. Ignore.\n", + entry->type + 1, type); } entry->response = kvmalloc(sz, GFP_KERNEL | __GFP_ZERO); @@ -313,9 +313,9 @@ static int ipc_server_config_on_startup(struct ksmbd_startup_request *req) ret |= ksmbd_tcp_set_interfaces(KSMBD_STARTUP_CONFIG_INTERFACES(req), req->ifc_list_sz); if (ret) { - ksmbd_err("Server configuration error: %s %s %s\n", - req->netbios_name, req->server_string, - req->work_group); + pr_err("Server configuration error: %s %s %s\n", + req->netbios_name, req->server_string, + req->work_group); return ret; } @@ -353,7 +353,7 @@ static int handle_startup_event(struct sk_buff *skb, struct genl_info *info) mutex_lock(&startup_lock); if (!ksmbd_server_configurable()) { mutex_unlock(&startup_lock); - ksmbd_err("Server reset is in progress, can't start daemon\n"); + pr_err("Server reset is in progress, can't start daemon\n"); return -EINVAL; } @@ -363,7 +363,7 @@ static int handle_startup_event(struct sk_buff *skb, struct genl_info *info) goto out; } - ksmbd_err("Reconnect to a new user space daemon\n"); + pr_err("Reconnect to a new user space daemon\n"); } else { struct ksmbd_startup_request *req; @@ -384,7 +384,7 @@ out: static int handle_unsupported_event(struct sk_buff *skb, struct genl_info *info) { - ksmbd_err("Unknown IPC event: %d, ignore.\n", info->genlhdr->cmd); + pr_err("Unknown IPC event: %d, ignore.\n", info->genlhdr->cmd); return -EINVAL; } @@ -827,7 +827,7 @@ static int __ipc_heartbeat(void) WRITE_ONCE(server_conf.state, SERVER_STATE_RESETTING); server_conf.ipc_last_active = 0; ksmbd_tools_pid = 0; - ksmbd_err("No IPC daemon response for %lus\n", delta / HZ); + pr_err("No IPC daemon response for %lus\n", delta / HZ); mutex_unlock(&startup_lock); return -EINVAL; } @@ -871,7 +871,7 @@ int ksmbd_ipc_init(void) ret = genl_register_family(&ksmbd_genl_family); if (ret) { - ksmbd_err("Failed to register KSMBD netlink interface %d\n", ret); + pr_err("Failed to register KSMBD netlink interface %d\n", ret); cancel_delayed_work_sync(&ipc_timer_work); } diff --git a/fs/cifsd/transport_rdma.c b/fs/cifsd/transport_rdma.c index 52237f023b66..bd7a090d5350 100644 --- a/fs/cifsd/transport_rdma.c +++ b/fs/cifsd/transport_rdma.c @@ -525,9 +525,9 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_RECV) { if (wc->status != IB_WC_WR_FLUSH_ERR) { - ksmbd_err("Recv error. status='%s (%d)' opcode=%d\n", - ib_wc_status_msg(wc->status), wc->status, - wc->opcode); + pr_err("Recv error. status='%s (%d)' opcode=%d\n", + ib_wc_status_msg(wc->status), wc->status, + wc->opcode); smb_direct_disconnect_rdma_connection(t); } put_empty_recvmsg(t, recvmsg); @@ -623,7 +623,7 @@ static int smb_direct_post_recv(struct smb_direct_transport *t, ret = ib_post_recv(t->qp, &wr, NULL); if (ret) { - ksmbd_err("Can't post recv: %d\n", ret); + pr_err("Can't post recv: %d\n", ret); ib_dma_unmap_single(t->cm_id->device, recvmsg->sge.addr, recvmsg->sge.length, DMA_FROM_DEVICE); @@ -645,7 +645,7 @@ static int smb_direct_read(struct ksmbd_transport *t, char *buf, again: if (st->status != SMB_DIRECT_CS_CONNECTED) { - ksmbd_err("disconnected\n"); + pr_err("disconnected\n"); return -ENOTCONN; } @@ -794,7 +794,7 @@ static void smb_direct_post_recv_credits(struct work_struct *work) ret = smb_direct_post_recv(t, recvmsg); if (ret) { - ksmbd_err("Can't post recv: %d\n", ret); + pr_err("Can't post recv: %d\n", ret); put_recvmsg(t, recvmsg); break; } @@ -829,9 +829,9 @@ static void send_done(struct ib_cq *cq, struct ib_wc *wc) wc->opcode); if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_SEND) { - ksmbd_err("Send error. status='%s (%d)', opcode=%d\n", - ib_wc_status_msg(wc->status), wc->status, - wc->opcode); + pr_err("Send error. status='%s (%d)', opcode=%d\n", + ib_wc_status_msg(wc->status), wc->status, + wc->opcode); smb_direct_disconnect_rdma_connection(t); } @@ -880,7 +880,7 @@ static int smb_direct_post_send(struct smb_direct_transport *t, ret = ib_post_send(t->qp, wr, NULL); if (ret) { - ksmbd_err("failed to post send: %d\n", ret); + pr_err("failed to post send: %d\n", ret); if (wr->num_sge > 1) { if (atomic_dec_and_test(&t->send_payload_pending)) wake_up(&t->wait_send_payload_pending); @@ -1158,11 +1158,11 @@ static int smb_direct_post_send_data(struct smb_direct_transport *t, sg, SMB_DIRECT_MAX_SEND_SGES - 1, DMA_TO_DEVICE); if (sg_cnt <= 0) { - ksmbd_err("failed to map buffer\n"); + pr_err("failed to map buffer\n"); ret = -ENOMEM; goto err; } else if (sg_cnt + msg->num_sge > SMB_DIRECT_MAX_SEND_SGES - 1) { - ksmbd_err("buffer not fitted into sges\n"); + pr_err("buffer not fitted into sges\n"); ret = -E2BIG; ib_dma_unmap_sg(t->cm_id->device, sg, sg_cnt, DMA_TO_DEVICE); @@ -1290,8 +1290,8 @@ static void read_write_done(struct ib_cq *cq, struct ib_wc *wc, struct smb_direct_transport *t = msg->t; if (wc->status != IB_WC_SUCCESS) { - ksmbd_err("read/write error. opcode = %d, status = %s(%d)\n", - wc->opcode, ib_wc_status_msg(wc->status), wc->status); + pr_err("read/write error. opcode = %d, status = %s(%d)\n", + wc->opcode, ib_wc_status_msg(wc->status), wc->status); smb_direct_disconnect_rdma_connection(t); } @@ -1348,7 +1348,7 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, void *buf, ret = get_sg_list(buf, buf_len, msg->sgt.sgl, msg->sgt.orig_nents); if (ret <= 0) { - ksmbd_err("failed to get pages\n"); + pr_err("failed to get pages\n"); goto err; } @@ -1357,7 +1357,7 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, void *buf, 0, remote_offset, remote_key, is_read ? DMA_FROM_DEVICE : DMA_TO_DEVICE); if (ret < 0) { - ksmbd_err("failed to init rdma_rw_ctx: %d\n", ret); + pr_err("failed to init rdma_rw_ctx: %d\n", ret); goto err; } @@ -1369,7 +1369,7 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, void *buf, ret = ib_post_send(t->qp, first_wr, NULL); if (ret) { - ksmbd_err("failed to post send wr: %d\n", ret); + pr_err("failed to post send wr: %d\n", ret); goto err; } @@ -1445,9 +1445,9 @@ static int smb_direct_cm_handler(struct rdma_cm_id *cm_id, break; } default: - ksmbd_err("Unexpected RDMA CM event. cm_id=%p, event=%s (%d)\n", - cm_id, rdma_event_msg(event->event), - event->event); + pr_err("Unexpected RDMA CM event. cm_id=%p, event=%s (%d)\n", + cm_id, rdma_event_msg(event->event), + event->event); break; } return 0; @@ -1557,7 +1557,7 @@ static int smb_direct_accept_client(struct smb_direct_transport *t) ret = rdma_accept(t->cm_id, &conn_param); if (ret) { - ksmbd_err("error at rdma_accept: %d\n", ret); + pr_err("error at rdma_accept: %d\n", ret); return ret; } @@ -1581,14 +1581,14 @@ static int smb_direct_negotiate(struct smb_direct_transport *t) ret = smb_direct_post_recv(t, recvmsg); if (ret) { - ksmbd_err("Can't post recv: %d\n", ret); + pr_err("Can't post recv: %d\n", ret); goto out; } t->negotiation_requested = false; ret = smb_direct_accept_client(t); if (ret) { - ksmbd_err("Can't accept client\n"); + pr_err("Can't accept client\n"); goto out; } @@ -1635,7 +1635,7 @@ static int smb_direct_init_params(struct smb_direct_transport *t, t->max_send_size = smb_direct_max_send_size; max_send_sges = DIV_ROUND_UP(t->max_send_size, PAGE_SIZE) + 2; if (max_send_sges > SMB_DIRECT_MAX_SEND_SGES) { - ksmbd_err("max_send_size %d is too large\n", t->max_send_size); + pr_err("max_send_size %d is too large\n", t->max_send_size); return -EINVAL; } @@ -1655,31 +1655,31 @@ static int smb_direct_init_params(struct smb_direct_transport *t, max_send_wrs = smb_direct_send_credit_target + max_rw_wrs; if (max_send_wrs > device->attrs.max_cqe || max_send_wrs > device->attrs.max_qp_wr) { - ksmbd_err("consider lowering send_credit_target = %d, or max_outstanding_rw_ops = %d\n", - smb_direct_send_credit_target, - smb_direct_max_outstanding_rw_ops); - ksmbd_err("Possible CQE overrun, device reporting max_cqe %d max_qp_wr %d\n", - device->attrs.max_cqe, device->attrs.max_qp_wr); + pr_err("consider lowering send_credit_target = %d, or max_outstanding_rw_ops = %d\n", + smb_direct_send_credit_target, + smb_direct_max_outstanding_rw_ops); + pr_err("Possible CQE overrun, device reporting max_cqe %d max_qp_wr %d\n", + device->attrs.max_cqe, device->attrs.max_qp_wr); return -EINVAL; } if (smb_direct_receive_credit_max > device->attrs.max_cqe || smb_direct_receive_credit_max > device->attrs.max_qp_wr) { - ksmbd_err("consider lowering receive_credit_max = %d\n", - smb_direct_receive_credit_max); - ksmbd_err("Possible CQE overrun, device reporting max_cpe %d max_qp_wr %d\n", - device->attrs.max_cqe, device->attrs.max_qp_wr); + pr_err("consider lowering receive_credit_max = %d\n", + smb_direct_receive_credit_max); + pr_err("Possible CQE overrun, device reporting max_cpe %d max_qp_wr %d\n", + device->attrs.max_cqe, device->attrs.max_qp_wr); return -EINVAL; } if (device->attrs.max_send_sge < SMB_DIRECT_MAX_SEND_SGES) { - ksmbd_err("warning: device max_send_sge = %d too small\n", - device->attrs.max_send_sge); + pr_err("warning: device max_send_sge = %d too small\n", + device->attrs.max_send_sge); return -EINVAL; } if (device->attrs.max_recv_sge < SMB_DIRECT_MAX_RECV_SGES) { - ksmbd_err("warning: device max_recv_sge = %d too small\n", - device->attrs.max_recv_sge); + pr_err("warning: device max_recv_sge = %d too small\n", + device->attrs.max_recv_sge); return -EINVAL; } @@ -1788,7 +1788,7 @@ static int smb_direct_create_qpair(struct smb_direct_transport *t, t->pd = ib_alloc_pd(t->cm_id->device, 0); if (IS_ERR(t->pd)) { - ksmbd_err("Can't create RDMA PD\n"); + pr_err("Can't create RDMA PD\n"); ret = PTR_ERR(t->pd); t->pd = NULL; return ret; @@ -1797,7 +1797,7 @@ static int smb_direct_create_qpair(struct smb_direct_transport *t, t->send_cq = ib_alloc_cq(t->cm_id->device, t, t->send_credit_target, 0, IB_POLL_WORKQUEUE); if (IS_ERR(t->send_cq)) { - ksmbd_err("Can't create RDMA send CQ\n"); + pr_err("Can't create RDMA send CQ\n"); ret = PTR_ERR(t->send_cq); t->send_cq = NULL; goto err; @@ -1807,7 +1807,7 @@ static int smb_direct_create_qpair(struct smb_direct_transport *t, cap->max_send_wr + cap->max_rdma_ctxs, 0, IB_POLL_WORKQUEUE); if (IS_ERR(t->recv_cq)) { - ksmbd_err("Can't create RDMA recv CQ\n"); + pr_err("Can't create RDMA recv CQ\n"); ret = PTR_ERR(t->recv_cq); t->recv_cq = NULL; goto err; @@ -1825,7 +1825,7 @@ static int smb_direct_create_qpair(struct smb_direct_transport *t, ret = rdma_create_qp(t->cm_id, t->pd, &qp_attr); if (ret) { - ksmbd_err("Can't create RDMA QP: %d\n", ret); + pr_err("Can't create RDMA QP: %d\n", ret); goto err; } @@ -1861,25 +1861,25 @@ static int smb_direct_prepare(struct ksmbd_transport *t) ret = smb_direct_init_params(st, &qp_cap); if (ret) { - ksmbd_err("Can't configure RDMA parameters\n"); + pr_err("Can't configure RDMA parameters\n"); return ret; } ret = smb_direct_create_pools(st); if (ret) { - ksmbd_err("Can't init RDMA pool: %d\n", ret); + pr_err("Can't init RDMA pool: %d\n", ret); return ret; } ret = smb_direct_create_qpair(st, &qp_cap); if (ret) { - ksmbd_err("Can't accept RDMA client: %d\n", ret); + pr_err("Can't accept RDMA client: %d\n", ret); return ret; } ret = smb_direct_negotiate(st); if (ret) { - ksmbd_err("Can't negotiate: %d\n", ret); + pr_err("Can't negotiate: %d\n", ret); return ret; } @@ -1917,7 +1917,7 @@ static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id) if (IS_ERR(KSMBD_TRANS(t)->handler)) { int ret = PTR_ERR(KSMBD_TRANS(t)->handler); - ksmbd_err("Can't start thread\n"); + pr_err("Can't start thread\n"); free_transport(t); return ret; } @@ -1933,7 +1933,7 @@ static int smb_direct_listen_handler(struct rdma_cm_id *cm_id, int ret = smb_direct_handle_connect_request(cm_id); if (ret) { - ksmbd_err("Can't create transport: %d\n", ret); + pr_err("Can't create transport: %d\n", ret); return ret; } @@ -1942,8 +1942,8 @@ static int smb_direct_listen_handler(struct rdma_cm_id *cm_id, break; } default: - ksmbd_err("Unexpected listen event. cm_id=%p, event=%s (%d)\n", - cm_id, rdma_event_msg(event->event), event->event); + pr_err("Unexpected listen event. cm_id=%p, event=%s (%d)\n", + cm_id, rdma_event_msg(event->event), event->event); break; } return 0; @@ -1962,13 +1962,13 @@ static int smb_direct_listen(int port) cm_id = rdma_create_id(&init_net, smb_direct_listen_handler, &smb_direct_listener, RDMA_PS_TCP, IB_QPT_RC); if (IS_ERR(cm_id)) { - ksmbd_err("Can't create cm id: %ld\n", PTR_ERR(cm_id)); + pr_err("Can't create cm id: %ld\n", PTR_ERR(cm_id)); return PTR_ERR(cm_id); } ret = rdma_bind_addr(cm_id, (struct sockaddr *)&sin); if (ret) { - ksmbd_err("Can't bind: %d\n", ret); + pr_err("Can't bind: %d\n", ret); goto err; } @@ -1976,7 +1976,7 @@ static int smb_direct_listen(int port) ret = rdma_listen(cm_id, 10); if (ret) { - ksmbd_err("Can't listen: %d\n", ret); + pr_err("Can't listen: %d\n", ret); goto err; } return 0; @@ -2006,7 +2006,7 @@ int ksmbd_rdma_init(void) if (ret) { destroy_workqueue(smb_direct_wq); smb_direct_wq = NULL; - ksmbd_err("Can't listen: %d\n", ret); + pr_err("Can't listen: %d\n", ret); return ret; } diff --git a/fs/cifsd/transport_tcp.c b/fs/cifsd/transport_tcp.c index 16702b7874f4..56ec11ff5a9f 100644 --- a/fs/cifsd/transport_tcp.c +++ b/fs/cifsd/transport_tcp.c @@ -190,7 +190,7 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk) csin = KSMBD_TCP_PEER_SOCKADDR(KSMBD_TRANS(t)->conn); if (kernel_getpeername(client_sk, csin) < 0) { - ksmbd_err("client ip resolution failed\n"); + pr_err("client ip resolution failed\n"); rc = -EINVAL; goto out_error; } @@ -200,7 +200,7 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk) "ksmbd:%u", ksmbd_tcp_get_port(csin)); if (IS_ERR(KSMBD_TRANS(t)->handler)) { - ksmbd_err("cannot start conn thread\n"); + pr_err("cannot start conn thread\n"); rc = PTR_ERR(KSMBD_TRANS(t)->handler); free_transport(t); } @@ -380,7 +380,7 @@ static void tcp_destroy_socket(struct socket *ksmbd_socket) ret = kernel_sock_shutdown(ksmbd_socket, SHUT_RDWR); if (ret) - ksmbd_err("Failed to shutdown socket: %d\n", ret); + pr_err("Failed to shutdown socket: %d\n", ret); else sock_release(ksmbd_socket); } @@ -400,11 +400,11 @@ static int create_socket(struct interface *iface) ret = sock_create(PF_INET6, SOCK_STREAM, IPPROTO_TCP, &ksmbd_socket); if (ret) { - ksmbd_err("Can't create socket for ipv6, try ipv4: %d\n", ret); + pr_err("Can't create socket for ipv6, try ipv4: %d\n", ret); ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &ksmbd_socket); if (ret) { - ksmbd_err("Can't create socket for ipv4: %d\n", ret); + pr_err("Can't create socket for ipv4: %d\n", ret); goto out_error; } @@ -427,7 +427,7 @@ static int create_socket(struct interface *iface) KERNEL_SOCKPTR(iface->name), strlen(iface->name)); if (ret != -ENODEV && ret < 0) { - ksmbd_err("Failed to set SO_BINDTODEVICE: %d\n", ret); + pr_err("Failed to set SO_BINDTODEVICE: %d\n", ret); goto out_error; } @@ -438,7 +438,7 @@ static int create_socket(struct interface *iface) ret = kernel_bind(ksmbd_socket, (struct sockaddr *)&sin6, sizeof(sin6)); if (ret) { - ksmbd_err("Failed to bind socket: %d\n", ret); + pr_err("Failed to bind socket: %d\n", ret); goto out_error; } @@ -447,14 +447,14 @@ static int create_socket(struct interface *iface) ret = kernel_listen(ksmbd_socket, KSMBD_SOCKET_BACKLOG); if (ret) { - ksmbd_err("Port listen() error: %d\n", ret); + pr_err("Port listen() error: %d\n", ret); goto out_error; } iface->ksmbd_socket = ksmbd_socket; ret = ksmbd_tcp_run_kthread(iface); if (ret) { - ksmbd_err("Can't start ksmbd main kthread: %d\n", ret); + pr_err("Can't start ksmbd main kthread: %d\n", ret); goto out_error; } iface->state = IFACE_STATE_CONFIGURED; @@ -540,7 +540,7 @@ static void tcp_stop_kthread(struct task_struct *kthread) ret = kthread_stop(kthread); if (ret) - ksmbd_err("failed to stop forker thread\n"); + pr_err("failed to stop forker thread\n"); } void ksmbd_tcp_destroy(void) diff --git a/fs/cifsd/vfs.c b/fs/cifsd/vfs.c index ef74e56cd05f..ad08bad8df4e 100644 --- a/fs/cifsd/vfs.c +++ b/fs/cifsd/vfs.c @@ -45,7 +45,7 @@ static char *extract_last_component(char *path) p++; } else { p = NULL; - ksmbd_err("Invalid path %s\n", path); + pr_err("Invalid path %s\n", path); } return p; } @@ -170,8 +170,8 @@ int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode) if (IS_ERR(dentry)) { err = PTR_ERR(dentry); if (err != -ENOENT) - ksmbd_err("path create failed for %s, err %d\n", - name, err); + pr_err("path create failed for %s, err %d\n", + name, err); return err; } @@ -181,7 +181,7 @@ int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode) ksmbd_vfs_inherit_owner(work, d_inode(path.dentry), d_inode(dentry)); } else { - ksmbd_err("File(%s): creation failed (err:%d)\n", name, err); + pr_err("File(%s): creation failed (err:%d)\n", name, err); } done_path_create(&path, dentry); return err; @@ -235,7 +235,7 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode) out: done_path_create(&path, dentry); if (err) - ksmbd_err("mkdir(%s): creation failed (err:%d)\n", name, err); + pr_err("mkdir(%s): creation failed (err:%d)\n", name, err); return err; } @@ -259,7 +259,7 @@ static ssize_t ksmbd_vfs_getcasexattr(struct dentry *dentry, char *attr_name, name, attr_value); if (value_len < 0) - ksmbd_err("failed to get xattr in file\n"); + pr_err("failed to get xattr in file\n"); break; } @@ -324,7 +324,7 @@ static int check_lock_range(struct file *filp, loff_t start, loff_t end, if (flock->fl_end >= start && end >= flock->fl_start) { if (flock->fl_type == F_RDLCK) { if (type == WRITE) { - ksmbd_err("not allow write by shared lock\n"); + pr_err("not allow write by shared lock\n"); error = 1; goto out; } @@ -332,7 +332,7 @@ static int check_lock_range(struct file *filp, loff_t start, loff_t end, /* check owner in lock */ if (flock->fl_file != filp) { error = 1; - ksmbd_err("not allow rw access by exclusive lock from other opens\n"); + pr_err("not allow rw access by exclusive lock from other opens\n"); goto out; } } @@ -368,7 +368,7 @@ int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count, if (work->conn->connection_type) { if (!(fp->daccess & (FILE_READ_DATA_LE | FILE_EXECUTE_LE))) { - ksmbd_err("no right to read(%s)\n", FP_FILENAME(fp)); + pr_err("no right to read(%s)\n", FP_FILENAME(fp)); return -EACCES; } } @@ -381,15 +381,15 @@ int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count, ret = check_lock_range(filp, *pos, *pos + count - 1, READ); if (ret) { - ksmbd_err("unable to read due to lock\n"); + pr_err("unable to read due to lock\n"); return -EAGAIN; } } nbytes = kernel_read(filp, rbuf, count, pos); if (nbytes < 0) { - ksmbd_err("smb read failed for (%s), err = %zd\n", - fp->filename, nbytes); + pr_err("smb read failed for (%s), err = %zd\n", + fp->filename, nbytes); return nbytes; } @@ -418,7 +418,7 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos, fp->stream.size, &stream_buf); if ((int)v_len < 0) { - ksmbd_err("not found stream in xattr : %zd\n", v_len); + pr_err("not found stream in xattr : %zd\n", v_len); err = (int)v_len; goto out; } @@ -476,7 +476,7 @@ int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp, if (sess->conn->connection_type) { if (!(fp->daccess & FILE_WRITE_DATA_LE)) { - ksmbd_err("no right to write(%s)\n", FP_FILENAME(fp)); + pr_err("no right to write(%s)\n", FP_FILENAME(fp)); err = -EACCES; goto out; } @@ -494,7 +494,7 @@ int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp, if (!work->tcon->posix_extensions) { err = check_lock_range(filp, *pos, *pos + count - 1, WRITE); if (err) { - ksmbd_err("unable to write due to lock\n"); + pr_err("unable to write due to lock\n"); err = -EAGAIN; goto out; } @@ -515,8 +515,8 @@ int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp, if (sync) { err = vfs_fsync_range(filp, offset, offset + *written, 0); if (err < 0) - ksmbd_err("fsync failed for filename = %s, err = %d\n", - FP_FILENAME(fp), err); + pr_err("fsync failed for filename = %s, err = %d\n", + FP_FILENAME(fp), err); } out: @@ -537,7 +537,7 @@ int ksmbd_vfs_getattr(struct path *path, struct kstat *stat) err = vfs_getattr(path, stat, STATX_BTIME, AT_STATX_SYNC_AS_STAT); if (err) - ksmbd_err("getattr failed, err %d\n", err); + pr_err("getattr failed, err %d\n", err); return err; } @@ -555,12 +555,12 @@ int ksmbd_vfs_fsync(struct ksmbd_work *work, u64 fid, u64 p_id) fp = ksmbd_lookup_fd_slow(work, fid, p_id); if (!fp) { - ksmbd_err("failed to get filp for fid %llu\n", fid); + pr_err("failed to get filp for fid %llu\n", fid); return -ENOENT; } err = vfs_fsync(fp->filp, 0); if (err < 0) - ksmbd_err("smb fsync failed, err = %d\n", err); + pr_err("smb fsync failed, err = %d\n", err); ksmbd_fd_put(work, fp); return err; } @@ -654,8 +654,8 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname, err = kern_path(oldname, flags, &oldpath); if (err) { - ksmbd_err("cannot get linux path for %s, err = %d\n", - oldname, err); + pr_err("cannot get linux path for %s, err = %d\n", + oldname, err); goto out1; } @@ -663,13 +663,13 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname, flags | LOOKUP_REVAL); if (IS_ERR(dentry)) { err = PTR_ERR(dentry); - ksmbd_err("path create err for %s, err %d\n", newname, err); + pr_err("path create err for %s, err %d\n", newname, err); goto out2; } err = -EXDEV; if (oldpath.mnt != newpath.mnt) { - ksmbd_err("vfs_link failed err %d\n", err); + pr_err("vfs_link failed err %d\n", err); goto out3; } @@ -730,7 +730,7 @@ static int __ksmbd_vfs_rename(struct ksmbd_work *work, dst_dent = lookup_one_len(dst_name, dst_dent_parent, strlen(dst_name)); err = PTR_ERR(dst_dent); if (IS_ERR(dst_dent)) { - ksmbd_err("lookup failed %s [%d]\n", dst_name, err); + pr_err("lookup failed %s [%d]\n", dst_name, err); goto out; } @@ -747,7 +747,7 @@ static int __ksmbd_vfs_rename(struct ksmbd_work *work, err = vfs_rename(&rd); } if (err) - ksmbd_err("vfs_rename failed err %d\n", err); + pr_err("vfs_rename failed err %d\n", err); if (dst_dent) dput(dst_dent); out: @@ -835,14 +835,14 @@ int ksmbd_vfs_truncate(struct ksmbd_work *work, const char *name, if (name) { err = kern_path(name, 0, &path); if (err) { - ksmbd_err("cannot get linux path for %s, err %d\n", - name, err); + pr_err("cannot get linux path for %s, err %d\n", + name, err); return err; } err = vfs_truncate(&path, size); if (err) - ksmbd_err("truncate failed for %s err %d\n", - name, err); + pr_err("truncate failed for %s err %d\n", + name, err); path_put(&path); } else { struct file *filp; @@ -864,15 +864,15 @@ int ksmbd_vfs_truncate(struct ksmbd_work *work, const char *name, } if (err) { - ksmbd_err("failed due to lock\n"); + pr_err("failed due to lock\n"); return -EAGAIN; } } err = vfs_truncate(&filp->f_path, size); if (err) - ksmbd_err("truncate failed for filename : %s err %d\n", - fp->filename, err); + pr_err("truncate failed for filename : %s err %d\n", + fp->filename, err); } return err; @@ -1458,7 +1458,7 @@ static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct inode *inode, xa_entry->type = SMB_ACL_MASK; break; default: - ksmbd_err("unknown type : 0x%x\n", pa_entry->e_tag); + pr_err("unknown type : 0x%x\n", pa_entry->e_tag); goto out; } @@ -1502,7 +1502,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, rc = ksmbd_gen_sd_hash(conn, acl.sd_buf, acl.sd_size, acl.hash); if (rc) { - ksmbd_err("failed to generate hash for ndr acl\n"); + pr_err("failed to generate hash for ndr acl\n"); return rc; } @@ -1513,27 +1513,27 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, rc = ndr_encode_posix_acl(&acl_ndr, inode, smb_acl, def_smb_acl); if (rc) { - ksmbd_err("failed to encode ndr to posix acl\n"); + pr_err("failed to encode ndr to posix acl\n"); goto out; } rc = ksmbd_gen_sd_hash(conn, acl_ndr.data, acl_ndr.offset, acl.posix_acl_hash); if (rc) { - ksmbd_err("failed to generate hash for ndr acl\n"); + pr_err("failed to generate hash for ndr acl\n"); goto out; } rc = ndr_encode_v4_ntacl(&sd_ndr, &acl); if (rc) { - ksmbd_err("failed to encode ndr to posix acl\n"); + pr_err("failed to encode ndr to posix acl\n"); goto out; } rc = ksmbd_vfs_setxattr(dentry, XATTR_NAME_SD, sd_ndr.data, sd_ndr.offset, 0); if (rc < 0) - ksmbd_err("Failed to store XATTR ntacl :%d\n", rc); + pr_err("Failed to store XATTR ntacl :%d\n", rc); kfree(sd_ndr.data); out: @@ -1570,19 +1570,19 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, rc = ndr_encode_posix_acl(&acl_ndr, inode, smb_acl, def_smb_acl); if (rc) { - ksmbd_err("failed to encode ndr to posix acl\n"); + pr_err("failed to encode ndr to posix acl\n"); goto out; } rc = ksmbd_gen_sd_hash(conn, acl_ndr.data, acl_ndr.offset, cmp_hash); if (rc) { - ksmbd_err("failed to generate hash for ndr acl\n"); + pr_err("failed to generate hash for ndr acl\n"); goto out; } if (memcmp(cmp_hash, acl.posix_acl_hash, XATTR_SD_HASH_SIZE)) { - ksmbd_err("hash value diff\n"); + pr_err("hash value diff\n"); rc = -EINVAL; goto out; } @@ -1821,11 +1821,11 @@ int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work, *total_size_written = 0; if (!(src_fp->daccess & (FILE_READ_DATA_LE | FILE_EXECUTE_LE))) { - ksmbd_err("no right to read(%s)\n", FP_FILENAME(src_fp)); + pr_err("no right to read(%s)\n", FP_FILENAME(src_fp)); return -EACCES; } if (!(dst_fp->daccess & (FILE_WRITE_DATA_LE | FILE_APPEND_DATA_LE))) { - ksmbd_err("no right to write(%s)\n", FP_FILENAME(dst_fp)); + pr_err("no right to write(%s)\n", FP_FILENAME(dst_fp)); return -EACCES; } diff --git a/fs/cifsd/vfs_cache.c b/fs/cifsd/vfs_cache.c index 4cf14c247e9e..c88210b15289 100644 --- a/fs/cifsd/vfs_cache.c +++ b/fs/cifsd/vfs_cache.c @@ -185,7 +185,7 @@ static struct ksmbd_inode *ksmbd_inode_get(struct ksmbd_file *fp) rc = ksmbd_inode_init(ci, fp); if (rc) { - ksmbd_err("inode initialized failed\n"); + pr_err("inode initialized failed\n"); kfree(ci); return NULL; } @@ -254,8 +254,8 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp) err = ksmbd_vfs_remove_xattr(filp->f_path.dentry, fp->stream.name); if (err) - ksmbd_err("remove xattr failed : %s\n", - fp->stream.name); + pr_err("remove xattr failed : %s\n", + fp->stream.name); } if (atomic_dec_and_test(&ci->m_count)) { @@ -542,7 +542,7 @@ struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp) fp = kmem_cache_zalloc(filp_cache, GFP_KERNEL); if (!fp) { - ksmbd_err("Failed to allocate memory\n"); + pr_err("Failed to allocate memory\n"); return ERR_PTR(-ENOMEM); } @@ -698,7 +698,7 @@ int ksmbd_init_file_cache(void) return 0; out: - ksmbd_err("failed to allocate file cache\n"); + pr_err("failed to allocate file cache\n"); return -ENOMEM; } From e8c061917133dd77410239bfc0fae151b1955af2 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Tue, 22 Jun 2021 11:06:11 +0900 Subject: [PATCH 13/45] ksmbd: opencode to avoid trivial wrappers Opencode to avoid trivial wrappers that just make the code hard to follow. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/cifsd/smb2pdu.c | 19 ++++++++++++------- fs/cifsd/vfs.c | 30 ++---------------------------- fs/cifsd/vfs.h | 4 ---- 3 files changed, 14 insertions(+), 39 deletions(-) diff --git a/fs/cifsd/smb2pdu.c b/fs/cifsd/smb2pdu.c index 84f4cd7f545f..96a0cb512882 100644 --- a/fs/cifsd/smb2pdu.c +++ b/fs/cifsd/smb2pdu.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "glob.h" #include "smb2pdu.h" @@ -2948,10 +2949,12 @@ int smb2_open(struct ksmbd_work *work) ksmbd_debug(SMB, "request smb2 create allocate size : %llu\n", alloc_size); - err = ksmbd_vfs_alloc_size(work, fp, alloc_size); + smb_break_all_levII_oplock(work, fp, 1); + err = vfs_fallocate(fp->filp, FALLOC_FL_KEEP_SIZE, 0, + alloc_size); if (err < 0) ksmbd_debug(SMB, - "ksmbd_vfs_alloc_size is failed : %d\n", + "vfs_fallocate is failed : %d\n", err); } @@ -3762,7 +3765,7 @@ int smb2_query_dir(struct ksmbd_work *work) dir_fp->readdir_data.private = &query_dir_private; set_ctx_actor(&dir_fp->readdir_data.ctx, __query_dir); - rc = ksmbd_vfs_readdir(dir_fp->filp, &dir_fp->readdir_data); + rc = iterate_dir(dir_fp->filp, &dir_fp->readdir_data.ctx); if (rc == 0) restart_ctx(&dir_fp->readdir_data.ctx); if (rc == -ENOSPC) @@ -5465,9 +5468,11 @@ static int set_file_allocation_info(struct ksmbd_work *work, inode = file_inode(fp->filp); if (alloc_blks > inode->i_blocks) { - rc = ksmbd_vfs_alloc_size(work, fp, alloc_blks * 512); + smb_break_all_levII_oplock(work, fp, 1); + rc = vfs_fallocate(fp->filp, FALLOC_FL_KEEP_SIZE, 0, + alloc_blks * 512); if (rc && rc != -EOPNOTSUPP) { - pr_err("ksmbd_vfs_alloc_size is failed : %d\n", rc); + pr_err("vfs_fallocate is failed : %d\n", rc); return rc; } } else if (alloc_blks < inode->i_blocks) { @@ -6672,7 +6677,7 @@ no_check_gl: flock = smb_lock->fl; list_del(&smb_lock->llist); retry: - err = ksmbd_vfs_lock(filp, smb_lock->cmd, flock); + err = vfs_lock_file(filp, smb_lock->cmd, flock, NULL); skip: if (flags & SMB2_LOCKFLAG_UNLOCK) { if (!err) { @@ -6785,7 +6790,7 @@ out: rlock->fl_start = smb_lock->start; rlock->fl_end = smb_lock->end; - err = ksmbd_vfs_lock(filp, 0, rlock); + err = vfs_lock_file(filp, 0, rlock, NULL); if (err) pr_err("rollback unlock fail : %d\n", err); list_del(&smb_lock->llist); diff --git a/fs/cifsd/vfs.c b/fs/cifsd/vfs.c index ad08bad8df4e..1ba3fd95ba6b 100644 --- a/fs/cifsd/vfs.c +++ b/fs/cifsd/vfs.c @@ -1000,32 +1000,6 @@ void ksmbd_vfs_set_fadvise(struct file *filp, __le32 option) } } -/** - * ksmbd_vfs_lock() - vfs helper for smb file locking - * @filp: the file to apply the lock to - * @cmd: type of locking operation (F_SETLK, F_GETLK, etc.) - * @flock: The lock to be applied - * - * Return: 0 on success, otherwise error - */ -int ksmbd_vfs_lock(struct file *filp, int cmd, struct file_lock *flock) -{ - ksmbd_debug(VFS, "calling vfs_lock_file\n"); - return vfs_lock_file(filp, cmd, flock, NULL); -} - -int ksmbd_vfs_readdir(struct file *file, struct ksmbd_readdir_data *rdata) -{ - return iterate_dir(file, &rdata->ctx); -} - -int ksmbd_vfs_alloc_size(struct ksmbd_work *work, struct ksmbd_file *fp, - loff_t len) -{ - smb_break_all_levII_oplock(work, fp, 1); - return vfs_fallocate(fp->filp, FALLOC_FL_KEEP_SIZE, 0, len); -} - int ksmbd_vfs_zero_data(struct ksmbd_work *work, struct ksmbd_file *fp, loff_t off, loff_t len) { @@ -1216,7 +1190,7 @@ int ksmbd_vfs_empty_dir(struct ksmbd_file *fp) set_ctx_actor(&readdir_data.ctx, __dir_empty); readdir_data.dirent_count = 0; - err = ksmbd_vfs_readdir(fp->filp, &readdir_data); + err = iterate_dir(fp->filp, &readdir_data.ctx); if (readdir_data.dirent_count > 2) err = -ENOTEMPTY; else @@ -1266,7 +1240,7 @@ static int ksmbd_vfs_lookup_in_dir(struct path *dir, char *name, size_t namelen) if (IS_ERR(dfilp)) return PTR_ERR(dfilp); - ret = ksmbd_vfs_readdir(dfilp, &readdir_data); + ret = iterate_dir(dfilp, &readdir_data.ctx); if (readdir_data.dirent_count > 0) ret = 0; fput(dfilp); diff --git a/fs/cifsd/vfs.h b/fs/cifsd/vfs.h index 03b877e6520b..e1021f579f37 100644 --- a/fs/cifsd/vfs.h +++ b/fs/cifsd/vfs.h @@ -232,10 +232,6 @@ int ksmbd_vfs_kern_path(char *name, unsigned int flags, struct path *path, bool caseless); int ksmbd_vfs_empty_dir(struct ksmbd_file *fp); 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_readdir(struct file *file, struct ksmbd_readdir_data *rdata); -int ksmbd_vfs_alloc_size(struct ksmbd_work *work, struct ksmbd_file *fp, - loff_t len); int ksmbd_vfs_zero_data(struct ksmbd_work *work, struct ksmbd_file *fp, loff_t off, loff_t len); struct file_allocated_range_buffer; From 4b637fc18902600dfe722f9b1a45950bfc8bc7b5 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Fri, 18 Jun 2021 10:20:24 +0900 Subject: [PATCH 14/45] ksmbd: factor out a ksmbd_validate_entry_in_use helper from __ksmbd_vfs_rename Factor out a self-contained helper to find sub file/dir in use. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/cifsd/vfs.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/fs/cifsd/vfs.c b/fs/cifsd/vfs.c index 1ba3fd95ba6b..ca4c6c020a8e 100644 --- a/fs/cifsd/vfs.c +++ b/fs/cifsd/vfs.c @@ -687,6 +687,29 @@ out1: return err; } +static int ksmbd_validate_entry_in_use(struct dentry *src_dent) +{ + struct dentry *dst_dent; + + spin_lock(&src_dent->d_lock); + list_for_each_entry(dst_dent, &src_dent->d_subdirs, d_child) { + struct ksmbd_file *child_fp; + + if (d_really_is_negative(dst_dent)) + continue; + + child_fp = ksmbd_lookup_fd_inode(d_inode(dst_dent)); + if (child_fp) { + spin_unlock(&src_dent->d_lock); + ksmbd_debug(VFS, "Forbid rename, sub file/dir is in use\n"); + return -EACCES; + } + } + spin_unlock(&src_dent->d_lock); + + return 0; +} + static int __ksmbd_vfs_rename(struct ksmbd_work *work, struct dentry *src_dent_parent, struct dentry *src_dent, @@ -698,21 +721,9 @@ static int __ksmbd_vfs_rename(struct ksmbd_work *work, int err; if (!work->tcon->posix_extensions) { - spin_lock(&src_dent->d_lock); - list_for_each_entry(dst_dent, &src_dent->d_subdirs, d_child) { - struct ksmbd_file *child_fp; - - if (d_really_is_negative(dst_dent)) - continue; - - child_fp = ksmbd_lookup_fd_inode(d_inode(dst_dent)); - if (child_fp) { - spin_unlock(&src_dent->d_lock); - ksmbd_debug(VFS, "Forbid rename, sub file/dir is in use\n"); - return -EACCES; - } - } - spin_unlock(&src_dent->d_lock); + err = ksmbd_validate_entry_in_use(src_dent); + if (err) + return err; } if (d_really_is_negative(src_dent_parent)) From 67d1c432994cbf30f63ec35abba493b027f0c910 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Tue, 22 Jun 2021 11:42:29 +0900 Subject: [PATCH 15/45] ksmbd: opencode posix acl functions instead of wrappers Add select FS_POSIX_ACL in Kconfig and then opencode posix acl functions instead of wrappers Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/cifsd/Kconfig | 1 + fs/cifsd/smb2pdu.c | 4 ++-- fs/cifsd/smbacl.c | 14 +++++++------- fs/cifsd/vfs.c | 44 +++++++++----------------------------------- fs/cifsd/vfs.h | 4 ---- 5 files changed, 19 insertions(+), 48 deletions(-) diff --git a/fs/cifsd/Kconfig b/fs/cifsd/Kconfig index e6448b04f46e..796f928a7da0 100644 --- a/fs/cifsd/Kconfig +++ b/fs/cifsd/Kconfig @@ -19,6 +19,7 @@ config SMB_SERVER select CRYPTO_GCM select ASN1 select OID_REGISTRY + select FS_POSIX_ACL default n help Choose Y here if you want to allow SMB3 compliant clients diff --git a/fs/cifsd/smb2pdu.c b/fs/cifsd/smb2pdu.c index 96a0cb512882..0d004c6d1c63 100644 --- a/fs/cifsd/smb2pdu.c +++ b/fs/cifsd/smb2pdu.c @@ -2327,9 +2327,9 @@ static void ksmbd_acls_fattr(struct smb_fattr *fattr, struct inode *inode) fattr->cf_mode = inode->i_mode; fattr->cf_dacls = NULL; - fattr->cf_acls = ksmbd_vfs_get_acl(inode, ACL_TYPE_ACCESS); + fattr->cf_acls = get_acl(inode, ACL_TYPE_ACCESS); if (S_ISDIR(inode->i_mode)) - fattr->cf_dacls = ksmbd_vfs_get_acl(inode, ACL_TYPE_DEFAULT); + fattr->cf_dacls = get_acl(inode, ACL_TYPE_DEFAULT); } /** diff --git a/fs/cifsd/smbacl.c b/fs/cifsd/smbacl.c index 23c952612db4..958937a548a1 100644 --- a/fs/cifsd/smbacl.c +++ b/fs/cifsd/smbacl.c @@ -532,7 +532,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, if (acl_state.users->n || acl_state.groups->n) { acl_state.mask.allow = 0x07; - fattr->cf_acls = ksmbd_vfs_posix_acl_alloc(acl_state.users->n + + fattr->cf_acls = posix_acl_alloc(acl_state.users->n + acl_state.groups->n + 4, GFP_KERNEL); if (fattr->cf_acls) { cf_pace = fattr->cf_acls->a_entries; @@ -543,7 +543,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, if (default_acl_state.users->n || default_acl_state.groups->n) { default_acl_state.mask.allow = 0x07; fattr->cf_dacls = - ksmbd_vfs_posix_acl_alloc(default_acl_state.users->n + + posix_acl_alloc(default_acl_state.users->n + default_acl_state.groups->n + 4, GFP_KERNEL); if (fattr->cf_dacls) { cf_pdace = fattr->cf_dacls->a_entries; @@ -1202,7 +1202,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry, granted = GENERIC_ALL_FLAGS; } - posix_acls = ksmbd_vfs_get_acl(d_inode(dentry), ACL_TYPE_ACCESS); + posix_acls = get_acl(d_inode(dentry), ACL_TYPE_ACCESS); if (posix_acls && !found) { unsigned int id = -1; @@ -1287,11 +1287,11 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, ksmbd_vfs_remove_acl_xattrs(dentry); /* Update posix acls */ if (fattr.cf_dacls) { - rc = ksmbd_vfs_set_posix_acl(inode, ACL_TYPE_ACCESS, - fattr.cf_acls); + rc = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS, + fattr.cf_acls); if (S_ISDIR(inode->i_mode) && fattr.cf_dacls) - rc = ksmbd_vfs_set_posix_acl(inode, ACL_TYPE_DEFAULT, - fattr.cf_dacls); + rc = set_posix_acl(&init_user_ns, inode, + ACL_TYPE_DEFAULT, fattr.cf_dacls); } /* Check it only calling from SD BUFFER context */ diff --git a/fs/cifsd/vfs.c b/fs/cifsd/vfs.c index ca4c6c020a8e..e34e536dc9ce 100644 --- a/fs/cifsd/vfs.c +++ b/fs/cifsd/vfs.c @@ -1407,7 +1407,7 @@ static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct inode *inode, struct xattr_acl_entry *xa_entry; int i; - posix_acls = ksmbd_vfs_get_acl(inode, acl_type); + posix_acls = get_acl(inode, acl_type); if (!posix_acls) return NULL; @@ -1630,34 +1630,6 @@ int ksmbd_vfs_get_dos_attrib_xattr(struct dentry *dentry, return err; } -struct posix_acl *ksmbd_vfs_posix_acl_alloc(int count, gfp_t flags) -{ -#if IS_ENABLED(CONFIG_FS_POSIX_ACL) - return posix_acl_alloc(count, flags); -#else - return NULL; -#endif -} - -struct posix_acl *ksmbd_vfs_get_acl(struct inode *inode, int type) -{ -#if IS_ENABLED(CONFIG_FS_POSIX_ACL) - return get_acl(inode, type); -#else - return NULL; -#endif -} - -int ksmbd_vfs_set_posix_acl(struct inode *inode, int type, - struct posix_acl *acl) -{ -#if IS_ENABLED(CONFIG_FS_POSIX_ACL) - return set_posix_acl(&init_user_ns, inode, type, acl); -#else - return -EOPNOTSUPP; -#endif -} - /** * ksmbd_vfs_init_kstat() - convert unix stat information to smb stat format * @p: destination buffer @@ -1895,19 +1867,20 @@ int ksmbd_vfs_set_init_posix_acl(struct inode *inode) acl_state.group.allow; acl_state.mask.allow = 0x07; - acls = ksmbd_vfs_posix_acl_alloc(6, GFP_KERNEL); + acls = posix_acl_alloc(6, GFP_KERNEL); if (!acls) { free_acl_state(&acl_state); return -ENOMEM; } posix_state_to_acl(&acl_state, acls->a_entries); - rc = ksmbd_vfs_set_posix_acl(inode, ACL_TYPE_ACCESS, acls); + rc = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS, acls); if (rc < 0) ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n", rc); else if (S_ISDIR(inode->i_mode)) { posix_state_to_acl(&acl_state, acls->a_entries); - rc = ksmbd_vfs_set_posix_acl(inode, ACL_TYPE_DEFAULT, acls); + rc = set_posix_acl(&init_user_ns, inode, ACL_TYPE_DEFAULT, + acls); if (rc < 0) ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n", rc); @@ -1923,7 +1896,7 @@ int ksmbd_vfs_inherit_posix_acl(struct inode *inode, struct inode *parent_inode) struct posix_acl_entry *pace; int rc, i; - acls = ksmbd_vfs_get_acl(parent_inode, ACL_TYPE_DEFAULT); + acls = get_acl(parent_inode, ACL_TYPE_DEFAULT); if (!acls) return -ENOENT; pace = acls->a_entries; @@ -1935,12 +1908,13 @@ int ksmbd_vfs_inherit_posix_acl(struct inode *inode, struct inode *parent_inode) } } - rc = ksmbd_vfs_set_posix_acl(inode, ACL_TYPE_ACCESS, acls); + rc = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS, acls); if (rc < 0) ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n", rc); if (S_ISDIR(inode->i_mode)) { - rc = ksmbd_vfs_set_posix_acl(inode, ACL_TYPE_DEFAULT, acls); + rc = set_posix_acl(&init_user_ns, inode, ACL_TYPE_DEFAULT, + acls); if (rc < 0) ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n", rc); diff --git a/fs/cifsd/vfs.h b/fs/cifsd/vfs.h index e1021f579f37..29352c227028 100644 --- a/fs/cifsd/vfs.h +++ b/fs/cifsd/vfs.h @@ -258,10 +258,6 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct dentry *dentry, struct xattr_dos_attrib *da); int ksmbd_vfs_get_dos_attrib_xattr(struct dentry *dentry, struct xattr_dos_attrib *da); -struct posix_acl *ksmbd_vfs_posix_acl_alloc(int count, gfp_t flags); -struct posix_acl *ksmbd_vfs_get_acl(struct inode *inode, int type); -int ksmbd_vfs_set_posix_acl(struct inode *inode, int type, - struct posix_acl *acl); int ksmbd_vfs_set_init_posix_acl(struct inode *inode); int ksmbd_vfs_inherit_posix_acl(struct inode *inode, struct inode *parent_inode); From ee2033e9c64139c4f052bed52e72eba44a08b40a Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Tue, 22 Jun 2021 13:26:24 +0900 Subject: [PATCH 16/45] ksmbd: change stream type macro to enumeration Change stream type macro to enumeration and move it to vfs.h. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/cifsd/glob.h | 3 --- fs/cifsd/vfs.h | 8 ++++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/cifsd/glob.h b/fs/cifsd/glob.h index 8119cb7ddbed..49a5a3afa118 100644 --- a/fs/cifsd/glob.h +++ b/fs/cifsd/glob.h @@ -16,9 +16,6 @@ extern int ksmbd_debug_types; -#define DATA_STREAM 1 -#define DIR_STREAM 2 - #define KSMBD_DEBUG_SMB BIT(0) #define KSMBD_DEBUG_AUTH BIT(1) #define KSMBD_DEBUG_VFS BIT(2) diff --git a/fs/cifsd/vfs.h b/fs/cifsd/vfs.h index 29352c227028..a9c14c5dee8d 100644 --- a/fs/cifsd/vfs.h +++ b/fs/cifsd/vfs.h @@ -101,6 +101,14 @@ struct xattr_ntacl { #define XATTR_NAME_SD_LEN \ (sizeof(XATTR_SECURITY_PREFIX SD_PREFIX) - 1) +/* + * Enumeration for stream type. + */ +enum { + DATA_STREAM = 1, /* type $DATA */ + DIR_STREAM /* type $INDEX_ALLOCATION */ +}; + /* CreateOptions */ /* Flag is set, it must not be a file , valid for directory only */ #define FILE_DIRECTORY_FILE_LE cpu_to_le32(0x00000001) From ee81cae1a6323fa4489313dfd9de436da7ff8519 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Sat, 26 Jun 2021 22:32:34 +0900 Subject: [PATCH 17/45] ksmbd: use f_bsize instead of q->limits.logical_block_size Use f_bsize instead of q->limits.logical_block_size. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/cifsd/smb2pdu.c | 25 +++++++------------------ fs/cifsd/vfs.c | 23 ----------------------- fs/cifsd/vfs.h | 1 - 3 files changed, 7 insertions(+), 42 deletions(-) diff --git a/fs/cifsd/smb2pdu.c b/fs/cifsd/smb2pdu.c index 0d004c6d1c63..341d51e711a5 100644 --- a/fs/cifsd/smb2pdu.c +++ b/fs/cifsd/smb2pdu.c @@ -4739,16 +4739,12 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, case FS_SIZE_INFORMATION: { struct filesystem_info *info; - unsigned short logical_sector_size; info = (struct filesystem_info *)(rsp->Buffer); - logical_sector_size = - ksmbd_vfs_logical_sector_size(d_inode(path.dentry)); - info->TotalAllocationUnits = cpu_to_le64(stfs.f_blocks); info->FreeAllocationUnits = cpu_to_le64(stfs.f_bfree); - info->SectorsPerAllocationUnit = cpu_to_le32(stfs.f_bsize >> 9); - info->BytesPerSector = cpu_to_le32(logical_sector_size); + info->SectorsPerAllocationUnit = cpu_to_le32(1); + info->BytesPerSector = cpu_to_le32(stfs.f_bsize); rsp->OutputBufferLength = cpu_to_le32(24); inc_rfc1001_len(rsp_org, 24); fs_infoclass_size = FS_SIZE_INFORMATION_SIZE; @@ -4757,19 +4753,15 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, case FS_FULL_SIZE_INFORMATION: { struct smb2_fs_full_size_info *info; - unsigned short logical_sector_size; info = (struct smb2_fs_full_size_info *)(rsp->Buffer); - logical_sector_size = - ksmbd_vfs_logical_sector_size(d_inode(path.dentry)); - info->TotalAllocationUnits = cpu_to_le64(stfs.f_blocks); info->CallerAvailableAllocationUnits = cpu_to_le64(stfs.f_bavail); info->ActualAvailableAllocationUnits = cpu_to_le64(stfs.f_bfree); - info->SectorsPerAllocationUnit = cpu_to_le32(stfs.f_bsize >> 9); - info->BytesPerSector = cpu_to_le32(logical_sector_size); + info->SectorsPerAllocationUnit = cpu_to_le32(1); + info->BytesPerSector = cpu_to_le32(stfs.f_bsize); rsp->OutputBufferLength = cpu_to_le32(32); inc_rfc1001_len(rsp_org, 32); fs_infoclass_size = FS_FULL_SIZE_INFORMATION_SIZE; @@ -4846,16 +4838,13 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, case FS_POSIX_INFORMATION: { struct filesystem_posix_info *info; - unsigned short logical_sector_size; if (!work->tcon->posix_extensions) { pr_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n"); rc = -EOPNOTSUPP; } else { info = (struct filesystem_posix_info *)(rsp->Buffer); - logical_sector_size = - ksmbd_vfs_logical_sector_size(d_inode(path.dentry)); - info->OptimalTransferSize = cpu_to_le32(logical_sector_size); + info->OptimalTransferSize = cpu_to_le32(stfs.f_bsize); info->BlockSize = cpu_to_le32(stfs.f_bsize); info->TotalBlocks = cpu_to_le64(stfs.f_blocks); info->BlocksAvail = cpu_to_le64(stfs.f_bfree); @@ -5588,13 +5577,13 @@ static int set_file_position_info(struct ksmbd_file *fp, char *buf) { struct smb2_file_pos_info *file_info; loff_t current_byte_offset; - unsigned short sector_size; + unsigned long sector_size; struct inode *inode; inode = file_inode(fp->filp); file_info = (struct smb2_file_pos_info *)buf; current_byte_offset = le64_to_cpu(file_info->CurrentByteOffset); - sector_size = ksmbd_vfs_logical_sector_size(inode); + sector_size = inode->i_sb->s_blocksize; if (current_byte_offset < 0 || (fp->coption == FILE_NO_INTERMEDIATE_BUFFERING_LE && diff --git a/fs/cifsd/vfs.c b/fs/cifsd/vfs.c index e34e536dc9ce..9c594e88b2c7 100644 --- a/fs/cifsd/vfs.c +++ b/fs/cifsd/vfs.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -1119,28 +1118,6 @@ out: return err; } -/* - * ksmbd_vfs_get_logical_sector_size() - get logical sector size from inode - * @inode: inode - * - * Return: logical sector size - */ -unsigned short ksmbd_vfs_logical_sector_size(struct inode *inode) -{ - struct request_queue *q; - unsigned short ret_val = 512; - - if (!inode->i_sb->s_bdev) - return ret_val; - - q = inode->i_sb->s_bdev->bd_disk->queue; - - if (q && q->limits.logical_block_size) - ret_val = q->limits.logical_block_size; - - return ret_val; -} - /* * ksmbd_vfs_get_smb2_sector_size() - get fs sector sizes * @inode: inode diff --git a/fs/cifsd/vfs.h b/fs/cifsd/vfs.h index a9c14c5dee8d..751bb6ea6e12 100644 --- a/fs/cifsd/vfs.h +++ b/fs/cifsd/vfs.h @@ -247,7 +247,6 @@ int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length, struct file_allocated_range_buffer *ranges, int in_count, int *out_count); int ksmbd_vfs_unlink(struct dentry *dir, struct dentry *dentry); -unsigned short ksmbd_vfs_logical_sector_size(struct inode *inode); void ksmbd_vfs_smb2_sector_size(struct inode *inode, struct ksmbd_fs_sector_size *fs_ss); void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat); From 560ac05130696de2491881bbc2a5024c94bc3912 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Tue, 22 Jun 2021 16:16:45 +0900 Subject: [PATCH 18/45] ksmbd: remove unneeded NULL check in the list iterator Remove unneeded NULL check in the list iterator. And use list_for_each_entry_safe instead of list_for_each_safe. Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/cifsd/mgmt/user_session.c | 13 +++++-------- fs/cifsd/smb2pdu.c | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/fs/cifsd/mgmt/user_session.c b/fs/cifsd/mgmt/user_session.c index 615b46f0762b..c5ba9694e1f1 100644 --- a/fs/cifsd/mgmt/user_session.c +++ b/fs/cifsd/mgmt/user_session.c @@ -30,15 +30,12 @@ struct ksmbd_session_rpc { static void free_channel_list(struct ksmbd_session *sess) { - struct channel *chann; - struct list_head *tmp, *t; + struct channel *chann, *tmp; - list_for_each_safe(tmp, t, &sess->ksmbd_chann_list) { - chann = list_entry(tmp, struct channel, chann_list); - if (chann) { - list_del(&chann->chann_list); - kfree(chann); - } + list_for_each_entry_safe(chann, tmp, &sess->ksmbd_chann_list, + chann_list) { + list_del(&chann->chann_list); + kfree(chann); } } diff --git a/fs/cifsd/smb2pdu.c b/fs/cifsd/smb2pdu.c index 341d51e711a5..bbb35e68abc4 100644 --- a/fs/cifsd/smb2pdu.c +++ b/fs/cifsd/smb2pdu.c @@ -76,7 +76,7 @@ struct channel *lookup_chann_list(struct ksmbd_session *sess, struct ksmbd_conn struct channel *chann; list_for_each_entry(chann, &sess->ksmbd_chann_list, chann_list) { - if (chann && chann->conn == conn) + if (chann->conn == conn) return chann; } From 131bac1ece2e16201674b2f29b64d2044c826b56 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Tue, 22 Jun 2021 16:20:47 +0900 Subject: [PATCH 19/45] ksmbd: use f_bsize in FS_SECTOR_SIZE_INFORMATION Use f_bsize in FS_SECTOR_SIZE_INFORMATION to avoid the access the block layer. Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/cifsd/smb2pdu.c | 12 ++++-------- fs/cifsd/vfs.c | 31 ------------------------------- fs/cifsd/vfs.h | 8 -------- 3 files changed, 4 insertions(+), 47 deletions(-) diff --git a/fs/cifsd/smb2pdu.c b/fs/cifsd/smb2pdu.c index bbb35e68abc4..1327ae806b17 100644 --- a/fs/cifsd/smb2pdu.c +++ b/fs/cifsd/smb2pdu.c @@ -4791,19 +4791,15 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work, case FS_SECTOR_SIZE_INFORMATION: { struct smb3_fs_ss_info *info; - struct ksmbd_fs_sector_size fs_ss; info = (struct smb3_fs_ss_info *)(rsp->Buffer); - ksmbd_vfs_smb2_sector_size(d_inode(path.dentry), &fs_ss); - info->LogicalBytesPerSector = - cpu_to_le32(fs_ss.logical_sector_size); + info->LogicalBytesPerSector = cpu_to_le32(stfs.f_bsize); info->PhysicalBytesPerSectorForAtomicity = - cpu_to_le32(fs_ss.physical_sector_size); - info->PhysicalBytesPerSectorForPerf = - cpu_to_le32(fs_ss.optimal_io_size); + cpu_to_le32(stfs.f_bsize); + info->PhysicalBytesPerSectorForPerf = cpu_to_le32(stfs.f_bsize); info->FSEffPhysicalBytesPerSectorForAtomicity = - cpu_to_le32(fs_ss.optimal_io_size); + cpu_to_le32(stfs.f_bsize); info->Flags = cpu_to_le32(SSINFO_FLAGS_ALIGNED_DEVICE | SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE); info->ByteOffsetForSectorAlignment = 0; diff --git a/fs/cifsd/vfs.c b/fs/cifsd/vfs.c index 9c594e88b2c7..fddabb4c7db6 100644 --- a/fs/cifsd/vfs.c +++ b/fs/cifsd/vfs.c @@ -1118,37 +1118,6 @@ out: return err; } -/* - * ksmbd_vfs_get_smb2_sector_size() - get fs sector sizes - * @inode: inode - * @fs_ss: fs sector size struct - */ -void ksmbd_vfs_smb2_sector_size(struct inode *inode, - struct ksmbd_fs_sector_size *fs_ss) -{ - struct request_queue *q; - - fs_ss->logical_sector_size = 512; - fs_ss->physical_sector_size = 512; - fs_ss->optimal_io_size = 512; - - if (!inode->i_sb->s_bdev) - return; - - q = inode->i_sb->s_bdev->bd_disk->queue; - - if (q) { - if (q->limits.logical_block_size) - fs_ss->logical_sector_size = - q->limits.logical_block_size; - if (q->limits.physical_block_size) - fs_ss->physical_sector_size = - q->limits.physical_block_size; - if (q->limits.io_opt) - fs_ss->optimal_io_size = q->limits.io_opt; - } -} - static int __dir_empty(struct dir_context *ctx, const char *name, int namlen, loff_t offset, u64 ino, unsigned int d_type) { diff --git a/fs/cifsd/vfs.h b/fs/cifsd/vfs.h index 751bb6ea6e12..49f0558ace32 100644 --- a/fs/cifsd/vfs.h +++ b/fs/cifsd/vfs.h @@ -192,12 +192,6 @@ struct ksmbd_kstat { __le32 file_attributes; }; -struct ksmbd_fs_sector_size { - unsigned short logical_sector_size; - unsigned int physical_sector_size; - unsigned int optimal_io_size; -}; - int ksmbd_vfs_inode_permission(struct dentry *dentry, int acc_mode, bool delete); int ksmbd_vfs_query_maximal_access(struct dentry *dentry, __le32 *daccess); @@ -247,8 +241,6 @@ int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length, struct file_allocated_range_buffer *ranges, int in_count, int *out_count); int ksmbd_vfs_unlink(struct dentry *dir, struct dentry *dentry); -void ksmbd_vfs_smb2_sector_size(struct inode *inode, - struct ksmbd_fs_sector_size *fs_ss); 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, struct ksmbd_kstat *ksmbd_kstat); From 1a93084b9a89818aec0ac7b59a5a51f2112bf203 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Thu, 24 Jun 2021 10:34:11 +0900 Subject: [PATCH 20/45] ksmbd: move fs/cifsd to fs/ksmbd Move fs/cifsd to fs/ksmbd and rename the remaining cifsd name to ksmbd. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- Documentation/filesystems/cifs/index.rst | 2 +- .../filesystems/cifs/{cifsd.rst => ksmbd.rst} | 10 +++++----- fs/Kconfig | 2 +- fs/Makefile | 2 +- fs/{cifsd => ksmbd}/Kconfig | 14 +++++++------- fs/{cifsd => ksmbd}/Makefile | 0 fs/{cifsd => ksmbd}/asn1.c | 0 fs/{cifsd => ksmbd}/asn1.h | 0 fs/{cifsd => ksmbd}/auth.c | 0 fs/{cifsd => ksmbd}/auth.h | 0 fs/{cifsd => ksmbd}/connection.c | 0 fs/{cifsd => ksmbd}/connection.h | 0 fs/{cifsd => ksmbd}/crypto_ctx.c | 0 fs/{cifsd => ksmbd}/crypto_ctx.h | 0 fs/{cifsd => ksmbd}/glob.h | 0 fs/{cifsd => ksmbd}/ksmbd_server.h | 0 fs/{cifsd => ksmbd}/ksmbd_spnego_negtokeninit.asn1 | 0 fs/{cifsd => ksmbd}/ksmbd_spnego_negtokentarg.asn1 | 0 fs/{cifsd => ksmbd}/ksmbd_work.c | 0 fs/{cifsd => ksmbd}/ksmbd_work.h | 0 fs/{cifsd => ksmbd}/mgmt/ksmbd_ida.c | 0 fs/{cifsd => ksmbd}/mgmt/ksmbd_ida.h | 0 fs/{cifsd => ksmbd}/mgmt/share_config.c | 0 fs/{cifsd => ksmbd}/mgmt/share_config.h | 0 fs/{cifsd => ksmbd}/mgmt/tree_connect.c | 0 fs/{cifsd => ksmbd}/mgmt/tree_connect.h | 0 fs/{cifsd => ksmbd}/mgmt/user_config.c | 0 fs/{cifsd => ksmbd}/mgmt/user_config.h | 0 fs/{cifsd => ksmbd}/mgmt/user_session.c | 0 fs/{cifsd => ksmbd}/mgmt/user_session.h | 0 fs/{cifsd => ksmbd}/misc.c | 0 fs/{cifsd => ksmbd}/misc.h | 0 fs/{cifsd => ksmbd}/ndr.c | 0 fs/{cifsd => ksmbd}/ndr.h | 0 fs/{cifsd => ksmbd}/nterr.h | 0 fs/{cifsd => ksmbd}/ntlmssp.h | 0 fs/{cifsd => ksmbd}/oplock.c | 0 fs/{cifsd => ksmbd}/oplock.h | 0 fs/{cifsd => ksmbd}/server.c | 0 fs/{cifsd => ksmbd}/server.h | 0 fs/{cifsd => ksmbd}/smb2misc.c | 0 fs/{cifsd => ksmbd}/smb2ops.c | 0 fs/{cifsd => ksmbd}/smb2pdu.c | 0 fs/{cifsd => ksmbd}/smb2pdu.h | 0 fs/{cifsd => ksmbd}/smb_common.c | 0 fs/{cifsd => ksmbd}/smb_common.h | 0 fs/{cifsd => ksmbd}/smbacl.c | 0 fs/{cifsd => ksmbd}/smbacl.h | 0 fs/{cifsd => ksmbd}/smbfsctl.h | 0 fs/{cifsd => ksmbd}/smbstatus.h | 0 fs/{cifsd => ksmbd}/transport_ipc.c | 0 fs/{cifsd => ksmbd}/transport_ipc.h | 0 fs/{cifsd => ksmbd}/transport_rdma.c | 0 fs/{cifsd => ksmbd}/transport_rdma.h | 0 fs/{cifsd => ksmbd}/transport_tcp.c | 0 fs/{cifsd => ksmbd}/transport_tcp.h | 0 fs/{cifsd => ksmbd}/unicode.c | 0 fs/{cifsd => ksmbd}/unicode.h | 0 fs/{cifsd => ksmbd}/uniupr.h | 0 fs/{cifsd => ksmbd}/vfs.c | 0 fs/{cifsd => ksmbd}/vfs.h | 0 fs/{cifsd => ksmbd}/vfs_cache.c | 0 fs/{cifsd => ksmbd}/vfs_cache.h | 0 63 files changed, 15 insertions(+), 15 deletions(-) rename Documentation/filesystems/cifs/{cifsd.rst => ksmbd.rst} (98%) rename fs/{cifsd => ksmbd}/Kconfig (81%) rename fs/{cifsd => ksmbd}/Makefile (100%) rename fs/{cifsd => ksmbd}/asn1.c (100%) rename fs/{cifsd => ksmbd}/asn1.h (100%) rename fs/{cifsd => ksmbd}/auth.c (100%) rename fs/{cifsd => ksmbd}/auth.h (100%) rename fs/{cifsd => ksmbd}/connection.c (100%) rename fs/{cifsd => ksmbd}/connection.h (100%) rename fs/{cifsd => ksmbd}/crypto_ctx.c (100%) rename fs/{cifsd => ksmbd}/crypto_ctx.h (100%) rename fs/{cifsd => ksmbd}/glob.h (100%) rename fs/{cifsd => ksmbd}/ksmbd_server.h (100%) rename fs/{cifsd => ksmbd}/ksmbd_spnego_negtokeninit.asn1 (100%) rename fs/{cifsd => ksmbd}/ksmbd_spnego_negtokentarg.asn1 (100%) rename fs/{cifsd => ksmbd}/ksmbd_work.c (100%) rename fs/{cifsd => ksmbd}/ksmbd_work.h (100%) rename fs/{cifsd => ksmbd}/mgmt/ksmbd_ida.c (100%) rename fs/{cifsd => ksmbd}/mgmt/ksmbd_ida.h (100%) rename fs/{cifsd => ksmbd}/mgmt/share_config.c (100%) rename fs/{cifsd => ksmbd}/mgmt/share_config.h (100%) rename fs/{cifsd => ksmbd}/mgmt/tree_connect.c (100%) rename fs/{cifsd => ksmbd}/mgmt/tree_connect.h (100%) rename fs/{cifsd => ksmbd}/mgmt/user_config.c (100%) rename fs/{cifsd => ksmbd}/mgmt/user_config.h (100%) rename fs/{cifsd => ksmbd}/mgmt/user_session.c (100%) rename fs/{cifsd => ksmbd}/mgmt/user_session.h (100%) rename fs/{cifsd => ksmbd}/misc.c (100%) rename fs/{cifsd => ksmbd}/misc.h (100%) rename fs/{cifsd => ksmbd}/ndr.c (100%) rename fs/{cifsd => ksmbd}/ndr.h (100%) rename fs/{cifsd => ksmbd}/nterr.h (100%) rename fs/{cifsd => ksmbd}/ntlmssp.h (100%) rename fs/{cifsd => ksmbd}/oplock.c (100%) rename fs/{cifsd => ksmbd}/oplock.h (100%) rename fs/{cifsd => ksmbd}/server.c (100%) rename fs/{cifsd => ksmbd}/server.h (100%) rename fs/{cifsd => ksmbd}/smb2misc.c (100%) rename fs/{cifsd => ksmbd}/smb2ops.c (100%) rename fs/{cifsd => ksmbd}/smb2pdu.c (100%) rename fs/{cifsd => ksmbd}/smb2pdu.h (100%) rename fs/{cifsd => ksmbd}/smb_common.c (100%) rename fs/{cifsd => ksmbd}/smb_common.h (100%) rename fs/{cifsd => ksmbd}/smbacl.c (100%) rename fs/{cifsd => ksmbd}/smbacl.h (100%) rename fs/{cifsd => ksmbd}/smbfsctl.h (100%) rename fs/{cifsd => ksmbd}/smbstatus.h (100%) rename fs/{cifsd => ksmbd}/transport_ipc.c (100%) rename fs/{cifsd => ksmbd}/transport_ipc.h (100%) rename fs/{cifsd => ksmbd}/transport_rdma.c (100%) rename fs/{cifsd => ksmbd}/transport_rdma.h (100%) rename fs/{cifsd => ksmbd}/transport_tcp.c (100%) rename fs/{cifsd => ksmbd}/transport_tcp.h (100%) rename fs/{cifsd => ksmbd}/unicode.c (100%) rename fs/{cifsd => ksmbd}/unicode.h (100%) rename fs/{cifsd => ksmbd}/uniupr.h (100%) rename fs/{cifsd => ksmbd}/vfs.c (100%) rename fs/{cifsd => ksmbd}/vfs.h (100%) rename fs/{cifsd => ksmbd}/vfs_cache.c (100%) rename fs/{cifsd => ksmbd}/vfs_cache.h (100%) diff --git a/Documentation/filesystems/cifs/index.rst b/Documentation/filesystems/cifs/index.rst index e762586b5dc7..1c8597a679ab 100644 --- a/Documentation/filesystems/cifs/index.rst +++ b/Documentation/filesystems/cifs/index.rst @@ -6,5 +6,5 @@ CIFS .. toctree:: :maxdepth: 1 - cifsd + ksmbd cifsroot diff --git a/Documentation/filesystems/cifs/cifsd.rst b/Documentation/filesystems/cifs/ksmbd.rst similarity index 98% rename from Documentation/filesystems/cifs/cifsd.rst rename to Documentation/filesystems/cifs/ksmbd.rst index 01a0be272ce6..1e111efecd45 100644 --- a/Documentation/filesystems/cifs/cifsd.rst +++ b/Documentation/filesystems/cifs/ksmbd.rst @@ -1,13 +1,13 @@ .. SPDX-License-Identifier: GPL-2.0 ========================== -CIFSD - SMB3 Kernel Server +KSMBD - SMB3 Kernel Server ========================== -CIFSD is a linux kernel server which implements SMB3 protocol in kernel space +KSMBD is a linux kernel server which implements SMB3 protocol in kernel space for sharing files over network. -CIFSD architecture +KSMBD architecture ================== The subset of performance related operations belong in kernelspace and @@ -60,7 +60,7 @@ NetServerGetInfo. Complete DCE/RPC response is prepared from the user space and passed over to the associated kernel thread for the client. -CIFSD Feature Status +KSMBD Feature Status ==================== ============================== ================================================= @@ -138,7 +138,7 @@ How to run 6. Access share from Windows or Linux using CIFS -Shutdown CIFSD +Shutdown KSMBD ============== 1. kill user and kernel space daemon diff --git a/fs/Kconfig b/fs/Kconfig index 7462761ebd2f..720c38f484c6 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -344,7 +344,7 @@ config NFS_V4_2_SSC_HELPER source "net/sunrpc/Kconfig" source "fs/ceph/Kconfig" source "fs/cifs/Kconfig" -source "fs/cifsd/Kconfig" +source "fs/ksmbd/Kconfig" source "fs/coda/Kconfig" source "fs/afs/Kconfig" source "fs/9p/Kconfig" diff --git a/fs/Makefile b/fs/Makefile index 542a77374d12..e03a048b2cd8 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -98,7 +98,7 @@ obj-$(CONFIG_NLS) += nls/ obj-$(CONFIG_UNICODE) += unicode/ obj-$(CONFIG_SYSV_FS) += sysv/ obj-$(CONFIG_CIFS) += cifs/ -obj-$(CONFIG_SMB_SERVER) += cifsd/ +obj-$(CONFIG_SMB_SERVER) += ksmbd/ obj-$(CONFIG_HPFS_FS) += hpfs/ obj-$(CONFIG_NTFS_FS) += ntfs/ obj-$(CONFIG_UFS_FS) += ufs/ diff --git a/fs/cifsd/Kconfig b/fs/ksmbd/Kconfig similarity index 81% rename from fs/cifsd/Kconfig rename to fs/ksmbd/Kconfig index 796f928a7da0..e9a5ac01b6e0 100644 --- a/fs/cifsd/Kconfig +++ b/fs/ksmbd/Kconfig @@ -1,5 +1,5 @@ config SMB_SERVER - tristate "SMB server support (EXPERIMENTAL)" + tristate "SMB3 server support (EXPERIMENTAL)" depends on INET depends on MULTIUSER depends on FILE_LOCKING @@ -31,13 +31,13 @@ config SMB_SERVER case you can choose N here. You also need to install user space programs which can be found - in cifsd-tools, available from - https://github.com/cifsd-team/cifsd-tools. - More detail about how to run the cifsd kernel server is + in ksmbd-tools, available from + https://github.com/cifsd-team/ksmbd-tools. + More detail about how to run the ksmbd kernel server is available via README file - (https://github.com/cifsd-team/cifsd-tools/blob/master/README). + (https://github.com/cifsd-team/ksmbd-tools/blob/master/README). - cifsd kernel server includes support for auto-negotiation, + ksmbd kernel server includes support for auto-negotiation, Secure negotiate, Pre-authentication integrity, oplock/lease, compound requests, multi-credit, packet signing, RDMA(smbdirect), smb3 encryption, copy-offload, secure per-user session @@ -61,7 +61,7 @@ config SMB_SERVER_CHECK_CAP_NET_ADMIN default y help - Prevent unprivileged processes to start the cifsd kernel server. + Prevent unprivileged processes to start the ksmbd kernel server. config SMB_SERVER_KERBEROS5 bool "Support for Kerberos 5" diff --git a/fs/cifsd/Makefile b/fs/ksmbd/Makefile similarity index 100% rename from fs/cifsd/Makefile rename to fs/ksmbd/Makefile diff --git a/fs/cifsd/asn1.c b/fs/ksmbd/asn1.c similarity index 100% rename from fs/cifsd/asn1.c rename to fs/ksmbd/asn1.c diff --git a/fs/cifsd/asn1.h b/fs/ksmbd/asn1.h similarity index 100% rename from fs/cifsd/asn1.h rename to fs/ksmbd/asn1.h diff --git a/fs/cifsd/auth.c b/fs/ksmbd/auth.c similarity index 100% rename from fs/cifsd/auth.c rename to fs/ksmbd/auth.c diff --git a/fs/cifsd/auth.h b/fs/ksmbd/auth.h similarity index 100% rename from fs/cifsd/auth.h rename to fs/ksmbd/auth.h diff --git a/fs/cifsd/connection.c b/fs/ksmbd/connection.c similarity index 100% rename from fs/cifsd/connection.c rename to fs/ksmbd/connection.c diff --git a/fs/cifsd/connection.h b/fs/ksmbd/connection.h similarity index 100% rename from fs/cifsd/connection.h rename to fs/ksmbd/connection.h diff --git a/fs/cifsd/crypto_ctx.c b/fs/ksmbd/crypto_ctx.c similarity index 100% rename from fs/cifsd/crypto_ctx.c rename to fs/ksmbd/crypto_ctx.c diff --git a/fs/cifsd/crypto_ctx.h b/fs/ksmbd/crypto_ctx.h similarity index 100% rename from fs/cifsd/crypto_ctx.h rename to fs/ksmbd/crypto_ctx.h diff --git a/fs/cifsd/glob.h b/fs/ksmbd/glob.h similarity index 100% rename from fs/cifsd/glob.h rename to fs/ksmbd/glob.h diff --git a/fs/cifsd/ksmbd_server.h b/fs/ksmbd/ksmbd_server.h similarity index 100% rename from fs/cifsd/ksmbd_server.h rename to fs/ksmbd/ksmbd_server.h diff --git a/fs/cifsd/ksmbd_spnego_negtokeninit.asn1 b/fs/ksmbd/ksmbd_spnego_negtokeninit.asn1 similarity index 100% rename from fs/cifsd/ksmbd_spnego_negtokeninit.asn1 rename to fs/ksmbd/ksmbd_spnego_negtokeninit.asn1 diff --git a/fs/cifsd/ksmbd_spnego_negtokentarg.asn1 b/fs/ksmbd/ksmbd_spnego_negtokentarg.asn1 similarity index 100% rename from fs/cifsd/ksmbd_spnego_negtokentarg.asn1 rename to fs/ksmbd/ksmbd_spnego_negtokentarg.asn1 diff --git a/fs/cifsd/ksmbd_work.c b/fs/ksmbd/ksmbd_work.c similarity index 100% rename from fs/cifsd/ksmbd_work.c rename to fs/ksmbd/ksmbd_work.c diff --git a/fs/cifsd/ksmbd_work.h b/fs/ksmbd/ksmbd_work.h similarity index 100% rename from fs/cifsd/ksmbd_work.h rename to fs/ksmbd/ksmbd_work.h diff --git a/fs/cifsd/mgmt/ksmbd_ida.c b/fs/ksmbd/mgmt/ksmbd_ida.c similarity index 100% rename from fs/cifsd/mgmt/ksmbd_ida.c rename to fs/ksmbd/mgmt/ksmbd_ida.c diff --git a/fs/cifsd/mgmt/ksmbd_ida.h b/fs/ksmbd/mgmt/ksmbd_ida.h similarity index 100% rename from fs/cifsd/mgmt/ksmbd_ida.h rename to fs/ksmbd/mgmt/ksmbd_ida.h diff --git a/fs/cifsd/mgmt/share_config.c b/fs/ksmbd/mgmt/share_config.c similarity index 100% rename from fs/cifsd/mgmt/share_config.c rename to fs/ksmbd/mgmt/share_config.c diff --git a/fs/cifsd/mgmt/share_config.h b/fs/ksmbd/mgmt/share_config.h similarity index 100% rename from fs/cifsd/mgmt/share_config.h rename to fs/ksmbd/mgmt/share_config.h diff --git a/fs/cifsd/mgmt/tree_connect.c b/fs/ksmbd/mgmt/tree_connect.c similarity index 100% rename from fs/cifsd/mgmt/tree_connect.c rename to fs/ksmbd/mgmt/tree_connect.c diff --git a/fs/cifsd/mgmt/tree_connect.h b/fs/ksmbd/mgmt/tree_connect.h similarity index 100% rename from fs/cifsd/mgmt/tree_connect.h rename to fs/ksmbd/mgmt/tree_connect.h diff --git a/fs/cifsd/mgmt/user_config.c b/fs/ksmbd/mgmt/user_config.c similarity index 100% rename from fs/cifsd/mgmt/user_config.c rename to fs/ksmbd/mgmt/user_config.c diff --git a/fs/cifsd/mgmt/user_config.h b/fs/ksmbd/mgmt/user_config.h similarity index 100% rename from fs/cifsd/mgmt/user_config.h rename to fs/ksmbd/mgmt/user_config.h diff --git a/fs/cifsd/mgmt/user_session.c b/fs/ksmbd/mgmt/user_session.c similarity index 100% rename from fs/cifsd/mgmt/user_session.c rename to fs/ksmbd/mgmt/user_session.c diff --git a/fs/cifsd/mgmt/user_session.h b/fs/ksmbd/mgmt/user_session.h similarity index 100% rename from fs/cifsd/mgmt/user_session.h rename to fs/ksmbd/mgmt/user_session.h diff --git a/fs/cifsd/misc.c b/fs/ksmbd/misc.c similarity index 100% rename from fs/cifsd/misc.c rename to fs/ksmbd/misc.c diff --git a/fs/cifsd/misc.h b/fs/ksmbd/misc.h similarity index 100% rename from fs/cifsd/misc.h rename to fs/ksmbd/misc.h diff --git a/fs/cifsd/ndr.c b/fs/ksmbd/ndr.c similarity index 100% rename from fs/cifsd/ndr.c rename to fs/ksmbd/ndr.c diff --git a/fs/cifsd/ndr.h b/fs/ksmbd/ndr.h similarity index 100% rename from fs/cifsd/ndr.h rename to fs/ksmbd/ndr.h diff --git a/fs/cifsd/nterr.h b/fs/ksmbd/nterr.h similarity index 100% rename from fs/cifsd/nterr.h rename to fs/ksmbd/nterr.h diff --git a/fs/cifsd/ntlmssp.h b/fs/ksmbd/ntlmssp.h similarity index 100% rename from fs/cifsd/ntlmssp.h rename to fs/ksmbd/ntlmssp.h diff --git a/fs/cifsd/oplock.c b/fs/ksmbd/oplock.c similarity index 100% rename from fs/cifsd/oplock.c rename to fs/ksmbd/oplock.c diff --git a/fs/cifsd/oplock.h b/fs/ksmbd/oplock.h similarity index 100% rename from fs/cifsd/oplock.h rename to fs/ksmbd/oplock.h diff --git a/fs/cifsd/server.c b/fs/ksmbd/server.c similarity index 100% rename from fs/cifsd/server.c rename to fs/ksmbd/server.c diff --git a/fs/cifsd/server.h b/fs/ksmbd/server.h similarity index 100% rename from fs/cifsd/server.h rename to fs/ksmbd/server.h diff --git a/fs/cifsd/smb2misc.c b/fs/ksmbd/smb2misc.c similarity index 100% rename from fs/cifsd/smb2misc.c rename to fs/ksmbd/smb2misc.c diff --git a/fs/cifsd/smb2ops.c b/fs/ksmbd/smb2ops.c similarity index 100% rename from fs/cifsd/smb2ops.c rename to fs/ksmbd/smb2ops.c diff --git a/fs/cifsd/smb2pdu.c b/fs/ksmbd/smb2pdu.c similarity index 100% rename from fs/cifsd/smb2pdu.c rename to fs/ksmbd/smb2pdu.c diff --git a/fs/cifsd/smb2pdu.h b/fs/ksmbd/smb2pdu.h similarity index 100% rename from fs/cifsd/smb2pdu.h rename to fs/ksmbd/smb2pdu.h diff --git a/fs/cifsd/smb_common.c b/fs/ksmbd/smb_common.c similarity index 100% rename from fs/cifsd/smb_common.c rename to fs/ksmbd/smb_common.c diff --git a/fs/cifsd/smb_common.h b/fs/ksmbd/smb_common.h similarity index 100% rename from fs/cifsd/smb_common.h rename to fs/ksmbd/smb_common.h diff --git a/fs/cifsd/smbacl.c b/fs/ksmbd/smbacl.c similarity index 100% rename from fs/cifsd/smbacl.c rename to fs/ksmbd/smbacl.c diff --git a/fs/cifsd/smbacl.h b/fs/ksmbd/smbacl.h similarity index 100% rename from fs/cifsd/smbacl.h rename to fs/ksmbd/smbacl.h diff --git a/fs/cifsd/smbfsctl.h b/fs/ksmbd/smbfsctl.h similarity index 100% rename from fs/cifsd/smbfsctl.h rename to fs/ksmbd/smbfsctl.h diff --git a/fs/cifsd/smbstatus.h b/fs/ksmbd/smbstatus.h similarity index 100% rename from fs/cifsd/smbstatus.h rename to fs/ksmbd/smbstatus.h diff --git a/fs/cifsd/transport_ipc.c b/fs/ksmbd/transport_ipc.c similarity index 100% rename from fs/cifsd/transport_ipc.c rename to fs/ksmbd/transport_ipc.c diff --git a/fs/cifsd/transport_ipc.h b/fs/ksmbd/transport_ipc.h similarity index 100% rename from fs/cifsd/transport_ipc.h rename to fs/ksmbd/transport_ipc.h diff --git a/fs/cifsd/transport_rdma.c b/fs/ksmbd/transport_rdma.c similarity index 100% rename from fs/cifsd/transport_rdma.c rename to fs/ksmbd/transport_rdma.c diff --git a/fs/cifsd/transport_rdma.h b/fs/ksmbd/transport_rdma.h similarity index 100% rename from fs/cifsd/transport_rdma.h rename to fs/ksmbd/transport_rdma.h diff --git a/fs/cifsd/transport_tcp.c b/fs/ksmbd/transport_tcp.c similarity index 100% rename from fs/cifsd/transport_tcp.c rename to fs/ksmbd/transport_tcp.c diff --git a/fs/cifsd/transport_tcp.h b/fs/ksmbd/transport_tcp.h similarity index 100% rename from fs/cifsd/transport_tcp.h rename to fs/ksmbd/transport_tcp.h diff --git a/fs/cifsd/unicode.c b/fs/ksmbd/unicode.c similarity index 100% rename from fs/cifsd/unicode.c rename to fs/ksmbd/unicode.c diff --git a/fs/cifsd/unicode.h b/fs/ksmbd/unicode.h similarity index 100% rename from fs/cifsd/unicode.h rename to fs/ksmbd/unicode.h diff --git a/fs/cifsd/uniupr.h b/fs/ksmbd/uniupr.h similarity index 100% rename from fs/cifsd/uniupr.h rename to fs/ksmbd/uniupr.h diff --git a/fs/cifsd/vfs.c b/fs/ksmbd/vfs.c similarity index 100% rename from fs/cifsd/vfs.c rename to fs/ksmbd/vfs.c diff --git a/fs/cifsd/vfs.h b/fs/ksmbd/vfs.h similarity index 100% rename from fs/cifsd/vfs.h rename to fs/ksmbd/vfs.h diff --git a/fs/cifsd/vfs_cache.c b/fs/ksmbd/vfs_cache.c similarity index 100% rename from fs/cifsd/vfs_cache.c rename to fs/ksmbd/vfs_cache.c diff --git a/fs/cifsd/vfs_cache.h b/fs/ksmbd/vfs_cache.h similarity index 100% rename from fs/cifsd/vfs_cache.h rename to fs/ksmbd/vfs_cache.h From 49be5aa47b69ad09b0045b662d61bad51e6309e7 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Thu, 24 Jun 2021 09:20:03 +0900 Subject: [PATCH 21/45] MAINTAINERS: rename cifsd to ksmbd Rename cifsd to ksmbd and update Sergey's mail address. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- MAINTAINERS | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index f23bb5cbfd70..6691ac75fce5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4540,16 +4540,6 @@ T: git git://git.samba.org/sfrench/cifs-2.6.git F: Documentation/admin-guide/cifs/ F: fs/cifs/ -COMMON INTERNET FILE SYSTEM SERVER (CIFSD) -M: Namjae Jeon -M: Sergey Senozhatsky -M: Steve French -M: Hyunchul Lee -L: linux-cifs@vger.kernel.org -L: linux-cifsd-devel@lists.sourceforge.net -S: Maintained -F: fs/cifsd/ - COMPACTPCI HOTPLUG CORE M: Scott Murray L: linux-pci@vger.kernel.org @@ -9948,6 +9938,15 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git F: Documentation/dev-tools/kselftest* F: tools/testing/selftests/ +KERNEL SMB3 SERVER (KSMBD) +M: Namjae Jeon +M: Sergey Senozhatsky +M: Steve French +M: Hyunchul Lee +L: linux-cifs@vger.kernel.org +S: Maintained +F: fs/ksmbd/ + KERNEL UNIT TESTING FRAMEWORK (KUnit) M: Brendan Higgins L: linux-kselftest@vger.kernel.org From 333111a6dc32a2768f581876bdb5ef4231f5084e Mon Sep 17 00:00:00 2001 From: Hyunchul Lee Date: Wed, 23 Jun 2021 11:07:43 +0900 Subject: [PATCH 22/45] ksmbd: factor out a ksmbd_vfs_lock_parent helper Factor out a self-contained helper to get stable parent dentry. Signed-off-by: Hyunchul Lee Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/vfs.c | 125 ++++++++++++++++++++++++------------------------- 1 file changed, 62 insertions(+), 63 deletions(-) diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c index fddabb4c7db6..e64eab7a58a8 100644 --- a/fs/ksmbd/vfs.c +++ b/fs/ksmbd/vfs.c @@ -60,6 +60,41 @@ static void ksmbd_vfs_inherit_owner(struct ksmbd_work *work, i_uid_write(inode, i_uid_read(parent_inode)); } +/** + * ksmbd_vfs_lock_parent() - lock parent dentry if it is stable + * + * the parent dentry got by dget_parent or @parent could be + * unstable, we try to lock a parent inode and lookup the + * child dentry again. + * + * the reference count of @parent isn't incremented. + */ +static int ksmbd_vfs_lock_parent(struct dentry *parent, struct dentry *child) +{ + struct dentry *dentry; + int ret = 0; + + inode_lock_nested(d_inode(parent), I_MUTEX_PARENT); + dentry = lookup_one_len(child->d_name.name, parent, + child->d_name.len); + if (IS_ERR(dentry)) { + ret = PTR_ERR(dentry); + goto out_err; + } + + if (dentry != child) { + ret = -ESTALE; + dput(dentry); + goto out_err; + } + + dput(dentry); + return 0; +out_err: + inode_unlock(d_inode(parent)); + return ret; +} + int ksmbd_vfs_inode_permission(struct dentry *dentry, int acc_mode, bool delete) { int mask, ret = 0; @@ -78,29 +113,18 @@ int ksmbd_vfs_inode_permission(struct dentry *dentry, int acc_mode, bool delete) return -EACCES; if (delete) { - struct dentry *child, *parent; + struct dentry *parent; parent = dget_parent(dentry); - inode_lock_nested(d_inode(parent), I_MUTEX_PARENT); - child = lookup_one_len(dentry->d_name.name, parent, - dentry->d_name.len); - if (IS_ERR(child)) { - ret = PTR_ERR(child); - goto out_lock; + ret = ksmbd_vfs_lock_parent(parent, dentry); + if (ret) { + dput(parent); + return ret; } - if (child != dentry) { - ret = -ESTALE; - dput(child); - goto out_lock; - } - dput(child); - - if (inode_permission(&init_user_ns, d_inode(parent), MAY_EXEC | MAY_WRITE)) { + if (inode_permission(&init_user_ns, d_inode(parent), MAY_EXEC | MAY_WRITE)) ret = -EACCES; - goto out_lock; - } -out_lock: + inode_unlock(d_inode(parent)); dput(parent); } @@ -109,7 +133,7 @@ out_lock: int ksmbd_vfs_query_maximal_access(struct dentry *dentry, __le32 *daccess) { - struct dentry *parent, *child; + struct dentry *parent; int ret = 0; *daccess = cpu_to_le32(FILE_READ_ATTRIBUTES | READ_CONTROL); @@ -127,25 +151,15 @@ int ksmbd_vfs_query_maximal_access(struct dentry *dentry, __le32 *daccess) *daccess |= FILE_EXECUTE_LE; parent = dget_parent(dentry); - inode_lock_nested(d_inode(parent), I_MUTEX_PARENT); - child = lookup_one_len(dentry->d_name.name, parent, - dentry->d_name.len); - if (IS_ERR(child)) { - ret = PTR_ERR(child); - goto out_lock; + ret = ksmbd_vfs_lock_parent(parent, dentry); + if (ret) { + dput(parent); + return ret; } - if (child != dentry) { - ret = -ESTALE; - dput(child); - goto out_lock; - } - dput(child); - if (!inode_permission(&init_user_ns, d_inode(parent), MAY_EXEC | MAY_WRITE)) *daccess |= FILE_DELETE_LE; -out_lock: inode_unlock(d_inode(parent)); dput(parent); return ret; @@ -573,7 +587,7 @@ int ksmbd_vfs_fsync(struct ksmbd_work *work, u64 fid, u64 p_id) int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name) { struct path path; - struct dentry *dentry, *parent; + struct dentry *parent; int err; int flags = 0; @@ -592,35 +606,32 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name) } parent = dget_parent(path.dentry); - inode_lock_nested(d_inode(parent), I_MUTEX_PARENT); - dentry = lookup_one_len(path.dentry->d_name.name, parent, - strlen(path.dentry->d_name.name)); - if (IS_ERR(dentry)) { - err = PTR_ERR(dentry); - ksmbd_debug(VFS, "%s: lookup failed, err %d\n", - path.dentry->d_name.name, err); - goto out_err; + err = ksmbd_vfs_lock_parent(parent, path.dentry); + if (err) { + dput(parent); + path_put(&path); + ksmbd_revert_fsids(work); + return err; } - if (!d_inode(dentry) || !d_inode(dentry)->i_nlink) { - dput(dentry); + if (!d_inode(path.dentry)->i_nlink) { err = -ENOENT; goto out_err; } - if (S_ISDIR(d_inode(dentry)->i_mode)) { - err = vfs_rmdir(&init_user_ns, d_inode(parent), dentry); + if (S_ISDIR(d_inode(path.dentry)->i_mode)) { + err = vfs_rmdir(&init_user_ns, d_inode(parent), path.dentry); if (err && err != -ENOTEMPTY) ksmbd_debug(VFS, "%s: rmdir failed, err %d\n", name, err); } else { - err = vfs_unlink(&init_user_ns, d_inode(parent), dentry, NULL); + err = vfs_unlink(&init_user_ns, d_inode(parent), path.dentry, + NULL); if (err) ksmbd_debug(VFS, "%s: unlink failed, err %d\n", name, err); } - dput(dentry); out_err: inode_unlock(d_inode(parent)); dput(parent); @@ -1086,30 +1097,18 @@ int ksmbd_vfs_remove_xattr(struct dentry *dentry, char *attr_name) int ksmbd_vfs_unlink(struct dentry *dir, struct dentry *dentry) { - struct dentry *child; int err = 0; - inode_lock_nested(d_inode(dir), I_MUTEX_PARENT); + err = ksmbd_vfs_lock_parent(dir, dentry); + if (err) + return err; dget(dentry); - child = lookup_one_len(dentry->d_name.name, dir, dentry->d_name.len); - if (IS_ERR(child)) { - err = PTR_ERR(child); - goto out; - } - - if (child != dentry) { - err = -ESTALE; - dput(child); - goto out; - } - dput(child); if (S_ISDIR(d_inode(dentry)->i_mode)) err = vfs_rmdir(&init_user_ns, d_inode(dir), dentry); else err = vfs_unlink(&init_user_ns, d_inode(dir), dentry, NULL); -out: dput(dentry); inode_unlock(d_inode(dir)); if (err) From 6c5e36d13e2a338ed611d2bcc6c615dd0550b17d Mon Sep 17 00:00:00 2001 From: Hyunchul Lee Date: Wed, 23 Jun 2021 13:48:24 +0900 Subject: [PATCH 23/45] ksmbd: set MAY_* flags together with open flags set MAY_* flags together with open flags and remove ksmbd_vfs_inode_permission(). Signed-off-by: Hyunchul Lee Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/smb2pdu.c | 38 ++++++++++++++++++++++++-------------- fs/ksmbd/vfs.c | 42 +++++++++++++----------------------------- fs/ksmbd/vfs.h | 3 +-- 3 files changed, 38 insertions(+), 45 deletions(-) diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index 1327ae806b17..25715d57c2bb 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -1836,21 +1836,27 @@ out_err1: * @file_present: is file already present * @access: file access flags * @disposition: file disposition flags + * @may_flags: set with MAY_ flags * * Return: file open flags */ static int smb2_create_open_flags(bool file_present, __le32 access, - __le32 disposition) + __le32 disposition, + int *may_flags) { int oflags = O_NONBLOCK | O_LARGEFILE; if (access & FILE_READ_DESIRED_ACCESS_LE && - access & FILE_WRITE_DESIRE_ACCESS_LE) + access & FILE_WRITE_DESIRE_ACCESS_LE) { oflags |= O_RDWR; - else if (access & FILE_WRITE_DESIRE_ACCESS_LE) + *may_flags = MAY_OPEN | MAY_READ | MAY_WRITE; + } else if (access & FILE_WRITE_DESIRE_ACCESS_LE) { oflags |= O_WRONLY; - else + *may_flags = MAY_OPEN | MAY_WRITE; + } else { oflags |= O_RDONLY; + *may_flags = MAY_OPEN | MAY_READ; + } if (access == FILE_READ_ATTRIBUTES_LE) oflags |= O_PATH; @@ -1884,6 +1890,7 @@ static int smb2_create_open_flags(bool file_present, __le32 access, break; } } + return oflags; } @@ -2355,7 +2362,7 @@ int smb2_open(struct ksmbd_work *work) struct create_ea_buf_req *ea_buf = NULL; struct oplock_info *opinfo; __le32 *next_ptr = NULL; - int req_op_level = 0, open_flags = 0, file_info = 0; + int req_op_level = 0, open_flags = 0, may_flags = 0, file_info = 0; int rc = 0, len = 0; int contxt_cnt = 0, query_disk_id = 0; int maximal_access_ctxt = 0, posix_ctxt = 0; @@ -2696,7 +2703,8 @@ int smb2_open(struct ksmbd_work *work) } open_flags = smb2_create_open_flags(file_present, daccess, - req->CreateDisposition); + req->CreateDisposition, + &may_flags); if (!test_tree_conn_flag(tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) { if (open_flags & O_CREAT) { @@ -2723,21 +2731,23 @@ int smb2_open(struct ksmbd_work *work) goto err_out; } } else if (!already_permitted) { - bool may_delete; - - may_delete = daccess & FILE_DELETE_LE || - req->CreateOptions & FILE_DELETE_ON_CLOSE_LE; - /* FILE_READ_ATTRIBUTE is allowed without inode_permission, * because execute(search) permission on a parent directory, * is already granted. */ if (daccess & ~(FILE_READ_ATTRIBUTES_LE | FILE_READ_CONTROL_LE)) { - rc = ksmbd_vfs_inode_permission(path.dentry, - open_flags & O_ACCMODE, - may_delete); + rc = inode_permission(&init_user_ns, + d_inode(path.dentry), + may_flags); if (rc) goto err_out; + + if ((daccess & FILE_DELETE_LE) || + (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) { + rc = ksmbd_vfs_may_delete(path.dentry); + if (rc) + goto err_out; + } } } diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c index e64eab7a58a8..6181a58e8a33 100644 --- a/fs/ksmbd/vfs.c +++ b/fs/ksmbd/vfs.c @@ -95,39 +95,23 @@ out_err: return ret; } -int ksmbd_vfs_inode_permission(struct dentry *dentry, int acc_mode, bool delete) +int ksmbd_vfs_may_delete(struct dentry *dentry) { - int mask, ret = 0; + struct dentry *parent; + int ret; - mask = 0; - acc_mode &= O_ACCMODE; - - if (acc_mode == O_RDONLY) - mask = MAY_READ; - else if (acc_mode == O_WRONLY) - mask = MAY_WRITE; - else if (acc_mode == O_RDWR) - mask = MAY_READ | MAY_WRITE; - - if (inode_permission(&init_user_ns, d_inode(dentry), mask | MAY_OPEN)) - return -EACCES; - - if (delete) { - struct dentry *parent; - - parent = dget_parent(dentry); - ret = ksmbd_vfs_lock_parent(parent, dentry); - if (ret) { - dput(parent); - return ret; - } - - if (inode_permission(&init_user_ns, d_inode(parent), MAY_EXEC | MAY_WRITE)) - ret = -EACCES; - - inode_unlock(d_inode(parent)); + parent = dget_parent(dentry); + ret = ksmbd_vfs_lock_parent(parent, dentry); + if (ret) { dput(parent); + return ret; } + + ret = inode_permission(&init_user_ns, d_inode(parent), + MAY_EXEC | MAY_WRITE); + + inode_unlock(d_inode(parent)); + dput(parent); return ret; } diff --git a/fs/ksmbd/vfs.h b/fs/ksmbd/vfs.h index 49f0558ace32..ae8eff1f0315 100644 --- a/fs/ksmbd/vfs.h +++ b/fs/ksmbd/vfs.h @@ -192,8 +192,7 @@ struct ksmbd_kstat { __le32 file_attributes; }; -int ksmbd_vfs_inode_permission(struct dentry *dentry, int acc_mode, - bool delete); +int ksmbd_vfs_may_delete(struct dentry *dentry); 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_mkdir(struct ksmbd_work *work, const char *name, umode_t mode); From b622948789a96a8f347c8e77e18d100c7f1a78fa Mon Sep 17 00:00:00 2001 From: Hyunchul Lee Date: Fri, 25 Jun 2021 07:02:06 +0900 Subject: [PATCH 24/45] ksmbd: remove macros in transport_ipc.c Remove macros in transport_ipc.c Reviewed-by: Christoph Hellwig Signed-off-by: Hyunchul Lee Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/transport_ipc.c | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/fs/ksmbd/transport_ipc.c b/fs/ksmbd/transport_ipc.c index 13eacfda64ac..ca5099118fdf 100644 --- a/fs/ksmbd/transport_ipc.c +++ b/fs/ksmbd/transport_ipc.c @@ -38,8 +38,6 @@ static DEFINE_IDA(ipc_ida); static unsigned int ksmbd_tools_pid; -#define KSMBD_IPC_MSG_HANDLE(m) (*(unsigned int *)m) - static bool ksmbd_ipc_validate_version(struct genl_info *m) { if (m->genlhdr->version != KSMBD_GENL_VERSION) { @@ -56,12 +54,9 @@ static bool ksmbd_ipc_validate_version(struct genl_info *m) struct ksmbd_ipc_msg { unsigned int type; unsigned int sz; - unsigned char ____payload[0]; + unsigned char payload[]; }; -#define KSMBD_IPC_MSG_PAYLOAD(m) \ - ((void *)(((struct ksmbd_ipc_msg *)(m))->____payload)) - struct ipc_msg_table_entry { unsigned int handle; unsigned int type; @@ -251,7 +246,7 @@ static void ipc_msg_handle_free(int handle) static int handle_response(int type, void *payload, size_t sz) { - int handle = KSMBD_IPC_MSG_HANDLE(payload); + unsigned int handle = *(unsigned int *)payload; struct ipc_msg_table_entry *entry; int ret = 0; @@ -432,7 +427,7 @@ static int ipc_msg_send(struct ksmbd_ipc_msg *msg) if (!nlh) goto out; - ret = nla_put(skb, msg->type, msg->sz, KSMBD_IPC_MSG_PAYLOAD(msg)); + ret = nla_put(skb, msg->type, msg->sz, msg->payload); if (ret) { genlmsg_cancel(skb, nlh); goto out; @@ -509,7 +504,7 @@ struct ksmbd_login_response *ksmbd_ipc_login_request(const char *account) return NULL; msg->type = KSMBD_EVENT_LOGIN_REQUEST; - req = KSMBD_IPC_MSG_PAYLOAD(msg); + req = (struct ksmbd_login_request *)msg->payload; req->handle = ksmbd_acquire_id(&ipc_ida); strscpy(req->account, account, KSMBD_REQ_MAX_ACCOUNT_NAME_SZ); @@ -532,7 +527,7 @@ ksmbd_ipc_spnego_authen_request(const char *spnego_blob, int blob_len) return NULL; msg->type = KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST; - req = KSMBD_IPC_MSG_PAYLOAD(msg); + req = (struct ksmbd_spnego_authen_request *)msg->payload; req->handle = ksmbd_acquire_id(&ipc_ida); req->spnego_blob_len = blob_len; memcpy(req->spnego_blob, spnego_blob, blob_len); @@ -564,7 +559,7 @@ ksmbd_ipc_tree_connect_request(struct ksmbd_session *sess, return NULL; msg->type = KSMBD_EVENT_TREE_CONNECT_REQUEST; - req = KSMBD_IPC_MSG_PAYLOAD(msg); + req = (struct ksmbd_tree_connect_request *)msg->payload; req->handle = ksmbd_acquire_id(&ipc_ida); req->account_flags = sess->user->flags; @@ -597,7 +592,7 @@ int ksmbd_ipc_tree_disconnect_request(unsigned long long session_id, return -ENOMEM; msg->type = KSMBD_EVENT_TREE_DISCONNECT_REQUEST; - req = KSMBD_IPC_MSG_PAYLOAD(msg); + req = (struct ksmbd_tree_disconnect_request *)msg->payload; req->session_id = session_id; req->connect_id = connect_id; @@ -620,7 +615,7 @@ int ksmbd_ipc_logout_request(const char *account) return -ENOMEM; msg->type = KSMBD_EVENT_LOGOUT_REQUEST; - req = KSMBD_IPC_MSG_PAYLOAD(msg); + req = (struct ksmbd_logout_request *)msg->payload; strscpy(req->account, account, KSMBD_REQ_MAX_ACCOUNT_NAME_SZ); ret = ipc_msg_send(msg); @@ -643,7 +638,7 @@ ksmbd_ipc_share_config_request(const char *name) return NULL; msg->type = KSMBD_EVENT_SHARE_CONFIG_REQUEST; - req = KSMBD_IPC_MSG_PAYLOAD(msg); + req = (struct ksmbd_share_config_request *)msg->payload; req->handle = ksmbd_acquire_id(&ipc_ida); strscpy(req->share_name, name, KSMBD_REQ_MAX_SHARE_NAME); @@ -664,7 +659,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_open(struct ksmbd_session *sess, int handle) return NULL; msg->type = KSMBD_EVENT_RPC_REQUEST; - req = KSMBD_IPC_MSG_PAYLOAD(msg); + req = (struct ksmbd_rpc_command *)msg->payload; req->handle = handle; req->flags = ksmbd_session_rpc_method(sess, handle); req->flags |= KSMBD_RPC_OPEN_METHOD; @@ -686,7 +681,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_close(struct ksmbd_session *sess, int handle return NULL; msg->type = KSMBD_EVENT_RPC_REQUEST; - req = KSMBD_IPC_MSG_PAYLOAD(msg); + req = (struct ksmbd_rpc_command *)msg->payload; req->handle = handle; req->flags = ksmbd_session_rpc_method(sess, handle); req->flags |= KSMBD_RPC_CLOSE_METHOD; @@ -709,7 +704,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle return NULL; msg->type = KSMBD_EVENT_RPC_REQUEST; - req = KSMBD_IPC_MSG_PAYLOAD(msg); + req = (struct ksmbd_rpc_command *)msg->payload; req->handle = handle; req->flags = ksmbd_session_rpc_method(sess, handle); req->flags |= rpc_context_flags(sess); @@ -733,7 +728,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess, int handle) return NULL; msg->type = KSMBD_EVENT_RPC_REQUEST; - req = KSMBD_IPC_MSG_PAYLOAD(msg); + req = (struct ksmbd_rpc_command *)msg->payload; req->handle = handle; req->flags = ksmbd_session_rpc_method(sess, handle); req->flags |= rpc_context_flags(sess); @@ -757,7 +752,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle return NULL; msg->type = KSMBD_EVENT_RPC_REQUEST; - req = KSMBD_IPC_MSG_PAYLOAD(msg); + req = (struct ksmbd_rpc_command *)req->payload; req->handle = handle; req->flags = ksmbd_session_rpc_method(sess, handle); req->flags |= rpc_context_flags(sess); @@ -782,7 +777,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_rap(struct ksmbd_session *sess, void *payloa return NULL; msg->type = KSMBD_EVENT_RPC_REQUEST; - req = KSMBD_IPC_MSG_PAYLOAD(msg); + req = (struct ksmbd_rpc_command *)req->payload; req->handle = ksmbd_acquire_id(&ipc_ida); req->flags = rpc_context_flags(sess); req->flags |= KSMBD_RPC_RAP_METHOD; From 8ad8dc34211742c816d45dd2ce62aa103a82f4c2 Mon Sep 17 00:00:00 2001 From: Hyunchul Lee Date: Fri, 25 Jun 2021 07:02:07 +0900 Subject: [PATCH 25/45] ksmbd: replace BUFFER_NR_PAGES with inline function Replace BUFFER_NR_PAGES with inline function Reviewed-by: Christoph Hellwig Signed-off-by: Hyunchul Lee Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/transport_rdma.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/fs/ksmbd/transport_rdma.c b/fs/ksmbd/transport_rdma.c index bd7a090d5350..b3af474d4cad 100644 --- a/fs/ksmbd/transport_rdma.c +++ b/fs/ksmbd/transport_rdma.c @@ -204,9 +204,11 @@ struct smb_direct_rdma_rw_msg { struct scatterlist sg_list[0]; }; -#define BUFFER_NR_PAGES(buf, len) \ - (DIV_ROUND_UP((unsigned long)(buf) + (len), PAGE_SIZE) \ - - (unsigned long)(buf) / PAGE_SIZE) +static inline int get_buf_page_count(void *buf, int size) +{ + return DIV_ROUND_UP((uintptr_t)buf + size, PAGE_SIZE) - + (uintptr_t)buf / PAGE_SIZE; +} static void smb_direct_destroy_pools(struct smb_direct_transport *transport); static void smb_direct_post_recv_credits(struct work_struct *work); @@ -1048,7 +1050,7 @@ static int get_sg_list(void *buf, int size, struct scatterlist *sg_list, int nen int offset, len; int i = 0; - if (nentries < BUFFER_NR_PAGES(buf, size)) + if (nentries < get_buf_page_count(buf, size)) return -EINVAL; offset = offset_in_page(buf); @@ -1338,7 +1340,7 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, void *buf, msg->sgt.sgl = &msg->sg_list[0]; ret = sg_alloc_table_chained(&msg->sgt, - BUFFER_NR_PAGES(buf, buf_len), + get_buf_page_count(buf, buf_len), msg->sg_list, SG_CHUNK_SIZE); if (ret) { atomic_inc(&t->rw_avail_ops); @@ -1353,7 +1355,7 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, void *buf, } ret = rdma_rw_ctx_init(&msg->rw_ctx, t->qp, t->qp->port, - msg->sg_list, BUFFER_NR_PAGES(buf, buf_len), + msg->sg_list, get_buf_page_count(buf, buf_len), 0, remote_offset, remote_key, is_read ? DMA_FROM_DEVICE : DMA_TO_DEVICE); if (ret < 0) { From c2220322b4577fc32ad3b7b4ddb856bd1f8c7461 Mon Sep 17 00:00:00 2001 From: Hyunchul Lee Date: Fri, 25 Jun 2021 07:02:08 +0900 Subject: [PATCH 26/45] ksmbd: replace KSMBD_ALIGN with kernel ALIGN macro Replace KSMBD_ALIGN with kernel ALIGN macro Reviewed-by: Christoph Hellwig Signed-off-by: Hyunchul Lee Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/ndr.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/fs/ksmbd/ndr.c b/fs/ksmbd/ndr.c index 46cc01475d38..db2ec07e076e 100644 --- a/fs/ksmbd/ndr.c +++ b/fs/ksmbd/ndr.c @@ -11,21 +11,6 @@ #define PAYLOAD_HEAD(d) ((d)->data + (d)->offset) -#define KSMBD_ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) - -#define KSMBD_ALIGN(x, a) \ - ({ \ - typeof(x) ret = (x); \ - if (((x) & ((typeof(x))(a) - 1)) != 0) \ - ret = KSMBD_ALIGN_MASK(x, (typeof(x))(a) - 1); \ - ret; \ - }) - -static void align_offset(struct ndr *ndr, int n) -{ - ndr->offset = KSMBD_ALIGN(ndr->offset, n); -} - static int try_to_realloc_ndr_blob(struct ndr *n, size_t sz) { char *data; @@ -85,7 +70,7 @@ static int ndr_write_string(struct ndr *n, void *value, size_t sz) strncpy(PAYLOAD_HEAD(n), value, sz); sz++; n->offset += sz; - align_offset(n, 2); + n->offset = ALIGN(n->offset, 2); return 0; } @@ -96,7 +81,7 @@ static int ndr_read_string(struct ndr *n, void *value, size_t sz) memcpy(value, PAYLOAD_HEAD(n), len); len++; n->offset += len; - align_offset(n, 2); + n->offset = ALIGN(n->offset, 2); return 0; } @@ -210,20 +195,20 @@ static int ndr_encode_posix_acl_entry(struct ndr *n, struct xattr_smb_acl *acl) int i; ndr_write_int32(n, acl->count); - align_offset(n, 8); + n->offset = ALIGN(n->offset, 8); ndr_write_int32(n, acl->count); ndr_write_int32(n, 0); for (i = 0; i < acl->count; i++) { - align_offset(n, 8); + n->offset = ALIGN(n->offset, 8); ndr_write_int16(n, acl->entries[i].type); ndr_write_int16(n, acl->entries[i].type); if (acl->entries[i].type == SMB_ACL_USER) { - align_offset(n, 8); + n->offset = ALIGN(n->offset, 8); ndr_write_int64(n, acl->entries[i].uid); } else if (acl->entries[i].type == SMB_ACL_GROUP) { - align_offset(n, 8); + n->offset = ALIGN(n->offset, 8); ndr_write_int64(n, acl->entries[i].gid); } From cb5b047f8e14e91774f68625dafb130fb160b4eb Mon Sep 17 00:00:00 2001 From: Hyunchul Lee Date: Fri, 25 Jun 2021 07:02:09 +0900 Subject: [PATCH 27/45] ksmbd: replace PAYLOAD_HEAD with inline function Replace PAYLOAD_HEAD with inline function. Reviewed-by: Christoph Hellwig Signed-off-by: Hyunchul Lee Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/ndr.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/fs/ksmbd/ndr.c b/fs/ksmbd/ndr.c index db2ec07e076e..bcf13a2aa9d4 100644 --- a/fs/ksmbd/ndr.c +++ b/fs/ksmbd/ndr.c @@ -9,7 +9,10 @@ #include "glob.h" #include "ndr.h" -#define PAYLOAD_HEAD(d) ((d)->data + (d)->offset) +static inline char *ndr_get_field(struct ndr *n) +{ + return n->data + n->offset; +} static int try_to_realloc_ndr_blob(struct ndr *n, size_t sz) { @@ -30,7 +33,7 @@ static void ndr_write_int16(struct ndr *n, __u16 value) if (n->length <= n->offset + sizeof(value)) try_to_realloc_ndr_blob(n, sizeof(value)); - *(__le16 *)PAYLOAD_HEAD(n) = cpu_to_le16(value); + *(__le16 *)ndr_get_field(n) = cpu_to_le16(value); n->offset += sizeof(value); } @@ -39,7 +42,7 @@ static void ndr_write_int32(struct ndr *n, __u32 value) if (n->length <= n->offset + sizeof(value)) try_to_realloc_ndr_blob(n, sizeof(value)); - *(__le32 *)PAYLOAD_HEAD(n) = cpu_to_le32(value); + *(__le32 *)ndr_get_field(n) = cpu_to_le32(value); n->offset += sizeof(value); } @@ -48,7 +51,7 @@ static void ndr_write_int64(struct ndr *n, __u64 value) if (n->length <= n->offset + sizeof(value)) try_to_realloc_ndr_blob(n, sizeof(value)); - *(__le64 *)PAYLOAD_HEAD(n) = cpu_to_le64(value); + *(__le64 *)ndr_get_field(n) = cpu_to_le64(value); n->offset += sizeof(value); } @@ -57,7 +60,7 @@ static int ndr_write_bytes(struct ndr *n, void *value, size_t sz) if (n->length <= n->offset + sz) try_to_realloc_ndr_blob(n, sz); - memcpy(PAYLOAD_HEAD(n), value, sz); + memcpy(ndr_get_field(n), value, sz); n->offset += sz; return 0; } @@ -67,7 +70,7 @@ static int ndr_write_string(struct ndr *n, void *value, size_t sz) if (n->length <= n->offset + sz) try_to_realloc_ndr_blob(n, sz); - strncpy(PAYLOAD_HEAD(n), value, sz); + strncpy(ndr_get_field(n), value, sz); sz++; n->offset += sz; n->offset = ALIGN(n->offset, 2); @@ -76,9 +79,9 @@ static int ndr_write_string(struct ndr *n, void *value, size_t sz) static int ndr_read_string(struct ndr *n, void *value, size_t sz) { - int len = strnlen(PAYLOAD_HEAD(n), sz); + int len = strnlen(ndr_get_field(n), sz); - memcpy(value, PAYLOAD_HEAD(n), len); + memcpy(value, ndr_get_field(n), len); len++; n->offset += len; n->offset = ALIGN(n->offset, 2); @@ -87,7 +90,7 @@ static int ndr_read_string(struct ndr *n, void *value, size_t sz) static int ndr_read_bytes(struct ndr *n, void *value, size_t sz) { - memcpy(value, PAYLOAD_HEAD(n), sz); + memcpy(value, ndr_get_field(n), sz); n->offset += sz; return 0; } @@ -96,7 +99,7 @@ static __u16 ndr_read_int16(struct ndr *n) { __u16 ret; - ret = le16_to_cpu(*(__le16 *)PAYLOAD_HEAD(n)); + ret = le16_to_cpu(*(__le16 *)ndr_get_field(n)); n->offset += sizeof(__u16); return ret; } @@ -105,7 +108,7 @@ static __u32 ndr_read_int32(struct ndr *n) { __u32 ret; - ret = le32_to_cpu(*(__le32 *)PAYLOAD_HEAD(n)); + ret = le32_to_cpu(*(__le32 *)ndr_get_field(n)); n->offset += sizeof(__u32); return ret; } @@ -114,7 +117,7 @@ static __u64 ndr_read_int64(struct ndr *n) { __u64 ret; - ret = le64_to_cpu(*(__le64 *)PAYLOAD_HEAD(n)); + ret = le64_to_cpu(*(__le64 *)ndr_get_field(n)); n->offset += sizeof(__u64); return ret; } From d4075abbc6b571e9d03d7a742e53fd6085223649 Mon Sep 17 00:00:00 2001 From: Hyunchul Lee Date: Fri, 25 Jun 2021 07:02:10 +0900 Subject: [PATCH 28/45] ksmbd: remove getting worker state macros Remove getting worker state macros Reviewed-by: Christoph Hellwig Signed-off-by: Hyunchul Lee Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/ksmbd_work.h | 4 ---- fs/ksmbd/smb2pdu.c | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/fs/ksmbd/ksmbd_work.h b/fs/ksmbd/ksmbd_work.h index 0e2d4f3fc49f..a91abd438a85 100644 --- a/fs/ksmbd/ksmbd_work.h +++ b/fs/ksmbd/ksmbd_work.h @@ -86,10 +86,6 @@ struct ksmbd_work { struct list_head interim_entry; }; -#define WORK_CANCELLED(w) ((w)->state == KSMBD_WORK_CANCELLED) -#define WORK_CLOSED(w) ((w)->state == KSMBD_WORK_CLOSED) -#define WORK_ACTIVE(w) ((w)->state == KSMBD_WORK_ACTIVE) - #define RESPONSE_BUF_NEXT(w) \ (((w)->response_buf + (w)->next_smb2_rsp_hdr_off)) #define REQUEST_BUF_NEXT(w) \ diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index 25715d57c2bb..38a36390b64d 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -6716,12 +6716,12 @@ skip: err = ksmbd_vfs_posix_lock_wait(flock); - if (!WORK_ACTIVE(work)) { + if (work->state != KSMBD_WORK_ACTIVE) { list_del(&smb_lock->llist); list_del(&smb_lock->glist); locks_free_lock(flock); - if (WORK_CANCELLED(work)) { + if (work->state == KSMBD_WORK_CANCELLED) { spin_lock(&fp->f_lock); list_del(&work->fp_entry); spin_unlock(&fp->f_lock); From d8fb29980cb5369c4ea520c0b4e1a8893e88f14c Mon Sep 17 00:00:00 2001 From: Hyunchul Lee Date: Fri, 25 Jun 2021 11:53:26 +0900 Subject: [PATCH 29/45] ksmbd: remove and replace macros with inline functions in smb_common.h Remove and replace macros with inline functions in smb_common.h Reviewed-by: Christoph Hellwig Signed-off-by: Hyunchul Lee Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/mgmt/user_session.c | 8 +++----- fs/ksmbd/oplock.c | 6 ++++-- fs/ksmbd/smb2pdu.c | 5 +++-- fs/ksmbd/smb_common.h | 12 ++++++------ 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/fs/ksmbd/mgmt/user_session.c b/fs/ksmbd/mgmt/user_session.c index c5ba9694e1f1..8d8ffd8c6f19 100644 --- a/fs/ksmbd/mgmt/user_session.c +++ b/fs/ksmbd/mgmt/user_session.c @@ -154,11 +154,9 @@ void ksmbd_session_destroy(struct ksmbd_session *sess) list_del(&sess->sessions_entry); - if (IS_SMB2(sess->conn)) { - down_write(&sessions_table_lock); - hash_del(&sess->hlist); - up_write(&sessions_table_lock); - } + down_write(&sessions_table_lock); + hash_del(&sess->hlist); + up_write(&sessions_table_lock); if (sess->user) ksmbd_free_user(sess->user); diff --git a/fs/ksmbd/oplock.c b/fs/ksmbd/oplock.c index 9027cb7d970f..71e15a591582 100644 --- a/fs/ksmbd/oplock.c +++ b/fs/ksmbd/oplock.c @@ -631,7 +631,8 @@ static void __smb2_oplock_break_noti(struct work_struct *wk) rsp_hdr = work->response_buf; memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2); - rsp_hdr->smb2_buf_length = cpu_to_be32(HEADER_SIZE_NO_BUF_LEN(conn)); + rsp_hdr->smb2_buf_length = + cpu_to_be32(smb2_hdr_size_no_buflen(conn->vals)); rsp_hdr->ProtocolId = SMB2_PROTO_NUMBER; rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE; rsp_hdr->CreditRequest = cpu_to_le16(0); @@ -737,7 +738,8 @@ static void __smb2_lease_break_noti(struct work_struct *wk) rsp_hdr = work->response_buf; memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2); - rsp_hdr->smb2_buf_length = cpu_to_be32(HEADER_SIZE_NO_BUF_LEN(conn)); + rsp_hdr->smb2_buf_length = + cpu_to_be32(smb2_hdr_size_no_buflen(conn->vals)); rsp_hdr->ProtocolId = SMB2_PROTO_NUMBER; rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE; rsp_hdr->CreditRequest = cpu_to_le16(0); diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index 38a36390b64d..ece03135127c 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -243,7 +243,7 @@ int init_smb2_neg_rsp(struct ksmbd_work *work) memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2); rsp_hdr->smb2_buf_length = - cpu_to_be32(HEADER_SIZE_NO_BUF_LEN(conn)); + cpu_to_be32(smb2_hdr_size_no_buflen(conn->vals)); rsp_hdr->ProtocolId = SMB2_PROTO_NUMBER; rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE; @@ -497,7 +497,8 @@ int init_smb2_rsp_hdr(struct ksmbd_work *work) struct ksmbd_conn *conn = work->conn; memset(rsp_hdr, 0, sizeof(struct smb2_hdr) + 2); - rsp_hdr->smb2_buf_length = cpu_to_be32(HEADER_SIZE_NO_BUF_LEN(conn)); + rsp_hdr->smb2_buf_length = + cpu_to_be32(smb2_hdr_size_no_buflen(conn->vals)); rsp_hdr->ProtocolId = rcv_hdr->ProtocolId; rsp_hdr->StructureSize = SMB2_HEADER_STRUCTURE_SIZE; rsp_hdr->Command = rcv_hdr->Command; diff --git a/fs/ksmbd/smb_common.h b/fs/ksmbd/smb_common.h index 084166ba7654..8489b92229fa 100644 --- a/fs/ksmbd/smb_common.h +++ b/fs/ksmbd/smb_common.h @@ -50,12 +50,6 @@ extern struct list_head global_lock_list; -#define IS_SMB2(x) ((x)->vals->protocol_id != SMB10_PROT_ID) - -#define HEADER_SIZE(conn) ((conn)->vals->header_size) -#define HEADER_SIZE_NO_BUF_LEN(conn) ((conn)->vals->header_size - 4) -#define MAX_HEADER_SIZE(conn) ((conn)->vals->max_header_size) - /* RFC 1002 session packet types */ #define RFC1002_SESSION_MESSAGE 0x00 #define RFC1002_SESSION_REQUEST 0x81 @@ -490,6 +484,12 @@ struct smb_version_cmds { int (*proc)(struct ksmbd_work *swork); }; +static inline size_t +smb2_hdr_size_no_buflen(struct smb_version_values *vals) +{ + return vals->header_size - 4; +} + int ksmbd_min_protocol(void); int ksmbd_max_protocol(void); From 02d4b4aa6d3b135b00f20da9d623d2bbae63768f Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Fri, 25 Jun 2021 13:43:01 +0900 Subject: [PATCH 30/45] ksmbd: replace SMB_DIRECT_TRANS macro with inline function replace SMB_DIRECT_TRANS macro with inline function. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/transport_rdma.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/fs/ksmbd/transport_rdma.c b/fs/ksmbd/transport_rdma.c index b3af474d4cad..171fb3dd018a 100644 --- a/fs/ksmbd/transport_rdma.c +++ b/fs/ksmbd/transport_rdma.c @@ -158,8 +158,6 @@ struct smb_direct_transport { }; #define KSMBD_TRANS(t) ((struct ksmbd_transport *)&((t)->transport)) -#define SMB_DIRECT_TRANS(t) ((struct smb_direct_transport *)container_of(t, \ - struct smb_direct_transport, transport)) enum { SMB_DIRECT_MSG_NEGOTIATE_REQ = 0, @@ -217,6 +215,12 @@ static int smb_direct_post_send_data(struct smb_direct_transport *t, struct kvec *iov, int niov, int remaining_data_length); +static inline struct smb_direct_transport * +smb_trans_direct_transfort(struct ksmbd_transport *t) +{ + return container_of(t, struct smb_direct_transport, transport); +} + static inline void *smb_direct_recvmsg_payload(struct smb_direct_recvmsg *recvmsg) { @@ -643,7 +647,7 @@ static int smb_direct_read(struct ksmbd_transport *t, char *buf, int to_copy, to_read, data_read, offset; u32 data_length, remaining_data_length, data_offset; int rc; - struct smb_direct_transport *st = SMB_DIRECT_TRANS(t); + struct smb_direct_transport *st = smb_trans_direct_transfort(t); again: if (st->status != SMB_DIRECT_CS_CONNECTED) { @@ -1194,7 +1198,7 @@ static int smb_direct_writev(struct ksmbd_transport *t, struct kvec *iov, int niovs, int buflen, bool need_invalidate, unsigned int remote_key) { - struct smb_direct_transport *st = SMB_DIRECT_TRANS(t); + struct smb_direct_transport *st = smb_trans_direct_transfort(t); int remaining_data_length; int start, i, j; int max_iov_size = st->max_send_size - @@ -1393,7 +1397,7 @@ static int smb_direct_rdma_write(struct ksmbd_transport *t, void *buf, unsigned int buflen, u32 remote_key, u64 remote_offset, u32 remote_len) { - return smb_direct_rdma_xmit(SMB_DIRECT_TRANS(t), buf, buflen, + return smb_direct_rdma_xmit(smb_trans_direct_transfort(t), buf, buflen, remote_key, remote_offset, remote_len, false); } @@ -1402,14 +1406,14 @@ static int smb_direct_rdma_read(struct ksmbd_transport *t, void *buf, unsigned int buflen, u32 remote_key, u64 remote_offset, u32 remote_len) { - return smb_direct_rdma_xmit(SMB_DIRECT_TRANS(t), buf, buflen, + return smb_direct_rdma_xmit(smb_trans_direct_transfort(t), buf, buflen, remote_key, remote_offset, remote_len, true); } static void smb_direct_disconnect(struct ksmbd_transport *t) { - struct smb_direct_transport *st = SMB_DIRECT_TRANS(t); + struct smb_direct_transport *st = smb_trans_direct_transfort(t); ksmbd_debug(RDMA, "Disconnecting cm_id=%p\n", st->cm_id); @@ -1857,7 +1861,7 @@ err: static int smb_direct_prepare(struct ksmbd_transport *t) { - struct smb_direct_transport *st = SMB_DIRECT_TRANS(t); + struct smb_direct_transport *st = smb_trans_direct_transfort(t); int ret; struct ib_qp_cap qp_cap; From 8a893315dc06158ce33d1a3292e07170ce2fcd64 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Fri, 25 Jun 2021 13:43:37 +0900 Subject: [PATCH 31/45] ksmbd: replace request and respone buffer macro with inline functions replace request and respone buffer macro with inline functions. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/ksmbd_work.h | 21 ++++++++++++++++---- fs/ksmbd/smb2misc.c | 2 +- fs/ksmbd/smb2pdu.c | 46 +++++++++++++++++++++---------------------- 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/fs/ksmbd/ksmbd_work.h b/fs/ksmbd/ksmbd_work.h index a91abd438a85..c655bf371ce5 100644 --- a/fs/ksmbd/ksmbd_work.h +++ b/fs/ksmbd/ksmbd_work.h @@ -86,10 +86,23 @@ struct ksmbd_work { struct list_head interim_entry; }; -#define RESPONSE_BUF_NEXT(w) \ - (((w)->response_buf + (w)->next_smb2_rsp_hdr_off)) -#define REQUEST_BUF_NEXT(w) \ - (((w)->request_buf + (w)->next_smb2_rcv_hdr_off)) +/** + * ksmbd_resp_buf_next - Get next buffer on compound response. + * @work: smb work containing response buffer + */ +static inline void *ksmbd_resp_buf_next(struct ksmbd_work *work) +{ + return work->response_buf + work->next_smb2_rsp_hdr_off; +} + +/** + * ksmbd_req_buf_next - Get next buffer on compound request. + * @work: smb work containing response buffer + */ +static inline void *ksmbd_req_buf_next(struct ksmbd_work *work) +{ + return work->request_buf + work->next_smb2_rcv_hdr_off; +} struct ksmbd_work *ksmbd_alloc_work_struct(void); void ksmbd_free_work_struct(struct ksmbd_work *work); diff --git a/fs/ksmbd/smb2misc.c b/fs/ksmbd/smb2misc.c index e412d69690ed..730d68032c46 100644 --- a/fs/ksmbd/smb2misc.c +++ b/fs/ksmbd/smb2misc.c @@ -341,7 +341,7 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work) __u32 len = get_rfc1002_len(pdu); if (work->next_smb2_rcv_hdr_off) { - pdu = REQUEST_BUF_NEXT(work); + pdu = ksmbd_req_buf_next(work); hdr = &pdu->hdr; } diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index ece03135127c..42fc3bd2d464 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -40,8 +40,8 @@ static void __wbuf(struct ksmbd_work *work, void **req, void **rsp) { if (work->next_smb2_rcv_hdr_off) { - *req = REQUEST_BUF_NEXT(work); - *rsp = RESPONSE_BUF_NEXT(work); + *req = ksmbd_req_buf_next(work); + *rsp = ksmbd_resp_buf_next(work); } else { *req = work->request_buf; *rsp = work->response_buf; @@ -126,7 +126,7 @@ void smb2_set_err_rsp(struct ksmbd_work *work) struct smb2_err_rsp *err_rsp; if (work->next_smb2_rcv_hdr_off) - err_rsp = RESPONSE_BUF_NEXT(work); + err_rsp = ksmbd_resp_buf_next(work); else err_rsp = work->response_buf; @@ -196,7 +196,7 @@ u16 get_smb2_cmd_val(struct ksmbd_work *work) struct smb2_hdr *rcv_hdr; if (work->next_smb2_rcv_hdr_off) - rcv_hdr = REQUEST_BUF_NEXT(work); + rcv_hdr = ksmbd_req_buf_next(work); else rcv_hdr = work->request_buf; return le16_to_cpu(rcv_hdr->Command); @@ -212,7 +212,7 @@ void set_smb2_rsp_status(struct ksmbd_work *work, __le32 err) struct smb2_hdr *rsp_hdr; if (work->next_smb2_rcv_hdr_off) - rsp_hdr = RESPONSE_BUF_NEXT(work); + rsp_hdr = ksmbd_resp_buf_next(work); else rsp_hdr = work->response_buf; rsp_hdr->Status = err; @@ -315,8 +315,8 @@ static int smb2_consume_credit_charge(struct ksmbd_work *work, */ int smb2_set_rsp_credits(struct ksmbd_work *work) { - struct smb2_hdr *req_hdr = REQUEST_BUF_NEXT(work); - struct smb2_hdr *hdr = RESPONSE_BUF_NEXT(work); + struct smb2_hdr *req_hdr = ksmbd_req_buf_next(work); + struct smb2_hdr *hdr = ksmbd_resp_buf_next(work); struct ksmbd_conn *conn = work->conn; unsigned short credits_requested = le16_to_cpu(req_hdr->CreditRequest); unsigned short credit_charge = 1, credits_granted = 0; @@ -383,8 +383,8 @@ out: */ static void init_chained_smb2_rsp(struct ksmbd_work *work) { - struct smb2_hdr *req = REQUEST_BUF_NEXT(work); - struct smb2_hdr *rsp = RESPONSE_BUF_NEXT(work); + struct smb2_hdr *req = ksmbd_req_buf_next(work); + struct smb2_hdr *rsp = ksmbd_resp_buf_next(work); struct smb2_hdr *rsp_hdr; struct smb2_hdr *rcv_hdr; int next_hdr_offset = 0; @@ -422,8 +422,8 @@ static void init_chained_smb2_rsp(struct ksmbd_work *work) new_len, work->next_smb2_rcv_hdr_off, work->next_smb2_rsp_hdr_off); - rsp_hdr = RESPONSE_BUF_NEXT(work); - rcv_hdr = REQUEST_BUF_NEXT(work); + rsp_hdr = ksmbd_resp_buf_next(work); + rcv_hdr = ksmbd_req_buf_next(work); if (!(rcv_hdr->Flags & SMB2_FLAGS_RELATED_OPERATIONS)) { ksmbd_debug(SMB, "related flag should be set\n"); @@ -462,7 +462,7 @@ bool is_chained_smb2_message(struct ksmbd_work *work) if (hdr->ProtocolId != SMB2_PROTO_NUMBER) return false; - hdr = REQUEST_BUF_NEXT(work); + hdr = ksmbd_req_buf_next(work); if (le32_to_cpu(hdr->NextCommand) > 0) { ksmbd_debug(SMB, "got SMB2 chained command\n"); init_chained_smb2_rsp(work); @@ -5725,8 +5725,8 @@ int smb2_set_info(struct ksmbd_work *work) rsp_org = work->response_buf; if (work->next_smb2_rcv_hdr_off) { - req = REQUEST_BUF_NEXT(work); - rsp = RESPONSE_BUF_NEXT(work); + req = ksmbd_req_buf_next(work); + rsp = ksmbd_resp_buf_next(work); if (!HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) { ksmbd_debug(SMB, "Compound request set FID = %u\n", work->compound_fid); @@ -7224,8 +7224,8 @@ int smb2_ioctl(struct ksmbd_work *work) rsp_org = work->response_buf; if (work->next_smb2_rcv_hdr_off) { - req = REQUEST_BUF_NEXT(work); - rsp = RESPONSE_BUF_NEXT(work); + req = ksmbd_req_buf_next(work); + rsp = ksmbd_resp_buf_next(work); if (!HAS_FILE_ID(le64_to_cpu(req->VolatileFileId))) { ksmbd_debug(SMB, "Compound request set FID = %u\n", work->compound_fid); @@ -7848,7 +7848,7 @@ int smb2_check_sign_req(struct ksmbd_work *work) hdr_org = hdr = work->request_buf; if (work->next_smb2_rcv_hdr_off) - hdr = REQUEST_BUF_NEXT(work); + hdr = ksmbd_req_buf_next(work); if (!hdr->NextCommand && !work->next_smb2_rcv_hdr_off) len = be32_to_cpu(hdr_org->smb2_buf_length); @@ -7892,9 +7892,9 @@ void smb2_set_sign_rsp(struct ksmbd_work *work) hdr_org = hdr = work->response_buf; if (work->next_smb2_rsp_hdr_off) - hdr = RESPONSE_BUF_NEXT(work); + hdr = ksmbd_resp_buf_next(work); - req_hdr = REQUEST_BUF_NEXT(work); + req_hdr = ksmbd_req_buf_next(work); if (!work->next_smb2_rsp_hdr_off) { len = get_rfc1002_len(hdr_org); @@ -7946,7 +7946,7 @@ int smb3_check_sign_req(struct ksmbd_work *work) hdr_org = hdr = work->request_buf; if (work->next_smb2_rcv_hdr_off) - hdr = REQUEST_BUF_NEXT(work); + hdr = ksmbd_req_buf_next(work); if (!hdr->NextCommand && !work->next_smb2_rcv_hdr_off) len = be32_to_cpu(hdr_org->smb2_buf_length); @@ -8005,9 +8005,9 @@ void smb3_set_sign_rsp(struct ksmbd_work *work) hdr_org = hdr = work->response_buf; if (work->next_smb2_rsp_hdr_off) - hdr = RESPONSE_BUF_NEXT(work); + hdr = ksmbd_resp_buf_next(work); - req_hdr = REQUEST_BUF_NEXT(work); + req_hdr = ksmbd_req_buf_next(work); if (!work->next_smb2_rsp_hdr_off) { len = get_rfc1002_len(hdr_org); @@ -8217,7 +8217,7 @@ bool smb3_11_final_sess_setup_resp(struct ksmbd_work *work) return false; if (work->next_smb2_rcv_hdr_off) - rsp = RESPONSE_BUF_NEXT(work); + rsp = ksmbd_resp_buf_next(work); if (le16_to_cpu(rsp->Command) == SMB2_SESSION_SETUP_HE && rsp->Status == STATUS_SUCCESS) From e294f78d34785151cb6d7199ff61d110f9520e65 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Mon, 28 Jun 2021 15:26:37 +0900 Subject: [PATCH 32/45] ksmbd: allow PROTECTED_DACL_SECINFO and UNPROTECTED_DACL_SECINFO addition information in smb2 set info security "cifsd: Fix regression in smb2_get_info" patch cause that dacl doesn't work. windows send smb2 set info security with PROTECTED_DACL_SECINFO to control dacl. But previous patch doesn't allow it. This patch add PROTECTED_DACL_SECINFO and UNPROTECTED_DACL_SECINFO addtional information flags in check. Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/smb2pdu.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index 42fc3bd2d464..7d8bec07630b 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -4888,9 +4888,11 @@ static int smb2_get_info_sec(struct ksmbd_work *work, int addition_info = le32_to_cpu(req->AdditionalInformation); int rc; - if (addition_info & ~(OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO)) { - ksmbd_debug(SMB, "Unsupported addition info: 0x%x)\n", - addition_info); + if (addition_info & ~(OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO | + PROTECTED_DACL_SECINFO | + UNPROTECTED_DACL_SECINFO)) { + pr_err("Unsupported addition info: 0x%x)\n", + addition_info); pntsd->revision = cpu_to_le16(1); pntsd->type = cpu_to_le16(SELF_RELATIVE | DACL_PROTECTED); From a5a25a114ab2412831f063361360eb1192ca6151 Mon Sep 17 00:00:00 2001 From: Marios Makassikis Date: Sat, 26 Jun 2021 22:56:48 +0900 Subject: [PATCH 33/45] ksmbd: Relax credit_charge check in smb2_validate_credit_charge() smb2_validate_credit_charge() checks the CreditCharge field in the request is valid with regards to the payload size. The current implementation rejects requests with CreditCharge = 0 and a payload < 64K, even though they should be accepted. Set CreditCharge to a minimum value of 1 to avoid rejecting such requests. This matches what samba4 does. Fixes share enumeration for jcifs-ng clients. Signed-off-by: Marios Makassikis Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/smb2misc.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/fs/ksmbd/smb2misc.c b/fs/ksmbd/smb2misc.c index 730d68032c46..4508631c5706 100644 --- a/fs/ksmbd/smb2misc.c +++ b/fs/ksmbd/smb2misc.c @@ -317,14 +317,12 @@ static int smb2_validate_credit_charge(struct smb2_hdr *hdr) return 0; } + credit_charge = max(1, credit_charge); max_len = max(req_len, expect_resp_len); calc_credit_num = DIV_ROUND_UP(max_len, SMB2_MAX_BUFFER_SIZE); - if (!credit_charge && max_len > SMB2_MAX_BUFFER_SIZE) { - pr_err("credit charge is zero and payload size(%d) is bigger than 64K\n", - max_len); - return 1; - } else if (credit_charge < calc_credit_num) { - pr_err("credit charge : %d, calc_credit_num : %d\n", + + if (credit_charge < calc_credit_num) { + pr_err("Insufficient credit charge, given: %d, needed: %d\n", credit_charge, calc_credit_num); return 1; } From 493fa2fbe4597db474e43d38fb8805cbaef654ac Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Tue, 29 Jun 2021 09:22:16 +0900 Subject: [PATCH 34/45] ksmbd: fix dentry racy with rename() Using ->d_name can be broken due to races with rename(). So use %pd with ->d_name to print filename and In other cases, use it under ->d_lock. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/smb2pdu.c | 19 ++++++++++--------- fs/ksmbd/vfs.c | 14 ++++++++------ fs/ksmbd/vfs_cache.h | 1 - 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index 7d8bec07630b..70e6d6e3e84b 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -3711,8 +3711,8 @@ int smb2_query_dir(struct ksmbd_work *work) if (!(dir_fp->daccess & FILE_LIST_DIRECTORY_LE) || inode_permission(&init_user_ns, file_inode(dir_fp->filp), MAY_READ | MAY_EXEC)) { - pr_err("no right to enumerate directory (%s)\n", - FP_FILENAME(dir_fp)); + pr_err("no right to enumerate directory (%pd)\n", + dir_fp->filp->f_path.dentry); rc = -EACCES; goto err_out2; } @@ -4266,14 +4266,15 @@ static void get_file_alternate_info(struct ksmbd_work *work, { struct ksmbd_conn *conn = work->conn; struct smb2_file_alt_name_info *file_info; + struct dentry *dentry = fp->filp->f_path.dentry; int conv_len; - char *filename; - filename = (char *)FP_FILENAME(fp); + spin_lock(&dentry->d_lock); file_info = (struct smb2_file_alt_name_info *)rsp->Buffer; conv_len = ksmbd_extract_shortname(conn, - filename, + dentry->d_name.name, file_info->FileName); + spin_unlock(&dentry->d_lock); file_info->FileNameLength = cpu_to_le32(conv_len); rsp->OutputBufferLength = cpu_to_le32(sizeof(struct smb2_file_alt_name_info) + conv_len); @@ -5938,8 +5939,8 @@ int smb2_read(struct ksmbd_work *work) goto out; } - ksmbd_debug(SMB, "filename %s, offset %lld, len %zu\n", FP_FILENAME(fp), - offset, length); + ksmbd_debug(SMB, "filename %pd, offset %lld, len %zu\n", + fp->filp->f_path.dentry, offset, length); work->aux_payload_buf = kvmalloc(length, GFP_KERNEL | __GFP_ZERO); if (!work->aux_payload_buf) { @@ -6216,8 +6217,8 @@ int smb2_write(struct ksmbd_work *work) if (le32_to_cpu(req->Flags) & SMB2_WRITEFLAG_WRITE_THROUGH) writethrough = true; - ksmbd_debug(SMB, "filename %s, offset %lld, len %zu\n", - FP_FILENAME(fp), offset, length); + ksmbd_debug(SMB, "filename %pd, offset %lld, len %zu\n", + fp->filp->f_path.dentry, offset, length); err = ksmbd_vfs_write(work, fp, data_buf, length, &offset, writethrough, &nbytes); if (err < 0) diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c index 6181a58e8a33..ed1c0626e205 100644 --- a/fs/ksmbd/vfs.c +++ b/fs/ksmbd/vfs.c @@ -365,7 +365,8 @@ int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count, if (work->conn->connection_type) { if (!(fp->daccess & (FILE_READ_DATA_LE | FILE_EXECUTE_LE))) { - pr_err("no right to read(%s)\n", FP_FILENAME(fp)); + pr_err("no right to read(%pd)\n", + fp->filp->f_path.dentry); return -EACCES; } } @@ -473,7 +474,8 @@ int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp, if (sess->conn->connection_type) { if (!(fp->daccess & FILE_WRITE_DATA_LE)) { - pr_err("no right to write(%s)\n", FP_FILENAME(fp)); + pr_err("no right to write(%pd)\n", + fp->filp->f_path.dentry); err = -EACCES; goto out; } @@ -512,8 +514,8 @@ int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp, if (sync) { err = vfs_fsync_range(filp, offset, offset + *written, 0); if (err < 0) - pr_err("fsync failed for filename = %s, err = %d\n", - FP_FILENAME(fp), err); + pr_err("fsync failed for filename = %pd, err = %d\n", + fp->filp->f_path.dentry, err); } out: @@ -1707,11 +1709,11 @@ int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work, *total_size_written = 0; if (!(src_fp->daccess & (FILE_READ_DATA_LE | FILE_EXECUTE_LE))) { - pr_err("no right to read(%s)\n", FP_FILENAME(src_fp)); + pr_err("no right to read(%pd)\n", src_fp->filp->f_path.dentry); return -EACCES; } if (!(dst_fp->daccess & (FILE_WRITE_DATA_LE | FILE_APPEND_DATA_LE))) { - pr_err("no right to write(%s)\n", FP_FILENAME(dst_fp)); + pr_err("no right to write(%pd)\n", dst_fp->filp->f_path.dentry); return -EACCES; } diff --git a/fs/ksmbd/vfs_cache.h b/fs/ksmbd/vfs_cache.h index 745855367106..03c36906cab0 100644 --- a/fs/ksmbd/vfs_cache.h +++ b/fs/ksmbd/vfs_cache.h @@ -25,7 +25,6 @@ #define KSMBD_NO_FID (UINT_MAX) #define SMB2_NO_FID (0xFFFFFFFFFFFFFFFFULL) -#define FP_FILENAME(fp) ((fp)->filp->f_path.dentry->d_name.name) #define FP_INODE(fp) d_inode((fp)->filp->f_path.dentry) #define PARENT_INODE(fp) d_inode((fp)->filp->f_path.dentry->d_parent) From ab0b263b749ade964db46b148a965eb88bd644be Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Tue, 29 Jun 2021 09:20:13 +0900 Subject: [PATCH 35/45] ksmbd: opencode to remove FP_INODE macro Opencode to remove FP_INODE macro. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/oplock.c | 2 +- fs/ksmbd/smb2pdu.c | 26 +++++++++++++------------- fs/ksmbd/smb_common.c | 2 +- fs/ksmbd/vfs.c | 2 +- fs/ksmbd/vfs_cache.c | 6 +++--- fs/ksmbd/vfs_cache.h | 1 - 6 files changed, 19 insertions(+), 20 deletions(-) diff --git a/fs/ksmbd/oplock.c b/fs/ksmbd/oplock.c index 71e15a591582..3f0dd9b35c78 100644 --- a/fs/ksmbd/oplock.c +++ b/fs/ksmbd/oplock.c @@ -1579,7 +1579,7 @@ 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) { struct create_posix_rsp *buf; - struct inode *inode = FP_INODE(fp); + struct inode *inode = file_inode(fp->filp); buf = (struct create_posix_rsp *)cc; memset(buf, 0, sizeof(struct create_posix_rsp)); diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index 70e6d6e3e84b..2d515e44d48e 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -2908,7 +2908,7 @@ int smb2_open(struct ksmbd_work *work) if (!test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_OPLOCKS) || (req_op_level == SMB2_OPLOCK_LEVEL_LEASE && !(conn->vals->capabilities & SMB2_GLOBAL_CAP_LEASING))) { - if (share_ret < 0 && !S_ISDIR(FP_INODE(fp)->i_mode)) { + if (share_ret < 0 && !S_ISDIR(file_inode(fp->filp)->i_mode)) { rc = share_ret; goto err_out; } @@ -2995,7 +2995,7 @@ int smb2_open(struct ksmbd_work *work) memcpy(fp->client_guid, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE); - generic_fillattr(&init_user_ns, FP_INODE(fp), &stat); + generic_fillattr(&init_user_ns, file_inode(fp->filp), &stat); rsp->StructureSize = cpu_to_le16(89); rcu_read_lock(); @@ -4123,7 +4123,7 @@ static int get_file_basic_info(struct smb2_query_info_rsp *rsp, } basic_info = (struct smb2_file_all_info *)rsp->Buffer; - generic_fillattr(&init_user_ns, FP_INODE(fp), &stat); + generic_fillattr(&init_user_ns, file_inode(fp->filp), &stat); basic_info->CreationTime = cpu_to_le64(fp->create_time); time = ksmbd_UnixTimeToNT(stat.atime); basic_info->LastAccessTime = cpu_to_le64(time); @@ -4163,7 +4163,7 @@ static void get_file_standard_info(struct smb2_query_info_rsp *rsp, struct inode *inode; struct kstat stat; - inode = FP_INODE(fp); + inode = file_inode(fp->filp); generic_fillattr(&init_user_ns, inode, &stat); sinfo = (struct smb2_file_standard_info *)rsp->Buffer; @@ -4218,7 +4218,7 @@ static int get_file_all_info(struct ksmbd_work *work, if (!filename) return -ENOMEM; - inode = FP_INODE(fp); + inode = file_inode(fp->filp); generic_fillattr(&init_user_ns, inode, &stat); ksmbd_debug(SMB, "filename = %s\n", filename); @@ -4294,7 +4294,7 @@ static void get_file_stream_info(struct ksmbd_work *work, ssize_t xattr_list_len; int nbytes = 0, streamlen, stream_name_len, next, idx = 0; - generic_fillattr(&init_user_ns, FP_INODE(fp), &stat); + generic_fillattr(&init_user_ns, file_inode(fp->filp), &stat); file_info = (struct smb2_file_stream_info *)rsp->Buffer; xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list); @@ -4373,7 +4373,7 @@ static void get_file_internal_info(struct smb2_query_info_rsp *rsp, struct smb2_file_internal_info *file_info; struct kstat stat; - generic_fillattr(&init_user_ns, FP_INODE(fp), &stat); + generic_fillattr(&init_user_ns, file_inode(fp->filp), &stat); file_info = (struct smb2_file_internal_info *)rsp->Buffer; file_info->IndexNumber = cpu_to_le64(stat.ino); rsp->OutputBufferLength = @@ -4397,7 +4397,7 @@ static int get_file_network_open_info(struct smb2_query_info_rsp *rsp, file_info = (struct smb2_file_ntwrk_info *)rsp->Buffer; - inode = FP_INODE(fp); + inode = file_inode(fp->filp); generic_fillattr(&init_user_ns, inode, &stat); file_info->CreationTime = cpu_to_le64(fp->create_time); @@ -4459,7 +4459,7 @@ static void get_file_compression_info(struct smb2_query_info_rsp *rsp, struct smb2_file_comp_info *file_info; struct kstat stat; - generic_fillattr(&init_user_ns, FP_INODE(fp), &stat); + generic_fillattr(&init_user_ns, file_inode(fp->filp), &stat); file_info = (struct smb2_file_comp_info *)rsp->Buffer; file_info->CompressedFileSize = cpu_to_le64(stat.blocks << 9); @@ -4498,7 +4498,7 @@ static int find_file_posix_info(struct smb2_query_info_rsp *rsp, struct ksmbd_file *fp, void *rsp_org) { struct smb311_posix_qinfo *file_info; - struct inode *inode = FP_INODE(fp); + struct inode *inode = file_inode(fp->filp); u64 time; file_info = (struct smb311_posix_qinfo *)rsp->Buffer; @@ -4927,7 +4927,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work, if (!fp) return -ENOENT; - inode = FP_INODE(fp); + inode = file_inode(fp->filp); ksmbd_acls_fattr(&fattr, inode); if (test_share_config_flag(work->tcon->share_conf, @@ -5109,7 +5109,7 @@ int smb2_close(struct ksmbd_work *work) goto out; } - inode = FP_INODE(fp); + inode = file_inode(fp->filp); rsp->Flags = SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB; rsp->AllocationSize = S_ISDIR(inode->i_mode) ? 0 : cpu_to_le64(inode->i_blocks << 9); @@ -7397,7 +7397,7 @@ int smb2_ioctl(struct ksmbd_work *work) } reparse_ptr->ReparseTag = - smb2_get_reparse_tag_special_file(FP_INODE(fp)->i_mode); + smb2_get_reparse_tag_special_file(file_inode(fp->filp)->i_mode); reparse_ptr->ReparseDataLength = 0; ksmbd_fd_put(work, fp); nbytes = sizeof(struct reparse_data_buffer); diff --git a/fs/ksmbd/smb_common.c b/fs/ksmbd/smb_common.c index 5bf644d7e321..b573575a1de5 100644 --- a/fs/ksmbd/smb_common.c +++ b/fs/ksmbd/smb_common.c @@ -488,7 +488,7 @@ int ksmbd_smb_check_shared_mode(struct file *filp, struct ksmbd_file *curr_fp) */ read_lock(&curr_fp->f_ci->m_lock); list_for_each_entry(prev_fp, &curr_fp->f_ci->m_fp_list, node) { - if (file_inode(filp) != FP_INODE(prev_fp)) + if (file_inode(filp) != file_inode(prev_fp->filp)) continue; if (filp == prev_fp->filp) diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c index ed1c0626e205..40783bb414d6 100644 --- a/fs/ksmbd/vfs.c +++ b/fs/ksmbd/vfs.c @@ -1024,7 +1024,7 @@ int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length, int in_count, int *out_count) { struct file *f = fp->filp; - struct inode *inode = FP_INODE(fp); + struct inode *inode = file_inode(fp->filp); loff_t maxbytes = (u64)inode->i_sb->s_maxbytes, end; loff_t extent_start, extent_end; int ret = 0; diff --git a/fs/ksmbd/vfs_cache.c b/fs/ksmbd/vfs_cache.c index c88210b15289..5c9efcfaeb5c 100644 --- a/fs/ksmbd/vfs_cache.c +++ b/fs/ksmbd/vfs_cache.c @@ -83,7 +83,7 @@ static struct ksmbd_inode *__ksmbd_inode_lookup(struct inode *inode) static struct ksmbd_inode *ksmbd_inode_lookup(struct ksmbd_file *fp) { - return __ksmbd_inode_lookup(FP_INODE(fp)); + return __ksmbd_inode_lookup(file_inode(fp->filp)); } static struct ksmbd_inode *ksmbd_inode_lookup_by_vfsinode(struct inode *inode) @@ -156,7 +156,7 @@ static void ksmbd_inode_unhash(struct ksmbd_inode *ci) static int ksmbd_inode_init(struct ksmbd_inode *ci, struct ksmbd_file *fp) { - ci->m_inode = FP_INODE(fp); + ci->m_inode = file_inode(fp->filp); atomic_set(&ci->m_count, 1); atomic_set(&ci->op_count, 0); atomic_set(&ci->sop_count, 0); @@ -479,7 +479,7 @@ struct ksmbd_file *ksmbd_lookup_fd_inode(struct inode *inode) read_lock(&ci->m_lock); list_for_each_entry(lfp, &ci->m_fp_list, node) { - if (inode == FP_INODE(lfp)) { + if (inode == file_inode(lfp->filp)) { atomic_dec(&ci->m_count); read_unlock(&ci->m_lock); return lfp; diff --git a/fs/ksmbd/vfs_cache.h b/fs/ksmbd/vfs_cache.h index 03c36906cab0..b01192ebd86b 100644 --- a/fs/ksmbd/vfs_cache.h +++ b/fs/ksmbd/vfs_cache.h @@ -25,7 +25,6 @@ #define KSMBD_NO_FID (UINT_MAX) #define SMB2_NO_FID (0xFFFFFFFFFFFFFFFFULL) -#define FP_INODE(fp) d_inode((fp)->filp->f_path.dentry) #define PARENT_INODE(fp) d_inode((fp)->filp->f_path.dentry->d_parent) #define ATTR_FP(fp) ((fp)->attrib_only && \ From 12202c0594b18218e1645fd0fad92cf77a1f3145 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Tue, 29 Jun 2021 09:23:56 +0900 Subject: [PATCH 36/45] ksmbd: use ksmbd_vfs_lock_parent to get stable parent dentry Use ksmbd_vfs_lock_parent to get stable parent dentry and remove PARENT_INODE macro. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/smb2pdu.c | 15 ++++++++++++++- fs/ksmbd/vfs.c | 2 +- fs/ksmbd/vfs.h | 1 + fs/ksmbd/vfs_cache.h | 2 -- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index 2d515e44d48e..bf798ee65b25 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -5538,6 +5538,9 @@ static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp, char *buf) { struct ksmbd_file *parent_fp; + struct dentry *parent; + struct dentry *dentry = fp->filp->f_path.dentry; + int ret; if (!(fp->daccess & FILE_DELETE_LE)) { pr_err("no right to delete : 0x%x\n", fp->daccess); @@ -5547,7 +5550,17 @@ static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp, if (ksmbd_stream_fd(fp)) goto next; - parent_fp = ksmbd_lookup_fd_inode(PARENT_INODE(fp)); + parent = dget_parent(dentry); + ret = ksmbd_vfs_lock_parent(parent, dentry); + if (ret) { + dput(parent); + return ret; + } + + parent_fp = ksmbd_lookup_fd_inode(d_inode(parent)); + inode_unlock(d_inode(parent)); + dput(parent); + if (parent_fp) { if (parent_fp->daccess & FILE_DELETE_LE) { pr_err("parent dir is opened with delete access\n"); diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c index 40783bb414d6..702166266f91 100644 --- a/fs/ksmbd/vfs.c +++ b/fs/ksmbd/vfs.c @@ -69,7 +69,7 @@ static void ksmbd_vfs_inherit_owner(struct ksmbd_work *work, * * the reference count of @parent isn't incremented. */ -static int ksmbd_vfs_lock_parent(struct dentry *parent, struct dentry *child) +int ksmbd_vfs_lock_parent(struct dentry *parent, struct dentry *child) { struct dentry *dentry; int ret = 0; diff --git a/fs/ksmbd/vfs.h b/fs/ksmbd/vfs.h index ae8eff1f0315..ba12fea004b5 100644 --- a/fs/ksmbd/vfs.h +++ b/fs/ksmbd/vfs.h @@ -192,6 +192,7 @@ struct ksmbd_kstat { __le32 file_attributes; }; +int ksmbd_vfs_lock_parent(struct dentry *parent, struct dentry *child); int ksmbd_vfs_may_delete(struct dentry *dentry); 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); diff --git a/fs/ksmbd/vfs_cache.h b/fs/ksmbd/vfs_cache.h index b01192ebd86b..752cbdab3522 100644 --- a/fs/ksmbd/vfs_cache.h +++ b/fs/ksmbd/vfs_cache.h @@ -25,8 +25,6 @@ #define KSMBD_NO_FID (UINT_MAX) #define SMB2_NO_FID (0xFFFFFFFFFFFFFFFFULL) -#define PARENT_INODE(fp) d_inode((fp)->filp->f_path.dentry->d_parent) - #define ATTR_FP(fp) ((fp)->attrib_only && \ ((fp)->cdoption != FILE_OVERWRITE_IF_LE && \ (fp)->cdoption != FILE_OVERWRITE_LE && \ From 849fbc549d4cca576d659d7df139c5f04104cb48 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Tue, 29 Jun 2021 09:24:31 +0900 Subject: [PATCH 37/45] ksmbd: opencode to remove ATTR_FP macro Opencode to remove ATTR_FP macro. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/oplock.c | 4 +++- fs/ksmbd/vfs_cache.h | 5 ----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/fs/ksmbd/oplock.c b/fs/ksmbd/oplock.c index 3f0dd9b35c78..43c8b7ce6095 100644 --- a/fs/ksmbd/oplock.c +++ b/fs/ksmbd/oplock.c @@ -1111,7 +1111,9 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid, goto set_lev; /* grant none-oplock if second open is trunc */ - if (ATTR_FP(fp)) { + if (fp->attrib_only && fp->cdoption != FILE_OVERWRITE_IF_LE && + fp->cdoption != FILE_OVERWRITE_LE && + fp->cdoption != FILE_SUPERSEDE_LE) { req_op_level = SMB2_OPLOCK_LEVEL_NONE; goto set_lev; } diff --git a/fs/ksmbd/vfs_cache.h b/fs/ksmbd/vfs_cache.h index 752cbdab3522..543494f664cb 100644 --- a/fs/ksmbd/vfs_cache.h +++ b/fs/ksmbd/vfs_cache.h @@ -25,11 +25,6 @@ #define KSMBD_NO_FID (UINT_MAX) #define SMB2_NO_FID (0xFFFFFFFFFFFFFFFFULL) -#define ATTR_FP(fp) ((fp)->attrib_only && \ - ((fp)->cdoption != FILE_OVERWRITE_IF_LE && \ - (fp)->cdoption != FILE_OVERWRITE_LE && \ - (fp)->cdoption != FILE_SUPERSEDE_LE)) - struct ksmbd_conn; struct ksmbd_session; From 0ae941ef2e481e478a4b6c52a16e73c7bb4b9e3e Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Wed, 30 Jun 2021 09:37:09 +0900 Subject: [PATCH 38/45] ksmbd: remove SMB1 oplock level macros ksmbd does not support SMB1. This patch remove SMB1 oplock level macros. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/oplock.c | 2 +- fs/ksmbd/oplock.h | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/fs/ksmbd/oplock.c b/fs/ksmbd/oplock.c index 43c8b7ce6095..a9f171ccf770 100644 --- a/fs/ksmbd/oplock.c +++ b/fs/ksmbd/oplock.c @@ -39,7 +39,7 @@ static struct oplock_info *alloc_opinfo(struct ksmbd_work *work, opinfo->sess = sess; opinfo->conn = sess->conn; - opinfo->level = OPLOCK_NONE; + opinfo->level = SMB2_OPLOCK_LEVEL_NONE; opinfo->op_state = OPLOCK_STATE_NONE; opinfo->pending_break = 0; opinfo->fid = id; diff --git a/fs/ksmbd/oplock.h b/fs/ksmbd/oplock.h index 9fb7ea74e86c..119b8047cfbd 100644 --- a/fs/ksmbd/oplock.h +++ b/fs/ksmbd/oplock.h @@ -11,12 +11,6 @@ #define OPLOCK_WAIT_TIME (35 * HZ) -/* SMB Oplock levels */ -#define OPLOCK_NONE 0 -#define OPLOCK_EXCLUSIVE 1 -#define OPLOCK_BATCH 2 -#define OPLOCK_READ 3 /* level 2 oplock */ - /* SMB2 Oplock levels */ #define SMB2_OPLOCK_LEVEL_NONE 0x00 #define SMB2_OPLOCK_LEVEL_II 0x01 From 6128468da50c790f56d0aed2f604333fb324f897 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Wed, 30 Jun 2021 09:37:43 +0900 Subject: [PATCH 39/45] ksmbd: change ACE types to enumeration Change ACE types to enumeration. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/smbacl.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/ksmbd/smbacl.h b/fs/ksmbd/smbacl.h index fb5480f0aa89..baa9b9b47a07 100644 --- a/fs/ksmbd/smbacl.h +++ b/fs/ksmbd/smbacl.h @@ -17,8 +17,13 @@ #define NUM_AUTHS (6) /* number of authority fields */ #define SID_MAX_SUB_AUTHORITIES (15) /* max number of sub authority fields */ -#define ACCESS_ALLOWED 0 -#define ACCESS_DENIED 1 +/* + * ACE types - see MS-DTYP 2.4.4.1 + */ +enum { + ACCESS_ALLOWED, + ACCESS_DENIED, +}; #define SIDOWNER 1 #define SIDGROUP 2 From 12411ad59d49e415f987719b8f676e2c6b99be37 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Wed, 30 Jun 2021 09:38:13 +0900 Subject: [PATCH 40/45] ksmbd: change sid types to enumeration Change sid types to enumeration. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/smbacl.h | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/fs/ksmbd/smbacl.h b/fs/ksmbd/smbacl.h index baa9b9b47a07..3e1345e9f24f 100644 --- a/fs/ksmbd/smbacl.h +++ b/fs/ksmbd/smbacl.h @@ -25,15 +25,20 @@ enum { ACCESS_DENIED, }; -#define SIDOWNER 1 -#define SIDGROUP 2 -#define SIDCREATOR_OWNER 3 -#define SIDCREATOR_GROUP 4 -#define SIDUNIX_USER 5 -#define SIDUNIX_GROUP 6 -#define SIDNFS_USER 7 -#define SIDNFS_GROUP 8 -#define SIDNFS_MODE 9 +/* + * Security ID types + */ +enum { + SIDOWNER = 1, + SIDGROUP, + SIDCREATOR_OWNER, + SIDCREATOR_GROUP, + SIDUNIX_USER, + SIDUNIX_GROUP, + SIDNFS_USER, + SIDNFS_GROUP, + SIDNFS_MODE, +}; /* Revision for ACLs */ #define SD_REVISION 1 From b9cbfb524d73ca953604dc421098b4a3aa14d095 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Wed, 30 Jun 2021 09:38:46 +0900 Subject: [PATCH 41/45] ksmbd: change server state type macro to enumeration Change server state type macro to enumeration. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/server.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/fs/ksmbd/server.h b/fs/ksmbd/server.h index b682d28963e8..2fce06e8b833 100644 --- a/fs/ksmbd/server.h +++ b/fs/ksmbd/server.h @@ -8,10 +8,15 @@ #include "smbacl.h" -#define SERVER_STATE_STARTING_UP 0 -#define SERVER_STATE_RUNNING 1 -#define SERVER_STATE_RESETTING 2 -#define SERVER_STATE_SHUTTING_DOWN 3 +/* + * Server state type + */ +enum { + SERVER_STATE_STARTING_UP, + SERVER_STATE_RUNNING, + SERVER_STATE_RESETTING, + SERVER_STATE_SHUTTING_DOWN, +}; #define SERVER_CONF_NETBIOS_NAME 0 #define SERVER_CONF_SERVER_STRING 1 From c63ee4a521e766da6ec5ee1d2058d1ec06216214 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Wed, 30 Jun 2021 09:39:15 +0900 Subject: [PATCH 42/45] ksmbd: change server config string index to enumeration Change server config string index to enumeration. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/server.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/ksmbd/server.h b/fs/ksmbd/server.h index 2fce06e8b833..ac9d932f8c8a 100644 --- a/fs/ksmbd/server.h +++ b/fs/ksmbd/server.h @@ -18,9 +18,14 @@ enum { SERVER_STATE_SHUTTING_DOWN, }; -#define SERVER_CONF_NETBIOS_NAME 0 -#define SERVER_CONF_SERVER_STRING 1 -#define SERVER_CONF_WORK_GROUP 2 +/* + * Server global config string index + */ +enum { + SERVER_CONF_NETBIOS_NAME, + SERVER_CONF_SERVER_STRING, + SERVER_CONF_WORK_GROUP, +}; struct ksmbd_server_config { unsigned int flags; From 8b758859dfbe9598ba41e8b9b01e44edcc0c2fc1 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Tue, 29 Jun 2021 14:52:00 +0900 Subject: [PATCH 43/45] ksmbd: reorder and document on-disk and netlink structures in headers Reorder and document on-disk and netlink structures in headers. This is a userspace ABI to communicate data between ksmbd and user IPC daemon using netlink. This is added to track and cache user account DB and share configuration info from userspace. - KSMBD_EVENT_HEARTBEAT_REQUEST(ksmbd_heartbeat) This event is to check whether user IPC daemon is alive. If user IPC daemon is dead, ksmbd keep existing connection till disconnecting and new connection will be denied. - KSMBD_EVENT_STARTING_UP(ksmbd_startup_request) This event is to receive the information that initializes the ksmbd server from the user IPC daemon and to start the server. The global section parameters are given from smb.conf as initialization information. - KSMBD_EVENT_SHUTTING_DOWN(ksmbd_shutdown_request) This event is to shutdown ksmbd server. - KSMBD_EVENT_LOGIN_REQUEST/RESPONSE(ksmbd_login_request/response) This event is to get user account info to user IPC daemon. - KSMBD_EVENT_SHARE_CONFIG_REQUEST/RESPONSE (ksmbd_share_config_request/response) This event is to get net share configuration info. - KSMBD_EVENT_TREE_CONNECT_REQUEST/RESPONSE (ksmbd_tree_connect_request/response) This event is to get session and tree connect info. - KSMBD_EVENT_TREE_DISCONNECT_REQUEST(ksmbd_tree_disconnect_request) This event is to send tree disconnect info to user IPC daemon. - KSMBD_EVENT_LOGOUT_REQUEST(ksmbd_logout_request) This event is to send logout request to user IPC daemon. - KSMBD_EVENT_RPC_REQUEST/RESPONSE(ksmbd_rpc_command) This event is to make DCE/RPC request like srvsvc, wkssvc, lsarpc, samr to be processed in userspace. - KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST/RESPONSE (ksmbd_spnego_authen_request/response) This event is to make kerberos authentication to be processed in userspace. Reviewed-by: Christoph Hellwig Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/{ksmbd_server.h => ksmbd_netlink.h} | 177 +++++++++++++++---- fs/ksmbd/ksmbd_work.c | 1 - fs/ksmbd/mgmt/tree_connect.h | 2 +- fs/ksmbd/smb2ops.c | 1 - fs/ksmbd/smbacl.c | 1 - fs/ksmbd/vfs.h | 87 +-------- fs/ksmbd/xattr.h | 122 +++++++++++++ 7 files changed, 269 insertions(+), 122 deletions(-) rename fs/ksmbd/{ksmbd_server.h => ksmbd_netlink.h} (55%) create mode 100644 fs/ksmbd/xattr.h diff --git a/fs/ksmbd/ksmbd_server.h b/fs/ksmbd/ksmbd_netlink.h similarity index 55% rename from fs/ksmbd/ksmbd_server.h rename to fs/ksmbd/ksmbd_netlink.h index 55b7602b79bd..2fbe2bc1e093 100644 --- a/fs/ksmbd/ksmbd_server.h +++ b/fs/ksmbd/ksmbd_netlink.h @@ -10,6 +10,49 @@ #include +/* + * This is a userspace ABI to communicate data between ksmbd and user IPC + * daemon using netlink. This is added to track and cache user account DB + * and share configuration info from userspace. + * + * - KSMBD_EVENT_HEARTBEAT_REQUEST(ksmbd_heartbeat) + * This event is to check whether user IPC daemon is alive. If user IPC + * daemon is dead, ksmbd keep existing connection till disconnecting and + * new connection will be denied. + * + * - KSMBD_EVENT_STARTING_UP(ksmbd_startup_request) + * This event is to receive the information that initializes the ksmbd + * server from the user IPC daemon and to start the server. The global + * section parameters are given from smb.conf as initialization + * information. + * + * - KSMBD_EVENT_SHUTTING_DOWN(ksmbd_shutdown_request) + * This event is to shutdown ksmbd server. + * + * - KSMBD_EVENT_LOGIN_REQUEST/RESPONSE(ksmbd_login_request/response) + * This event is to get user account info to user IPC daemon. + * + * - KSMBD_EVENT_SHARE_CONFIG_REQUEST/RESPONSE(ksmbd_share_config_request/response) + * This event is to get net share configuration info. + * + * - KSMBD_EVENT_TREE_CONNECT_REQUEST/RESPONSE(ksmbd_tree_connect_request/response) + * This event is to get session and tree connect info. + * + * - KSMBD_EVENT_TREE_DISCONNECT_REQUEST(ksmbd_tree_disconnect_request) + * This event is to send tree disconnect info to user IPC daemon. + * + * - KSMBD_EVENT_LOGOUT_REQUEST(ksmbd_logout_request) + * This event is to send logout request to user IPC daemon. + * + * - KSMBD_EVENT_RPC_REQUEST/RESPONSE(ksmbd_rpc_command) + * This event is to make DCE/RPC request like srvsvc, wkssvc, lsarpc, + * samr to be processed in userspace. + * + * - KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST/RESPONSE(ksmbd_spnego_authen_request/response) + * This event is to make kerberos authentication to be processed in + * userspace. + */ + #define KSMBD_GENL_NAME "SMBD_GENL" #define KSMBD_GENL_VERSION 0x01 @@ -17,6 +60,9 @@ #define KSMBD_REQ_MAX_HASH_SZ 18 #define KSMBD_REQ_MAX_SHARE_NAME 64 +/* + * IPC heartbeat frame to check whether user IPC daemon is alive. + */ struct ksmbd_heartbeat { __u32 handle; }; @@ -29,53 +75,79 @@ struct ksmbd_heartbeat { #define KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION BIT(1) #define KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL BIT(2) +/* + * IPC request for ksmbd server startup + */ struct ksmbd_startup_request { - __u32 flags; - __s32 signing; - __s8 min_prot[16]; - __s8 max_prot[16]; + __u32 flags; /* Flags for global config */ + __s32 signing; /* Signing enabled */ + __s8 min_prot[16]; /* The minimum SMB protocol version */ + __s8 max_prot[16]; /* The maximum SMB protocol version */ __s8 netbios_name[16]; - __s8 work_group[64]; - __s8 server_string[64]; - __u16 tcp_port; - __u16 ipc_timeout; - __u32 deadtime; - __u32 file_max; - __u32 smb2_max_write; - __u32 smb2_max_read; - __u32 smb2_max_trans; - __u32 share_fake_fscaps; - __u32 sub_auth[3]; - __u32 ifc_list_sz; + __s8 work_group[64]; /* Workgroup */ + __s8 server_string[64]; /* Server string */ + __u16 tcp_port; /* tcp port */ + __u16 ipc_timeout; /* + * specifies the number of seconds + * server will wait for the userspace to + * reply to heartbeat frames. + */ + __u32 deadtime; /* Number of minutes of inactivity */ + __u32 file_max; /* Limits the maximum number of open files */ + __u32 smb2_max_write; /* MAX write size */ + __u32 smb2_max_read; /* MAX read size */ + __u32 smb2_max_trans; /* MAX trans size */ + __u32 share_fake_fscaps; /* + * Support some special application that + * makes QFSINFO calls to check whether + * we set the SPARSE_FILES bit (0x40). + */ + __u32 sub_auth[3]; /* Subauth value for Security ID */ + __u32 ifc_list_sz; /* interfaces list size */ __s8 ____payload[]; }; #define KSMBD_STARTUP_CONFIG_INTERFACES(s) ((s)->____payload) +/* + * IPC request to shutdown ksmbd server. + */ struct ksmbd_shutdown_request { __s32 reserved; }; +/* + * IPC user login request. + */ struct ksmbd_login_request { __u32 handle; - __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; + __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; /* user account name */ }; +/* + * IPC user login response. + */ struct ksmbd_login_response { __u32 handle; - __u32 gid; - __u32 uid; - __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; + __u32 gid; /* group id */ + __u32 uid; /* user id */ + __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; /* user account name */ __u16 status; - __u16 hash_sz; - __s8 hash[KSMBD_REQ_MAX_HASH_SZ]; + __u16 hash_sz; /* hash size */ + __s8 hash[KSMBD_REQ_MAX_HASH_SZ]; /* password hash */ }; +/* + * IPC request to fetch net share config. + */ struct ksmbd_share_config_request { __u32 handle; - __s8 share_name[KSMBD_REQ_MAX_SHARE_NAME]; + __s8 share_name[KSMBD_REQ_MAX_SHARE_NAME]; /* share name */ }; +/* + * IPC response to the net share config request. + */ struct ksmbd_share_config_response { __u32 handle; __u32 flags; @@ -102,6 +174,10 @@ ksmbd_share_config_path(struct ksmbd_share_config_response *sc) return p; } +/* + * IPC request for tree connection. This request include session and tree + * connect info from client. + */ struct ksmbd_tree_connect_request { __u32 handle; __u16 account_flags; @@ -113,21 +189,34 @@ struct ksmbd_tree_connect_request { __s8 peer_addr[64]; }; +/* + * IPC Response structure for tree connection. + */ struct ksmbd_tree_connect_response { __u32 handle; __u16 status; __u16 connection_flags; }; +/* + * IPC Request struture to disconnect tree connection. + */ struct ksmbd_tree_disconnect_request { - __u64 session_id; - __u64 connect_id; + __u64 session_id; /* session id */ + __u64 connect_id; /* tree connection id */ }; +/* + * IPC Response structure to logout user account. + */ struct ksmbd_logout_request { - __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; + __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; /* user account name */ }; +/* + * RPC command structure to send rpc request like srvsvc or wkssvc to + * IPC user daemon. + */ struct ksmbd_rpc_command { __u32 handle; __u32 flags; @@ -135,18 +224,36 @@ struct ksmbd_rpc_command { __u8 payload[]; }; +/* + * IPC Request Kerberos authentication + */ struct ksmbd_spnego_authen_request { __u32 handle; - __u16 spnego_blob_len; - __u8 spnego_blob[0]; + __u16 spnego_blob_len; /* the length of spnego_blob */ + __u8 spnego_blob[0]; /* + * the GSS token from SecurityBuffer of + * SMB2 SESSION SETUP request + */ }; +/* + * Response data which includes the GSS token and the session key generated by + * user daemon. + */ struct ksmbd_spnego_authen_response { __u32 handle; - struct ksmbd_login_response login_response; - __u16 session_key_len; - __u16 spnego_blob_len; - __u8 payload[]; /* session key + AP_REP */ + struct ksmbd_login_response login_response; /* + * the login response with + * a user identified by the + * GSS token from a client + */ + __u16 session_key_len; /* the length of the session key */ + __u16 spnego_blob_len; /* + * the length of the GSS token which will be + * stored in SecurityBuffer of SMB2 SESSION + * SETUP response + */ + __u8 payload[]; /* session key + AP_REP */ }; /* @@ -185,6 +292,9 @@ enum ksmbd_event { KSMBD_EVENT_MAX }; +/* + * Enumeration for IPC tree connect status. + */ enum KSMBD_TREE_CONN_STATUS { KSMBD_TREE_CONN_STATUS_OK = 0, KSMBD_TREE_CONN_STATUS_NOMEM, @@ -262,6 +372,9 @@ enum KSMBD_TREE_CONN_STATUS { #define KSMBD_RPC_LSARPC_METHOD_INVOKE BIT(11) #define KSMBD_RPC_LSARPC_METHOD_RETURN (KSMBD_RPC_LSARPC_METHOD_INVOKE | KSMBD_RPC_METHOD_RETURN) +/* + * RPC status definitions. + */ #define KSMBD_RPC_OK 0 #define KSMBD_RPC_EBAD_FUNC 0x00000001 #define KSMBD_RPC_EACCESS_DENIED 0x00000005 diff --git a/fs/ksmbd/ksmbd_work.c b/fs/ksmbd/ksmbd_work.c index 7c914451bbe1..fd58eb4809f6 100644 --- a/fs/ksmbd/ksmbd_work.c +++ b/fs/ksmbd/ksmbd_work.c @@ -12,7 +12,6 @@ #include "connection.h" #include "ksmbd_work.h" #include "mgmt/ksmbd_ida.h" -#include "ksmbd_server.h" static struct kmem_cache *work_cache; static struct workqueue_struct *ksmbd_wq; diff --git a/fs/ksmbd/mgmt/tree_connect.h b/fs/ksmbd/mgmt/tree_connect.h index 4e40ec3f4774..18e2a996e0aa 100644 --- a/fs/ksmbd/mgmt/tree_connect.h +++ b/fs/ksmbd/mgmt/tree_connect.h @@ -8,7 +8,7 @@ #include -#include "../ksmbd_server.h" +#include "../ksmbd_netlink.h" struct ksmbd_share_config; struct ksmbd_user; diff --git a/fs/ksmbd/smb2ops.c b/fs/ksmbd/smb2ops.c index f7e5f21d4ae2..8262908e467c 100644 --- a/fs/ksmbd/smb2ops.c +++ b/fs/ksmbd/smb2ops.c @@ -12,7 +12,6 @@ #include "connection.h" #include "smb_common.h" #include "server.h" -#include "ksmbd_server.h" static struct smb_version_values smb21_server_values = { .version_string = SMB21_VERSION_STRING, diff --git a/fs/ksmbd/smbacl.c b/fs/ksmbd/smbacl.c index 958937a548a1..d385c7045cc0 100644 --- a/fs/ksmbd/smbacl.c +++ b/fs/ksmbd/smbacl.c @@ -14,7 +14,6 @@ #include "smb_common.h" #include "server.h" #include "misc.h" -#include "ksmbd_server.h" #include "mgmt/share_config.h" static const struct smb_sid domain = {1, 4, {0, 0, 0, 0, 0, 5}, diff --git a/fs/ksmbd/vfs.h b/fs/ksmbd/vfs.h index ba12fea004b5..e30174a0e5a1 100644 --- a/fs/ksmbd/vfs.h +++ b/fs/ksmbd/vfs.h @@ -14,92 +14,7 @@ #include #include "smbacl.h" - -/* STREAM XATTR PREFIX */ -#define STREAM_PREFIX "DosStream." -#define STREAM_PREFIX_LEN (sizeof(STREAM_PREFIX) - 1) -#define XATTR_NAME_STREAM (XATTR_USER_PREFIX STREAM_PREFIX) -#define XATTR_NAME_STREAM_LEN (sizeof(XATTR_NAME_STREAM) - 1) - -enum { - XATTR_DOSINFO_ATTRIB = 0x00000001, - XATTR_DOSINFO_EA_SIZE = 0x00000002, - XATTR_DOSINFO_SIZE = 0x00000004, - XATTR_DOSINFO_ALLOC_SIZE = 0x00000008, - XATTR_DOSINFO_CREATE_TIME = 0x00000010, - XATTR_DOSINFO_CHANGE_TIME = 0x00000020, - XATTR_DOSINFO_ITIME = 0x00000040 -}; - -struct xattr_dos_attrib { - __u16 version; - __u32 flags; - __u32 attr; - __u32 ea_size; - __u64 size; - __u64 alloc_size; - __u64 create_time; - __u64 change_time; - __u64 itime; -}; - -/* DOS ATTRIBUITE XATTR PREFIX */ -#define DOS_ATTRIBUTE_PREFIX "DOSATTRIB" -#define DOS_ATTRIBUTE_PREFIX_LEN (sizeof(DOS_ATTRIBUTE_PREFIX) - 1) -#define XATTR_NAME_DOS_ATTRIBUTE \ - (XATTR_USER_PREFIX DOS_ATTRIBUTE_PREFIX) -#define XATTR_NAME_DOS_ATTRIBUTE_LEN \ - (sizeof(XATTR_USER_PREFIX DOS_ATTRIBUTE_PREFIX) - 1) - -#define XATTR_SD_HASH_TYPE_SHA256 0x1 -#define XATTR_SD_HASH_SIZE 64 - -#define SMB_ACL_READ 4 -#define SMB_ACL_WRITE 2 -#define SMB_ACL_EXECUTE 1 - -enum { - SMB_ACL_TAG_INVALID = 0, - SMB_ACL_USER, - SMB_ACL_USER_OBJ, - SMB_ACL_GROUP, - SMB_ACL_GROUP_OBJ, - SMB_ACL_OTHER, - SMB_ACL_MASK -}; - -struct xattr_acl_entry { - int type; - uid_t uid; - gid_t gid; - mode_t perm; -}; - -struct xattr_smb_acl { - int count; - int next; - struct xattr_acl_entry entries[0]; -}; - -struct xattr_ntacl { - __u16 version; - void *sd_buf; - __u32 sd_size; - __u16 hash_type; - __u8 desc[10]; - __u16 desc_len; - __u64 current_time; - __u8 hash[XATTR_SD_HASH_SIZE]; - __u8 posix_acl_hash[XATTR_SD_HASH_SIZE]; -}; - -/* SECURITY DESCRIPTOR XATTR PREFIX */ -#define SD_PREFIX "NTACL" -#define SD_PREFIX_LEN (sizeof(SD_PREFIX) - 1) -#define XATTR_NAME_SD \ - (XATTR_SECURITY_PREFIX SD_PREFIX) -#define XATTR_NAME_SD_LEN \ - (sizeof(XATTR_SECURITY_PREFIX SD_PREFIX) - 1) +#include "xattr.h" /* * Enumeration for stream type. diff --git a/fs/ksmbd/xattr.h b/fs/ksmbd/xattr.h new file mode 100644 index 000000000000..8857c01093d9 --- /dev/null +++ b/fs/ksmbd/xattr.h @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2021 Samsung Electronics Co., Ltd. + */ + +#ifndef __XATTR_H__ +#define __XATTR_H__ + +/* + * These are on-disk structures to store additional metadata into xattr to + * reproduce windows filesystem semantics. And they are encoded with NDR to + * compatible with samba's xattr meta format. The compatibility with samba + * is important because it can lose the information(file attribute, + * creation time, acls) about the existing files when switching between + * ksmbd and samba. + */ + +/* + * Dos attribute flags used for what variable is valid. + */ +enum { + XATTR_DOSINFO_ATTRIB = 0x00000001, + XATTR_DOSINFO_EA_SIZE = 0x00000002, + XATTR_DOSINFO_SIZE = 0x00000004, + XATTR_DOSINFO_ALLOC_SIZE = 0x00000008, + XATTR_DOSINFO_CREATE_TIME = 0x00000010, + XATTR_DOSINFO_CHANGE_TIME = 0x00000020, + XATTR_DOSINFO_ITIME = 0x00000040 +}; + +/* + * Dos attribute structure which is compatible with samba's one. + * Storing it into the xattr named "DOSATTRIB" separately from inode + * allows ksmbd to faithfully reproduce windows filesystem semantics + * on top of a POSIX filesystem. + */ +struct xattr_dos_attrib { + __u16 version; /* version 3 or version 4 */ + __u32 flags; /* valid flags */ + __u32 attr; /* Dos attribute */ + __u32 ea_size; /* EA size */ + __u64 size; + __u64 alloc_size; + __u64 create_time; /* File creation time */ + __u64 change_time; /* File change time */ + __u64 itime; /* Invented/Initial time */ +}; + +/* + * Enumeration is used for computing posix acl hash. + */ +enum { + SMB_ACL_TAG_INVALID = 0, + SMB_ACL_USER, + SMB_ACL_USER_OBJ, + SMB_ACL_GROUP, + SMB_ACL_GROUP_OBJ, + SMB_ACL_OTHER, + SMB_ACL_MASK +}; + +#define SMB_ACL_READ 4 +#define SMB_ACL_WRITE 2 +#define SMB_ACL_EXECUTE 1 + +struct xattr_acl_entry { + int type; + uid_t uid; + gid_t gid; + mode_t perm; +}; + +/* + * xattr_smb_acl structure is used for computing posix acl hash. + */ +struct xattr_smb_acl { + int count; + int next; + struct xattr_acl_entry entries[0]; +}; + +/* 64bytes hash in xattr_ntacl is computed with sha256 */ +#define XATTR_SD_HASH_TYPE_SHA256 0x1 +#define XATTR_SD_HASH_SIZE 64 + +/* + * xattr_ntacl is used for storing ntacl and hashes. + * Hash is used for checking valid posix acl and ntacl in xattr. + */ +struct xattr_ntacl { + __u16 version; /* version 4*/ + void *sd_buf; + __u32 sd_size; + __u16 hash_type; /* hash type */ + __u8 desc[10]; /* posix_acl description */ + __u16 desc_len; + __u64 current_time; + __u8 hash[XATTR_SD_HASH_SIZE]; /* 64bytes hash for ntacl */ + __u8 posix_acl_hash[XATTR_SD_HASH_SIZE]; /* 64bytes hash for posix acl */ +}; + +/* DOS ATTRIBUITE XATTR PREFIX */ +#define DOS_ATTRIBUTE_PREFIX "DOSATTRIB" +#define DOS_ATTRIBUTE_PREFIX_LEN (sizeof(DOS_ATTRIBUTE_PREFIX) - 1) +#define XATTR_NAME_DOS_ATTRIBUTE (XATTR_USER_PREFIX DOS_ATTRIBUTE_PREFIX) +#define XATTR_NAME_DOS_ATTRIBUTE_LEN \ + (sizeof(XATTR_USER_PREFIX DOS_ATTRIBUTE_PREFIX) - 1) + +/* STREAM XATTR PREFIX */ +#define STREAM_PREFIX "DosStream." +#define STREAM_PREFIX_LEN (sizeof(STREAM_PREFIX) - 1) +#define XATTR_NAME_STREAM (XATTR_USER_PREFIX STREAM_PREFIX) +#define XATTR_NAME_STREAM_LEN (sizeof(XATTR_NAME_STREAM) - 1) + +/* SECURITY DESCRIPTOR(NTACL) XATTR PREFIX */ +#define SD_PREFIX "NTACL" +#define SD_PREFIX_LEN (sizeof(SD_PREFIX) - 1) +#define XATTR_NAME_SD (XATTR_SECURITY_PREFIX SD_PREFIX) +#define XATTR_NAME_SD_LEN \ + (sizeof(XATTR_SECURITY_PREFIX SD_PREFIX) - 1) + +#endif /* __XATTR_H__ */ From ef24c962d0f29036041a007a75bcd0f50233c83e Mon Sep 17 00:00:00 2001 From: Hyunchul Lee Date: Wed, 30 Jun 2021 18:25:52 +0900 Subject: [PATCH 44/45] ksmbd: replace struct dentry with struct path in some function's arguments For user namespace support, we need to pass struct user_namespace with struct dentry to some functions. For reducing the number of arguments, replace the struct dentry with struct path in these functions. Reviewed-by: Christoph Hellwig Signed-off-by: Hyunchul Lee Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/smb2pdu.c | 21 +++++++++++---------- fs/ksmbd/smbacl.c | 25 +++++++++++++------------ fs/ksmbd/smbacl.h | 6 +++--- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index bf798ee65b25..d79ea3eb57a7 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -2172,13 +2172,13 @@ static noinline int smb2_set_stream_name_xattr(struct path *path, return 0; } -static int smb2_remove_smb_xattrs(struct dentry *dentry) +static int smb2_remove_smb_xattrs(struct path *path) { char *name, *xattr_list = NULL; ssize_t xattr_list_len; int err = 0; - xattr_list_len = ksmbd_vfs_listxattr(dentry, &xattr_list); + xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list); if (xattr_list_len < 0) { goto out; } else if (!xattr_list_len) { @@ -2196,7 +2196,7 @@ static int smb2_remove_smb_xattrs(struct dentry *dentry) strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX, STREAM_PREFIX_LEN)) continue; - err = ksmbd_vfs_remove_xattr(dentry, name); + err = ksmbd_vfs_remove_xattr(path->dentry, name); if (err) ksmbd_debug(SMB, "remove xattr failed : %s\n", name); } @@ -2214,7 +2214,7 @@ static int smb2_create_truncate(struct path *path) return rc; } - rc = smb2_remove_smb_xattrs(path->dentry); + rc = smb2_remove_smb_xattrs(path); if (rc == -EOPNOTSUPP) rc = 0; if (rc) @@ -2305,7 +2305,7 @@ static int smb2_creat(struct ksmbd_work *work, struct path *path, char *name, static int smb2_create_sd_buffer(struct ksmbd_work *work, struct smb2_create_req *req, - struct dentry *dentry) + struct path *path) { struct create_context *context; int rc = -ENOENT; @@ -2321,7 +2321,8 @@ static int smb2_create_sd_buffer(struct ksmbd_work *work, ksmbd_debug(SMB, "Set ACLs using SMB2_CREATE_SD_BUFFER context\n"); sd_buf = (struct create_sd_buf_req *)context; - rc = set_info_sec(work->conn, work->tcon, dentry, &sd_buf->ntsd, + rc = set_info_sec(work->conn, work->tcon, + path, &sd_buf->ntsd, le32_to_cpu(sd_buf->ccontext.DataLength), true); } @@ -2684,7 +2685,7 @@ int smb2_open(struct ksmbd_work *work) daccess = smb_map_generic_desired_access(req->DesiredAccess); if (file_present && !(req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) { - rc = smb_check_perm_dacl(conn, path.dentry, &daccess, + rc = smb_check_perm_dacl(conn, &path, &daccess, sess->user->uid); if (rc) goto err_out; @@ -2814,12 +2815,12 @@ int smb2_open(struct ksmbd_work *work) if (test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) { - rc = smb_inherit_dacl(conn, path.dentry, sess->user->uid, + rc = smb_inherit_dacl(conn, &path, sess->user->uid, sess->user->gid); } if (rc) { - rc = smb2_create_sd_buffer(work, req, path.dentry); + rc = smb2_create_sd_buffer(work, req, &path); if (rc) { if (posix_acl_rc) ksmbd_vfs_set_init_posix_acl(inode); @@ -5719,7 +5720,7 @@ static int smb2_set_info_sec(struct ksmbd_file *fp, int addition_info, fp->saccess |= FILE_SHARE_DELETE_LE; - return set_info_sec(fp->conn, fp->tcon, fp->filp->f_path.dentry, pntsd, + return set_info_sec(fp->conn, fp->tcon, &fp->filp->f_path, pntsd, buf_len, false); } diff --git a/fs/ksmbd/smbacl.c b/fs/ksmbd/smbacl.c index d385c7045cc0..e0825d3771a1 100644 --- a/fs/ksmbd/smbacl.c +++ b/fs/ksmbd/smbacl.c @@ -941,7 +941,8 @@ static void smb_set_ace(struct smb_ace *ace, const struct smb_sid *sid, u8 type, ace->size = cpu_to_le16(1 + 1 + 2 + 4 + 1 + 1 + 6 + (sid->num_subauth * 4)); } -int smb_inherit_dacl(struct ksmbd_conn *conn, struct dentry *dentry, +int smb_inherit_dacl(struct ksmbd_conn *conn, + struct path *path, unsigned int uid, unsigned int gid) { const struct smb_sid *psid, *creator = NULL; @@ -949,11 +950,11 @@ int smb_inherit_dacl(struct ksmbd_conn *conn, struct dentry *dentry, struct smb_acl *parent_pdacl; struct smb_ntsd *parent_pntsd = NULL; struct smb_sid owner_sid, group_sid; - struct dentry *parent = dentry->d_parent; + struct dentry *parent = path->dentry->d_parent; int inherited_flags = 0, flags = 0, i, ace_cnt = 0, nt_size = 0; int rc = -ENOENT, num_aces, dacloffset, pntsd_type, acl_len; char *aces_base; - bool is_dir = S_ISDIR(d_inode(dentry)->i_mode); + bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode); acl_len = ksmbd_vfs_get_sd_xattr(conn, parent, &parent_pntsd); if (acl_len <= 0) @@ -1086,7 +1087,7 @@ pass: pntsd_size += sizeof(struct smb_acl) + nt_size; } - ksmbd_vfs_set_sd_xattr(conn, dentry, pntsd, pntsd_size); + ksmbd_vfs_set_sd_xattr(conn, path->dentry, pntsd, pntsd_size); kfree(pntsd); rc = 0; } @@ -1109,7 +1110,7 @@ bool smb_inherit_flags(int flags, bool is_dir) return false; } -int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry, +int smb_check_perm_dacl(struct ksmbd_conn *conn, struct path *path, __le32 *pdaccess, int uid) { struct smb_ntsd *pntsd = NULL; @@ -1127,7 +1128,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry, char *end_of_acl; ksmbd_debug(SMB, "check permission using windows acl\n"); - acl_size = ksmbd_vfs_get_sd_xattr(conn, dentry, &pntsd); + acl_size = ksmbd_vfs_get_sd_xattr(conn, path->dentry, &pntsd); if (acl_size <= 0 || !pntsd || !pntsd->dacloffset) { kfree(pntsd); return 0; @@ -1201,7 +1202,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry, granted = GENERIC_ALL_FLAGS; } - posix_acls = get_acl(d_inode(dentry), ACL_TYPE_ACCESS); + posix_acls = get_acl(d_inode(path->dentry), ACL_TYPE_ACCESS); if (posix_acls && !found) { unsigned int id = -1; @@ -1261,12 +1262,12 @@ err_out: } int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, - struct dentry *dentry, struct smb_ntsd *pntsd, int ntsd_len, + struct path *path, struct smb_ntsd *pntsd, int ntsd_len, bool type_check) { int rc; struct smb_fattr fattr = {{0}}; - struct inode *inode = d_inode(dentry); + struct inode *inode = d_inode(path->dentry); fattr.cf_uid = INVALID_UID; fattr.cf_gid = INVALID_GID; @@ -1283,7 +1284,7 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, inode->i_gid = fattr.cf_gid; mark_inode_dirty(inode); - ksmbd_vfs_remove_acl_xattrs(dentry); + ksmbd_vfs_remove_acl_xattrs(path->dentry); /* Update posix acls */ if (fattr.cf_dacls) { rc = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS, @@ -1299,8 +1300,8 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, if (test_share_config_flag(tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) { /* Update WinACL in xattr */ - ksmbd_vfs_remove_sd_xattrs(dentry); - ksmbd_vfs_set_sd_xattr(conn, dentry, pntsd, ntsd_len); + ksmbd_vfs_remove_sd_xattrs(path->dentry); + ksmbd_vfs_set_sd_xattr(conn, path->dentry, pntsd, ntsd_len); } out: diff --git a/fs/ksmbd/smbacl.h b/fs/ksmbd/smbacl.h index 3e1345e9f24f..4ee7bda32e5f 100644 --- a/fs/ksmbd/smbacl.h +++ b/fs/ksmbd/smbacl.h @@ -200,12 +200,12 @@ void posix_state_to_acl(struct posix_acl_state *state, struct posix_acl_entry *pace); int compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid); bool smb_inherit_flags(int flags, bool is_dir); -int smb_inherit_dacl(struct ksmbd_conn *conn, struct dentry *dentry, +int smb_inherit_dacl(struct ksmbd_conn *conn, struct path *path, unsigned int uid, unsigned int gid); -int smb_check_perm_dacl(struct ksmbd_conn *conn, struct dentry *dentry, +int smb_check_perm_dacl(struct ksmbd_conn *conn, struct path *path, __le32 *pdaccess, int uid); int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, - struct dentry *dentry, struct smb_ntsd *pntsd, int ntsd_len, + struct path *path, struct smb_ntsd *pntsd, int ntsd_len, bool type_check); void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid); void ksmbd_init_domain(u32 *sub_auth); From af34983e831587472333e47c86a350a2360c6093 Mon Sep 17 00:00:00 2001 From: Hyunchul Lee Date: Wed, 30 Jun 2021 18:25:53 +0900 Subject: [PATCH 45/45] ksmbd: add user namespace support For user namespace support, call vfs functions with struct user_namespace got from struct path. This patch have been tested mannually as below. Create an id-mapped mount using the mount-idmapped utility (https://github.com/brauner/mount-idmapped). $ mount-idmapped --map-mount b:1003:1002:1 /home/foo /foo (the user, "foo" is 1003, and the user "bar" is 1002). And mount the export directory using cifs with the user, "bar". succeed to create/delete/stat/read/write files and directory in the /foo. But fail with a bind mount for /home/foo. Reviewed-by: Christoph Hellwig Signed-off-by: Hyunchul Lee Signed-off-by: Namjae Jeon Signed-off-by: Steve French --- fs/ksmbd/ndr.c | 8 +- fs/ksmbd/ndr.h | 4 +- fs/ksmbd/oplock.c | 4 +- fs/ksmbd/smb2pdu.c | 113 +++++++++++++++++---------- fs/ksmbd/smb_common.c | 5 +- fs/ksmbd/smb_common.h | 1 + fs/ksmbd/smbacl.c | 99 +++++++++++++----------- fs/ksmbd/smbacl.h | 10 +-- fs/ksmbd/vfs.c | 172 ++++++++++++++++++++++++++---------------- fs/ksmbd/vfs.h | 51 +++++++++---- fs/ksmbd/vfs_cache.c | 5 +- 11 files changed, 294 insertions(+), 178 deletions(-) diff --git a/fs/ksmbd/ndr.c b/fs/ksmbd/ndr.c index bcf13a2aa9d4..cf0df78259c9 100644 --- a/fs/ksmbd/ndr.c +++ b/fs/ksmbd/ndr.c @@ -222,7 +222,9 @@ static int ndr_encode_posix_acl_entry(struct ndr *n, struct xattr_smb_acl *acl) return 0; } -int ndr_encode_posix_acl(struct ndr *n, struct inode *inode, +int ndr_encode_posix_acl(struct ndr *n, + struct user_namespace *user_ns, + struct inode *inode, struct xattr_smb_acl *acl, struct xattr_smb_acl *def_acl) { @@ -250,8 +252,8 @@ int ndr_encode_posix_acl(struct ndr *n, struct inode *inode, ndr_write_int32(n, 0); } - 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_kuid(user_ns, inode->i_uid)); + ndr_write_int64(n, from_kgid(user_ns, inode->i_gid)); ndr_write_int32(n, inode->i_mode); if (acl) { diff --git a/fs/ksmbd/ndr.h b/fs/ksmbd/ndr.h index 77b2d1ac93a0..60ca265d1bb0 100644 --- a/fs/ksmbd/ndr.h +++ b/fs/ksmbd/ndr.h @@ -14,8 +14,8 @@ struct ndr { int ndr_encode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da); int ndr_decode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da); -int ndr_encode_posix_acl(struct ndr *n, struct inode *inode, - struct xattr_smb_acl *acl, +int ndr_encode_posix_acl(struct ndr *n, struct user_namespace *user_ns, + struct inode *inode, struct xattr_smb_acl *acl, struct xattr_smb_acl *def_acl); int ndr_encode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl); int ndr_encode_v3_ntacl(struct ndr *n, struct xattr_ntacl *acl); diff --git a/fs/ksmbd/oplock.c b/fs/ksmbd/oplock.c index a9f171ccf770..5484b5bf75b0 100644 --- a/fs/ksmbd/oplock.c +++ b/fs/ksmbd/oplock.c @@ -1612,9 +1612,9 @@ void create_posix_rsp_buf(char *cc, struct ksmbd_file *fp) buf->nlink = cpu_to_le32(inode->i_nlink); buf->reparse_tag = cpu_to_le32(fp->volatile_id); buf->mode = cpu_to_le32(inode->i_mode); - id_to_sid(from_kuid(&init_user_ns, inode->i_uid), + id_to_sid(from_kuid(file_mnt_user_ns(fp->filp), inode->i_uid), SIDNFS_USER, (struct smb_sid *)&buf->SidBuffer[0]); - id_to_sid(from_kgid(&init_user_ns, inode->i_gid), + id_to_sid(from_kgid(file_mnt_user_ns(fp->filp), inode->i_gid), SIDNFS_GROUP, (struct smb_sid *)&buf->SidBuffer[20]); } diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index d79ea3eb57a7..dda90812feef 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -2081,14 +2081,16 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, struct path *path) value = (char *)&eabuf->name + eabuf->EaNameLength + 1; if (!eabuf->EaValueLength) { - rc = ksmbd_vfs_casexattr_len(path->dentry, + rc = ksmbd_vfs_casexattr_len(mnt_user_ns(path->mnt), + path->dentry, attr_name, XATTR_USER_PREFIX_LEN + eabuf->EaNameLength); /* delete the EA only when it exits */ if (rc > 0) { - rc = ksmbd_vfs_remove_xattr(path->dentry, + rc = ksmbd_vfs_remove_xattr(mnt_user_ns(path->mnt), + path->dentry, attr_name); if (rc < 0) { @@ -2102,7 +2104,8 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, struct path *path) /* if the EA doesn't exist, just do nothing. */ rc = 0; } else { - rc = ksmbd_vfs_setxattr(path->dentry, attr_name, value, + rc = ksmbd_vfs_setxattr(mnt_user_ns(path->mnt), + path->dentry, attr_name, value, le16_to_cpu(eabuf->EaValueLength), 0); if (rc < 0) { ksmbd_debug(SMB, @@ -2155,7 +2158,8 @@ static noinline int smb2_set_stream_name_xattr(struct path *path, fp->stream.size = xattr_stream_size; /* Check if there is stream prefix in xattr space */ - rc = ksmbd_vfs_casexattr_len(path->dentry, + rc = ksmbd_vfs_casexattr_len(mnt_user_ns(path->mnt), + path->dentry, xattr_stream_name, xattr_stream_size); if (rc >= 0) @@ -2166,7 +2170,8 @@ static noinline int smb2_set_stream_name_xattr(struct path *path, return -EBADF; } - rc = ksmbd_vfs_setxattr(path->dentry, xattr_stream_name, NULL, 0, 0); + rc = ksmbd_vfs_setxattr(mnt_user_ns(path->mnt), + path->dentry, xattr_stream_name, NULL, 0, 0); if (rc < 0) pr_err("Failed to store XATTR stream name :%d\n", rc); return 0; @@ -2196,7 +2201,8 @@ static int smb2_remove_smb_xattrs(struct path *path) strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX, STREAM_PREFIX_LEN)) continue; - err = ksmbd_vfs_remove_xattr(path->dentry, name); + err = ksmbd_vfs_remove_xattr(mnt_user_ns(path->mnt), + path->dentry, name); if (err) ksmbd_debug(SMB, "remove xattr failed : %s\n", name); } @@ -2240,7 +2246,8 @@ static void smb2_new_xattrs(struct ksmbd_tree_connect *tcon, struct path *path, da.flags = XATTR_DOSINFO_ATTRIB | XATTR_DOSINFO_CREATE_TIME | XATTR_DOSINFO_ITIME; - rc = ksmbd_vfs_set_dos_attrib_xattr(path->dentry, &da); + rc = ksmbd_vfs_set_dos_attrib_xattr(mnt_user_ns(path->mnt), + path->dentry, &da); if (rc) ksmbd_debug(SMB, "failed to store file attribute into xattr\n"); } @@ -2258,7 +2265,8 @@ static void smb2_update_xattrs(struct ksmbd_tree_connect *tcon, KSMBD_SHARE_FLAG_STORE_DOS_ATTRS)) return; - rc = ksmbd_vfs_get_dos_attrib_xattr(path->dentry, &da); + rc = ksmbd_vfs_get_dos_attrib_xattr(mnt_user_ns(path->mnt), + path->dentry, &da); if (rc > 0) { fp->f_ci->m_fattr = cpu_to_le32(da.attr); fp->create_time = da.create_time; @@ -2634,7 +2642,7 @@ int smb2_open(struct ksmbd_work *work) rc = 0; } else { file_present = true; - generic_fillattr(&init_user_ns, d_inode(path.dentry), &stat); + generic_fillattr(mnt_user_ns(path.mnt), d_inode(path.dentry), &stat); } if (stream_name) { if (req->CreateOptions & FILE_DIRECTORY_FILE_LE) { @@ -2695,7 +2703,8 @@ int smb2_open(struct ksmbd_work *work) if (!file_present) { daccess = cpu_to_le32(GENERIC_ALL_FLAGS); } else { - rc = ksmbd_vfs_query_maximal_access(path.dentry, + rc = ksmbd_vfs_query_maximal_access(mnt_user_ns(path.mnt), + path.dentry, &daccess); if (rc) goto err_out; @@ -2738,7 +2747,7 @@ int smb2_open(struct ksmbd_work *work) * is already granted. */ if (daccess & ~(FILE_READ_ATTRIBUTES_LE | FILE_READ_CONTROL_LE)) { - rc = inode_permission(&init_user_ns, + rc = inode_permission(mnt_user_ns(path.mnt), d_inode(path.dentry), may_flags); if (rc) @@ -2746,7 +2755,8 @@ int smb2_open(struct ksmbd_work *work) if ((daccess & FILE_DELETE_LE) || (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) { - rc = ksmbd_vfs_may_delete(path.dentry); + rc = ksmbd_vfs_may_delete(mnt_user_ns(path.mnt), + path.dentry); if (rc) goto err_out; } @@ -2809,7 +2819,9 @@ int smb2_open(struct ksmbd_work *work) int posix_acl_rc; struct inode *inode = d_inode(path.dentry); - posix_acl_rc = ksmbd_vfs_inherit_posix_acl(inode, d_inode(path.dentry->d_parent)); + posix_acl_rc = ksmbd_vfs_inherit_posix_acl(mnt_user_ns(path.mnt), + inode, + d_inode(path.dentry->d_parent)); if (posix_acl_rc) ksmbd_debug(SMB, "inherit posix acl failed : %d\n", posix_acl_rc); @@ -2823,7 +2835,8 @@ int smb2_open(struct ksmbd_work *work) rc = smb2_create_sd_buffer(work, req, &path); if (rc) { if (posix_acl_rc) - ksmbd_vfs_set_init_posix_acl(inode); + ksmbd_vfs_set_init_posix_acl(mnt_user_ns(path.mnt), + inode); if (test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) { @@ -2845,15 +2858,17 @@ int smb2_open(struct ksmbd_work *work) if (!pntsd) goto err_out; - rc = build_sec_desc(pntsd, NULL, + rc = build_sec_desc(mnt_user_ns(path.mnt), + pntsd, NULL, OWNER_SECINFO | - GROUP_SECINFO | - DACL_SECINFO, + GROUP_SECINFO | + DACL_SECINFO, &pntsd_size, &fattr); posix_acl_release(fattr.cf_acls); posix_acl_release(fattr.cf_dacls); rc = ksmbd_vfs_set_sd_xattr(conn, + mnt_user_ns(path.mnt), path.dentry, pntsd, pntsd_size); @@ -2895,7 +2910,7 @@ int smb2_open(struct ksmbd_work *work) rc = ksmbd_vfs_getattr(&path, &stat); if (rc) { - generic_fillattr(&init_user_ns, d_inode(path.dentry), &stat); + generic_fillattr(mnt_user_ns(path.mnt), d_inode(path.dentry), &stat); rc = 0; } @@ -2996,7 +3011,8 @@ int smb2_open(struct ksmbd_work *work) memcpy(fp->client_guid, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE); - generic_fillattr(&init_user_ns, file_inode(fp->filp), &stat); + generic_fillattr(file_mnt_user_ns(fp->filp), file_inode(fp->filp), + &stat); rsp->StructureSize = cpu_to_le16(89); rcu_read_lock(); @@ -3048,7 +3064,8 @@ int smb2_open(struct ksmbd_work *work) struct create_context *mxac_ccontext; if (maximal_access == 0) - ksmbd_vfs_query_maximal_access(path.dentry, + ksmbd_vfs_query_maximal_access(mnt_user_ns(path.mnt), + path.dentry, &maximal_access); mxac_ccontext = (struct create_context *)(rsp->Buffer + le32_to_cpu(rsp->CreateContextsLength)); @@ -3251,6 +3268,7 @@ static int dentry_name(struct ksmbd_dir_info *d_info, int info_level) * @conn: connection instance * @info_level: smb information level * @d_info: structure included variables for query dir + * @user_ns: user namespace * @ksmbd_kstat: ksmbd wrapper of dirent stat information * * if directory has many entries, find first can't read it fully. @@ -3260,6 +3278,7 @@ static int dentry_name(struct ksmbd_dir_info *d_info, int info_level) */ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level, struct ksmbd_dir_info *d_info, + struct user_namespace *user_ns, struct ksmbd_kstat *ksmbd_kstat) { int next_entry_offset = 0; @@ -3412,9 +3431,9 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level, S_ISDIR(ksmbd_kstat->kstat->mode) ? ATTR_DIRECTORY_LE : ATTR_ARCHIVE_LE; if (d_info->hide_dot_file && d_info->name[0] == '.') posix_info->DosAttributes |= ATTR_HIDDEN_LE; - id_to_sid(from_kuid(&init_user_ns, ksmbd_kstat->kstat->uid), + id_to_sid(from_kuid(user_ns, ksmbd_kstat->kstat->uid), SIDNFS_USER, (struct smb_sid *)&posix_info->SidBuffer[0]); - id_to_sid(from_kgid(&init_user_ns, ksmbd_kstat->kstat->gid), + id_to_sid(from_kgid(user_ns, ksmbd_kstat->kstat->gid), SIDNFS_GROUP, (struct smb_sid *)&posix_info->SidBuffer[20]); memcpy(posix_info->name, conv_name, conv_len); posix_info->name_len = cpu_to_le32(conv_len); @@ -3496,12 +3515,14 @@ static int process_query_dir_entries(struct smb2_query_dir_private *priv) ksmbd_kstat.kstat = &kstat; if (priv->info_level != FILE_NAMES_INFORMATION) ksmbd_vfs_fill_dentry_attrs(priv->work, + file_mnt_user_ns(priv->dir_fp->filp), dent, &ksmbd_kstat); rc = smb2_populate_readdir_entry(priv->work->conn, priv->info_level, priv->d_info, + file_mnt_user_ns(priv->dir_fp->filp), &ksmbd_kstat); dput(dent); if (rc) @@ -3710,7 +3731,8 @@ int smb2_query_dir(struct ksmbd_work *work) } if (!(dir_fp->daccess & FILE_LIST_DIRECTORY_LE) || - inode_permission(&init_user_ns, file_inode(dir_fp->filp), + inode_permission(file_mnt_user_ns(dir_fp->filp), + file_inode(dir_fp->filp), MAY_READ | MAY_EXEC)) { pr_err("no right to enumerate directory (%pd)\n", dir_fp->filp->f_path.dentry); @@ -4035,7 +4057,8 @@ static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp, buf_free_len -= (offsetof(struct smb2_ea_info, name) + name_len + 1); /* bailout if xattr can't fit in buf_free_len */ - value_len = ksmbd_vfs_getxattr(path->dentry, name, &buf); + value_len = ksmbd_vfs_getxattr(mnt_user_ns(path->mnt), + path->dentry, name, &buf); if (value_len <= 0) { rc = -ENOENT; rsp->hdr.Status = STATUS_INVALID_HANDLE; @@ -4124,7 +4147,8 @@ static int get_file_basic_info(struct smb2_query_info_rsp *rsp, } basic_info = (struct smb2_file_all_info *)rsp->Buffer; - generic_fillattr(&init_user_ns, file_inode(fp->filp), &stat); + generic_fillattr(file_mnt_user_ns(fp->filp), file_inode(fp->filp), + &stat); basic_info->CreationTime = cpu_to_le64(fp->create_time); time = ksmbd_UnixTimeToNT(stat.atime); basic_info->LastAccessTime = cpu_to_le64(time); @@ -4165,7 +4189,7 @@ static void get_file_standard_info(struct smb2_query_info_rsp *rsp, struct kstat stat; inode = file_inode(fp->filp); - generic_fillattr(&init_user_ns, inode, &stat); + generic_fillattr(file_mnt_user_ns(fp->filp), inode, &stat); sinfo = (struct smb2_file_standard_info *)rsp->Buffer; delete_pending = ksmbd_inode_pending_delete(fp); @@ -4220,7 +4244,7 @@ static int get_file_all_info(struct ksmbd_work *work, return -ENOMEM; inode = file_inode(fp->filp); - generic_fillattr(&init_user_ns, inode, &stat); + generic_fillattr(file_mnt_user_ns(fp->filp), inode, &stat); ksmbd_debug(SMB, "filename = %s\n", filename); delete_pending = ksmbd_inode_pending_delete(fp); @@ -4295,7 +4319,8 @@ static void get_file_stream_info(struct ksmbd_work *work, ssize_t xattr_list_len; int nbytes = 0, streamlen, stream_name_len, next, idx = 0; - generic_fillattr(&init_user_ns, file_inode(fp->filp), &stat); + generic_fillattr(file_mnt_user_ns(fp->filp), file_inode(fp->filp), + &stat); file_info = (struct smb2_file_stream_info *)rsp->Buffer; xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list); @@ -4374,7 +4399,8 @@ static void get_file_internal_info(struct smb2_query_info_rsp *rsp, struct smb2_file_internal_info *file_info; struct kstat stat; - generic_fillattr(&init_user_ns, file_inode(fp->filp), &stat); + generic_fillattr(file_mnt_user_ns(fp->filp), file_inode(fp->filp), + &stat); file_info = (struct smb2_file_internal_info *)rsp->Buffer; file_info->IndexNumber = cpu_to_le64(stat.ino); rsp->OutputBufferLength = @@ -4399,7 +4425,7 @@ static int get_file_network_open_info(struct smb2_query_info_rsp *rsp, file_info = (struct smb2_file_ntwrk_info *)rsp->Buffer; inode = file_inode(fp->filp); - generic_fillattr(&init_user_ns, inode, &stat); + generic_fillattr(file_mnt_user_ns(fp->filp), inode, &stat); file_info->CreationTime = cpu_to_le64(fp->create_time); time = ksmbd_UnixTimeToNT(stat.atime); @@ -4460,7 +4486,8 @@ static void get_file_compression_info(struct smb2_query_info_rsp *rsp, struct smb2_file_comp_info *file_info; struct kstat stat; - generic_fillattr(&init_user_ns, file_inode(fp->filp), &stat); + generic_fillattr(file_mnt_user_ns(fp->filp), file_inode(fp->filp), + &stat); file_info = (struct smb2_file_comp_info *)rsp->Buffer; file_info->CompressedFileSize = cpu_to_le64(stat.blocks << 9); @@ -4933,9 +4960,11 @@ static int smb2_get_info_sec(struct ksmbd_work *work, if (test_share_config_flag(work->tcon->share_conf, 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, file_mnt_user_ns(fp->filp), + fp->filp->f_path.dentry, &ppntsd); - rc = build_sec_desc(pntsd, ppntsd, addition_info, &secdesclen, &fattr); + rc = build_sec_desc(file_mnt_user_ns(fp->filp), + pntsd, ppntsd, addition_info, &secdesclen, &fattr); posix_acl_release(fattr.cf_acls); posix_acl_release(fattr.cf_dacls); kfree(ppntsd); @@ -5228,7 +5257,8 @@ static int smb2_rename(struct ksmbd_work *work, struct ksmbd_file *fp, if (rc) goto out; - rc = ksmbd_vfs_setxattr(fp->filp->f_path.dentry, + rc = ksmbd_vfs_setxattr(file_mnt_user_ns(fp->filp), + fp->filp->f_path.dentry, xattr_stream_name, NULL, 0, 0); if (rc < 0) { @@ -5412,7 +5442,8 @@ static int set_file_basic_info(struct ksmbd_file *fp, char *buf, da.flags = XATTR_DOSINFO_ATTRIB | XATTR_DOSINFO_CREATE_TIME | XATTR_DOSINFO_ITIME; - rc = ksmbd_vfs_set_dos_attrib_xattr(filp->f_path.dentry, &da); + rc = ksmbd_vfs_set_dos_attrib_xattr(file_mnt_user_ns(filp), + filp->f_path.dentry, &da); if (rc) ksmbd_debug(SMB, "failed to restore file attribute in EA\n"); @@ -5433,14 +5464,14 @@ static int set_file_basic_info(struct ksmbd_file *fp, char *buf, if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) return -EACCES; - rc = setattr_prepare(&init_user_ns, dentry, &attrs); + rc = setattr_prepare(file_mnt_user_ns(filp), dentry, &attrs); if (rc) return -EINVAL; inode_lock(inode); - setattr_copy(&init_user_ns, inode, &attrs); + setattr_copy(file_mnt_user_ns(filp), inode, &attrs); attrs.ia_valid &= ~ATTR_CTIME; - rc = notify_change(&init_user_ns, dentry, &attrs, NULL); + rc = notify_change(file_mnt_user_ns(filp), dentry, &attrs, NULL); inode_unlock(inode); } return 0; @@ -7188,12 +7219,14 @@ static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id, KSMBD_SHARE_FLAG_STORE_DOS_ATTRS)) { 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(file_mnt_user_ns(fp->filp), + fp->filp->f_path.dentry, &da); if (ret <= 0) goto out; da.attr = le32_to_cpu(fp->f_ci->m_fattr); - ret = ksmbd_vfs_set_dos_attrib_xattr(fp->filp->f_path.dentry, &da); + ret = ksmbd_vfs_set_dos_attrib_xattr(file_mnt_user_ns(fp->filp), + fp->filp->f_path.dentry, &da); if (ret) fp->f_ci->m_fattr = old_fattr; } diff --git a/fs/ksmbd/smb_common.c b/fs/ksmbd/smb_common.c index b573575a1de5..f770f3ffb840 100644 --- a/fs/ksmbd/smb_common.c +++ b/fs/ksmbd/smb_common.c @@ -274,6 +274,7 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level, char *search_pattern, int (*fn)(struct ksmbd_conn *, int, struct ksmbd_dir_info *, + struct user_namespace *, struct ksmbd_kstat *)) { int i, rc = 0; @@ -300,9 +301,11 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level, ksmbd_kstat.kstat = &kstat; ksmbd_vfs_fill_dentry_attrs(work, + file_mnt_user_ns(dir->filp), dir->filp->f_path.dentry->d_parent, &ksmbd_kstat); - rc = fn(conn, info_level, d_info, &ksmbd_kstat); + rc = fn(conn, info_level, d_info, + file_mnt_user_ns(dir->filp), &ksmbd_kstat); if (rc) break; if (d_info->out_buf_len <= 0) diff --git a/fs/ksmbd/smb_common.h b/fs/ksmbd/smb_common.h index 8489b92229fa..6ab28aa33024 100644 --- a/fs/ksmbd/smb_common.h +++ b/fs/ksmbd/smb_common.h @@ -514,6 +514,7 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int (*fn)(struct ksmbd_conn *, int, struct ksmbd_dir_info *, + struct user_namespace *, struct ksmbd_kstat *)); int ksmbd_extract_shortname(struct ksmbd_conn *conn, diff --git a/fs/ksmbd/smbacl.c b/fs/ksmbd/smbacl.c index e0825d3771a1..4ee714b9b351 100644 --- a/fs/ksmbd/smbacl.c +++ b/fs/ksmbd/smbacl.c @@ -253,7 +253,8 @@ void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid) ssid->num_subauth++; } -static int sid_to_id(struct smb_sid *psid, uint sidtype, +static int sid_to_id(struct user_namespace *user_ns, + struct smb_sid *psid, uint sidtype, struct smb_fattr *fattr) { int rc = -EINVAL; @@ -274,8 +275,8 @@ static int sid_to_id(struct smb_sid *psid, uint sidtype, id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]); if (id > 0) { - uid = make_kuid(&init_user_ns, id); - if (uid_valid(uid) && kuid_has_mapping(&init_user_ns, uid)) { + uid = make_kuid(user_ns, id); + if (uid_valid(uid) && kuid_has_mapping(user_ns, uid)) { fattr->cf_uid = uid; rc = 0; } @@ -286,8 +287,8 @@ static int sid_to_id(struct smb_sid *psid, uint sidtype, id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]); if (id > 0) { - gid = make_kgid(&init_user_ns, id); - if (gid_valid(gid) && kgid_has_mapping(&init_user_ns, gid)) { + gid = make_kgid(user_ns, id); + if (gid_valid(gid) && kgid_has_mapping(user_ns, gid)) { fattr->cf_gid = gid; rc = 0; } @@ -362,7 +363,8 @@ void free_acl_state(struct posix_acl_state *state) kfree(state->groups); } -static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, +static void parse_dacl(struct user_namespace *user_ns, + struct smb_acl *pdacl, char *end_of_acl, struct smb_sid *pownersid, struct smb_sid *pgrpsid, struct smb_fattr *fattr) { @@ -474,7 +476,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, acl_mode = access_flags_to_mode(fattr, ppace[i]->access_req, ppace[i]->type); temp_fattr.cf_uid = INVALID_UID; - ret = sid_to_id(&ppace[i]->sid, SIDOWNER, &temp_fattr); + ret = sid_to_id(user_ns, &ppace[i]->sid, SIDOWNER, &temp_fattr); if (ret || uid_eq(temp_fattr.cf_uid, INVALID_UID)) { pr_err("%s: Error %d mapping Owner SID to uid\n", __func__, ret); @@ -553,7 +555,8 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, free_acl_state(&default_acl_state); } -static void set_posix_acl_entries_dacl(struct smb_ace *pndace, +static void set_posix_acl_entries_dacl(struct user_namespace *user_ns, + struct smb_ace *pndace, struct smb_fattr *fattr, u32 *num_aces, u16 *size, u32 nt_aces_num) { @@ -577,14 +580,14 @@ static void set_posix_acl_entries_dacl(struct smb_ace *pndace, uid_t uid; unsigned int sid_type = SIDOWNER; - uid = from_kuid(&init_user_ns, pace->e_uid); + uid = from_kuid(user_ns, pace->e_uid); if (!uid) sid_type = SIDUNIX_USER; id_to_sid(uid, sid_type, sid); } else if (pace->e_tag == ACL_GROUP) { gid_t gid; - gid = from_kgid(&init_user_ns, pace->e_gid); + gid = from_kgid(user_ns, pace->e_gid); id_to_sid(gid, SIDUNIX_GROUP, sid); } else if (pace->e_tag == ACL_OTHER && !nt_aces_num) { smb_copy_sid(sid, &sid_everyone); @@ -643,12 +646,12 @@ posix_default_acl: if (pace->e_tag == ACL_USER) { uid_t uid; - uid = from_kuid(&init_user_ns, pace->e_uid); + uid = from_kuid(user_ns, pace->e_uid); id_to_sid(uid, SIDCREATOR_OWNER, sid); } else if (pace->e_tag == ACL_GROUP) { gid_t gid; - gid = from_kgid(&init_user_ns, pace->e_gid); + gid = from_kgid(user_ns, pace->e_gid); id_to_sid(gid, SIDCREATOR_GROUP, sid); } else { kfree(sid); @@ -666,7 +669,9 @@ posix_default_acl: } } -static void set_ntacl_dacl(struct smb_acl *pndacl, struct smb_acl *nt_dacl, +static void set_ntacl_dacl(struct user_namespace *user_ns, + struct smb_acl *pndacl, + struct smb_acl *nt_dacl, const struct smb_sid *pownersid, const struct smb_sid *pgrpsid, struct smb_fattr *fattr) @@ -687,12 +692,14 @@ static void set_ntacl_dacl(struct smb_acl *pndacl, struct smb_acl *nt_dacl, } } - set_posix_acl_entries_dacl(pndace, fattr, &num_aces, &size, nt_num_aces); + set_posix_acl_entries_dacl(user_ns, pndace, fattr, + &num_aces, &size, nt_num_aces); pndacl->num_aces = cpu_to_le32(num_aces); pndacl->size = cpu_to_le16(le16_to_cpu(pndacl->size) + size); } -static void set_mode_dacl(struct smb_acl *pndacl, struct smb_fattr *fattr) +static void set_mode_dacl(struct user_namespace *user_ns, + struct smb_acl *pndacl, struct smb_fattr *fattr) { struct smb_ace *pace, *pndace; u32 num_aces = 0; @@ -703,12 +710,13 @@ static void set_mode_dacl(struct smb_acl *pndacl, struct smb_fattr *fattr) pace = pndace = (struct smb_ace *)((char *)pndacl + sizeof(struct smb_acl)); if (fattr->cf_acls) { - set_posix_acl_entries_dacl(pndace, fattr, &num_aces, &size, num_aces); + set_posix_acl_entries_dacl(user_ns, pndace, fattr, + &num_aces, &size, num_aces); goto out; } /* owner RID */ - uid = from_kuid(&init_user_ns, fattr->cf_uid); + uid = from_kuid(user_ns, fattr->cf_uid); if (uid) sid = &server_conf.domain_sid; else @@ -725,7 +733,7 @@ static void set_mode_dacl(struct smb_acl *pndacl, struct smb_fattr *fattr) ace_size = fill_ace_for_sid(pace, &sid_unix_groups, ACCESS_ALLOWED, 0, fattr->cf_mode, 0070); pace->sid.sub_auth[pace->sid.num_subauth++] = - cpu_to_le32(from_kgid(&init_user_ns, fattr->cf_gid)); + cpu_to_le32(from_kgid(user_ns, fattr->cf_gid)); pace->size = cpu_to_le16(ace_size + 4); size += le16_to_cpu(pace->size); pace = (struct smb_ace *)((char *)pndace + size); @@ -771,8 +779,8 @@ static int parse_sid(struct smb_sid *psid, char *end_of_acl) } /* Convert CIFS ACL to POSIX form */ -int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len, - struct smb_fattr *fattr) +int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd, + int acl_len, struct smb_fattr *fattr) { int rc = 0; struct smb_sid *owner_sid_ptr, *group_sid_ptr; @@ -811,7 +819,7 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len, return rc; } - rc = sid_to_id(owner_sid_ptr, SIDOWNER, fattr); + rc = sid_to_id(user_ns, owner_sid_ptr, SIDOWNER, fattr); if (rc) { pr_err("%s: Error %d mapping Owner SID to uid\n", __func__, rc); @@ -826,7 +834,7 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len, __func__, rc); return rc; } - rc = sid_to_id(group_sid_ptr, SIDUNIX_GROUP, fattr); + rc = sid_to_id(user_ns, group_sid_ptr, SIDUNIX_GROUP, fattr); if (rc) { pr_err("%s: Error %d mapping Group SID to gid\n", __func__, rc); @@ -841,15 +849,16 @@ int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len, pntsd->type |= cpu_to_le16(DACL_PROTECTED); if (dacloffset) { - parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr, - fattr); + parse_dacl(user_ns, dacl_ptr, end_of_acl, + owner_sid_ptr, group_sid_ptr, fattr); } return 0; } /* Convert permission bits from mode to equivalent CIFS ACL */ -int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd, +int build_sec_desc(struct user_namespace *user_ns, + struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd, int addition_info, __u32 *secdesclen, struct smb_fattr *fattr) { @@ -866,7 +875,7 @@ int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd, if (!nowner_sid_ptr) return -ENOMEM; - uid = from_kuid(&init_user_ns, fattr->cf_uid); + uid = from_kuid(user_ns, fattr->cf_uid); if (!uid) sid_type = SIDUNIX_USER; id_to_sid(uid, sid_type, nowner_sid_ptr); @@ -877,7 +886,7 @@ int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd, return -ENOMEM; } - gid = from_kgid(&init_user_ns, fattr->cf_gid); + gid = from_kgid(user_ns, fattr->cf_gid); id_to_sid(gid, SIDUNIX_GROUP, ngroup_sid_ptr); offset = sizeof(struct smb_ntsd); @@ -909,7 +918,7 @@ int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd, dacl_ptr->num_aces = 0; if (!ppntsd) { - set_mode_dacl(dacl_ptr, fattr); + set_mode_dacl(user_ns, dacl_ptr, fattr); } else if (!ppntsd->dacloffset) { goto out; } else { @@ -917,8 +926,8 @@ int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd, ppdacl_ptr = (struct smb_acl *)((char *)ppntsd + le32_to_cpu(ppntsd->dacloffset)); - set_ntacl_dacl(dacl_ptr, ppdacl_ptr, nowner_sid_ptr, - ngroup_sid_ptr, fattr); + set_ntacl_dacl(user_ns, dacl_ptr, ppdacl_ptr, + nowner_sid_ptr, ngroup_sid_ptr, fattr); } pntsd->dacloffset = cpu_to_le32(offset); offset += le16_to_cpu(dacl_ptr->size); @@ -956,7 +965,8 @@ int smb_inherit_dacl(struct ksmbd_conn *conn, char *aces_base; bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode); - acl_len = ksmbd_vfs_get_sd_xattr(conn, parent, &parent_pntsd); + acl_len = ksmbd_vfs_get_sd_xattr(conn, mnt_user_ns(path->mnt), + parent, &parent_pntsd); if (acl_len <= 0) return rc; dacloffset = le32_to_cpu(parent_pntsd->dacloffset); @@ -1087,7 +1097,8 @@ pass: pntsd_size += sizeof(struct smb_acl) + nt_size; } - ksmbd_vfs_set_sd_xattr(conn, path->dentry, pntsd, pntsd_size); + ksmbd_vfs_set_sd_xattr(conn, mnt_user_ns(path->mnt), + path->dentry, pntsd, pntsd_size); kfree(pntsd); rc = 0; } @@ -1128,7 +1139,8 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct path *path, char *end_of_acl; ksmbd_debug(SMB, "check permission using windows acl\n"); - acl_size = ksmbd_vfs_get_sd_xattr(conn, path->dentry, &pntsd); + acl_size = ksmbd_vfs_get_sd_xattr(conn, mnt_user_ns(path->mnt), + path->dentry, &pntsd); if (acl_size <= 0 || !pntsd || !pntsd->dacloffset) { kfree(pntsd); return 0; @@ -1209,9 +1221,11 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct path *path, pa_entry = posix_acls->a_entries; for (i = 0; i < posix_acls->a_count; i++, pa_entry++) { if (pa_entry->e_tag == ACL_USER) - id = from_kuid(&init_user_ns, pa_entry->e_uid); + id = from_kuid(mnt_user_ns(path->mnt), + pa_entry->e_uid); else if (pa_entry->e_tag == ACL_GROUP) - id = from_kgid(&init_user_ns, pa_entry->e_gid); + id = from_kgid(mnt_user_ns(path->mnt), + pa_entry->e_gid); else continue; @@ -1273,7 +1287,7 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, fattr.cf_gid = INVALID_GID; fattr.cf_mode = inode->i_mode; - rc = parse_sec_desc(pntsd, ntsd_len, &fattr); + rc = parse_sec_desc(mnt_user_ns(path->mnt), pntsd, ntsd_len, &fattr); if (rc) goto out; @@ -1284,13 +1298,13 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, inode->i_gid = fattr.cf_gid; mark_inode_dirty(inode); - ksmbd_vfs_remove_acl_xattrs(path->dentry); + ksmbd_vfs_remove_acl_xattrs(mnt_user_ns(path->mnt), path->dentry); /* Update posix acls */ if (fattr.cf_dacls) { - rc = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS, - fattr.cf_acls); + rc = set_posix_acl(mnt_user_ns(path->mnt), inode, + ACL_TYPE_ACCESS, fattr.cf_acls); if (S_ISDIR(inode->i_mode) && fattr.cf_dacls) - rc = set_posix_acl(&init_user_ns, inode, + rc = set_posix_acl(mnt_user_ns(path->mnt), inode, ACL_TYPE_DEFAULT, fattr.cf_dacls); } @@ -1300,8 +1314,9 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, if (test_share_config_flag(tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) { /* Update WinACL in xattr */ - ksmbd_vfs_remove_sd_xattrs(path->dentry); - ksmbd_vfs_set_sd_xattr(conn, path->dentry, pntsd, ntsd_len); + ksmbd_vfs_remove_sd_xattrs(mnt_user_ns(path->mnt), path->dentry); + ksmbd_vfs_set_sd_xattr(conn, mnt_user_ns(path->mnt), + path->dentry, pntsd, ntsd_len); } out: diff --git a/fs/ksmbd/smbacl.h b/fs/ksmbd/smbacl.h index 4ee7bda32e5f..940f686a1d95 100644 --- a/fs/ksmbd/smbacl.h +++ b/fs/ksmbd/smbacl.h @@ -189,11 +189,11 @@ struct posix_acl_state { struct posix_ace_state_array *groups; }; -int parse_sec_desc(struct smb_ntsd *pntsd, int acl_len, - struct smb_fattr *fattr); -int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd, - int addition_info, __u32 *secdesclen, - struct smb_fattr *fattr); +int parse_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd, + int acl_len, struct smb_fattr *fattr); +int build_sec_desc(struct user_namespace *user_ns, struct smb_ntsd *pntsd, + struct smb_ntsd *ppntsd, int addition_info, + __u32 *secdesclen, struct smb_fattr *fattr); int init_acl_state(struct posix_acl_state *state, int cnt); void free_acl_state(struct posix_acl_state *state); void posix_state_to_acl(struct posix_acl_state *state, diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c index 702166266f91..0f5a4fb8215f 100644 --- a/fs/ksmbd/vfs.c +++ b/fs/ksmbd/vfs.c @@ -95,7 +95,8 @@ out_err: return ret; } -int ksmbd_vfs_may_delete(struct dentry *dentry) +int ksmbd_vfs_may_delete(struct user_namespace *user_ns, + struct dentry *dentry) { struct dentry *parent; int ret; @@ -107,7 +108,7 @@ int ksmbd_vfs_may_delete(struct dentry *dentry) return ret; } - ret = inode_permission(&init_user_ns, d_inode(parent), + ret = inode_permission(user_ns, d_inode(parent), MAY_EXEC | MAY_WRITE); inode_unlock(d_inode(parent)); @@ -115,23 +116,24 @@ int ksmbd_vfs_may_delete(struct dentry *dentry) return ret; } -int ksmbd_vfs_query_maximal_access(struct dentry *dentry, __le32 *daccess) +int ksmbd_vfs_query_maximal_access(struct user_namespace *user_ns, + struct dentry *dentry, __le32 *daccess) { struct dentry *parent; int ret = 0; *daccess = cpu_to_le32(FILE_READ_ATTRIBUTES | READ_CONTROL); - if (!inode_permission(&init_user_ns, d_inode(dentry), MAY_OPEN | MAY_WRITE)) + if (!inode_permission(user_ns, d_inode(dentry), MAY_OPEN | MAY_WRITE)) *daccess |= cpu_to_le32(WRITE_DAC | WRITE_OWNER | SYNCHRONIZE | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES | FILE_DELETE_CHILD); - if (!inode_permission(&init_user_ns, d_inode(dentry), MAY_OPEN | MAY_READ)) + if (!inode_permission(user_ns, d_inode(dentry), MAY_OPEN | MAY_READ)) *daccess |= FILE_READ_DATA_LE | FILE_READ_EA_LE; - if (!inode_permission(&init_user_ns, d_inode(dentry), MAY_OPEN | MAY_EXEC)) + if (!inode_permission(user_ns, d_inode(dentry), MAY_OPEN | MAY_EXEC)) *daccess |= FILE_EXECUTE_LE; parent = dget_parent(dentry); @@ -141,7 +143,7 @@ int ksmbd_vfs_query_maximal_access(struct dentry *dentry, __le32 *daccess) return ret; } - if (!inode_permission(&init_user_ns, d_inode(parent), MAY_EXEC | MAY_WRITE)) + if (!inode_permission(user_ns, d_inode(parent), MAY_EXEC | MAY_WRITE)) *daccess |= FILE_DELETE_LE; inode_unlock(d_inode(parent)); @@ -173,7 +175,8 @@ int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode) } mode |= S_IFREG; - err = vfs_create(&init_user_ns, d_inode(path.dentry), dentry, mode, true); + err = vfs_create(mnt_user_ns(path.mnt), d_inode(path.dentry), + dentry, mode, true); if (!err) { ksmbd_vfs_inherit_owner(work, d_inode(path.dentry), d_inode(dentry)); @@ -208,7 +211,8 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char *name, umode_t mode) } mode |= S_IFDIR; - err = vfs_mkdir(&init_user_ns, d_inode(path.dentry), dentry, mode); + err = vfs_mkdir(mnt_user_ns(path.mnt), d_inode(path.dentry), + dentry, mode); if (err) { goto out; } else if (d_unhashed(dentry)) { @@ -236,7 +240,8 @@ out: return err; } -static ssize_t ksmbd_vfs_getcasexattr(struct dentry *dentry, char *attr_name, +static ssize_t ksmbd_vfs_getcasexattr(struct user_namespace *user_ns, + struct dentry *dentry, char *attr_name, int attr_name_len, char **attr_value) { char *name, *xattr_list = NULL; @@ -252,7 +257,8 @@ static ssize_t ksmbd_vfs_getcasexattr(struct dentry *dentry, char *attr_name, if (strncasecmp(attr_name, name, attr_name_len)) continue; - value_len = ksmbd_vfs_getxattr(dentry, + value_len = ksmbd_vfs_getxattr(user_ns, + dentry, name, attr_value); if (value_len < 0) @@ -274,7 +280,8 @@ static int ksmbd_vfs_stream_read(struct ksmbd_file *fp, char *buf, loff_t *pos, ksmbd_debug(VFS, "read stream data pos : %llu, count : %zd\n", *pos, count); - v_len = ksmbd_vfs_getcasexattr(fp->filp->f_path.dentry, + v_len = ksmbd_vfs_getcasexattr(file_mnt_user_ns(fp->filp), + fp->filp->f_path.dentry, fp->stream.name, fp->stream.size, &stream_buf); @@ -411,7 +418,8 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos, count = (*pos + count) - XATTR_SIZE_MAX; } - v_len = ksmbd_vfs_getcasexattr(fp->filp->f_path.dentry, + v_len = ksmbd_vfs_getcasexattr(file_mnt_user_ns(fp->filp), + fp->filp->f_path.dentry, fp->stream.name, fp->stream.size, &stream_buf); @@ -436,7 +444,8 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos, memcpy(&stream_buf[*pos], buf, count); - err = ksmbd_vfs_setxattr(fp->filp->f_path.dentry, + err = ksmbd_vfs_setxattr(file_mnt_user_ns(fp->filp), + fp->filp->f_path.dentry, fp->stream.name, (void *)stream_buf, size, @@ -606,13 +615,14 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name) } if (S_ISDIR(d_inode(path.dentry)->i_mode)) { - err = vfs_rmdir(&init_user_ns, d_inode(parent), path.dentry); + err = vfs_rmdir(mnt_user_ns(path.mnt), d_inode(parent), + path.dentry); if (err && err != -ENOTEMPTY) ksmbd_debug(VFS, "%s: rmdir failed, err %d\n", name, err); } else { - err = vfs_unlink(&init_user_ns, d_inode(parent), path.dentry, - NULL); + err = vfs_unlink(mnt_user_ns(path.mnt), d_inode(parent), + path.dentry, NULL); if (err) ksmbd_debug(VFS, "%s: unlink failed, err %d\n", name, err); @@ -669,7 +679,8 @@ int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname, goto out3; } - err = vfs_link(oldpath.dentry, &init_user_ns, d_inode(newpath.dentry), + err = vfs_link(oldpath.dentry, mnt_user_ns(newpath.mnt), + d_inode(newpath.dentry), dentry, NULL); if (err) ksmbd_debug(VFS, "vfs_link failed err %d\n", err); @@ -707,8 +718,10 @@ static int ksmbd_validate_entry_in_use(struct dentry *src_dent) } static int __ksmbd_vfs_rename(struct ksmbd_work *work, + struct user_namespace *src_user_ns, struct dentry *src_dent_parent, struct dentry *src_dent, + struct user_namespace *dst_user_ns, struct dentry *dst_dent_parent, struct dentry *trap_dent, char *dst_name) @@ -744,10 +757,10 @@ static int __ksmbd_vfs_rename(struct ksmbd_work *work, err = -ENOTEMPTY; if (dst_dent != trap_dent && !d_really_is_positive(dst_dent)) { struct renamedata rd = { - .old_mnt_userns = &init_user_ns, + .old_mnt_userns = src_user_ns, .old_dir = d_inode(src_dent_parent), .old_dentry = src_dent, - .new_mnt_userns = &init_user_ns, + .new_mnt_userns = dst_user_ns, .new_dir = d_inode(dst_dent_parent), .new_dentry = dst_dent, }; @@ -809,8 +822,10 @@ int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp, dput(src_child); err = __ksmbd_vfs_rename(work, + file_mnt_user_ns(fp->filp), src_dent_parent, src_dent, + mnt_user_ns(dst_path.mnt), dst_dent_parent, trap_dent, dst_name); @@ -917,27 +932,30 @@ ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list) return size; } -static ssize_t ksmbd_vfs_xattr_len(struct dentry *dentry, char *xattr_name) +static ssize_t ksmbd_vfs_xattr_len(struct user_namespace *user_ns, + struct dentry *dentry, char *xattr_name) { - return vfs_getxattr(&init_user_ns, dentry, xattr_name, NULL, 0); + return vfs_getxattr(user_ns, dentry, xattr_name, NULL, 0); } /** * ksmbd_vfs_getxattr() - vfs helper for smb get extended attributes value + * @user_ns: user namespace * @dentry: dentry of file for getting xattrs * @xattr_name: name of xattr name to query * @xattr_buf: destination buffer xattr value * * Return: read xattr value length on success, otherwise error */ -ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name, - char **xattr_buf) +ssize_t ksmbd_vfs_getxattr(struct user_namespace *user_ns, + struct dentry *dentry, + char *xattr_name, char **xattr_buf) { ssize_t xattr_len; char *buf; *xattr_buf = NULL; - xattr_len = ksmbd_vfs_xattr_len(dentry, xattr_name); + xattr_len = ksmbd_vfs_xattr_len(user_ns, dentry, xattr_name); if (xattr_len < 0) return xattr_len; @@ -945,7 +963,7 @@ ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name, if (!buf) return -ENOMEM; - xattr_len = vfs_getxattr(&init_user_ns, dentry, xattr_name, + xattr_len = vfs_getxattr(user_ns, dentry, xattr_name, (void *)buf, xattr_len); if (xattr_len > 0) *xattr_buf = buf; @@ -956,6 +974,7 @@ ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name, /** * ksmbd_vfs_setxattr() - vfs helper for smb set extended attributes value + * @user_ns: user namespace * @dentry: dentry to set XATTR at * @name: xattr name for setxattr * @value: xattr value to set @@ -964,12 +983,14 @@ ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name, * * Return: 0 on success, otherwise error */ -int ksmbd_vfs_setxattr(struct dentry *dentry, const char *attr_name, +int ksmbd_vfs_setxattr(struct user_namespace *user_ns, + struct dentry *dentry, const char *attr_name, const void *attr_value, size_t attr_size, int flags) { int err; - err = vfs_setxattr(&init_user_ns, dentry, + err = vfs_setxattr(user_ns, + dentry, attr_name, attr_value, attr_size, @@ -1076,12 +1097,14 @@ int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length, return ret; } -int ksmbd_vfs_remove_xattr(struct dentry *dentry, char *attr_name) +int ksmbd_vfs_remove_xattr(struct user_namespace *user_ns, + struct dentry *dentry, char *attr_name) { - return vfs_removexattr(&init_user_ns, dentry, attr_name); + return vfs_removexattr(user_ns, dentry, attr_name); } -int ksmbd_vfs_unlink(struct dentry *dir, struct dentry *dentry) +int ksmbd_vfs_unlink(struct user_namespace *user_ns, + struct dentry *dir, struct dentry *dentry) { int err = 0; @@ -1091,9 +1114,9 @@ int ksmbd_vfs_unlink(struct dentry *dir, struct dentry *dentry) dget(dentry); if (S_ISDIR(d_inode(dentry)->i_mode)) - err = vfs_rmdir(&init_user_ns, d_inode(dir), dentry); + err = vfs_rmdir(user_ns, d_inode(dir), dentry); else - err = vfs_unlink(&init_user_ns, d_inode(dir), dentry, NULL); + err = vfs_unlink(user_ns, d_inode(dir), dentry, NULL); dput(dentry); inode_unlock(d_inode(dir)); @@ -1267,7 +1290,8 @@ out: return err; } -int ksmbd_vfs_remove_acl_xattrs(struct dentry *dentry) +int ksmbd_vfs_remove_acl_xattrs(struct user_namespace *user_ns, + struct dentry *dentry) { char *name, *xattr_list = NULL; ssize_t xattr_list_len; @@ -1289,7 +1313,7 @@ int ksmbd_vfs_remove_acl_xattrs(struct dentry *dentry) sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1) || !strncmp(name, XATTR_NAME_POSIX_ACL_DEFAULT, sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1)) { - err = ksmbd_vfs_remove_xattr(dentry, name); + err = ksmbd_vfs_remove_xattr(user_ns, dentry, name); if (err) ksmbd_debug(SMB, "remove acl xattr failed : %s\n", name); @@ -1300,7 +1324,8 @@ out: return err; } -int ksmbd_vfs_remove_sd_xattrs(struct dentry *dentry) +int ksmbd_vfs_remove_sd_xattrs(struct user_namespace *user_ns, + struct dentry *dentry) { char *name, *xattr_list = NULL; ssize_t xattr_list_len; @@ -1319,7 +1344,7 @@ int ksmbd_vfs_remove_sd_xattrs(struct dentry *dentry) ksmbd_debug(SMB, "%s, len %zd\n", name, strlen(name)); if (!strncmp(name, XATTR_NAME_SD, XATTR_NAME_SD_LEN)) { - err = ksmbd_vfs_remove_xattr(dentry, name); + err = ksmbd_vfs_remove_xattr(user_ns, dentry, name); if (err) ksmbd_debug(SMB, "remove xattr failed : %s\n", name); } @@ -1329,7 +1354,8 @@ out: return err; } -static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct inode *inode, +static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct user_namespace *user_ns, + struct inode *inode, int acl_type) { struct xattr_smb_acl *smb_acl = NULL; @@ -1355,14 +1381,14 @@ static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct inode *inode, switch (pa_entry->e_tag) { case ACL_USER: xa_entry->type = SMB_ACL_USER; - xa_entry->uid = from_kuid(&init_user_ns, pa_entry->e_uid); + xa_entry->uid = from_kuid(user_ns, pa_entry->e_uid); break; case ACL_USER_OBJ: xa_entry->type = SMB_ACL_USER_OBJ; break; case ACL_GROUP: xa_entry->type = SMB_ACL_GROUP; - xa_entry->gid = from_kgid(&init_user_ns, pa_entry->e_gid); + xa_entry->gid = from_kgid(user_ns, pa_entry->e_gid); break; case ACL_GROUP_OBJ: xa_entry->type = SMB_ACL_GROUP_OBJ; @@ -1390,7 +1416,9 @@ out: return smb_acl; } -int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, +int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, + struct user_namespace *user_ns, + struct dentry *dentry, struct smb_ntsd *pntsd, int len) { int rc; @@ -1422,12 +1450,14 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, return rc; } - smb_acl = ksmbd_vfs_make_xattr_posix_acl(inode, ACL_TYPE_ACCESS); + smb_acl = ksmbd_vfs_make_xattr_posix_acl(user_ns, inode, + ACL_TYPE_ACCESS); if (S_ISDIR(inode->i_mode)) - def_smb_acl = ksmbd_vfs_make_xattr_posix_acl(inode, + def_smb_acl = ksmbd_vfs_make_xattr_posix_acl(user_ns, inode, ACL_TYPE_DEFAULT); - rc = ndr_encode_posix_acl(&acl_ndr, inode, smb_acl, def_smb_acl); + rc = ndr_encode_posix_acl(&acl_ndr, user_ns, inode, + smb_acl, def_smb_acl); if (rc) { pr_err("failed to encode ndr to posix acl\n"); goto out; @@ -1446,7 +1476,8 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, goto out; } - rc = ksmbd_vfs_setxattr(dentry, XATTR_NAME_SD, sd_ndr.data, + rc = ksmbd_vfs_setxattr(user_ns, dentry, + XATTR_NAME_SD, sd_ndr.data, sd_ndr.offset, 0); if (rc < 0) pr_err("Failed to store XATTR ntacl :%d\n", rc); @@ -1459,13 +1490,15 @@ out: return rc; } -int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, +int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, + struct user_namespace *user_ns, + struct dentry *dentry, struct smb_ntsd **pntsd) { int rc; struct ndr n; - rc = ksmbd_vfs_getxattr(dentry, XATTR_NAME_SD, &n.data); + rc = ksmbd_vfs_getxattr(user_ns, dentry, XATTR_NAME_SD, &n.data); if (rc > 0) { struct inode *inode = d_inode(dentry); struct ndr acl_ndr = {0}; @@ -1478,13 +1511,15 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, if (rc) return rc; - smb_acl = ksmbd_vfs_make_xattr_posix_acl(inode, + smb_acl = ksmbd_vfs_make_xattr_posix_acl(user_ns, inode, ACL_TYPE_ACCESS); if (S_ISDIR(inode->i_mode)) - def_smb_acl = ksmbd_vfs_make_xattr_posix_acl(inode, + def_smb_acl = ksmbd_vfs_make_xattr_posix_acl(user_ns, + inode, ACL_TYPE_DEFAULT); - rc = ndr_encode_posix_acl(&acl_ndr, inode, smb_acl, def_smb_acl); + rc = ndr_encode_posix_acl(&acl_ndr, user_ns, inode, + smb_acl, def_smb_acl); if (rc) { pr_err("failed to encode ndr to posix acl\n"); goto out; @@ -1522,7 +1557,8 @@ out: return rc; } -int ksmbd_vfs_set_dos_attrib_xattr(struct dentry *dentry, +int ksmbd_vfs_set_dos_attrib_xattr(struct user_namespace *user_ns, + struct dentry *dentry, struct xattr_dos_attrib *da) { struct ndr n; @@ -1532,7 +1568,7 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct dentry *dentry, if (err) return err; - err = ksmbd_vfs_setxattr(dentry, XATTR_NAME_DOS_ATTRIBUTE, + err = ksmbd_vfs_setxattr(user_ns, dentry, XATTR_NAME_DOS_ATTRIBUTE, (void *)n.data, n.offset, 0); if (err) ksmbd_debug(SMB, "failed to store dos attribute in xattr\n"); @@ -1541,13 +1577,14 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct dentry *dentry, return err; } -int ksmbd_vfs_get_dos_attrib_xattr(struct dentry *dentry, +int ksmbd_vfs_get_dos_attrib_xattr(struct user_namespace *user_ns, + struct dentry *dentry, struct xattr_dos_attrib *da) { struct ndr n; int err; - err = ksmbd_vfs_getxattr(dentry, XATTR_NAME_DOS_ATTRIBUTE, + err = ksmbd_vfs_getxattr(user_ns, dentry, XATTR_NAME_DOS_ATTRIBUTE, (char **)&n.data); if (err > 0) { n.length = err; @@ -1593,13 +1630,15 @@ void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat) return info; } -int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, struct dentry *dentry, +int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, + struct user_namespace *user_ns, + struct dentry *dentry, struct ksmbd_kstat *ksmbd_kstat) { u64 time; int rc; - generic_fillattr(&init_user_ns, d_inode(dentry), ksmbd_kstat->kstat); + generic_fillattr(user_ns, d_inode(dentry), ksmbd_kstat->kstat); time = ksmbd_UnixTimeToNT(ksmbd_kstat->kstat->ctime); ksmbd_kstat->create_time = time; @@ -1617,7 +1656,7 @@ int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, struct dentry *dentry, KSMBD_SHARE_FLAG_STORE_DOS_ATTRS)) { struct xattr_dos_attrib da; - rc = ksmbd_vfs_get_dos_attrib_xattr(dentry, &da); + rc = ksmbd_vfs_get_dos_attrib_xattr(user_ns, dentry, &da); if (rc > 0) { ksmbd_kstat->file_attributes = cpu_to_le32(da.attr); ksmbd_kstat->create_time = da.create_time; @@ -1629,7 +1668,8 @@ int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work, struct dentry *dentry, return 0; } -ssize_t ksmbd_vfs_casexattr_len(struct dentry *dentry, char *attr_name, +ssize_t ksmbd_vfs_casexattr_len(struct user_namespace *user_ns, + struct dentry *dentry, char *attr_name, int attr_name_len) { char *name, *xattr_list = NULL; @@ -1645,7 +1685,7 @@ ssize_t ksmbd_vfs_casexattr_len(struct dentry *dentry, char *attr_name, if (strncasecmp(attr_name, name, attr_name_len)) continue; - value_len = ksmbd_vfs_xattr_len(dentry, name); + value_len = ksmbd_vfs_xattr_len(user_ns, dentry, name); break; } @@ -1775,7 +1815,8 @@ void ksmbd_vfs_posix_lock_unblock(struct file_lock *flock) locks_delete_block(flock); } -int ksmbd_vfs_set_init_posix_acl(struct inode *inode) +int ksmbd_vfs_set_init_posix_acl(struct user_namespace *user_ns, + struct inode *inode) { struct posix_acl_state acl_state; struct posix_acl *acls; @@ -1804,13 +1845,13 @@ int ksmbd_vfs_set_init_posix_acl(struct inode *inode) return -ENOMEM; } posix_state_to_acl(&acl_state, acls->a_entries); - rc = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS, acls); + rc = set_posix_acl(user_ns, inode, ACL_TYPE_ACCESS, acls); if (rc < 0) ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n", rc); else if (S_ISDIR(inode->i_mode)) { posix_state_to_acl(&acl_state, acls->a_entries); - rc = set_posix_acl(&init_user_ns, inode, ACL_TYPE_DEFAULT, + rc = set_posix_acl(user_ns, inode, ACL_TYPE_DEFAULT, acls); if (rc < 0) ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n", @@ -1821,7 +1862,8 @@ int ksmbd_vfs_set_init_posix_acl(struct inode *inode) return rc; } -int ksmbd_vfs_inherit_posix_acl(struct inode *inode, struct inode *parent_inode) +int ksmbd_vfs_inherit_posix_acl(struct user_namespace *user_ns, + struct inode *inode, struct inode *parent_inode) { struct posix_acl *acls; struct posix_acl_entry *pace; @@ -1839,12 +1881,12 @@ int ksmbd_vfs_inherit_posix_acl(struct inode *inode, struct inode *parent_inode) } } - rc = set_posix_acl(&init_user_ns, inode, ACL_TYPE_ACCESS, acls); + rc = set_posix_acl(user_ns, inode, ACL_TYPE_ACCESS, acls); if (rc < 0) ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n", rc); if (S_ISDIR(inode->i_mode)) { - rc = set_posix_acl(&init_user_ns, inode, ACL_TYPE_DEFAULT, + rc = set_posix_acl(user_ns, inode, ACL_TYPE_DEFAULT, acls); if (rc < 0) ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n", diff --git a/fs/ksmbd/vfs.h b/fs/ksmbd/vfs.h index e30174a0e5a1..b255f90acf8f 100644 --- a/fs/ksmbd/vfs.h +++ b/fs/ksmbd/vfs.h @@ -108,8 +108,9 @@ struct ksmbd_kstat { }; int ksmbd_vfs_lock_parent(struct dentry *parent, struct dentry *child); -int ksmbd_vfs_may_delete(struct dentry *dentry); -int ksmbd_vfs_query_maximal_access(struct dentry *dentry, __le32 *daccess); +int ksmbd_vfs_may_delete(struct user_namespace *user_ns, struct dentry *dentry); +int ksmbd_vfs_query_maximal_access(struct user_namespace *user_ns, + struct dentry *dentry, __le32 *daccess); 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_read(struct ksmbd_work *work, struct ksmbd_file *fp, @@ -136,15 +137,20 @@ int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work, unsigned int *chunk_size_written, loff_t *total_size_written); ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list); -ssize_t ksmbd_vfs_getxattr(struct dentry *dentry, char *xattr_name, +ssize_t ksmbd_vfs_getxattr(struct user_namespace *user_ns, + struct dentry *dentry, + char *xattr_name, char **xattr_buf); -ssize_t ksmbd_vfs_casexattr_len(struct dentry *dentry, char *attr_name, +ssize_t ksmbd_vfs_casexattr_len(struct user_namespace *user_ns, + struct dentry *dentry, char *attr_name, int attr_name_len); -int ksmbd_vfs_setxattr(struct dentry *dentry, const char *attr_name, +int ksmbd_vfs_setxattr(struct user_namespace *user_ns, + struct dentry *dentry, 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_remove_xattr(struct dentry *dentry, char *attr_name); +int ksmbd_vfs_remove_xattr(struct user_namespace *user_ns, + struct dentry *dentry, char *attr_name); int ksmbd_vfs_kern_path(char *name, unsigned int flags, struct path *path, bool caseless); int ksmbd_vfs_empty_dir(struct ksmbd_file *fp); @@ -155,24 +161,37 @@ struct file_allocated_range_buffer; int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length, struct file_allocated_range_buffer *ranges, int in_count, int *out_count); -int ksmbd_vfs_unlink(struct dentry *dir, struct dentry *dentry); +int ksmbd_vfs_unlink(struct user_namespace *user_ns, + struct dentry *dir, struct dentry *dentry); 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 user_namespace *user_ns, + struct dentry *dentry, struct ksmbd_kstat *ksmbd_kstat); int ksmbd_vfs_posix_lock_wait(struct file_lock *flock); int ksmbd_vfs_posix_lock_wait_timeout(struct file_lock *flock, long timeout); void ksmbd_vfs_posix_lock_unblock(struct file_lock *flock); -int ksmbd_vfs_remove_acl_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_remove_acl_xattrs(struct user_namespace *user_ns, + struct dentry *dentry); +int ksmbd_vfs_remove_sd_xattrs(struct user_namespace *user_ns, + struct dentry *dentry); +int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, + struct user_namespace *user_ns, + struct dentry *dentry, struct smb_ntsd *pntsd, int len); -int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, struct dentry *dentry, +int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, + struct user_namespace *user_ns, + struct dentry *dentry, struct smb_ntsd **pntsd); -int ksmbd_vfs_set_dos_attrib_xattr(struct dentry *dentry, +int ksmbd_vfs_set_dos_attrib_xattr(struct user_namespace *user_ns, + struct dentry *dentry, struct xattr_dos_attrib *da); -int ksmbd_vfs_get_dos_attrib_xattr(struct dentry *dentry, +int ksmbd_vfs_get_dos_attrib_xattr(struct user_namespace *user_ns, + struct dentry *dentry, struct xattr_dos_attrib *da); -int ksmbd_vfs_set_init_posix_acl(struct inode *inode); -int ksmbd_vfs_inherit_posix_acl(struct inode *inode, +int ksmbd_vfs_set_init_posix_acl(struct user_namespace *user_ns, + struct inode *inode); +int ksmbd_vfs_inherit_posix_acl(struct user_namespace *user_ns, + struct inode *inode, struct inode *parent_inode); #endif /* __KSMBD_VFS_H__ */ diff --git a/fs/ksmbd/vfs_cache.c b/fs/ksmbd/vfs_cache.c index 5c9efcfaeb5c..1941ad3f5aa5 100644 --- a/fs/ksmbd/vfs_cache.c +++ b/fs/ksmbd/vfs_cache.c @@ -251,7 +251,8 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp) filp = fp->filp; if (ksmbd_stream_fd(fp) && (ci->m_flags & S_DEL_ON_CLS_STREAM)) { ci->m_flags &= ~S_DEL_ON_CLS_STREAM; - err = ksmbd_vfs_remove_xattr(filp->f_path.dentry, + err = ksmbd_vfs_remove_xattr(file_mnt_user_ns(filp), + filp->f_path.dentry, fp->stream.name); if (err) pr_err("remove xattr failed : %s\n", @@ -265,7 +266,7 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp) dir = dentry->d_parent; ci->m_flags &= ~(S_DEL_ON_CLS | S_DEL_PENDING); write_unlock(&ci->m_lock); - ksmbd_vfs_unlink(dir, dentry); + ksmbd_vfs_unlink(file_mnt_user_ns(filp), dir, dentry); write_lock(&ci->m_lock); } write_unlock(&ci->m_lock);