1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-07 01:58:28 +03:00

Fix for 64 bit issues with oplocks and allocation size.

Jeremy.
This commit is contained in:
Jeremy Allison -
parent 81be3a1429
commit 4a9c995e50
8 changed files with 2562 additions and 2169 deletions

1529
source/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -898,6 +898,7 @@ case "$host_os" in
LDSHFLAGS="-G"
SONAMEFLAG="-Wl,-h,"
PICFLAG="-KPIC" # Is this correct for SunOS
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
*freebsd*) BLDSHARED="true"
LDSHFLAGS="-shared"
@ -955,22 +956,32 @@ case "$host_os" in
DYNEXP="-Wl,-E"
AC_DEFINE(STAT_ST_BLOCKSIZE,8192,[The size of a block])
;;
*qnx*) AC_DEFINE(QNX,1,[Whether the host os is qnx]);;
*qnx*) AC_DEFINE(QNX,1,[Whether the host os is qnx])
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
*osf*) AC_DEFINE(OSF1,1,[Whether the host os is osf1])
BLDSHARED="true"
LDSHFLAGS="-shared"
SONAMEFLAG="-Wl,-soname,"
PICFLAG="-fPIC"
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
*sco*) AC_DEFINE(SCO,1,[Whether the host os is sco unix]);;
*sco*) AC_DEFINE(SCO,1,[Whether the host os is sco unix])
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
*unixware*) AC_DEFINE(UNIXWARE,1,[Whether the host os is unixware])
BLDSHARED="true"
LDSHFLAGS="-shared"
SONAMEFLAG="-Wl,-soname,"
PICFLAG="-KPIC"
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
*next2*) AC_DEFINE(NEXT2,1,[Whether the host os is NeXT v2]);;
*dgux*) AC_CHECK_PROG( ROFF, groff, [groff -etpsR -Tascii -man]);;
*next2*) AC_DEFINE(NEXT2,1,[Whether the host os is NeXT v2])
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
*dgux*) AC_CHECK_PROG( ROFF, groff, [groff -etpsR -Tascii -man])
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
*sysv4*) AC_DEFINE(SYSV,1,[Whether this is a system V system])
case "$host" in
*-univel-*) if [ test "$GCC" != yes ]; then
@ -981,6 +992,7 @@ case "$host_os" in
;;
*mips-sni-sysv4*) AC_DEFINE(RELIANTUNIX,1,[Whether the host os is reliantunix]);;
esac
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
*sysv5*) AC_DEFINE(SYSV,1,[Whether this is a system V system])
@ -988,6 +1000,7 @@ case "$host_os" in
AC_DEFINE(HAVE_MEMSET,1,[Whether memset() is available])
fi
LDSHFLAGS="-G"
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
esac
AC_SUBST(DYNEXP)

File diff suppressed because it is too large Load Diff

View File

@ -365,8 +365,8 @@ typedef struct files_struct
SMB_INO_T inode;
BOOL delete_on_close;
SMB_OFF_T pos;
SMB_OFF_T size;
SMB_OFF_T initial_allocation_size; /* Faked up initial allocation on disk. */
SMB_BIG_UINT size;
SMB_BIG_UINT initial_allocation_size; /* Faked up initial allocation on disk. */
mode_t mode;
uint16 vuid;
write_bmpx_struct *wbmpx_ptr;

View File

