From 9dc3ec5af335ffea93135129d22461cc66e310c9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 4 Dec 2002 03:12:28 +0000 Subject: Fix for 64 bit issues with oplocks and allocation size. Jeremy. (This used to be commit 4a9c995e50b24e6ee6ec58c46da32100a8197724) --- source3/smbd/fileio.c | 56 ++++++++++++++++++++++++++++++++------------------ source3/smbd/nttrans.c | 18 ++++++++-------- source3/smbd/trans2.c | 20 +++++++++--------- source3/smbd/vfs.c | 21 +++++++++++-------- 4 files changed, 68 insertions(+), 47 deletions(-) (limited to 'source3/smbd') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 6bae1df996..9e37b951e5 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -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) { diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 8aecd63de0..bdefa6c4c1 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -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 */ diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index a2627021d9..33828c32bd 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -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); diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index f6dad7b6e7..7e60d3dacb 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -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; -- cgit