int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len) { int ret; SMB_STRUCT_STAT st; connection_struct *conn = fsp->conn; SMB_BIG_UINT space_avail; SMB_BIG_UINT bsize,dfree,dsize; release_level_2_oplocks_on_change(fsp); /* * Actually try and commit the space on disk.... */ DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n", fsp->fsp_name, (double)len )); /* Foxconn removed start pling 11/18/2009 */ /* Don't check negative length, to avoid "disk full" error * when copy file from Vista/Win7 to USB. */ #if 0 if (((SMB_OFF_T)len) < 0) { DEBUG(0,("vfs_allocate_file_space: %s negative len requested.\n", fsp->fsp_name )); errno = EINVAL; return -1; } #endif /* Foxconn removed end pling 11/18/2009 */ ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st); if (ret == -1) return ret; if (len == (SMB_BIG_UINT)st.st_size) return 0; 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 = SMB_VFS_FTRUNCATE(fsp, fsp->fh->fd, (SMB_OFF_T)len)) != -1) { set_filelen_write_cache(fsp, len); } return ret; } /* Grow - we need to test if we have enough space. */ if (!lp_strict_allocate(SNUM(fsp->conn))) return 0; len -= st.st_size; len /= 1024; /* Len is now number of 1k blocks needed. */ space_avail = get_dfree_info(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize); if (space_avail == (SMB_BIG_UINT)-1) { return -1; } 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; return -1; } return 0; }
int vfs_allocate_file_space(files_struct *fsp, uint64_t len) { int ret; SMB_STRUCT_STAT st; connection_struct *conn = fsp->conn; uint64_t space_avail; uint64_t bsize,dfree,dsize; /* * Actually try and commit the space on disk.... */ DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n", fsp_str_dbg(fsp), (double)len)); if (((SMB_OFF_T)len) < 0) { DEBUG(0,("vfs_allocate_file_space: %s negative len " "requested.\n", fsp_str_dbg(fsp))); errno = EINVAL; return -1; } ret = SMB_VFS_FSTAT(fsp, &st); if (ret == -1) return ret; if (len == (uint64_t)st.st_ex_size) return 0; if (len < (uint64_t)st.st_ex_size) { /* Shrink - use ftruncate. */ DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current " "size %.0f\n", fsp_str_dbg(fsp), (double)st.st_ex_size)); contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK); flush_write_cache(fsp, SIZECHANGE_FLUSH); if ((ret = SMB_VFS_FTRUNCATE(fsp, (SMB_OFF_T)len)) != -1) { set_filelen_write_cache(fsp, len); } contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK); return ret; } /* Grow - we need to test if we have enough space. */ contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW); contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW); if (!lp_strict_allocate(SNUM(fsp->conn))) return 0; len -= st.st_ex_size; len /= 1024; /* Len is now number of 1k blocks needed. */ space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false, &bsize, &dfree, &dsize); if (space_avail == (uint64_t)-1) { return -1; } DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, " "needed blocks = %.0f, space avail = %.0f\n", fsp_str_dbg(fsp), (double)st.st_ex_size, (double)len, (double)space_avail)); if (len > space_avail) { errno = ENOSPC; return -1; } return 0; }