From d8d5d4c7428683da04fa4c8b344504e7044f9b1c Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Mon, 18 Nov 2013 14:54:30 +0100 Subject: vfs: add [GET/SET]_COMPRESSION hooks The VFS interfaces are sychronous, as the operations only modify meta-data. These hooks are dependent on support for transparent compression by the underlying filesystem - vfs_default returns INVALID_DEVICE_REQUEST. Support for other filesystems providing transparent comression, such as Btrfs and ZFS, can be added in future. The get_compression function takes fsp and smb_fname arguments. The smb_fname argument is needed due to the current dosmode() code-path. Signed-off-by: David Disseldorp Reviewed-by: Jeremy Allison --- docs-xml/manpages/vfs_full_audit.8.xml | 2 ++ examples/VFS/skel_opaque.c | 19 ++++++++++++ examples/VFS/skel_transparent.c | 21 ++++++++++++++ source3/include/vfs.h | 19 ++++++++++++ source3/include/vfs_macros.h | 12 +++++++- source3/modules/vfs_default.c | 19 ++++++++++++ source3/modules/vfs_full_audit.c | 40 +++++++++++++++++++++++++ source3/modules/vfs_time_audit.c | 53 ++++++++++++++++++++++++++++++++++ source3/smbd/vfs.c | 21 ++++++++++++++ 9 files changed, 205 insertions(+), 1 deletion(-) diff --git a/docs-xml/manpages/vfs_full_audit.8.xml b/docs-xml/manpages/vfs_full_audit.8.xml index 1266b1fbb6c..2be26b03c47 100644 --- a/docs-xml/manpages/vfs_full_audit.8.xml +++ b/docs-xml/manpages/vfs_full_audit.8.xml @@ -62,6 +62,7 @@ fstat fsync ftruncate + get_compression get_nt_acl get_quota get_shadow_copy_data @@ -91,6 +92,7 @@ rmdir seekdir sendfile + set_compression set_nt_acl set_quota setxattr diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index 53c64cafb88..5abea20dd06 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -528,6 +528,23 @@ static NTSTATUS skel_copy_chunk_recv(struct vfs_handle_struct *handle, return NT_STATUS_OK; } +static NTSTATUS skel_get_compression(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct files_struct *fsp, + struct smb_filename *smb_fname, + uint16_t *_compression_fmt) +{ + return NT_STATUS_INVALID_DEVICE_REQUEST; +} + +static NTSTATUS skel_set_compression(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct files_struct *fsp, + uint16_t compression_fmt) +{ + return NT_STATUS_INVALID_DEVICE_REQUEST; +} + static NTSTATUS skel_streaminfo(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *fname, @@ -867,6 +884,8 @@ struct vfs_fn_pointers skel_opaque_fns = { .file_id_create_fn = skel_file_id_create, .copy_chunk_send_fn = skel_copy_chunk_send, .copy_chunk_recv_fn = skel_copy_chunk_recv, + .get_compression_fn = skel_get_compression, + .set_compression_fn = skel_set_compression, .streaminfo_fn = skel_streaminfo, .get_real_filename_fn = skel_get_real_filename, diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index 99feadec600..f042b2aead4 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -645,6 +645,25 @@ static NTSTATUS skel_copy_chunk_recv(struct vfs_handle_struct *handle, return NT_STATUS_OK; } +static NTSTATUS skel_get_compression(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct files_struct *fsp, + struct smb_filename *smb_fname, + uint16_t *_compression_fmt) +{ + return SMB_VFS_NEXT_GET_COMPRESSION(handle, mem_ctx, fsp, smb_fname, + _compression_fmt); +} + +static NTSTATUS skel_set_compression(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct files_struct *fsp, + uint16_t compression_fmt) +{ + return SMB_VFS_NEXT_SET_COMPRESSION(handle, mem_ctx, fsp, + compression_fmt); +} + static NTSTATUS skel_streaminfo(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *fname, @@ -973,6 +992,8 @@ struct vfs_fn_pointers skel_transparent_fns = { .file_id_create_fn = skel_file_id_create, .copy_chunk_send_fn = skel_copy_chunk_send, .copy_chunk_recv_fn = skel_copy_chunk_recv, + .get_compression_fn = skel_get_compression, + .set_compression_fn = skel_set_compression, .streaminfo_fn = skel_streaminfo, .get_real_filename_fn = skel_get_real_filename, diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 0e5b0748678..1bea0b8df01 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -154,6 +154,7 @@ /* Leave at 31 - not yet released. add SMB_VFS_COPY_CHUNK() */ /* Leave at 31 - not yet released. Remove the unused fsp->pending_break_messages array */ +/* Leave at 31 - not yet released. add SMB_VFS_[GET/SET]_COMPRESSION() */ #define SMB_VFS_INTERFACE_VERSION 31 @@ -626,6 +627,15 @@ struct vfs_fn_pointers { NTSTATUS (*copy_chunk_recv_fn)(struct vfs_handle_struct *handle, struct tevent_req *req, off_t *copied); + NTSTATUS (*get_compression_fn)(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct files_struct *fsp, + struct smb_filename *smb_fname, + uint16_t *_compression_fmt); + NTSTATUS (*set_compression_fn)(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct files_struct *fsp, + uint16_t compression_fmt); NTSTATUS (*streaminfo_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, @@ -1109,6 +1119,15 @@ struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle, struct tevent_req *req, off_t *copied); +NTSTATUS smb_vfs_call_get_compression(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct files_struct *fsp, + struct smb_filename *smb_fname, + uint16_t *_compression_fmt); +NTSTATUS smb_vfs_call_set_compression(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct files_struct *fsp, + uint16_t compression_fmt); NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32 security_info, diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index 15e8492747f..704054d3f9a 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -409,8 +409,18 @@ #define SMB_VFS_NEXT_COPY_CHUNK_RECV(handle, req, copied) \ smb_vfs_call_copy_chunk_recv((handle)->next, (req), (copied)) +#define SMB_VFS_GET_COMPRESSION(conn, mem_ctx, fsp, smb_fname, _compression_fmt) \ + smb_vfs_call_get_compression((conn)->vfs_handles, (mem_ctx), (fsp), (smb_fname), (_compression_fmt)) +#define SMB_VFS_NEXT_GET_COMPRESSION(handle, mem_ctx, fsp, smb_fname, _compression_fmt) \ + smb_vfs_call_get_compression((handle)->next, (mem_ctx), (fsp), (smb_fname), (_compression_fmt)) + +#define SMB_VFS_SET_COMPRESSION(conn, mem_ctx, fsp, compression_fmt) \ + smb_vfs_call_set_compression((conn)->vfs_handles, (mem_ctx), (fsp), (compression_fmt)) +#define SMB_VFS_NEXT_SET_COMPRESSION(handle, mem_ctx, fsp, compression_fmt) \ + smb_vfs_call_set_compression((handle)->next, (mem_ctx), (fsp), (compression_fmt)) + #define SMB_VFS_FGET_NT_ACL(fsp, security_info, mem_ctx, ppdesc) \ - smb_vfs_call_fget_nt_acl((fsp)->conn->vfs_handles, (fsp), (security_info), (mem_ctx), (ppdesc)) + smb_vfs_call_fget_nt_acl((fsp)->conn->vfs_handles, (fsp), (security_info), (mem_ctx), (ppdesc)) #define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, mem_ctx, ppdesc) \ smb_vfs_call_fget_nt_acl((handle)->next, (fsp), (security_info), (mem_ctx), (ppdesc)) diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index edac0debc97..90c772b89e1 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -1489,6 +1489,23 @@ static NTSTATUS vfswrap_copy_chunk_recv(struct vfs_handle_struct *handle, return NT_STATUS_OK; } +static NTSTATUS vfswrap_get_compression(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct files_struct *fsp, + struct smb_fname *smb_fname, + uint16_t *_compression_fmt) +{ + return NT_STATUS_INVALID_DEVICE_REQUEST; +} + +static NTSTATUS vfswrap_set_compression(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct files_struct *fsp, + uint16_t compression_fmt) +{ + return NT_STATUS_INVALID_DEVICE_REQUEST; +} + /******************************************************************** Given a stat buffer return the allocated size on disk, taking into account sparse files. @@ -2535,6 +2552,8 @@ static struct vfs_fn_pointers vfs_default_fns = { .fsctl_fn = vfswrap_fsctl, .copy_chunk_send_fn = vfswrap_copy_chunk_send, .copy_chunk_recv_fn = vfswrap_copy_chunk_recv, + .get_compression_fn = vfswrap_get_compression, + .set_compression_fn = vfswrap_set_compression, /* NT ACL operations. */ diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index 37d8aa45030..99e3fcbb454 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -163,6 +163,8 @@ typedef enum _vfs_op_type { SMB_VFS_OP_TRANSLATE_NAME, SMB_VFS_OP_COPY_CHUNK_SEND, SMB_VFS_OP_COPY_CHUNK_RECV, + SMB_VFS_OP_GET_COMPRESSION, + SMB_VFS_OP_SET_COMPRESSION, /* NT ACL operations. */ @@ -285,6 +287,8 @@ static struct { { SMB_VFS_OP_TRANSLATE_NAME, "translate_name" }, { SMB_VFS_OP_COPY_CHUNK_SEND, "copy_chunk_send" }, { SMB_VFS_OP_COPY_CHUNK_RECV, "copy_chunk_recv" }, + { SMB_VFS_OP_GET_COMPRESSION, "get_compression" }, + { SMB_VFS_OP_SET_COMPRESSION, "set_compression" }, { SMB_VFS_OP_FGET_NT_ACL, "fget_nt_acl" }, { SMB_VFS_OP_GET_NT_ACL, "get_nt_acl" }, { SMB_VFS_OP_FSET_NT_ACL, "fset_nt_acl" }, @@ -1771,6 +1775,40 @@ static NTSTATUS smb_full_audit_copy_chunk_recv(struct vfs_handle_struct *handle, return result; } +static NTSTATUS smb_full_audit_get_compression(vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct files_struct *fsp, + struct smb_filename *smb_fname, + uint16_t *_compression_fmt) +{ + NTSTATUS result; + + result = SMB_VFS_NEXT_GET_COMPRESSION(handle, mem_ctx, fsp, smb_fname, + _compression_fmt); + + do_log(SMB_VFS_OP_GET_COMPRESSION, NT_STATUS_IS_OK(result), handle, + "%s", + (fsp ? fsp_str_do_log(fsp) : smb_fname_str_do_log(smb_fname))); + + return result; +} + +static NTSTATUS smb_full_audit_set_compression(vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct files_struct *fsp, + uint16_t compression_fmt) +{ + NTSTATUS result; + + result = SMB_VFS_NEXT_SET_COMPRESSION(handle, mem_ctx, fsp, + compression_fmt); + + do_log(SMB_VFS_OP_SET_COMPRESSION, NT_STATUS_IS_OK(result), handle, + "%s", fsp_str_do_log(fsp)); + + return result; +} + static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info, TALLOC_CTX *mem_ctx, @@ -2172,6 +2210,8 @@ static struct vfs_fn_pointers vfs_full_audit_fns = { .translate_name_fn = smb_full_audit_translate_name, .copy_chunk_send_fn = smb_full_audit_copy_chunk_send, .copy_chunk_recv_fn = smb_full_audit_copy_chunk_recv, + .get_compression_fn = smb_full_audit_get_compression, + .set_compression_fn = smb_full_audit_set_compression, .fget_nt_acl_fn = smb_full_audit_fget_nt_acl, .get_nt_acl_fn = smb_full_audit_get_nt_acl, .fset_nt_acl_fn = smb_full_audit_fset_nt_acl, diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c index a9289536e1c..fd9eb522099 100644 --- a/source3/modules/vfs_time_audit.c +++ b/source3/modules/vfs_time_audit.c @@ -1751,6 +1751,57 @@ static NTSTATUS smb_time_audit_copy_chunk_recv(struct vfs_handle_struct *handle, return NT_STATUS_OK; } +static NTSTATUS smb_time_audit_get_compression(vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct files_struct *fsp, + struct smb_filename *smb_fname, + uint16_t *_compression_fmt) +{ + NTSTATUS result; + struct timespec ts1,ts2; + double timediff; + + clock_gettime_mono(&ts1); + result = SMB_VFS_NEXT_GET_COMPRESSION(handle, mem_ctx, fsp, smb_fname, + _compression_fmt); + clock_gettime_mono(&ts2); + timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9; + + if (timediff > audit_timeout) { + if (fsp != NULL) { + smb_time_audit_log_fsp("get_compression", + timediff, fsp); + } else { + smb_time_audit_log_smb_fname("get_compression", + timediff, smb_fname); + } + } + + return result; +} + +static NTSTATUS smb_time_audit_set_compression(vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct files_struct *fsp, + uint16_t compression_fmt) +{ + NTSTATUS result; + struct timespec ts1,ts2; + double timediff; + + clock_gettime_mono(&ts1); + result = SMB_VFS_NEXT_SET_COMPRESSION(handle, mem_ctx, fsp, + compression_fmt); + clock_gettime_mono(&ts2); + timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9; + + if (timediff > audit_timeout) { + smb_time_audit_log_fsp("set_compression", timediff, fsp); + } + + return result; +} + static NTSTATUS smb_time_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info, @@ -2370,6 +2421,8 @@ static struct vfs_fn_pointers vfs_time_audit_fns = { .translate_name_fn = smb_time_audit_translate_name, .copy_chunk_send_fn = smb_time_audit_copy_chunk_send, .copy_chunk_recv_fn = smb_time_audit_copy_chunk_recv, + .get_compression_fn = smb_time_audit_get_compression, + .set_compression_fn = smb_time_audit_set_compression, .fget_nt_acl_fn = smb_time_audit_fget_nt_acl, .get_nt_acl_fn = smb_time_audit_get_nt_acl, .fset_nt_acl_fn = smb_time_audit_fset_nt_acl, diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index de0cc972056..a8e181ab420 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -2200,6 +2200,27 @@ NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle, return handle->fns->copy_chunk_recv_fn(handle, req, copied); } +NTSTATUS smb_vfs_call_get_compression(vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct files_struct *fsp, + struct smb_filename *smb_fname, + uint16_t *_compression_fmt) +{ + VFS_FIND(get_compression); + return handle->fns->get_compression_fn(handle, mem_ctx, fsp, smb_fname, + _compression_fmt); +} + +NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct files_struct *fsp, + uint16_t compression_fmt) +{ + VFS_FIND(set_compression); + return handle->fns->set_compression_fn(handle, mem_ctx, fsp, + compression_fmt); +} + NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32 security_info, -- cgit