Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/smbd/smb2_write.c

    r414 r745  
    2020
    2121#include "includes.h"
     22#include "smbd/smbd.h"
    2223#include "smbd/globals.h"
    2324#include "../libcli/smb/smb_common.h"
     25#include "../lib/util/tevent_ntstatus.h"
     26#include "rpc_server/srv_pipe_hnd.h"
    2427
    2528static struct tevent_req *smbd_smb2_write_send(TALLOC_CTX *mem_ctx,
     
    8285
    8386        /* check the max write size */
    84         if (in_data_length > 0x00010000) {
    85                 DEBUG(0,("here:%s: 0x%08X: 0x%08X\n",
    86                         __location__, in_data_length, 0x00010000));
     87        if (in_data_length > lp_smb2_max_write()) {
     88                /* This is a warning. */
     89                DEBUG(2,("smbd_smb2_request_process_write : "
     90                        "client ignored max write :%s: 0x%08X: 0x%08X\n",
     91                        __location__, in_data_length, lp_smb2_max_write()));
     92#if 0
    8793                return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
     94#endif
    8895        }
    8996
     
    93100        if (req->compat_chain_fsp) {
    94101                /* skip check */
    95         } else if (in_file_id_persistent != 0) {
     102        } else if (in_file_id_persistent != in_file_id_volatile) {
    96103                return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
    97104        }
     
    168175struct smbd_smb2_write_state {
    169176        struct smbd_smb2_request *smb2req;
     177        files_struct *fsp;
     178        bool write_through;
    170179        uint32_t in_length;
     180        uint64_t in_offset;
    171181        uint32_t out_count;
    172182};
    173183
    174184static void smbd_smb2_write_pipe_done(struct tevent_req *subreq);
     185
     186NTSTATUS smb2_write_complete(struct tevent_req *req, ssize_t nwritten, int err)
     187{
     188        NTSTATUS status;
     189        struct smbd_smb2_write_state *state = tevent_req_data(req,
     190                                        struct smbd_smb2_write_state);
     191        files_struct *fsp = state->fsp;
     192
     193        DEBUG(3,("smb2: fnum=[%d/%s] "
     194                "length=%lu offset=%lu wrote=%lu\n",
     195                fsp->fnum,
     196                fsp_str_dbg(fsp),
     197                (unsigned long)state->in_length,
     198                (unsigned long)state->in_offset,
     199                (unsigned long)nwritten));
     200
     201        if (nwritten == -1) {
     202                return map_nt_error_from_unix(err);
     203        }
     204
     205        if ((nwritten == 0) && (state->in_length != 0)) {
     206                DEBUG(5,("smb2: write [%s] disk full\n",
     207                        fsp_str_dbg(fsp)));
     208                return NT_STATUS_DISK_FULL;
     209        }
     210
     211        status = sync_file(fsp->conn, fsp, state->write_through);
     212        if (!NT_STATUS_IS_OK(status)) {
     213                DEBUG(5,("smb2: sync_file for %s returned %s\n",
     214                        fsp_str_dbg(fsp),
     215                        nt_errstr(status)));
     216                return status;
     217        }
     218
     219        state->out_count = nwritten;
     220
     221        return NT_STATUS_OK;
     222}
    175223
    176224static struct tevent_req *smbd_smb2_write_send(TALLOC_CTX *mem_ctx,
     
    184232{
    185233        NTSTATUS status;
    186         struct tevent_req *req;
    187         struct smbd_smb2_write_state *state;
    188         struct smb_request *smbreq;
     234        struct tevent_req *req = NULL;
     235        struct smbd_smb2_write_state *state = NULL;
     236        struct smb_request *smbreq = NULL;
    189237        connection_struct *conn = smb2req->tcon->compat_conn;
    190         files_struct *fsp;
     238        files_struct *fsp = NULL;
    191239        ssize_t nwritten;
    192         bool write_through = false;
    193240        struct lock_struct lock;
    194241
     
    199246        }
    200247        state->smb2req = smb2req;
     248        if (in_flags & 0x00000001) {
     249                state->write_through = true;
     250        }
    201251        state->in_length = in_data.length;
    202252        state->out_count = 0;
     
    224274        }
    225275
     276        state->fsp = fsp;
     277
    226278        if (IS_IPC(smbreq->conn)) {
    227                 struct tevent_req *subreq;
     279                struct tevent_req *subreq = NULL;
    228280
    229281                if (!fsp_is_np(fsp)) {
     
    250302        }
    251303
     304        /* Try and do an asynchronous write. */
     305        status = schedule_aio_smb2_write(conn,
     306                                        smbreq,
     307                                        fsp,
     308                                        in_offset,
     309                                        in_data,
     310                                        state->write_through);
     311
     312        if (NT_STATUS_IS_OK(status)) {
     313                /*
     314                 * Doing an async write. Don't
     315                 * send a "gone async" message
     316                 * as we expect this to be less
     317                 * than the client timeout period.
     318                 * JRA. FIXME for offline files..
     319                 * FIXME - add cancel code..
     320                 */
     321                smb2req->async = true;
     322                return req;
     323        }
     324
     325        if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
     326                /* Real error in setting up aio. Fail. */
     327                tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);
     328                return tevent_req_post(req, ev);
     329        }
     330
     331        /* Fallback to synchronous. */
    252332        init_strict_lock_struct(fsp,
    253                                 in_smbpid,
     333                                in_file_id_volatile,
    254334                                in_offset,
    255335                                in_data.length,
     
    267347                              in_data.length);
    268348
    269         if (((nwritten == 0) && (in_data.length != 0)) || (nwritten < 0)) {
    270                 DEBUG(5,("smbd_smb2_write: write_file[%s] disk full\n",
    271                          fsp_str_dbg(fsp)));
    272                 SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
    273                 tevent_req_nterror(req, NT_STATUS_DISK_FULL);
    274                 return tevent_req_post(req, ev);
    275         }
    276 
    277         DEBUG(3,("smbd_smb2_write: fnum=[%d/%s] length=%d offset=%d wrote=%d\n",
    278                 fsp->fnum, fsp_str_dbg(fsp), (int)in_data.length,
    279                 (int)in_offset, (int)nwritten));
    280 
    281         if (in_flags & 0x00000001) {
    282                 write_through = true;
    283         }
    284 
    285         status = sync_file(conn, fsp, write_through);
     349        status = smb2_write_complete(req, nwritten, errno);
     350
     351        SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
     352
     353        DEBUG(10,("smb2: write on "
     354                "file %s, offset %.0f, requested %u, written = %u\n",
     355                fsp_str_dbg(fsp),
     356                (double)in_offset,
     357                (unsigned int)in_data.length,
     358                (unsigned int)nwritten ));
     359
    286360        if (!NT_STATUS_IS_OK(status)) {
    287                 DEBUG(5,("smbd_smb2_write: sync_file for %s returned %s\n",
    288                         fsp_str_dbg(fsp), nt_errstr(status)));
    289                 SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
    290361                tevent_req_nterror(req, status);
    291                 return tevent_req_post(req, ev);
    292         }
    293 
    294         SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
    295 
    296         state->out_count = nwritten;
    297 
    298         tevent_req_done(req);
     362        } else {
     363                /* Success. */
     364                tevent_req_done(req);
     365        }
     366
    299367        return tevent_req_post(req, ev);
    300368}
Note: See TracChangeset for help on using the changeset viewer.