summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/smbd/trans2.c27
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);
}