From cc35d1300d487c65f1dc8a275140701ba276adaf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 15 Jun 2007 19:24:04 +0000 Subject: r23508: Fix sync_file() to return NTSTATUS and return this on failure in the write path. Jeremy. (This used to be commit cd3f7dbee809fb40194af0e7509142166e02b252) --- source3/smbd/aio.c | 9 +++++++- source3/smbd/fileio.c | 15 +++++++++---- source3/smbd/reply.c | 58 ++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 69 insertions(+), 13 deletions(-) (limited to 'source3/smbd') diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c index bee6ebc89a..f747cf5c06 100644 --- a/source3/smbd/aio.c +++ b/source3/smbd/aio.c @@ -468,6 +468,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) ret = errno; } else { BOOL write_through = BITSETW(aio_ex->inbuf+smb_vwv7,0); + NTSTATUS status; SSVAL(outbuf,smb_vwv2,nwritten); SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1); @@ -478,7 +479,13 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) DEBUG(3,("handle_aio_write: fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten)); - sync_file(fsp->conn,fsp, write_through); + status = sync_file(fsp->conn,fsp, write_through); + if (!NT_STATUS_IS_OK(status)) { + UNIXERROR(ERRHRD,ERRdiskfull); + ret = errno; + DEBUG(5,("handle_aio_write: sync_file for %s returned %s\n", + fsp->fsp_name, nt_errstr(status) )); + } } show_msg(outbuf); diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 65238c0e9e..1227d12b08 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -834,16 +834,23 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) sync a file ********************************************************************/ -void sync_file(connection_struct *conn, files_struct *fsp, BOOL write_through) +NTSTATUS sync_file(connection_struct *conn, files_struct *fsp, BOOL write_through) { if (fsp->fh->fd == -1) - return; + return NT_STATUS_INVALID_HANDLE; if (lp_strict_sync(SNUM(conn)) && (lp_syncalways(SNUM(conn)) || write_through)) { - flush_write_cache(fsp, SYNC_FLUSH); - SMB_VFS_FSYNC(fsp,fsp->fh->fd); + int ret = flush_write_cache(fsp, SYNC_FLUSH); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + ret = SMB_VFS_FSYNC(fsp,fsp->fh->fd); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } } + return NT_STATUS_OK; } /************************************************************ diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 205374cff7..33ccb7f386 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -2787,6 +2787,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, BOOL write_through; files_struct *fsp = file_fsp(inbuf,smb_vwv0); int outsize = 0; + NTSTATUS status; START_PROFILE(SMBwritebraw); if (srv_is_signing_active()) { @@ -2891,7 +2892,13 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, SSVAL(outbuf,smb_vwv0,total_written); - sync_file(conn, fsp, write_through); + status = sync_file(conn, fsp, write_through); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(5,("reply_writebraw: sync_file for %s returned %s\n", + fsp->fsp_name, nt_errstr(status) )); + END_PROFILE(SMBwritebraw); + return ERROR_NT(status); + } DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n", fsp->fnum, (double)startpos, (int)numtowrite,(int)total_written)); @@ -2956,7 +2963,13 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, nwritten = write_file(fsp,data,startpos,numtowrite); } - sync_file(conn, fsp, False /* write through */); + status = sync_file(conn, fsp, False /* write through */); + if (!NT_STATUS_IS_OK(status)) { + END_PROFILE(SMBwriteunlock); + DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n", + fsp->fsp_name, nt_errstr(status) )); + return ERROR_NT(status); + } if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { END_PROFILE(SMBwriteunlock); @@ -3003,6 +3016,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d char *data; files_struct *fsp = file_fsp(inbuf,smb_vwv0); int outsize = 0; + NTSTATUS status; START_PROFILE(SMBwrite); /* If it's an IPC, pass off the pipe handler. */ @@ -3013,6 +3027,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d CHECK_FSP(fsp,conn); if (!CHECK_WRITE(fsp)) { + END_PROFILE(SMBwrite); return(ERROR_DOS(ERRDOS,ERRbadaccess)); } @@ -3048,7 +3063,13 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d } else nwritten = write_file(fsp,data,startpos,numtowrite); - sync_file(conn, fsp, False); + status = sync_file(conn, fsp, False); + if (!NT_STATUS_IS_OK(status)) { + END_PROFILE(SMBwrite); + DEBUG(5,("reply_write: sync_file for %s returned %s\n", + fsp->fsp_name, nt_errstr(status) )); + return ERROR_NT(status); + } if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { END_PROFILE(SMBwrite); @@ -3085,6 +3106,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng unsigned int smblen = smb_len(inbuf); char *data; BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF)); + NTSTATUS status; START_PROFILE(SMBwriteX); /* If it's an IPC, pass off the pipe handler. */ @@ -3175,7 +3197,13 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten)); - sync_file(conn, fsp, write_through); + status = sync_file(conn, fsp, write_through); + if (!NT_STATUS_IS_OK(status)) { + END_PROFILE(SMBwriteX); + DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n", + fsp->fsp_name, nt_errstr(status) )); + return ERROR_NT(status); + } END_PROFILE(SMBwriteX); return chain_reply(inbuf,outbuf,length,bufsize); @@ -3272,7 +3300,13 @@ int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int if (!fsp) { file_sync_all(conn); } else { - sync_file(conn,fsp, True); + NTSTATUS status = sync_file(conn, fsp, True); + if (!NT_STATUS_IS_OK(status)) { + END_PROFILE(SMBflush); + DEBUG(5,("reply_flush: sync_file for %s returned %s\n", + fsp->fsp_name, nt_errstr(status) )); + return ERROR_NT(status); + } } DEBUG(3,("flush\n")); @@ -5886,6 +5920,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int smb_doff; char *data; files_struct *fsp = file_fsp(inbuf,smb_vwv0); + NTSTATUS status; START_PROFILE(SMBwriteBmpx); CHECK_FSP(fsp,conn); @@ -5915,7 +5950,13 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, nwritten = write_file(fsp,data,startpos,numtowrite); - sync_file(conn, fsp, write_through); + status = sync_file(conn, fsp, write_through); + if (!NT_STATUS_IS_OK(status)) { + END_PROFILE(SMBwriteBmpx); + DEBUG(5,("reply_writebmpx: sync_file for %s returned %s\n", + fsp->fsp_name, nt_errstr(status) )); + return ERROR_NT(status); + } if(nwritten < (ssize_t)numtowrite) { END_PROFILE(SMBwriteBmpx); @@ -5991,6 +6032,7 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz write_bmpx_struct *wbms; BOOL send_response = False; files_struct *fsp = file_fsp(inbuf,smb_vwv0); + NTSTATUS status; START_PROFILE(SMBwriteBs); CHECK_FSP(fsp,conn); @@ -6027,9 +6069,9 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz nwritten = write_file(fsp,data,startpos,numtowrite); - sync_file(conn, fsp, write_through); + status = sync_file(conn, fsp, write_through); - if (nwritten < (ssize_t)numtowrite) { + if (nwritten < (ssize_t)numtowrite || !NT_STATUS_IS_OK(status)) { if(write_through) { /* We are returning an error - we can delete the aux struct */ if (wbms) -- cgit