vfs: add [GET/SET]_COMPRESSION hooks
authorDavid Disseldorp <ddiss@samba.org>
Mon, 18 Nov 2013 13:54:30 +0000 (14:54 +0100)
committerJeremy Allison <jra@samba.org>
Fri, 22 Nov 2013 16:56:45 +0000 (08:56 -0800)
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>
docs-xml/manpages/vfs_full_audit.8.xml
examples/VFS/skel_opaque.c
examples/VFS/skel_transparent.c
source3/include/vfs.h
source3/include/vfs_macros.h
source3/modules/vfs_default.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_time_audit.c
source3/smbd/vfs.c

index 1266b1fbb6c2b67a065e792f112685040bfcdfac..2be26b03c476d6af8ddf6565cf54d2c34d88032c 100644 (file)
@@ -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>
index 53c64cafb88396a553297db93a8159db58d245ab..5abea20dd06bf14a12c7f4147162ff8a8f567061 100644 (file)
@@ -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,
index 99feadec600fe962158eec9abbfeb518038f882f..f042b2aead4622d901a602b534ee79713accf113 100644 (file)
@@ -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,
index 0e5b0748678d97dbf12e8c7a98f76ce37353b9d9..1bea0b8df0178122c3d6b9696433426955b63e2c 100644 (file)
 /* 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,
index 15e8492747fb862530fac0135fe59d11c43841f4..704054d3f9a636e64f06ecdb19ef2e2c8314b69f 100644 (file)
 #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))
 
index edac0debc970312b48db32a7720a4dbbb419bc80..90c772b89e12cc6a5b662c79d9641f942926be5c 100644 (file)
@@ -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. */
 
index 37d8aa45030a855e4bd4eef70f7d778b62eeb558..99e3fcbb45448211b108b45e9bb86355673e5249 100644 (file)
@@ -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,
index a9289536e1c1b38737c909ea71c8eecd4bde43fc..fd9eb522099f098199caf239f2d9dacf467d717d 100644 (file)
@@ -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,
index de0cc97205697487630400d24697e8a39c6e02ef..a8e181ab420317de5351963dad048ed28495908c 100644 (file)
@@ -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,