@ -172,7 +172,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
if (fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&st) == 0) {
int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st);
fsp->size = st.st_size;
fsp->size = (SMB_BIG_UINT)st.st_size;
if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode))
file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st);
@ -233,8 +233,8 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
if(!wcp) {
DO_PROFILE_INC(writecache_direct_writes);
total_written = real_write_file(fsp, data, pos, n);
if ((total_written != -1) && (pos + total_written > fsp->size))
fsp->size = pos + total_written;
if ((total_written != -1) && (pos + total_written > (SMB_OFF_T)fsp->size))
fsp->size = (SMB_BIG_UINT)(pos + total_written);
return total_written;
}
@ -283,8 +283,10 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
* Update the file size if changed.
*/
if (wcp->offset + wcp->data_size > wcp->file_size)
fsp->size = wcp->file_size = wcp->offset + wcp->data_size;
if (wcp->offset + wcp->data_size > wcp->file_size) {
wcp->file_size = wcp->offset + wcp->data_size;
fsp->size = (SMB_BIG_UINT)wcp->file_size;
}
/*
* If we used all the data then
@ -344,8 +346,10 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
* Update the file size if changed.
*/
if (wcp->offset + wcp->data_size > wcp->file_size)
fsp->size = wcp->file_size = wcp->offset + wcp->data_size;
if (wcp->offset + wcp->data_size > wcp->file_size) {
wcp->file_size = wcp->offset + wcp->data_size;
fsp->size = (SMB_BIG_UINT)wcp->file_size;
}
/*
* We don't need to move the start of data, but we
@ -418,8 +422,10 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
* Update the file size if changed.
*/
if (wcp->offset + wcp->data_size > wcp->file_size)
fsp->size = wcp->file_size = wcp->offset + wcp->data_size;
if (wcp->offset + wcp->data_size > wcp->file_size) {
wcp->file_size = wcp->offset + wcp->data_size;
fsp->size = (SMB_BIG_UINT)wcp->file_size;
}
/*
* If we used all the data then
@ -493,8 +499,10 @@ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigne
* Update the file size if needed.
*/
if(pos + n > wcp->file_size)
fsp->size = wcp->file_size = pos + n;
if(pos + n > wcp->file_size) {
wcp->file_size = pos + n;
fsp->size = (SMB_BIG_UINT)wcp->file_size;
}
/*
* If write would fit in the cache, and is larger than
@ -525,8 +533,10 @@ cache: fd = %d, off=%.0f, size=%u\n", fsp->fd, (double)wcp->offset, (unsigned in
if (ret == -1)
return ret;
if (pos + ret > wcp->file_size)
fsp->size = wcp->file_size = pos + ret;
if (pos + ret > wcp->file_size) {
wcp->file_size = pos + ret;
fsp->size = (SMB_BIG_UINT)wcp->file_size;
}
return ret;
}
@ -535,8 +545,10 @@ cache: fd = %d, off=%.0f, size=%u\n", fsp->fd, (double)wcp->offset, (unsigned in
}
if(wcp->data_size > wcp->file_size)
fsp->size = wcp->file_size = wcp->data_size;
if(wcp->data_size > wcp->file_size) {
wcp->file_size = wcp->data_size;
fsp->size = (SMB_BIG_UINT)wcp->file_size;
}
if (cache_flush_needed) {
DEBUG(3,("WRITE_FLUSH:%d: due to noncontinuous write: fd = %d, size = %.0f, pos = %.0f, \
@ -558,8 +570,10 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n",
if (ret == -1)
return -1;
if (pos + ret > wcp->file_size)
fsp->size = wcp->file_size = pos + n;
if (pos + ret > wcp->file_size) {
wcp->file_size = pos + n;
fsp->size = (SMB_BIG_UINT)wcp->file_size;
}
DO_PROFILE_INC(writecache_direct_writes);
return total_written + n;
@ -588,8 +602,10 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n",
* Update the file size if changed.
*/
if (wcp->offset + wcp->data_size > wcp->file_size)
fsp->size = wcp->file_size = wcp->offset + wcp->data_size;
if (wcp->offset + wcp->data_size > wcp->file_size) {
wcp->file_size = wcp->offset + wcp->data_size;
fsp->size = (SMB_BIG_UINT)wcp->file_size;
}
DEBUG(9,("wcp->offset = %.0f wcp->data_size = %u cache return %u\n",
(double)wcp->offset, (unsigned int)wcp->data_size, (unsigned int)n));
@ -674,7 +690,7 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size)
void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size)
{
fsp->size = file_size;
fsp->size = (SMB_BIG_UINT)file_size;
if(fsp->wcp) {
/* The cache *must* have been flushed before we do this. */
if (fsp->wcp->data_size != 0) {

View File

@ -548,7 +548,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition);
uint32 create_options = IVAL(inbuf,smb_ntcreate_CreateOptions);
uint16 root_dir_fid = (uint16)IVAL(inbuf,smb_ntcreate_RootDirectoryFid);
SMB_OFF_T allocation_size = 0;
SMB_BIG_UINT allocation_size = 0;
int smb_ofun;
int smb_open_mode;
int smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
@ -807,11 +807,11 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
}
/* Save the requested allocation size. */
allocation_size = IVAL(inbuf,smb_ntcreate_AllocationSize);
allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize);
#ifdef LARGE_SMB_OFF_T
allocation_size |= (((SMB_OFF_T)IVAL(inbuf,smb_ntcreate_AllocationSize + 4)) << 32);
allocation_size |= (((SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize + 4)) << 32);
#endif
if (allocation_size && (allocation_size > file_len)) {
if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) {
fsp->initial_allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE);
if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
close_file(fsp,False);
@ -819,7 +819,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_ROUNDUP(file_len,SMB_ROUNDUP_ALLOCATION_SIZE);
fsp->initial_allocation_size = SMB_ROUNDUP(((SMB_BIG_UINT)file_len),SMB_ROUNDUP_ALLOCATION_SIZE);
}
/*
@ -1065,7 +1065,7 @@ static int call_nt_transact_create(connection_struct *conn,
uint32 create_options;
uint32 sd_len;
uint16 root_dir_fid;
SMB_OFF_T allocation_size = 0;
SMB_BIG_UINT allocation_size = 0;
int smb_ofun;
int smb_open_mode;
int smb_attr;
@ -1304,9 +1304,9 @@ static int call_nt_transact_create(connection_struct *conn,
restore_case_semantics(file_attributes);
/* Save the requested allocation size. */
allocation_size = IVAL_TO_SMB_OFF_T(params,12);
allocation_size = (SMB_BIG_UINT)IVAL(params,12);
#ifdef LARGE_SMB_OFF_T
allocation_size |= ((IVAL_TO_SMB_OFF_T(params,16)) << 32);
allocation_size |= (((SMB_BIG_UINT)IVAL(params,16)) << 32);
#endif
if (allocation_size && (allocation_size > file_len)) {
fsp->initial_allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE);
@ -1316,7 +1316,7 @@ static int call_nt_transact_create(connection_struct *conn,
return ERROR_NT(NT_STATUS_DISK_FULL);
}
} else {
fsp->initial_allocation_size = SMB_ROUNDUP(file_len,SMB_ROUNDUP_ALLOCATION_SIZE);
fsp->initial_allocation_size = SMB_ROUNDUP(((SMB_BIG_UINT)file_len),SMB_ROUNDUP_ALLOCATION_SIZE);
}
/* Realloc the size of parameters and data we will return */

