static NTSTATUS cmd_ftruncate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { int fd; SMB_OFF_T off; if (argc != 3) { printf("Usage: ftruncate <fd> <length>\n"); return NT_STATUS_OK; } fd = atoi(argv[1]); off = atoi(argv[2]); if (fd < 0 || fd > 1024) { printf("ftruncate: error=%d (file descriptor out of range)\n", EBADF); return NT_STATUS_OK; } if (vfs->files[fd] == NULL) { printf("ftruncate: error=%d (invalid file descriptor)\n", EBADF); return NT_STATUS_OK; } if (SMB_VFS_FTRUNCATE(vfs->files[fd], fd, off) == -1) { printf("ftruncate: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } printf("ftruncate: ok\n"); return NT_STATUS_OK; }
static int wcp_file_size_change(files_struct *fsp) { int ret; write_cache *wcp = fsp->wcp; wcp->file_size = wcp->offset + wcp->data_size; ret = SMB_VFS_FTRUNCATE(fsp, wcp->file_size); if (ret == -1) { DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f " "error %s\n", fsp_str_dbg(fsp), (double)wcp->file_size, strerror(errno))); } return ret; }
static int truncate_unless_locked(struct connection_struct *conn, files_struct *fsp) { SMB_BIG_UINT mask = (SMB_BIG_UINT)-1; if (is_locked(fsp,fsp->conn,mask,0,WRITE_LOCK,True)){ errno = EACCES; unix_ERR_class = ERRDOS; unix_ERR_code = ERRlock; unix_ERR_ntstatus = dos_to_ntstatus(ERRDOS, ERRlock); return -1; } else { return SMB_VFS_FTRUNCATE(fsp,fsp->fd,0); } }
static int wcp_file_size_change(files_struct *fsp) { /* AVM: Fuer Pruefung des freien Speichers auf dem Datentraeger wird SMB_VFS_FTRUNCATE aufgerufen, auch falls es langsam sein sollte */ int ret; write_cache *wcp = fsp->wcp; wcp->file_size = wcp->offset + wcp->data_size; ret = SMB_VFS_FTRUNCATE(fsp, fsp->fh->fd, wcp->file_size); if (ret == -1) { DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f error %s\n", fsp->fsp_name, (double)wcp->file_size, strerror(errno) )); } return ret; }
int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len) { int ret; release_level_2_oplocks_on_change(fsp); DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", fsp->fsp_name, (double)len)); flush_write_cache(fsp, SIZECHANGE_FLUSH); if (len > 0 && len < 0x1000000) { if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fh->fd, len)) != -1) { set_filelen_write_cache(fsp, len); notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_ATTRIBUTES, fsp->fsp_name); } }else ret=0; return ret; }
int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len) { int ret; contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN); DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", fsp_str_dbg(fsp), (double)len)); flush_write_cache(fsp, SIZECHANGE_FLUSH); if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) { set_filelen_write_cache(fsp, len); notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_ATTRIBUTES, fsp->fsp_name->base_name); } contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN); return ret; }
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; }