diff options
Diffstat (limited to 'source3/modules')
-rw-r--r-- | source3/modules/onefs_streams.c | 8 | ||||
-rw-r--r-- | source3/modules/vfs_default.c | 37 | ||||
-rw-r--r-- | source3/modules/vfs_full_audit.c | 17 | ||||
-rw-r--r-- | source3/modules/vfs_onefs.c | 27 | ||||
-rw-r--r-- | source3/modules/vfs_streams_depot.c | 8 | ||||
-rw-r--r-- | source3/modules/vfs_streams_xattr.c | 4 |
6 files changed, 90 insertions, 11 deletions
diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c index e9543e237f..78b0fd61bf 100644 --- a/source3/modules/onefs_streams.c +++ b/source3/modules/onefs_streams.c @@ -533,8 +533,8 @@ static NTSTATUS walk_onefs_streams(connection_struct *conn, files_struct *fsp, if (!add_one_stream(state->mem_ctx, &state->num_streams, &state->streams, dp->d_name, stream_sbuf.st_size, - get_allocation_size(conn, NULL, - &stream_sbuf))) { + SMB_VFS_GET_ALLOC_SIZE(conn, NULL, + &stream_sbuf))) { state->status = NT_STATUS_NO_MEMORY; break; } @@ -594,8 +594,8 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle, if (!add_one_stream(mem_ctx, &state.num_streams, &state.streams, "", sbuf.st_size, - get_allocation_size(handle->conn, fsp, - &sbuf))) { + SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp, + &sbuf))) { return NT_STATUS_NO_MEMORY; } } diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index a9aabab768..f8ac3e85d3 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -551,6 +551,39 @@ int vfswrap_lstat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT 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; @@ -1043,7 +1076,7 @@ static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle, } 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) { @@ -1443,6 +1476,8 @@ static vfs_op_tuple vfs_default_ops[] = { 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, diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index 73758a2d9d..c6d62fdd87 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -155,6 +155,8 @@ static int smb_full_audit_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf); static int smb_full_audit_lstat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf); +static int smb_full_audit_get_alloc_size(vfs_handle_struct *handle, + files_struct *fsp, const SMB_STRUCT_STAT *sbuf); static int smb_full_audit_unlink(vfs_handle_struct *handle, const char *path); static int smb_full_audit_chmod(vfs_handle_struct *handle, @@ -403,6 +405,8 @@ static vfs_op_tuple audit_op_tuples[] = { SMB_VFS_LAYER_LOGGER}, {SMB_VFS_OP(smb_full_audit_lstat), SMB_VFS_OP_LSTAT, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(smb_full_audit_get_alloc_size), SMB_VFS_OP_GET_ALLOC_SIZE, + SMB_VFS_LAYER_LOGGER}, {SMB_VFS_OP(smb_full_audit_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_LOGGER}, {SMB_VFS_OP(smb_full_audit_chmod), SMB_VFS_OP_CHMOD, @@ -597,6 +601,7 @@ static struct { { SMB_VFS_OP_STAT, "stat" }, { SMB_VFS_OP_FSTAT, "fstat" }, { SMB_VFS_OP_LSTAT, "lstat" }, + { SMB_VFS_OP_GET_ALLOC_SIZE, "get_alloc_size" }, { SMB_VFS_OP_UNLINK, "unlink" }, { SMB_VFS_OP_CHMOD, "chmod" }, { SMB_VFS_OP_FCHMOD, "fchmod" }, @@ -1325,6 +1330,18 @@ static int smb_full_audit_lstat(vfs_handle_struct *handle, return result; } +static int smb_full_audit_get_alloc_size(vfs_handle_struct *handle, + files_struct *fsp, const SMB_STRUCT_STAT *sbuf) +{ + int result; + + result = SMB_VFS_NEXT_GET_ALLOC_SIZE(handle, fsp, sbuf); + + do_log(SMB_VFS_OP_GET_ALLOC_SIZE, (result >= 0), handle, "%d", result); + + return result; +} + static int smb_full_audit_unlink(vfs_handle_struct *handle, const char *path) { diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c index e048e89589..e2f272aa11 100644 --- a/source3/modules/vfs_onefs.c +++ b/source3/modules/vfs_onefs.c @@ -40,6 +40,31 @@ static int onefs_open(vfs_handle_struct *handle, const char *fname, return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); } +static uint64_t onefs_get_alloc_size(struct vfs_handle_struct *handle, 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; + } + + /* Just use the file size since st_blocks is unreliable on OneFS. */ + result = get_file_size_stat(sbuf); + + 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 onefs_statvfs(vfs_handle_struct *handle, const char *path, vfs_statvfs_struct *statbuf) { @@ -123,6 +148,8 @@ static vfs_op_tuple onefs_ops[] = { SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(onefs_lstat), SMB_VFS_OP_LSTAT, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_get_alloc_size), SMB_VFS_OP_GET_ALLOC_SIZE, + SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(onefs_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(onefs_ntimes), SMB_VFS_OP_NTIMES, diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c index 54c17db1ce..77efb277de 100644 --- a/source3/modules/vfs_streams_depot.c +++ b/source3/modules/vfs_streams_depot.c @@ -648,8 +648,8 @@ static bool collect_one_stream(const char *dirname, if (!add_one_stream(state->mem_ctx, &state->num_streams, &state->streams, dirent, sbuf.st_size, - get_allocation_size( - state->handle->conn, NULL, &sbuf))) { + SMB_VFS_GET_ALLOC_SIZE(state->handle->conn, NULL, + &sbuf))) { state->status = NT_STATUS_NO_MEMORY; return false; } @@ -693,8 +693,8 @@ static NTSTATUS streams_depot_streaminfo(vfs_handle_struct *handle, if (!add_one_stream(mem_ctx, &state.num_streams, &state.streams, "::$DATA", sbuf.st_size, - get_allocation_size(handle->conn, fsp, - &sbuf))) { + SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp, + &sbuf))) { return NT_STATUS_NO_MEMORY; } } diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index 1df4932167..37473439dd 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -732,8 +732,8 @@ static NTSTATUS streams_xattr_streaminfo(vfs_handle_struct *handle, if (!add_one_stream(mem_ctx, &state.num_streams, &state.streams, "::$DATA", sbuf.st_size, - get_allocation_size(handle->conn, fsp, - &sbuf))) { + SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp, + &sbuf))) { return NT_STATUS_NO_MEMORY; } } |