r23508: Fix sync_file() to return NTSTATUS and return this
authorJeremy Allison <jra@samba.org>
Fri, 15 Jun 2007 19:24:04 +0000 (19:24 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:23:23 +0000 (12:23 -0500)
on failure in the write path.
Jeremy.
(This used to be commit cd3f7dbee809fb40194af0e7509142166e02b252)

source3/smbd/aio.c
source3/smbd/fileio.c
source3/smbd/reply.c

index bee6ebc89a9292381a974fee090fe9db4f439411..f747cf5c065c3a586c137e0ebe715ffed2d74705 100644 (file)
@@ -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);
index 65238c0e9ee60bb0e7c47767e2182caaa2363319..1227d12b08e5333314ebc93f20e6d8e82871b12a 100644 (file)
@@ -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;
 }
 
 /************************************************************
index 205374cff74d957d9a00fcbbb3ca309fa1e1c7ee..33ccb7f386548417922bd31be447a7b9de2919c3 100644 (file)
@@ -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)