View File

@ -33,15 +33,15 @@ extern uint32 global_client_caps;
/* given a stat buffer return the allocated size on disk, taking into
account sparse files */
SMB_OFF_T get_allocation_size(files_struct *fsp, SMB_STRUCT_STAT *sbuf)
SMB_BIG_UINT get_allocation_size(files_struct *fsp, SMB_STRUCT_STAT *sbuf)
{
SMB_OFF_T ret;
SMB_BIG_UINT ret;
#if defined(HAVE_STAT_ST_BLKSIZE) && defined(HAVE_STAT_ST_BLOCKS)
ret = sbuf->st_blksize * (SMB_OFF_T)sbuf->st_blocks;
ret = (SMB_BIG_UINT)sbuf->st_blksize * (SMB_BIG_UINT)sbuf->st_blocks;
#elif defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
ret = (SMB_OFF_T)STAT_ST_BLOCKSIZE * (SMB_OFF_T)sbuf->st_blocks;
ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks;
#else
ret = get_file_size(*sbuf);
ret = (SMB_BIG_UINT)get_file_size(*sbuf);
#endif
if (!ret && fsp && fsp->initial_allocation_size)
ret = fsp->initial_allocation_size;
@ -473,7 +473,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
int prev_dirpos=0;
int mode=0;
SMB_OFF_T file_size = 0;
SMB_OFF_T allocation_size = 0;
SMB_BIG_UINT allocation_size = 0;
uint32 len;
time_t mdate=0, adate=0, cdate=0;
char *nameptr;
@ -1552,7 +1552,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
uint16 info_level;
int mode=0;
SMB_OFF_T file_size=0;
SMB_OFF_T allocation_size=0;
SMB_BIG_UINT allocation_size=0;
unsigned int data_size;
SMB_STRUCT_STAT sbuf;
pstring fname, dos_fname;
@ -2428,14 +2428,14 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
case SMB_SET_FILE_ALLOCATION_INFO:
{
int ret = -1;
SMB_OFF_T allocation_size;
SMB_BIG_UINT allocation_size;
if (total_data < 8)
return(ERROR_DOS(ERRDOS,ERRinvalidparam));
allocation_size = IVAL(pdata,0);
allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
#ifdef LARGE_SMB_OFF_T
allocation_size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
#else /* LARGE_SMB_OFF_T */
if (IVAL(pdata,4) != 0) /* more than 32 bits? */
return ERROR_DOS(ERRDOS,ERRunknownlevel);

View File

@ -423,13 +423,13 @@ ssize_t vfs_write_data(files_struct *fsp,const char *buffer,size_t N)
Returns 0 on success, -1 on failure.
****************************************************************************/
int vfs_allocate_file_space(files_struct *fsp, SMB_OFF_T len)
int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len)
{
int ret;
SMB_STRUCT_STAT st;
connection_struct *conn = fsp->conn;
struct vfs_ops *vfs_ops = &conn->vfs_ops;
SMB_OFF_T space_avail;
SMB_BIG_UINT space_avail;
SMB_BIG_UINT bsize,dfree,dsize;
release_level_2_oplocks_on_change(fsp);
@ -440,21 +440,26 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_OFF_T len)
DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n", fsp->fsp_name, (double)len ));
if (((SMB_OFF_T)len) < 0) {
DEBUG(0,("vfs_allocate_file_space: %s negative len requested.\n", fsp->fsp_name ));
return -1;
}
ret = vfs_fstat(fsp,fsp->fd,&st);
if (ret == -1)
return ret;
if (len == st.st_size)
if (len == (SMB_BIG_UINT)st.st_size)
return 0;
if (len < st.st_size) {
if (len < (SMB_BIG_UINT)st.st_size) {
/* Shrink - use ftruncate. */
DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current size %.0f\n",
fsp->fsp_name, (double)st.st_size ));
flush_write_cache(fsp, SIZECHANGE_FLUSH);
if ((ret = vfs_ops->ftruncate(fsp, fsp->fd, len)) != -1) {
if ((ret = vfs_ops->ftruncate(fsp, fsp->fd, (SMB_OFF_T)len)) != -1) {
set_filelen_write_cache(fsp, len);
}
return ret;
@ -467,10 +472,10 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_OFF_T len)
len -= st.st_size;
len /= 1024; /* Len is now number of 1k blocks needed. */
space_avail = (SMB_OFF_T)conn->vfs_ops.disk_free(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize);
space_avail = conn->vfs_ops.disk_free(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize);
DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, needed blocks = %lu, space avail = %lu\n",
fsp->fsp_name, (double)st.st_size, (unsigned long)len, (unsigned long)space_avail ));
DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, needed blocks = %.0f, space avail = %.0f\n",
fsp->fsp_name, (double)st.st_size, (double)len, (double)space_avail ));
if (len > space_avail) {
errno = ENOSPC;