Lines Matching defs:work

42 static void __wbuf(struct ksmbd_work *work, void **req, void **rsp)
44 if (work->next_smb2_rcv_hdr_off) {
45 *req = ksmbd_req_buf_next(work);
46 *rsp = ksmbd_resp_buf_next(work);
48 *req = smb2_get_msg(work->request_buf);
49 *rsp = smb2_get_msg(work->response_buf);
83 * @work: smb work
88 int smb2_get_ksmbd_tcon(struct ksmbd_work *work)
90 struct smb2_hdr *req_hdr = ksmbd_req_buf_next(work);
101 if (xa_empty(&work->sess->tree_conns)) {
110 * Just validate tree id in header with work->tcon->id.
112 if (work->next_smb2_rcv_hdr_off) {
113 if (!work->tcon) {
117 if (tree_id != UINT_MAX && work->tcon->id != tree_id) {
119 tree_id, work->tcon->id);
125 work->tcon = ksmbd_tree_conn_lookup(work->sess, tree_id);
126 if (!work->tcon) {
136 * @work: smb work containing response buffer
138 void smb2_set_err_rsp(struct ksmbd_work *work)
142 if (work->next_smb2_rcv_hdr_off)
143 err_rsp = ksmbd_resp_buf_next(work);
145 err_rsp = smb2_get_msg(work->response_buf);
155 err = ksmbd_iov_pin_rsp(work, (void *)err_rsp,
159 work->send_no_response = 1;
165 * @work: smb work containing smb header
169 bool is_smb2_neg_cmd(struct ksmbd_work *work)
171 struct smb2_hdr *hdr = smb2_get_msg(work->request_buf);
189 * @work: smb work containing smb response buffer
193 bool is_smb2_rsp(struct ksmbd_work *work)
195 struct smb2_hdr *hdr = smb2_get_msg(work->response_buf);
210 * @work: smb work containing smb request buffer
214 u16 get_smb2_cmd_val(struct ksmbd_work *work)
218 if (work->next_smb2_rcv_hdr_off)
219 rcv_hdr = ksmbd_req_buf_next(work);
221 rcv_hdr = smb2_get_msg(work->request_buf);
227 * @work: smb work containing response buffer
230 void set_smb2_rsp_status(struct ksmbd_work *work, __le32 err)
234 rsp_hdr = smb2_get_msg(work->response_buf);
237 work->iov_idx = 0;
238 work->iov_cnt = 0;
239 work->next_smb2_rcv_hdr_off = 0;
240 smb2_set_err_rsp(work);
245 * @work: smb work containing smb request buffer
250 int init_smb2_neg_rsp(struct ksmbd_work *work)
254 struct ksmbd_conn *conn = work->conn;
257 rsp_hdr = smb2_get_msg(work->response_buf);
271 rsp = smb2_get_msg(work->response_buf);
297 err = ksmbd_iov_pin_rsp(work, rsp,
309 * @work: smb work containing smb response buffer
311 int smb2_set_rsp_credits(struct ksmbd_work *work)
313 struct smb2_hdr *req_hdr = ksmbd_req_buf_next(work);
314 struct smb2_hdr *hdr = ksmbd_resp_buf_next(work);
315 struct ksmbd_conn *conn = work->conn;
319 if (work->send_no_response)
356 work->credits_granted += credits_granted;
360 hdr->CreditRequest = cpu_to_le16(work->credits_granted);
371 * @work: smb work containing smb response buffer
373 static void init_chained_smb2_rsp(struct ksmbd_work *work)
375 struct smb2_hdr *req = ksmbd_req_buf_next(work);
376 struct smb2_hdr *rsp = ksmbd_resp_buf_next(work);
390 work->compound_fid = ((struct smb2_create_rsp *)rsp)->VolatileFileId;
391 work->compound_pfid = ((struct smb2_create_rsp *)rsp)->PersistentFileId;
392 work->compound_sid = le64_to_cpu(rsp->SessionId);
395 len = get_rfc1002_len(work->response_buf) - work->next_smb2_rsp_hdr_off;
399 work->iov[work->iov_idx].iov_len += (new_len - len);
400 inc_rfc1001_len(work->response_buf, new_len - len);
403 work->next_smb2_rcv_hdr_off += next_hdr_offset;
404 work->curr_smb2_rsp_hdr_off = work->next_smb2_rsp_hdr_off;
405 work->next_smb2_rsp_hdr_off += new_len;
408 new_len, work->next_smb2_rcv_hdr_off,
409 work->next_smb2_rsp_hdr_off);
411 rsp_hdr = ksmbd_resp_buf_next(work);
412 rcv_hdr = ksmbd_req_buf_next(work);
416 work->compound_fid = KSMBD_NO_FID;
417 work->compound_pfid = KSMBD_NO_FID;
439 * @work: smb work containing smb request buffer
443 bool is_chained_smb2_message(struct ksmbd_work *work)
445 struct smb2_hdr *hdr = smb2_get_msg(work->request_buf);
451 hdr = ksmbd_req_buf_next(work);
454 if ((u64)work->next_smb2_rcv_hdr_off + next_cmd +
456 get_rfc1002_len(work->request_buf)) {
462 if ((u64)get_rfc1002_len(work->response_buf) + MAX_CIFS_SMALL_BUFFER_SIZE >
463 work->response_sz) {
469 init_chained_smb2_rsp(work);
471 } else if (work->next_smb2_rcv_hdr_off) {
476 len = ALIGN(get_rfc1002_len(work->response_buf), 8);
477 len = len - get_rfc1002_len(work->response_buf);
480 work->iov[work->iov_idx].iov_len += len;
481 inc_rfc1001_len(work->response_buf, len);
483 work->curr_smb2_rsp_hdr_off = work->next_smb2_rsp_hdr_off;
490 * @work: smb work containing smb request buffer
494 int init_smb2_rsp_hdr(struct ksmbd_work *work)
496 struct smb2_hdr *rsp_hdr = smb2_get_msg(work->response_buf);
497 struct smb2_hdr *rcv_hdr = smb2_get_msg(work->request_buf);
520 * @work: smb work containing smb request buffer
524 int smb2_allocate_rsp_buf(struct ksmbd_work *work)
526 struct smb2_hdr *hdr = smb2_get_msg(work->request_buf);
528 size_t large_sz = small_sz + work->conn->vals->max_trans_size;
538 req = smb2_get_msg(work->request_buf);
550 work->response_buf = kvzalloc(sz, GFP_KERNEL);
551 if (!work->response_buf)
554 work->response_sz = sz;
560 * @work: smb work containing smb request buffer
564 int smb2_check_user_session(struct ksmbd_work *work)
566 struct smb2_hdr *req_hdr = ksmbd_req_buf_next(work);
567 struct ksmbd_conn *conn = work->conn;
587 * Just validate session id in header with work->sess->id.
589 if (work->next_smb2_rcv_hdr_off) {
590 if (!work->sess) {
594 if (sess_id != ULLONG_MAX && work->sess->id != sess_id) {
596 sess_id, work->sess->id);
603 work->sess = ksmbd_session_lookup_all(conn, sess_id);
604 if (work->sess)
658 int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg)
660 struct ksmbd_conn *conn = work->conn;
668 work->asynchronous = true;
669 work->async_id = id;
673 work->async_id);
675 work->cancel_fn = fn;
676 work->cancel_argv = arg;
678 if (list_empty(&work->async_request_entry)) {
680 list_add_tail(&work->async_request_entry, &conn->async_requests);
687 void release_async_work(struct ksmbd_work *work)
689 struct ksmbd_conn *conn = work->conn;
692 list_del_init(&work->async_request_entry);
695 work->asynchronous = 0;
696 work->cancel_fn = NULL;
697 kfree(work->cancel_argv);
698 work->cancel_argv = NULL;
699 if (work->async_id) {
700 ksmbd_release_id(&conn->async_ida, work->async_id);
701 work->async_id = 0;
705 void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status)
716 in_work->conn = work->conn;
717 memcpy(smb2_get_msg(in_work->response_buf), ksmbd_resp_buf_next(work),
722 rsp_hdr->Id.AsyncId = cpu_to_le64(work->async_id);
1091 * @work: smb work containing smb request buffer
1095 int smb2_handle_negotiate(struct ksmbd_work *work)
1097 struct ksmbd_conn *conn = work->conn;
1098 struct smb2_negotiate_req *req = smb2_get_msg(work->request_buf);
1099 struct smb2_negotiate_rsp *rsp = smb2_get_msg(work->response_buf);
1108 work->send_no_response = 1;
1112 smb2_buf_len = get_rfc1002_len(work->request_buf);
1170 get_rfc1002_len(work->request_buf));
1190 work->request_buf,
1266 rc = ksmbd_iov_pin_rsp(work, rsp,
1270 smb2_set_err_rsp(work);
1288 static int generate_preauth_hash(struct ksmbd_work *work)
1290 struct ksmbd_conn *conn = work->conn;
1291 struct ksmbd_session *sess = work->sess;
1315 ksmbd_gen_preauth_integrity_hash(conn, work->request_buf, preauth_hash);
1336 static int ntlm_negotiate(struct ksmbd_work *work,
1347 rc = ksmbd_decode_ntlmssp_neg_blob(negblob, negblob_len, work->conn);
1356 if (!work->conn->use_spnego) {
1357 sz = ksmbd_build_ntlmssp_challenge_blob(chgblob, work->conn);
1373 sz = ksmbd_build_ntlmssp_challenge_blob(chgblob, work->conn);
1447 static int ntlm_authenticate(struct ksmbd_work *work,
1451 struct ksmbd_conn *conn = work->conn;
1452 struct ksmbd_session *sess = work->sess;
1586 static int krb5_authenticate(struct ksmbd_work *work,
1590 struct ksmbd_conn *conn = work->conn;
1591 struct ksmbd_session *sess = work->sess;
1603 out_len = work->response_sz -
1666 static int krb5_authenticate(struct ksmbd_work *work,
1674 int smb2_sess_setup(struct ksmbd_work *work)
1676 struct ksmbd_conn *conn = work->conn;
1686 WORK_BUFFERS(work, req, rsp);
1783 work->sess = sess;
1808 rc = generate_preauth_hash(work);
1814 rc = krb5_authenticate(work, req, rsp);
1828 rc = ntlm_negotiate(work, negblob, negblob_len, rsp);
1834 rc = ntlm_authenticate(work, req, rsp);
1917 smb2_set_err_rsp(work);
1926 rc = ksmbd_iov_pin_rsp(work, rsp, iov_len);
1937 * @work: smb work containing smb request buffer
1941 int smb2_tree_connect(struct ksmbd_work *work)
1943 struct ksmbd_conn *conn = work->conn;
1946 struct ksmbd_session *sess = work->sess;
1952 WORK_BUFFERS(work, req, rsp);
2016 rc = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_tree_connect_rsp));
2052 smb2_set_err_rsp(work);
2122 * @work: smb work containing request buffer
2126 int smb2_tree_disconnect(struct ksmbd_work *work)
2130 struct ksmbd_session *sess = work->sess;
2131 struct ksmbd_tree_connect *tcon = work->tcon;
2134 WORK_BUFFERS(work, req, rsp);
2146 ksmbd_close_tree_conn_fds(work);
2166 work->tcon = NULL;
2169 err = ksmbd_iov_pin_rsp(work, rsp,
2179 smb2_set_err_rsp(work);
2186 * @work: smb work containing request buffer
2190 int smb2_session_logoff(struct ksmbd_work *work)
2192 struct ksmbd_conn *conn = work->conn;
2199 WORK_BUFFERS(work, req, rsp);
2207 smb2_set_err_rsp(work);
2214 ksmbd_close_session_fds(work);
2225 smb2_set_err_rsp(work);
2237 err = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_logoff_rsp));
2240 smb2_set_err_rsp(work);
2248 * @work: smb work containing request buffer
2252 static noinline int create_smb2_pipe(struct ksmbd_work *work)
2260 WORK_BUFFERS(work, req, rsp);
2263 1, work->conn->local_nls);
2270 id = ksmbd_session_rpc_open(work->sess, name);
2295 err = ksmbd_iov_pin_rsp(work, rsp, offsetof(struct smb2_create_rsp, Buffer));
2316 smb2_set_err_rsp(work);
2559 static int smb2_creat(struct ksmbd_work *work, struct path *parent_path,
2563 struct ksmbd_tree_connect *tcon = work->tcon;
2576 rc = ksmbd_vfs_mkdir(work, name, mode);
2583 rc = ksmbd_vfs_create(work, name, mode);
2588 rc = ksmbd_vfs_kern_path_locked(work, name, 0, parent_path, path, 0);
2597 static int smb2_create_sd_buffer(struct ksmbd_work *work,
2621 return set_info_sec(work->conn, work->tcon, path, &sd_buf->ntsd,
2647 * @work: smb work containing request buffer
2651 int smb2_open(struct ksmbd_work *work)
2653 struct ksmbd_conn *conn = work->conn;
2654 struct ksmbd_session *sess = work->sess;
2655 struct ksmbd_tree_connect *tcon = work->tcon;
2684 WORK_BUFFERS(work, req, rsp);
2686 if (req->hdr.NextCommand && !work->next_smb2_rcv_hdr_off &&
2690 smb2_set_err_rsp(work);
2696 return create_smb2_pipe(work);
2709 work->conn->local_nls);
2720 if (!test_share_config_flag(work->tcon->share_conf,
2871 if (ksmbd_override_fsids(work)) {
2876 rc = ksmbd_vfs_kern_path_locked(work, name, LOOKUP_NO_SYMLINKS,
2997 rc = smb2_creat(work, &parent_path, &path, name, open_flags,
3078 fp = ksmbd_open_fd(work, filp);
3109 if (test_share_config_flag(work->tcon->share_conf,
3116 rc = smb2_create_sd_buffer(work, req, &path);
3122 if (test_share_config_flag(work->tcon->share_conf,
3206 smb_break_all_oplock(work, fp);
3215 if (!test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_OPLOCKS) ||
3243 rc = smb_grant_oplock(work, req_op_level,
3282 smb_break_all_levII_oplock(work, fp, 1);
3428 ksmbd_revert_fsids(work);
3432 ksmbd_update_fstate(&work->sess->file_table, fp, FP_INITED);
3433 rc = ksmbd_iov_pin_rsp(work, (void *)rsp, iov_len);
3462 ksmbd_fd_put(work, fp);
3463 smb2_set_err_rsp(work);
3775 struct ksmbd_work *work;
3832 ksmbd_vfs_fill_dentry_attrs(priv->work,
3837 rc = smb2_populate_readdir_entry(priv->work->conn,
3970 if (ksmbd_share_veto_filename(priv->work->tcon->share_conf, name))
4003 static int smb2_resp_buf_len(struct ksmbd_work *work, unsigned short hdr2_len)
4007 free_len = (int)(work->response_sz -
4008 (get_rfc1002_len(work->response_buf) + 4)) - hdr2_len;
4012 static int smb2_calc_max_out_buf_len(struct ksmbd_work *work,
4018 if (out_buf_len > work->conn->vals->max_trans_size)
4021 free_len = smb2_resp_buf_len(work, hdr2_len);
4028 int smb2_query_dir(struct ksmbd_work *work)
4030 struct ksmbd_conn *conn = work->conn;
4033 struct ksmbd_share_config *share = work->tcon->share_conf;
4042 WORK_BUFFERS(work, req, rsp);
4044 if (ksmbd_override_fsids(work)) {
4046 smb2_set_err_rsp(work);
4056 dir_fp = ksmbd_lookup_fd_slow(work, req->VolatileFileId, req->PersistentFileId);
4098 smb2_calc_max_out_buf_len(work, 8,
4110 rc = ksmbd_populate_dot_dotdot_entries(work, req->FileInformationClass,
4123 query_dir_private.work = work;
4160 rc = ksmbd_iov_pin_rsp(work, (void *)rsp,
4175 rc = ksmbd_iov_pin_rsp(work, (void *)rsp,
4183 ksmbd_fd_put(work, dir_fp);
4184 ksmbd_revert_fsids(work);
4209 smb2_set_err_rsp(work);
4210 ksmbd_fd_put(work, dir_fp);
4211 ksmbd_revert_fsids(work);
4305 * @work: smb work containing query info command buffer
4313 static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp,
4348 smb2_calc_max_out_buf_len(work, 8,
4541 static int get_file_all_info(struct ksmbd_work *work,
4546 struct ksmbd_conn *conn = work->conn;
4561 filename = convert_to_nt_pathname(work->tcon->share_conf, &fp->filp->f_path);
4605 static void get_file_alternate_info(struct ksmbd_work *work,
4610 struct ksmbd_conn *conn = work->conn;
4626 static void get_file_stream_info(struct ksmbd_work *work,
4631 struct ksmbd_conn *conn = work->conn;
4639 struct smb2_query_info_req *req = ksmbd_req_buf_next(work);
4646 smb2_calc_max_out_buf_len(work, 8,
4887 static int smb2_get_info_file(struct ksmbd_work *work,
4896 if (test_share_config_flag(work->tcon->share_conf,
4899 return smb2_get_info_file_pipe(work->sess, req, rsp,
4900 work->response_buf);
4903 if (work->next_smb2_rcv_hdr_off) {
4906 work->compound_fid);
4907 id = work->compound_fid;
4908 pid = work->compound_pfid;
4917 fp = ksmbd_lookup_fd_slow(work, id, pid);
4925 get_file_access_info(rsp, fp, work->response_buf);
4929 rc = get_file_basic_info(rsp, fp, work->response_buf);
4933 get_file_standard_info(rsp, fp, work->response_buf);
4937 get_file_alignment_info(rsp, work->response_buf);
4941 rc = get_file_all_info(work, rsp, fp, work->response_buf);
4945 get_file_alternate_info(work, rsp, fp, work->response_buf);
4949 get_file_stream_info(work, rsp, fp, work->response_buf);
4953 get_file_internal_info(rsp, fp, work->response_buf);
4957 rc = get_file_network_open_info(rsp, fp, work->response_buf);
4961 get_file_ea_info(rsp, work->response_buf);
4965 rc = smb2_get_ea(work, fp, req, rsp, work->response_buf);
4969 get_file_position_info(rsp, fp, work->response_buf);
4973 get_file_mode_info(rsp, fp, work->response_buf);
4977 get_file_compression_info(rsp, fp, work->response_buf);
4981 rc = get_file_attribute_tag_info(rsp, fp, work->response_buf);
4984 if (!work->tcon->posix_extensions) {
4988 find_file_posix_info(rsp, fp, work->response_buf);
4998 rsp, work->response_buf);
4999 ksmbd_fd_put(work, fp);
5003 static int smb2_get_info_filesystem(struct ksmbd_work *work,
5007 struct ksmbd_session *sess = work->sess;
5008 struct ksmbd_conn *conn = work->conn;
5009 struct ksmbd_share_config *share = work->tcon->share_conf;
5060 if (test_share_config_flag(work->tcon->share_conf,
5190 if (!work->tcon->posix_extensions) {
5211 rsp, work->response_buf);
5216 static int smb2_get_info_sec(struct ksmbd_work *work,
5249 if (work->next_smb2_rcv_hdr_off) {
5252 work->compound_fid);
5253 id = work->compound_fid;
5254 pid = work->compound_pfid;
5263 fp = ksmbd_lookup_fd_slow(work, id, pid);
5271 if (test_share_config_flag(work->tcon->share_conf,
5273 ppntsd_size = ksmbd_vfs_get_sd_xattr(work->conn, idmap,
5278 if (smb2_resp_buf_len(work, 8) > ppntsd_size)
5284 ksmbd_fd_put(work, fp);
5294 * @work: smb work containing query info request buffer
5298 int smb2_query_info(struct ksmbd_work *work)
5304 WORK_BUFFERS(work, req, rsp);
5311 rc = smb2_get_info_file(work, req, rsp);
5315 rc = smb2_get_info_filesystem(work, req, rsp);
5319 rc = smb2_get_info_sec(work, req, rsp);
5330 rc = ksmbd_iov_pin_rsp(work, (void *)rsp,
5346 smb2_set_err_rsp(work);
5357 * @work: smb work containing close request buffer
5361 static noinline int smb2_close_pipe(struct ksmbd_work *work)
5367 WORK_BUFFERS(work, req, rsp);
5370 ksmbd_session_rpc_close(work->sess, id);
5383 return ksmbd_iov_pin_rsp(work, (void *)rsp,
5389 * @work: smb work containing close request buffer
5393 int smb2_close(struct ksmbd_work *work)
5399 struct ksmbd_conn *conn = work->conn;
5405 WORK_BUFFERS(work, req, rsp);
5407 if (test_share_config_flag(work->tcon->share_conf,
5410 return smb2_close_pipe(work);
5415 sess_id = work->compound_sid;
5417 work->compound_sid = 0;
5419 work->compound_sid = sess_id;
5428 if (work->next_smb2_rcv_hdr_off &&
5430 if (!has_file_id(work->compound_fid)) {
5439 work->compound_fid,
5440 work->compound_pfid);
5441 volatile_id = work->compound_fid;
5444 work->compound_fid = KSMBD_NO_FID;
5445 work->compound_pfid = KSMBD_NO_FID;
5456 fp = ksmbd_lookup_fd_fast(work, volatile_id);
5475 ksmbd_fd_put(work, fp);
5487 err = ksmbd_close_fd(work, volatile_id);
5490 err = ksmbd_iov_pin_rsp(work, (void *)rsp,
5496 smb2_set_err_rsp(work);
5504 * @work: smb work containing echo request buffer
5508 int smb2_echo(struct ksmbd_work *work)
5510 struct smb2_echo_rsp *rsp = smb2_get_msg(work->response_buf);
5512 if (work->next_smb2_rcv_hdr_off)
5513 rsp = ksmbd_resp_buf_next(work);
5517 return ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_echo_rsp));
5520 static int smb2_rename(struct ksmbd_work *work,
5584 smb_break_all_levII_oplock(work, fp, 0);
5585 rc = ksmbd_vfs_rename(work, &fp->filp->f_path, new_name, flags);
5591 static int smb2_create_link(struct ksmbd_work *work,
5627 rc = ksmbd_vfs_kern_path_locked(work, link_name, LOOKUP_NO_SYMLINKS,
5637 rc = ksmbd_vfs_remove_file(work, &path);
5653 rc = ksmbd_vfs_link(work, target_name, link_name);
5750 static int set_file_allocation_info(struct ksmbd_work *work,
5771 smb_break_all_levII_oplock(work, fp, 1);
5789 rc = ksmbd_vfs_truncate(work, fp, alloc_blks * 512);
5800 static int set_end_of_file_info(struct ksmbd_work *work, struct ksmbd_file *fp,
5822 rc = ksmbd_vfs_truncate(work, fp, newsize);
5833 static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp,
5849 return smb2_rename(work, fp, rename_info, work->conn->local_nls);
5920 * @work: smb work containing set info command buffer
5928 static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
5947 return set_file_allocation_info(work, fp,
5955 return set_end_of_file_info(work, fp,
5963 return set_rename_info(work, fp,
5972 return smb2_create_link(work, work->tcon->share_conf,
5975 work->conn->local_nls);
6032 * @work: smb work containing set info request buffer
6036 int smb2_set_info(struct ksmbd_work *work)
6046 if (work->next_smb2_rcv_hdr_off) {
6047 req = ksmbd_req_buf_next(work);
6048 rsp = ksmbd_resp_buf_next(work);
6051 work->compound_fid);
6052 id = work->compound_fid;
6053 pid = work->compound_pfid;
6056 req = smb2_get_msg(work->request_buf);
6057 rsp = smb2_get_msg(work->response_buf);
6060 if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
6072 fp = ksmbd_lookup_fd_slow(work, id, pid);
6082 rc = smb2_set_info_file(work, fp, req, work->tcon->share_conf);
6086 if (ksmbd_override_fsids(work)) {
6094 ksmbd_revert_fsids(work);
6104 rc = ksmbd_iov_pin_rsp(work, (void *)rsp,
6108 ksmbd_fd_put(work, fp);
6130 smb2_set_err_rsp(work);
6131 ksmbd_fd_put(work, fp);
6138 * @work: smb work containing read IPC pipe command buffer
6142 static noinline int smb2_read_pipe(struct ksmbd_work *work)
6150 WORK_BUFFERS(work, req, rsp);
6154 rpc_resp = ksmbd_rpc_read(work->sess, id);
6173 err = ksmbd_iov_pin_rsp_read(work, (void *)rsp,
6182 err = ksmbd_iov_pin_rsp(work, (void *)rsp,
6198 smb2_set_err_rsp(work);
6203 static int smb2_set_remote_key_for_rdma(struct ksmbd_work *work,
6210 if (work->conn->dialect == SMB30_PROT_ID &&
6226 work->need_invalidate_rkey =
6229 work->remote_key = le32_to_cpu(desc->token);
6233 static ssize_t smb2_read_rdma_channel(struct ksmbd_work *work,
6239 err = ksmbd_conn_rdma_write(work->conn, data_buf, length,
6251 * @work: smb work containing read command buffer
6255 int smb2_read(struct ksmbd_work *work)
6257 struct ksmbd_conn *conn = work->conn;
6270 if (test_share_config_flag(work->tcon->share_conf,
6273 return smb2_read_pipe(work);
6276 if (work->next_smb2_rcv_hdr_off) {
6277 req = ksmbd_req_buf_next(work);
6278 rsp = ksmbd_resp_buf_next(work);
6281 work->compound_fid);
6282 id = work->compound_fid;
6283 pid = work->compound_pfid;
6286 req = smb2_get_msg(work->request_buf);
6287 rsp = smb2_get_msg(work->response_buf);
6308 err = smb2_set_remote_key_for_rdma(work,
6317 fp = ksmbd_lookup_fd_slow(work, id, pid);
6349 nbytes = ksmbd_vfs_read(work, fp, length, &offset, aux_payload_buf);
6358 smb2_set_err_rsp(work);
6359 ksmbd_fd_put(work, fp);
6368 remain_bytes = smb2_read_rdma_channel(work, req,
6386 err = ksmbd_iov_pin_rsp_read(work, (void *)rsp,
6393 ksmbd_fd_put(work, fp);
6413 smb2_set_err_rsp(work);
6415 ksmbd_fd_put(work, fp);
6421 * @work: smb work containing write IPC pipe command buffer
6425 static noinline int smb2_write_pipe(struct ksmbd_work *work)
6435 WORK_BUFFERS(work, req, rsp);
6441 get_rfc1002_len(work->request_buf)) {
6444 get_rfc1002_len(work->request_buf));
6452 rpc_resp = ksmbd_rpc_write(work->sess, id, data_buf, length);
6457 smb2_set_err_rsp(work);
6462 smb2_set_err_rsp(work);
6475 err = ksmbd_iov_pin_rsp(work, (void *)rsp,
6480 smb2_set_err_rsp(work);
6486 static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work,
6499 ret = ksmbd_conn_rdma_read(work->conn, data_buf, length,
6508 ret = ksmbd_vfs_write(work, fp, data_buf, length, &offset, sync, &nbytes);
6518 * @work: smb work containing write command buffer
6522 int smb2_write(struct ksmbd_work *work)
6533 unsigned int max_write_size = work->conn->vals->max_write_size;
6535 WORK_BUFFERS(work, req, rsp);
6537 if (test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_PIPE)) {
6539 return smb2_write_pipe(work);
6560 err = smb2_set_remote_key_for_rdma(work,
6569 if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
6575 fp = ksmbd_lookup_fd_slow(work, req->VolatileFileId, req->PersistentFileId);
6610 err = ksmbd_vfs_write(work, fp, data_buf, length, &offset,
6618 nbytes = smb2_write_rdma_channel(work, req, fp, offset, length,
6632 err = ksmbd_iov_pin_rsp(work, rsp, offsetof(struct smb2_write_rsp, Buffer));
6635 ksmbd_fd_put(work, fp);
6654 smb2_set_err_rsp(work);
6655 ksmbd_fd_put(work, fp);
6661 * @work: smb work containing flush command buffer
6665 int smb2_flush(struct ksmbd_work *work)
6671 WORK_BUFFERS(work, req, rsp);
6675 err = ksmbd_vfs_fsync(work, req->VolatileFileId, req->PersistentFileId);
6681 return ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_flush_rsp));
6685 smb2_set_err_rsp(work);
6691 * @work: smb work containing cancel command buffer
6695 int smb2_cancel(struct ksmbd_work *work)
6697 struct ksmbd_conn *conn = work->conn;
6698 struct smb2_hdr *hdr = smb2_get_msg(work->request_buf);
6703 if (work->next_smb2_rcv_hdr_off)
6704 hdr = ksmbd_resp_buf_next(work);
6739 iter == work)
6753 work->send_no_response = 1;
6859 * @work: smb work containing lock command buffer
6863 int smb2_lock(struct ksmbd_work *work)
6883 WORK_BUFFERS(work, req, rsp);
6886 fp = ksmbd_lookup_fd_slow(work, req->VolatileFileId, req->PersistentFileId);
7099 rc = setup_async_work(work,
7108 list_add(&work->fp_entry, &fp->blocked_works);
7111 smb2_send_interim_resp(work, STATUS_PENDING);
7116 list_del(&work->fp_entry);
7119 if (work->state != KSMBD_WORK_ACTIVE) {
7123 if (work->state == KSMBD_WORK_CANCELLED) {
7127 smb2_send_interim_resp(work,
7129 work->send_no_response = 1;
7140 release_async_work(work);
7144 spin_lock(&work->conn->llist_lock);
7146 &work->conn->lock_list);
7149 spin_unlock(&work->conn->llist_lock);
7158 smb_break_all_oplock(work, fp);
7164 err = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_lock_rsp));
7168 ksmbd_fd_put(work, fp);
7191 spin_lock(&work->conn->llist_lock);
7195 spin_unlock(&work->conn->llist_lock);
7215 smb2_set_err_rsp(work);
7216 ksmbd_fd_put(work, fp);
7220 static int fsctl_copychunk(struct ksmbd_work *work,
7274 src_fp = ksmbd_lookup_foreign_fd(work,
7276 dst_fp = ksmbd_lookup_fd_slow(work, volatile_id, persistent_id);
7299 ret = ksmbd_vfs_copy_file_ranges(work, src_fp, dst_fp,
7327 ksmbd_fd_put(work, src_fp);
7328 ksmbd_fd_put(work, dst_fp);
7500 static int fsctl_query_allocated_ranges(struct ksmbd_work *work, u64 id,
7519 fp = ksmbd_lookup_fd_fast(work, id);
7528 ksmbd_fd_put(work, fp);
7532 static int fsctl_pipe_transceive(struct ksmbd_work *work, u64 id,
7541 rpc_resp = ksmbd_rpc_ioctl(work->sess, id, data_buf,
7577 static inline int fsctl_set_sparse(struct ksmbd_work *work, u64 id,
7585 fp = ksmbd_lookup_fd_fast(work, id);
7597 test_share_config_flag(work->tcon->share_conf,
7615 ksmbd_fd_put(work, fp);
7619 static int fsctl_request_resume_key(struct ksmbd_work *work,
7625 fp = ksmbd_lookup_fd_slow(work, req->VolatileFileId, req->PersistentFileId);
7632 ksmbd_fd_put(work, fp);
7639 * @work: smb work containing ioctl command buffer
7643 int smb2_ioctl(struct ksmbd_work *work)
7649 struct ksmbd_conn *conn = work->conn;
7652 if (work->next_smb2_rcv_hdr_off) {
7653 req = ksmbd_req_buf_next(work);
7654 rsp = ksmbd_resp_buf_next(work);
7657 work->compound_fid);
7658 id = work->compound_fid;
7661 req = smb2_get_msg(work->request_buf);
7662 rsp = smb2_get_msg(work->response_buf);
7674 ret = smb2_calc_max_out_buf_len(work, 48,
7710 nbytes = fsctl_pipe_transceive(work, id, out_buf_len, req, rsp);
7752 ret = fsctl_request_resume_key(work, req,
7762 if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
7782 fsctl_copychunk(work,
7796 ret = fsctl_set_sparse(work, id,
7807 if (!test_tree_conn_flag(work->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
7831 fp = ksmbd_lookup_fd_fast(work, id);
7837 ret = ksmbd_vfs_zero_data(work, fp, off, len);
7838 ksmbd_fd_put(work, fp);
7850 ret = fsctl_query_allocated_ranges(work, id,
7870 fp = ksmbd_lookup_fd_fast(work, id);
7880 ksmbd_fd_put(work, fp);
7897 fp_in = ksmbd_lookup_fd_slow(work, dup_ext->VolatileFileHandle,
7905 fp_out = ksmbd_lookup_fd_fast(work, id);
7942 ksmbd_fd_put(work, fp_in);
7943 ksmbd_fd_put(work, fp_out);
7964 ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_ioctl_rsp) + nbytes);
7979 smb2_set_err_rsp(work);
7985 * @work: smb work containing oplock break command buffer
7989 static void smb20_oplock_break_ack(struct ksmbd_work *work)
8001 WORK_BUFFERS(work, req, rsp);
8009 fp = ksmbd_lookup_fd_slow(work, volatile_id, persistent_id);
8012 smb2_set_err_rsp(work);
8020 smb2_set_err_rsp(work);
8021 ksmbd_fd_put(work, fp);
8093 ksmbd_fd_put(work, fp);
8101 ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_oplock_break));
8110 ksmbd_fd_put(work, fp);
8111 smb2_set_err_rsp(work);
8131 * @work: smb work containing lease break command buffer
8135 static void smb21_lease_break_ack(struct ksmbd_work *work)
8137 struct ksmbd_conn *conn = work->conn;
8147 WORK_BUFFERS(work, req, rsp);
8154 smb2_set_err_rsp(work);
8253 ret = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_lease_ack));
8263 smb2_set_err_rsp(work);
8268 * @work: smb work containing oplock/lease break command buffer
8272 int smb2_oplock_break(struct ksmbd_work *work)
8277 WORK_BUFFERS(work, req, rsp);
8281 smb20_oplock_break_ack(work);
8284 smb21_lease_break_ack(work);
8290 smb2_set_err_rsp(work);
8298 * @work: smb work containing notify command buffer
8302 int smb2_notify(struct ksmbd_work *work)
8307 WORK_BUFFERS(work, req, rsp);
8309 if (work->next_smb2_rcv_hdr_off && req->hdr.NextCommand) {
8311 smb2_set_err_rsp(work);
8315 smb2_set_err_rsp(work);
8322 * @work: smb work containing notify command buffer
8327 bool smb2_is_sign_req(struct ksmbd_work *work, unsigned int command)
8329 struct smb2_hdr *rcv_hdr2 = smb2_get_msg(work->request_buf);
8342 * @work: smb work containing notify command buffer
8346 int smb2_check_sign_req(struct ksmbd_work *work)
8354 hdr = smb2_get_msg(work->request_buf);
8355 if (work->next_smb2_rcv_hdr_off)
8356 hdr = ksmbd_req_buf_next(work);
8358 if (!hdr->NextCommand && !work->next_smb2_rcv_hdr_off)
8359 len = get_rfc1002_len(work->request_buf);
8363 len = get_rfc1002_len(work->request_buf) -
8364 work->next_smb2_rcv_hdr_off;
8372 if (ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, 1,
8386 * @work: smb work containing notify command buffer
8389 void smb2_set_sign_rsp(struct ksmbd_work *work)
8396 hdr = ksmbd_resp_buf_curr(work);
8401 iov = &work->iov[work->iov_idx - 1];
8404 iov = &work->iov[work->iov_idx];
8407 if (!ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, n_vec,
8414 * @work: smb work containing notify command buffer
8418 int smb3_check_sign_req(struct ksmbd_work *work)
8420 struct ksmbd_conn *conn = work->conn;
8429 hdr = smb2_get_msg(work->request_buf);
8430 if (work->next_smb2_rcv_hdr_off)
8431 hdr = ksmbd_req_buf_next(work);
8433 if (!hdr->NextCommand && !work->next_smb2_rcv_hdr_off)
8434 len = get_rfc1002_len(work->request_buf);
8438 len = get_rfc1002_len(work->request_buf) -
8439 work->next_smb2_rcv_hdr_off;
8442 signing_key = work->sess->smb3signingkey;
8444 chann = lookup_chann_list(work->sess, conn);
8474 * @work: smb work containing notify command buffer
8477 void smb3_set_sign_rsp(struct ksmbd_work *work)
8479 struct ksmbd_conn *conn = work->conn;
8487 hdr = ksmbd_resp_buf_curr(work);
8491 signing_key = work->sess->smb3signingkey;
8493 chann = lookup_chann_list(work->sess, work->conn);
8507 iov = &work->iov[work->iov_idx - 1];
8510 iov = &work->iov[work->iov_idx];
8520 * @work: smb work containing response buffer
8523 void smb3_preauth_hash_rsp(struct ksmbd_work *work)
8525 struct ksmbd_conn *conn = work->conn;
8526 struct ksmbd_session *sess = work->sess;
8532 WORK_BUFFERS(work, req, rsp);
8536 ksmbd_gen_preauth_integrity_hash(conn, work->response_buf,
8554 ksmbd_gen_preauth_integrity_hash(conn, work->response_buf,
8579 int smb3_encrypt_resp(struct ksmbd_work *work)
8581 struct kvec *iov = work->iov;
8590 fill_transform_hdr(tr_buf, work->response_buf, work->conn->cipher_type);
8594 work->tr_buf = tr_buf;
8596 return ksmbd_crypt_message(work, iov, work->iov_idx + 1, 1);
8606 int smb3_decrypt_req(struct ksmbd_work *work)
8609 char *buf = work->request_buf;
8628 sess = ksmbd_session_lookup_all(work->conn, le64_to_cpu(tr_hdr->SessionId));
8639 rc = ksmbd_crypt_message(work, iov, 2, 0);
8649 bool smb3_11_final_sess_setup_resp(struct ksmbd_work *work)
8651 struct ksmbd_conn *conn = work->conn;
8652 struct ksmbd_session *sess = work->sess;
8653 struct smb2_hdr *rsp = smb2_get_msg(work->response_buf);
8658 if (work->next_smb2_rcv_hdr_off)
8659 rsp = ksmbd_resp_buf_next(work);