s3: Return correct error code from SMB2 AIO read failure
[samba.git] / source3 / smbd / smb2_read.c
index ba352f7c254a63e991b46bcb6e398da68944d590..6478326ac068dfe10ff0dbdca77dd6c85d6b5ea8 100644 (file)
@@ -166,6 +166,7 @@ struct smbd_smb2_read_state {
        uint32_t in_length;
        uint64_t in_offset;
        uint32_t in_minimum;
+       DATA_BLOB out_headers;
        DATA_BLOB out_data;
        uint32_t out_remaining;
 };
@@ -180,10 +181,10 @@ static int smb2_sendfile_send_data(struct smbd_smb2_read_state *state)
        ssize_t nread;
 
        nread = SMB_VFS_SENDFILE(fsp->conn->sconn->sock,
-                                       fsp,
-                                       NULL,
-                                       in_offset,
-                                       in_length);
+                                fsp,
+                                state->smb2req->queue_entry.sendfile_header,
+                                in_offset,
+                                in_length);
        DEBUG(10,("smb2_sendfile_send_data: SMB_VFS_SENDFILE returned %d on file %s\n",
                (int)nread,
                fsp_str_dbg(fsp) ));
@@ -275,14 +276,15 @@ static NTSTATUS schedule_smb2_sendfile_read(struct smbd_smb2_request *smb2req,
        */
 
        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)) {
+           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;
        }
 
@@ -300,6 +302,7 @@ static NTSTATUS schedule_smb2_sendfile_read(struct smbd_smb2_request *smb2req,
        }
        *state_copy = *state;
        talloc_set_destructor(state_copy, smb2_sendfile_send_data);
+       state->smb2req->queue_entry.sendfile_header = &state_copy->out_headers;
        return NT_STATUS_OK;
 }
 
@@ -362,8 +365,6 @@ static bool smbd_smb2_read_cancel(struct tevent_req *req)
                tevent_req_data(req,
                struct smbd_smb2_read_state);
 
-       state->smb2req->cancelled = true;
-
        return cancel_smb2_aio(state->smbreq);
 }
 
@@ -463,7 +464,7 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
 
        if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
                /* Real error in setting up aio. Fail. */
-               tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);
+               tevent_req_nterror(req, status);
                return tevent_req_post(req, ev);
        }