summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Disseldorp <ddiss@samba.org>2013-11-18 14:54:30 +0100
committerJeremy Allison <jra@samba.org>2013-11-22 08:56:45 -0800
commitd8d5d4c7428683da04fa4c8b344504e7044f9b1c (patch)
tree5ce00faa4dbb6113f2c6d18ae312dd6dc5bc39fd
parent2b435ad4b45ec39b0cf70f55699daba3bcfcee08 (diff)
downloadsamba-d8d5d4c7428683da04fa4c8b344504e7044f9b1c.tar.gz
samba-d8d5d4c7428683da04fa4c8b344504e7044f9b1c.tar.xz
samba-d8d5d4c7428683da04fa4c8b344504e7044f9b1c.zip
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 <ddiss@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
-rw-r--r--docs-xml/manpages/vfs_full_audit.8.xml2
-rw-r--r--examples/VFS/skel_opaque.c19
-rw-r--r--examples/VFS/skel_transparent.c21
-rw-r--r--source3/include/vfs.h19
-rw-r--r--source3/include/vfs_macros.h12
-rw-r--r--source3/modules/vfs_default.c19
-rw-r--r--source3/modules/vfs_full_audit.c40
-rw-r--r--source3/modules/vfs_time_audit.c53
-rw-r--r--source3/smbd/vfs.c21
9 files changed, 205 insertions, 1 deletions
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 @@
<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 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,