[PATCH 2/8] vfs: add [GET/SET]_COMPRESSION hooks

David Disseldorp ddiss at samba.org
Mon Sep 16 09:52:47 CEST 2013


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.

Both get_compression and set_compression functions take fsp and
smb_fname arguments. The smb_fname argument is needed due to the current
dosmode() code-path.

Signed-off-by: David Disseldorp <ddiss at samba.org>
---
 docs-xml/manpages/vfs_full_audit.8.xml |  2 ++
 examples/VFS/skel_opaque.c             | 20 ++++++++++++++
 examples/VFS/skel_transparent.c        | 22 ++++++++++++++++
 source3/include/vfs.h                  | 21 +++++++++++++++
 source3/include/vfs_macros.h           | 12 ++++++++-
 source3/modules/vfs_default.c          | 18 +++++++++++++
 source3/modules/vfs_full_audit.c       | 40 ++++++++++++++++++++++++++++
 source3/modules/vfs_time_audit.c       | 48 ++++++++++++++++++++++++++++++++++
 source3/smbd/vfs.c                     | 22 ++++++++++++++++
 9 files changed, 204 insertions(+), 1 deletion(-)

diff --git a/docs-xml/manpages/vfs_full_audit.8.xml b/docs-xml/manpages/vfs_full_audit.8.xml
index 1266b1f..2be26b0 100644
--- a/docs-xml/manpages/vfs_full_audit.8.xml
+++ b/docs-xml/manpages/vfs_full_audit.8.xml
@@ -62,6 +62,7 @@
         <member>fstat</member>
         <member>fsync</member>
         <member>ftruncate</member>
+        <member>get_compression</member>
         <member>get_nt_acl</member>
         <member>get_quota</member>
         <member>get_shadow_copy_data</member>
@@ -91,6 +92,7 @@
         <member>rmdir</member>
         <member>seekdir</member>
         <member>sendfile</member>
+        <member>set_compression</member>
         <member>set_nt_acl</member>
         <member>set_quota</member>
         <member>setxattr</member>
diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index 53c64ca..e7dc330 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -528,6 +528,24 @@ 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,
+				     struct smb_filename *smb_fname,
+				     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 +885,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 99feade..314f5f2 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -645,6 +645,26 @@ 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,
+				     struct smb_filename *smb_fname,
+				     uint16_t compression_fmt)
+{
+	return SMB_VFS_NEXT_SET_COMPRESSION(handle, mem_ctx, fsp, smb_fname,
+					    compression_fmt);
+}
+
 static NTSTATUS skel_streaminfo(struct vfs_handle_struct *handle,
 				struct files_struct *fsp,
 				const char *fname,
@@ -973,6 +993,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 0e5b074..fd0635a 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,16 @@ 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,
+				       struct smb_filename *smb_fname,
+				       uint16_t compression_fmt);
 
 	NTSTATUS (*streaminfo_fn)(struct vfs_handle_struct *handle,
 				  struct files_struct *fsp,
@@ -1109,6 +1120,16 @@ 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,
+				      struct smb_filename *smb_fname,
+				      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 364a4ca..a6dc41b6 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, smb_fname, compression_fmt)		\
+	smb_vfs_call_set_compression((conn)->vfs_handles, (mem_ctx), (fsp), (smb_fname), (compression_fmt))
+#define SMB_VFS_NEXT_SET_COMPRESSION(handle, mem_ctx, fsp, smb_fname, compression_fmt)		\
+	smb_vfs_call_set_compression((handle)->next, (mem_ctx), (fsp), (smb_fname), (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 edac0de..5e971c2 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -1489,6 +1489,22 @@ 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,
+					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 +2551,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 37d8aa4..d385904 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_str_do_log(fsp));
+
+	return result;
+}
+
+static NTSTATUS smb_full_audit_set_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_SET_COMPRESSION(handle, mem_ctx, fsp, smb_fname,
+					      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 98a6151..91e7c91 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -1751,6 +1751,52 @@ 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) {
+		smb_time_audit_log_fsp("get_compression", timediff, fsp);
+	}
+
+	return result;
+}
+
+static NTSTATUS smb_time_audit_set_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_SET_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) {
+		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,
@@ -2264,6 +2310,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 ca6500c..5db6a1d 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -2200,6 +2200,28 @@ 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,
+				      struct smb_filename *smb_fname,
+				      uint16_t compression_fmt)
+{
+	VFS_FIND(set_compression);
+	return handle->fns->set_compression_fn(handle, mem_ctx, fsp, smb_fname,
+					       compression_fmt);
+}
+
 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
 				  struct files_struct *fsp,
 				  uint32 security_info,
-- 
1.8.1.4



More information about the samba-technical mailing list