diff options
Diffstat (limited to 'source3/smbd/trans2.c')
-rw-r--r-- | source3/smbd/trans2.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index fc14772c57..ad78c51fdf 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -727,7 +727,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i time_t open_time; #endif int open_ofun; - int32 open_size; + uint32 open_size; char *pname; pstring fname; SMB_OFF_T size=0; @@ -860,6 +860,30 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i return(ERROR_DOS(ERRDOS,ERRnoaccess)); } + /* Save the requested allocation size. */ + /* Allocate space for the file if a size hint is supplied */ + if ((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) { + SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)open_size; + if (allocation_size && (allocation_size > (SMB_BIG_UINT)size)) { + fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size); + if (fsp->is_directory) { + close_file(fsp,ERROR_CLOSE); + /* Can't set allocation size on a directory. */ + return ERROR_NT(NT_STATUS_ACCESS_DENIED); + } + if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) { + close_file(fsp,ERROR_CLOSE); + return ERROR_NT(NT_STATUS_DISK_FULL); + } + + /* Adjust size here to return the right size in the reply. + Windows does it this way. */ + size = fsp->initial_allocation_size; + } else { + fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)size); + } + } + if (total_data && smb_action == FILE_WAS_CREATED) { status = set_ea(conn, fsp, fname, ea_list); talloc_destroy(ctx); @@ -5238,6 +5262,7 @@ int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf, } else { DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count)); DEBUG(2,("Transaction is %d\n",tran_call)); + TALLOC_FREE(state); END_PROFILE(SMBtrans2); return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } |