static NTSTATUS schedule_smb2_sendfile_read(struct smbd_smb2_request *smb2req, struct smbd_smb2_read_state *state) { struct smbd_smb2_read_state *state_copy = NULL; files_struct *fsp = state->fsp; /* * We cannot use sendfile if... * We were not configured to do so OR * Signing is active OR * This is a compound SMB2 operation OR * fsp is a STREAM file OR * We're using a write cache OR * It's not a regular file OR * Requested offset is greater than file size OR * there's not enough data in the file. * Phew :-). Luckily this means most * reads on most normal files. JRA. */ if (!lp__use_sendfile(SNUM(fsp->conn)) || smb2req->do_signing || smb2req->in.vector_count != 4 || (fsp->base_fsp != NULL) || (fsp->wcp != NULL) || (!S_ISREG(fsp->fsp_name->st.st_ex_mode)) || (state->in_offset >= fsp->fsp_name->st.st_ex_size) || (fsp->fsp_name->st.st_ex_size < state->in_offset + state->in_length)) { return NT_STATUS_RETRY; } /* We've already checked there's this amount of data to read. */ state->out_data.length = state->in_length; state->out_remaining = 0; /* Make a copy of state attached to the smb2req. Attach the destructor here as this will trigger the sendfile call when the request is destroyed. */ state_copy = talloc(smb2req, struct smbd_smb2_read_state); if (!state_copy) { return NT_STATUS_NO_MEMORY; } *state_copy = *state; talloc_set_destructor(state_copy, smb2_sendfile_send_data); return NT_STATUS_OK; }
static NTSTATUS schedule_smb2_sendfile_read(struct smbd_smb2_request *smb2req, struct smbd_smb2_read_state *state) { files_struct *fsp = state->fsp; /* * We cannot use sendfile if... * We were not configured to do so OR * Signing is active OR * This is a compound SMB2 operation OR * fsp is a STREAM file OR * We're using a write cache OR * It's not a regular file OR * Requested offset is greater than file size OR * there's not enough data in the file. * Phew :-). Luckily this means most * reads on most normal files. JRA. */ if (!lp__use_sendfile(SNUM(fsp->conn)) || smb2req->do_signing || smb2req->do_encryption || smb2req->in.vector_count >= (2*SMBD_SMB2_NUM_IOV_PER_REQ) || (fsp->base_fsp != NULL) || (fsp->wcp != NULL) || (!S_ISREG(fsp->fsp_name->st.st_ex_mode)) || (state->in_offset >= fsp->fsp_name->st.st_ex_size) || (fsp->fsp_name->st.st_ex_size < state->in_offset + state->in_length)) { return NT_STATUS_RETRY; } /* We've already checked there's this amount of data to read. */ state->out_data.length = state->in_length; state->out_remaining = 0; state->out_headers = data_blob_const(state->_out_hdr_buf, sizeof(state->_out_hdr_buf)); return NT_STATUS_OK; }