From 833ca101772bfab65dbd79eb64f63464177f144e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Mar 2005 03:43:57 +0000 Subject: [PATCH] r5636: Re-add the allocation size - parameterized by share as "allocation roundup size", by default set as 1Mb. From advice by BlueArc about Windows client behaviour. VC++ people can set this to zero to turn it off. Jeremy. --- source/configure.in | 2 +- source/include/local.h | 3 +++ source/include/smb_macros.h | 2 ++ source/param/loadparm.c | 4 ++++ source/smbd/nttrans.c | 8 ++++---- source/smbd/trans2.c | 23 ++++++++++++++++++++++- 6 files changed, 36 insertions(+), 6 deletions(-) diff --git a/source/configure.in b/source/configure.in index 54499292c55..40aa263c7a1 100644 --- a/source/configure.in +++ b/source/configure.in @@ -238,7 +238,7 @@ AC_ARG_ENABLE(debug, AC_ARG_ENABLE(developer, [ --enable-developer Turn on developer warnings and debugging (default=no)], [if eval "test x$enable_developer = xyes"; then developer=yes - CFLAGS="${CFLAGS} -gstabs -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wdeclaration-after-statement -DDEBUG_PASSWORD -DDEVELOPER" + CFLAGS="${CFLAGS} -gstabs -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER" fi]) AC_ARG_ENABLE(krb5developer, [ --enable-krb5developer Turn on developer warnings and debugging, except -Wstrict-prototypes (default=no)], diff --git a/source/include/local.h b/source/include/local.h index 7d5baa21fa8..8960a4af553 100644 --- a/source/include/local.h +++ b/source/include/local.h @@ -198,6 +198,9 @@ /* the maximum age in seconds of a password. Should be a lp_ parameter */ #define MAX_PASSWORD_AGE (21*24*60*60) +/* Default allocation roundup. */ +#define SMB_ROUNDUP_ALLOCATION_SIZE 0x100000 + /* shall we deny oplocks to clients that get timeouts? */ #define FASCIST_OPLOCK_BACKOFF 1 diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h index b1ac617f5cf..4fa9ffa5ace 100644 --- a/source/include/smb_macros.h +++ b/source/include/smb_macros.h @@ -178,6 +178,8 @@ /* this is how errors are generated */ #define UNIXERROR(defclass,deferror) unix_error_packet(outbuf,defclass,deferror,__LINE__,__FILE__) +#define SMB_ROUNDUP(x,r) ( ((x)%(r)) ? ( (((x)+(r))/(r))*(r) ) : (x)) + /* Extra macros added by Ying Chen at IBM - speed increase by inlining. */ #define smb_buf(buf) (((char *)(buf)) + smb_size + CVAL(buf,smb_wct)*2) #define smb_buflen(buf) (SVAL(buf,smb_vwv0 + (int)CVAL(buf, smb_wct)*2)) diff --git a/source/param/loadparm.c b/source/param/loadparm.c index ac979566454..21abafb5783 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -424,6 +424,7 @@ typedef struct BOOL bMap_acl_inherit; BOOL bAfs_Share; BOOL bEASupport; + int iallocation_roundup_size; param_opt_struct *param_opt; char dummy[3]; /* for alignment */ @@ -549,6 +550,7 @@ static service sDefault = { False, /* bMap_acl_inherit */ False, /* bAfs_Share */ False, /* bEASupport */ + SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */ NULL, /* Parametric options */ @@ -893,6 +895,7 @@ static struct parm_struct parm_table[] = { {N_("Protocol Options"), P_SEP, P_SEPARATOR}, + {"allocation roundup size", P_INTEGER, P_LOCAL, &sDefault.iallocation_roundup_size, NULL, NULL, FLAG_ADVANCED}, {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED}, {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED}, {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED}, @@ -1931,6 +1934,7 @@ FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit) FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy) FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize) FN_LOCAL_INTEGER(lp_block_size, iBlock_size) +FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size); FN_LOCAL_CHAR(lp_magicchar, magic_char) FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time) FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase) diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c index 675da4c7478..aaf1d1679b3 100644 --- a/source/smbd/nttrans.c +++ b/source/smbd/nttrans.c @@ -929,7 +929,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib allocation_size |= (((SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize + 4)) << 32); #endif if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) { - fsp->initial_allocation_size = allocation_size; + fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size); if (fsp->is_directory) { close_file(fsp,False); END_PROFILE(SMBntcreateX); @@ -942,7 +942,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib return ERROR_NT(NT_STATUS_DISK_FULL); } } else { - fsp->initial_allocation_size = (SMB_BIG_UINT)file_len; + fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)file_len); } /* @@ -1472,7 +1472,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o allocation_size |= (((SMB_BIG_UINT)IVAL(params,16)) << 32); #endif if (allocation_size && (allocation_size > file_len)) { - fsp->initial_allocation_size = allocation_size; + fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size); if (fsp->is_directory) { close_file(fsp,False); END_PROFILE(SMBntcreateX); @@ -1484,7 +1484,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o return ERROR_NT(NT_STATUS_DISK_FULL); } } else { - fsp->initial_allocation_size = (SMB_BIG_UINT)file_len; + fsp->initial_allocation_size = smb_roundup(fsp->conn, (SMB_BIG_UINT)file_len); } /* Realloc the size of parameters and data we will return */ diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c index d22705214e4..16cea326f92 100644 --- a/source/smbd/trans2.c +++ b/source/smbd/trans2.c @@ -32,6 +32,23 @@ extern struct current_user current_user; #define get_file_size(sbuf) ((sbuf).st_size) #define DIR_ENTRY_SAFETY_MARGIN 4096 +/******************************************************************** + Roundup a value to the nearest allocation roundup size boundary. + Only do this for Windows clients. +********************************************************************/ + +SMB_BIG_UINT smb_roundup(connection_struct *conn, SMB_BIG_UINT val) +{ + SMB_BIG_UINT rval = lp_allocation_roundup_size(SNUM(conn)); + + /* Only roundup for Windows clients. */ + enum remote_arch_types ra_type = get_remote_arch(); + if (rval && (ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) { + val = SMB_ROUNDUP(val,rval); + } + return val; +} + /******************************************************************** Given a stat buffer return the allocated size on disk, taking into account sparse files. @@ -50,7 +67,7 @@ SMB_BIG_UINT get_allocation_size(files_struct *fsp, SMB_STRUCT_STAT *sbuf) if (!ret && fsp && fsp->initial_allocation_size) ret = fsp->initial_allocation_size; - return ret; + return smb_roundup(fsp->conn, ret); } /**************************************************************************** @@ -3333,6 +3350,10 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", fname, (double)allocation_size )); + if (allocation_size) { + allocation_size = smb_roundup(conn, allocation_size); + } + if(allocation_size != get_file_size(sbuf)) { SMB_STRUCT_STAT new_sbuf;