/* Disk operations */
-static SMB_BIG_UINT vfswrap_disk_free(vfs_handle_struct *handle, const char *path, bool small_query, SMB_BIG_UINT *bsize,
- SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
+static uint64_t vfswrap_disk_free(vfs_handle_struct *handle, const char *path, bool small_query, uint64_t *bsize,
+ uint64_t *dfree, uint64_t *dsize)
{
- SMB_BIG_UINT result;
+ uint64_t result;
result = sys_disk_free(handle->conn, path, small_query, bsize, dfree, dsize);
return result;
return result;
}
-static SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp)
+static SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle,
+ SMB_STRUCT_DIR *dirp,
+ SMB_STRUCT_STAT *sbuf)
{
SMB_STRUCT_DIRENT *result;
START_PROFILE(syscall_readdir);
result = sys_readdir(dirp);
+ /* Default Posix readdir() does not give us stat info.
+ * Set to invalid to indicate we didn't return this info. */
+ if (sbuf)
+ SET_STAT_INVALID(*sbuf);
END_PROFILE(syscall_readdir);
return result;
}
{
int result;
bool has_dacl = False;
+ char *parent = NULL;
START_PROFILE(syscall_mkdir);
- if (lp_inherit_acls(SNUM(handle->conn)) && (has_dacl = directory_has_default_acl(handle->conn, parent_dirname(path))))
+ if (lp_inherit_acls(SNUM(handle->conn))
+ && parent_dirname(talloc_tos(), path, &parent, NULL)
+ && (has_dacl = directory_has_default_acl(handle->conn, parent)))
mode = 0777;
+ TALLOC_FREE(parent);
+
result = mkdir(path, mode);
if (result == 0 && !has_dacl) {
return result;
}
-static int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
+static NTSTATUS vfswrap_create_file(vfs_handle_struct *handle,
+ struct smb_request *req,
+ uint16_t root_dir_fid,
+ const char *fname,
+ uint32_t create_file_flags,
+ uint32_t access_mask,
+ uint32_t share_access,
+ uint32_t create_disposition,
+ uint32_t create_options,
+ uint32_t file_attributes,
+ uint32_t oplock_request,
+ uint64_t allocation_size,
+ struct security_descriptor *sd,
+ struct ea_list *ea_list,
+ files_struct **result,
+ int *pinfo,
+ SMB_STRUCT_STAT *psbuf)
+{
+ return create_file_default(handle->conn, req, root_dir_fid, fname,
+ create_file_flags, access_mask, share_access,
+ create_disposition, create_options,
+ file_attributes, oplock_request,
+ allocation_size, sd, ea_list, result, pinfo,
+ psbuf);
+}
+
+static int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp)
{
int result;
START_PROFILE(syscall_close);
-
- result = close(fd);
+ result = fd_close_posix(fsp);
END_PROFILE(syscall_close);
return result;
}
return result;
}
+/********************************************************************
+ Given a stat buffer return the allocated size on disk, taking into
+ account sparse files.
+********************************************************************/
+static uint64_t vfswrap_get_alloc_size(vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ const SMB_STRUCT_STAT *sbuf)
+{
+ uint64_t result;
+
+ START_PROFILE(syscall_get_alloc_size);
+
+ if(S_ISDIR(sbuf->st_mode)) {
+ result = 0;
+ goto out;
+ }
+
+#if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
+ result = (uint64_t)STAT_ST_BLOCKSIZE * (uint64_t)sbuf->st_blocks;
+#else
+ result = get_file_size_stat(sbuf);
+#endif
+
+ if (fsp && fsp->initial_allocation_size)
+ result = MAX(result,fsp->initial_allocation_size);
+
+ result = smb_roundup(handle->conn, result);
+
+ out:
+ END_PROFILE(syscall_get_alloc_size);
+ return result;
+}
+
static int vfswrap_unlink(vfs_handle_struct *handle, const char *path)
{
int result;
int result;
START_PROFILE(syscall_chown);
- result = sys_chown(path, uid, gid);
+ result = chown(path, uid, gid);
END_PROFILE(syscall_chown);
return result;
}
int result;
START_PROFILE(syscall_lchown);
- result = sys_lchown(path, uid, gid);
+ result = lchown(path, uid, gid);
END_PROFILE(syscall_lchown);
return result;
}
system will support.
**********************************************************************/
-static int vfswrap_ntimes(vfs_handle_struct *handle, const char *path, const struct timespec ts[2])
+static int vfswrap_ntimes(vfs_handle_struct *handle, const char *path,
+ struct smb_file_time *ft)
{
int result;
START_PROFILE(syscall_ntimes);
#if defined(HAVE_UTIMES)
- {
+ if (ft != NULL) {
struct timeval tv[2];
- tv[0] = convert_timespec_to_timeval(ts[0]);
- tv[1] = convert_timespec_to_timeval(ts[1]);
+ tv[0] = convert_timespec_to_timeval(ft->atime);
+ tv[1] = convert_timespec_to_timeval(ft->mtime);
result = utimes(path, tv);
+ } else {
+ result = utimes(path, NULL);
}
#elif defined(HAVE_UTIME)
- {
+ if (ft != NULL) {
struct utimbuf times;
- times.actime = convert_timespec_to_time_t(ts[0]);
- times.modtime = convert_timespec_to_time_t(ts[1]);
- result = utime(path, times);
+ times.actime = convert_timespec_to_time_t(ft->atime);
+ times.modtime = convert_timespec_to_time_t(ft->mtime);
+ result = utime(path, ×);
+ } else {
+ result = utime(path, NULL);
}
#else
errno = ENOSYS;
if (st.st_size > len)
return sys_ftruncate(fsp->fh->fd, len);
+ /* available disk space is enough or not? */
+ if (lp_strict_allocate(SNUM(fsp->conn))){
+ uint64_t space_avail;
+ uint64_t bsize,dfree,dsize;
+
+ space_avail = get_dfree_info(fsp->conn,fsp->fsp_name,false,&bsize,&dfree,&dsize);
+ /* space_avail is 1k blocks */
+ if (space_avail == (uint64_t)-1 ||
+ ((uint64_t)space_to_write/1024 > space_avail) ) {
+ errno = ENOSPC;
+ return -1;
+ }
+ }
+
/* Write out the real space on disk. */
if (SMB_VFS_LSEEK(fsp, st.st_size, SEEK_SET) != st.st_size)
return -1;
int result;
START_PROFILE(syscall_symlink);
- result = sys_symlink(oldpath, newpath);
+ result = symlink(oldpath, newpath);
END_PROFILE(syscall_symlink);
return result;
}
int result;
START_PROFILE(syscall_readlink);
- result = sys_readlink(path, buf, bufsiz);
+ result = readlink(path, buf, bufsiz);
END_PROFILE(syscall_readlink);
return result;
}
int result;
START_PROFILE(syscall_link);
- result = sys_link(oldpath, newpath);
+ result = link(oldpath, newpath);
END_PROFILE(syscall_link);
return result;
}
char *result;
START_PROFILE(syscall_realpath);
- result = sys_realpath(path, resolved_path);
+ result = realpath(path, resolved_path);
END_PROFILE(syscall_realpath);
return result;
}
}
streams->size = sbuf.st_size;
- streams->alloc_size = get_allocation_size(handle->conn, fsp, &sbuf);
+ streams->alloc_size = SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp, &sbuf);
streams->name = talloc_strdup(streams, "::$DATA");
if (streams->name == NULL) {
return NT_STATUS_OK;
}
+static int vfswrap_get_real_filename(struct vfs_handle_struct *handle,
+ const char *path,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name)
+{
+ return get_real_filename(handle->conn, path, name, mem_ctx,
+ found_name);
+}
+
static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle,
files_struct *fsp,
uint32 security_info, SEC_DESC **ppdesc)
return result;
}
-static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
+static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, const SEC_DESC *psd)
{
NTSTATUS result;
return result;
}
-static NTSTATUS vfswrap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd)
-{
- NTSTATUS result;
-
- START_PROFILE(set_nt_acl);
- result = set_nt_acl(fsp, security_info_sent, psd);
- END_PROFILE(set_nt_acl);
- return result;
-}
-
static int vfswrap_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode)
{
#ifdef HAVE_NO_ACL
{SMB_VFS_OP(vfswrap_open), SMB_VFS_OP_OPEN,
SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_create_file), SMB_VFS_OP_CREATE_FILE,
+ SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(vfswrap_close), SMB_VFS_OP_CLOSE,
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(vfswrap_read), SMB_VFS_OP_READ,
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(vfswrap_lstat), SMB_VFS_OP_LSTAT,
SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_get_alloc_size), SMB_VFS_OP_GET_ALLOC_SIZE,
+ SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(vfswrap_unlink), SMB_VFS_OP_UNLINK,
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(vfswrap_chmod), SMB_VFS_OP_CHMOD,
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(vfswrap_streaminfo), SMB_VFS_OP_STREAMINFO,
SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_get_real_filename), SMB_VFS_OP_GET_REAL_FILENAME,
+ SMB_VFS_LAYER_OPAQUE},
/* NT ACL operations. */
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(vfswrap_fset_nt_acl), SMB_VFS_OP_FSET_NT_ACL,
SMB_VFS_LAYER_OPAQUE},
- {SMB_VFS_OP(vfswrap_set_nt_acl), SMB_VFS_OP_SET_NT_ACL,
- SMB_VFS_LAYER_OPAQUE},
/* POSIX ACL operations. */