From 73d5f14c04f2487f67695ce2e9ff025e25b2b026 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 17 Feb 2009 20:39:03 -0800 Subject: s3 OneFS: Add shadow copy module --- source3/modules/vfs_onefs_shadow_copy.c | 717 ++++++++++++++++++++++++++++++++ 1 file changed, 717 insertions(+) create mode 100644 source3/modules/vfs_onefs_shadow_copy.c (limited to 'source3/modules/vfs_onefs_shadow_copy.c') diff --git a/source3/modules/vfs_onefs_shadow_copy.c b/source3/modules/vfs_onefs_shadow_copy.c new file mode 100644 index 0000000000..28bc0c5081 --- /dev/null +++ b/source3/modules/vfs_onefs_shadow_copy.c @@ -0,0 +1,717 @@ +/* + * OneFS shadow copy implementation that utilizes the file system's native + * snapshot support. This is based on the original shadow copy module from + * 2004. + * + * Copyright (C) Stefan Metzmacher 2003-2004 + * Copyright (C) Tim Prouty 2009 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" +#include "onefs_shadow_copy.h" + +static int vfs_onefs_shadow_copy_debug_level = DBGC_VFS; + +#undef DBGC_CLASS +#define DBGC_CLASS vfs_onefs_shadow_copy_debug_level + +#define SHADOW_COPY_PREFIX "@GMT-" +#define SHADOW_COPY_SAMPLE "@GMT-2004.02.18-15.44.00" + +bool +shadow_copy_match_name(const char *name, char **snap_component) +{ + uint32 i = 0; + char delim[] = SHADOW_COPY_PREFIX; + char* start; + + start = strstr( name, delim ); + + /* + * The name could have SHADOW_COPY_PREFIX in it so we need to keep + * trying until we get something that is the full length of the + * SHADOW_COPY_SAMPLE. + */ + while (start != NULL) { + + DEBUG(10,("Processing %s\n", name)); + + /* size / correctness check */ + *snap_component = start; + for ( i = sizeof(SHADOW_COPY_PREFIX); + i < sizeof(SHADOW_COPY_SAMPLE); i++) { + if (start[i] == '/') { + if (i == sizeof(SHADOW_COPY_SAMPLE) - 1) + return true; + else + break; + } else if (start[i] == '\0') + return (i == sizeof(SHADOW_COPY_SAMPLE) - 1); + } + + start = strstr( start, delim ); + } + + return false; +} + +static int +onefs_shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, + files_struct *fsp, + SHADOW_COPY_DATA *shadow_copy_data, + bool labels) +{ + void *p = osc_version_opendir(); + char *snap_component = NULL; + shadow_copy_data->num_volumes = 0; + shadow_copy_data->labels = NULL; + + if (!p) { + DEBUG(0, ("shadow_copy_get_shadow_copy_data: osc_opendir() " + "failed for [%s]\n",fsp->conn->connectpath)); + return -1; + } + + while (true) { + SHADOW_COPY_LABEL *tlabels; + char *d; + + d = osc_version_readdir(p); + if (d == NULL) + break; + + if (!shadow_copy_match_name(d, &snap_component)) { + DEBUG(10,("shadow_copy_get_shadow_copy_data: ignore " + "[%s]\n",d)); + continue; + } + + DEBUG(7,("shadow_copy_get_shadow_copy_data: not ignore " + "[%s]\n",d)); + + if (!labels) { + shadow_copy_data->num_volumes++; + continue; + } + + tlabels = (SHADOW_COPY_LABEL *)TALLOC_REALLOC( + shadow_copy_data->mem_ctx, + shadow_copy_data->labels, + (shadow_copy_data->num_volumes+1) * + sizeof(SHADOW_COPY_LABEL)); + + if (tlabels == NULL) { + DEBUG(0,("shadow_copy_get_shadow_copy_data: Out of " + "memory\n")); + osc_version_closedir(p); + return -1; + } + + snprintf(tlabels[shadow_copy_data->num_volumes++], + sizeof(*tlabels), "%s",d); + + shadow_copy_data->labels = tlabels; + } + + osc_version_closedir(p); + + return 0; +} + +#define SHADOW_NEXT(op, args, rtype) do { \ + char *cpath = NULL; \ + char *snap_component = NULL; \ + rtype ret; \ + if (shadow_copy_match_name(path, &snap_component)) \ + cpath = osc_canonicalize_path(path, snap_component); \ + ret = SMB_VFS_NEXT_ ## op args; \ + SAFE_FREE(cpath); \ + return ret; \ + } while (0) \ + + + +static uint64_t +onefs_shadow_copy_disk_free(vfs_handle_struct *handle, const char *path, + bool small_query, uint64_t *bsize, uint64_t *dfree, + uint64_t *dsize) +{ + + SHADOW_NEXT(DISK_FREE, + (handle, cpath ?: path, small_query, bsize, dfree, dsize), + uint64_t); + +} + +static int +onefs_shadow_copy_statvfs(struct vfs_handle_struct *handle, const char *path, + struct vfs_statvfs_struct *statbuf) +{ + SHADOW_NEXT(STATVFS, + (handle, cpath ?: path, statbuf), + int); +} + +static SMB_STRUCT_DIR * +onefs_shadow_copy_opendir(vfs_handle_struct *handle, const char *path, + const char *mask, uint32_t attr) +{ + SHADOW_NEXT(OPENDIR, + (handle, cpath ?: path, mask, attr), + SMB_STRUCT_DIR *); +} + +static int +onefs_shadow_copy_mkdir(vfs_handle_struct *handle, const char *path, + mode_t mode) +{ + SHADOW_NEXT(MKDIR, + (handle, cpath ?: path, mode), + int); +} + +static int +onefs_shadow_copy_rmdir(vfs_handle_struct *handle, const char *path) +{ + SHADOW_NEXT(RMDIR, + (handle, cpath ?: path), + int); +} + +static int +onefs_shadow_copy_open(vfs_handle_struct *handle, const char *path, + files_struct *fsp, int flags, mode_t mode) +{ + SHADOW_NEXT(OPEN, + (handle, cpath ?: path, fsp, flags, mode), + int); +} + +static NTSTATUS +onefs_shadow_copy_create_file(vfs_handle_struct *handle, + struct smb_request *req, + uint16_t root_dir_fid, + const char *path, + uint32_t create_file_flags, + uint32_t access_mask, + uint32_t share_access, + uint32_t create_disposition, + uint32_t create_options, + uint32_t file_attributes, + uint32_t oplock_request, + uint64_t allocation_size, + struct security_descriptor *sd, + struct ea_list *ea_list, + files_struct **result, + int *pinfo, + SMB_STRUCT_STAT *psbuf) +{ + SHADOW_NEXT(CREATE_FILE, + (handle, req, root_dir_fid, cpath ?: path, + create_file_flags, access_mask, share_access, + create_disposition, create_options, file_attributes, + oplock_request, allocation_size, sd, ea_list, result, + pinfo, psbuf), + NTSTATUS); +} + +/** + * XXX: macro-ize + */ +static int +onefs_shadow_copy_rename(vfs_handle_struct *handle, const char *old_name, + const char *new_name) +{ + char *old_cpath = NULL; + char *old_snap_component = NULL; + char *new_cpath = NULL; + char *new_snap_component = NULL; + int ret; + + if (shadow_copy_match_name(old_name, &old_snap_component)) + old_cpath = osc_canonicalize_path(old_name, old_snap_component); + + if (shadow_copy_match_name(new_name, &new_snap_component)) + new_cpath = osc_canonicalize_path(new_name, new_snap_component); + + ret = SMB_VFS_NEXT_RENAME(handle, old_cpath ?: old_name, + new_cpath ?: new_name); + + SAFE_FREE(old_cpath); + SAFE_FREE(new_cpath); + + return ret; +} + +static int +onefs_shadow_copy_stat(vfs_handle_struct *handle, const char *path, + SMB_STRUCT_STAT *sbuf) +{ + SHADOW_NEXT(STAT, + (handle, cpath ?: path, sbuf), + int); +} + +static int +onefs_shadow_copy_lstat(vfs_handle_struct *handle, const char *path, + SMB_STRUCT_STAT *sbuf) +{ + SHADOW_NEXT(LSTAT, + (handle, cpath ?: path, sbuf), + int); +} + +static int +onefs_shadow_copy_unlink(vfs_handle_struct *handle, const char *path) +{ + SHADOW_NEXT(UNLINK, + (handle, cpath ?: path), + int); +} + +static int +onefs_shadow_copy_chmod(vfs_handle_struct *handle, const char *path, + mode_t mode) +{ + SHADOW_NEXT(CHMOD, + (handle, cpath ?: path, mode), + int); +} + +static int +onefs_shadow_copy_chown(vfs_handle_struct *handle, const char *path, + uid_t uid, gid_t gid) +{ + SHADOW_NEXT(CHOWN, + (handle, cpath ?: path, uid, gid), + int); +} + +static int +onefs_shadow_copy_lchown(vfs_handle_struct *handle, const char *path, + uid_t uid, gid_t gid) +{ + SHADOW_NEXT(LCHOWN, + (handle, cpath ?: path, uid, gid), + int); +} + +static int +onefs_shadow_copy_chdir(vfs_handle_struct *handle, const char *path) +{ + SHADOW_NEXT(CHDIR, + (handle, cpath ?: path), + int); +} + +static int +onefs_shadow_copy_ntimes(vfs_handle_struct *handle, const char *path, + struct smb_file_time *ft) +{ + SHADOW_NEXT(NTIMES, + (handle, cpath ?: path, ft), + int); + +} + +/** + * XXX: macro-ize + */ +static bool +onefs_shadow_copy_symlink(vfs_handle_struct *handle, + const char *oldpath, const char *newpath) +{ + char *old_cpath = NULL; + char *old_snap_component = NULL; + char *new_cpath = NULL; + char *new_snap_component = NULL; + bool ret; + + if (shadow_copy_match_name(oldpath, &old_snap_component)) + old_cpath = osc_canonicalize_path(oldpath, old_snap_component); + + if (shadow_copy_match_name(newpath, &new_snap_component)) + new_cpath = osc_canonicalize_path(newpath, new_snap_component); + + ret = SMB_VFS_NEXT_SYMLINK(handle, old_cpath ?: oldpath, + new_cpath ?: newpath); + + SAFE_FREE(old_cpath); + SAFE_FREE(new_cpath); + + return ret; +} + +static bool +onefs_shadow_copy_readlink(vfs_handle_struct *handle, const char *path, + char *buf, size_t bufsiz) +{ + SHADOW_NEXT(READLINK, + (handle, cpath ?: path, buf, bufsiz), + bool); +} + +/** + * XXX: macro-ize + */ +static int +onefs_shadow_copy_link(vfs_handle_struct *handle, const char *oldpath, + const char *newpath) +{ + char *old_cpath = NULL; + char *old_snap_component = NULL; + char *new_cpath = NULL; + char *new_snap_component = NULL; + int ret; + + if (shadow_copy_match_name(oldpath, &old_snap_component)) + old_cpath = osc_canonicalize_path(oldpath, old_snap_component); + + if (shadow_copy_match_name(newpath, &new_snap_component)) + new_cpath = osc_canonicalize_path(newpath, new_snap_component); + + ret = SMB_VFS_NEXT_LINK(handle, old_cpath ?: oldpath, + new_cpath ?: newpath); + + SAFE_FREE(old_cpath); + SAFE_FREE(new_cpath); + + return ret; +} + +static int +onefs_shadow_copy_mknod(vfs_handle_struct *handle, const char *path, + mode_t mode, SMB_DEV_T dev) +{ + SHADOW_NEXT(MKNOD, + (handle, cpath ?: path, mode, dev), + int); +} + +static char * +onefs_shadow_copy_realpath(vfs_handle_struct *handle, const char *path, + char *resolved_path) +{ + SHADOW_NEXT(REALPATH, + (handle, cpath ?: path, resolved_path), + char *); +} + +static int onefs_shadow_copy_chflags(struct vfs_handle_struct *handle, + const char *path, unsigned int flags) +{ + SHADOW_NEXT(CHFLAGS, + (handle, cpath ?: path, flags), + int); +} + +static NTSTATUS +onefs_shadow_copy_streaminfo(struct vfs_handle_struct *handle, + struct files_struct *fsp, + const char *path, + TALLOC_CTX *mem_ctx, + unsigned int *num_streams, + struct stream_struct **streams) +{ + SHADOW_NEXT(STREAMINFO, + (handle, fsp, cpath ?: path, mem_ctx, num_streams, + streams), + NTSTATUS); +} + +static int +onefs_shadow_copy_get_real_filename(struct vfs_handle_struct *handle, + const char *full_path, + const char *path, + TALLOC_CTX *mem_ctx, + char **found_name) +{ + SHADOW_NEXT(GET_REAL_FILENAME, + (handle, full_path, cpath ?: path, mem_ctx, found_name), + int); +} + +static NTSTATUS +onefs_shadow_copy_get_nt_acl(struct vfs_handle_struct *handle, + const char *path, uint32 security_info, + struct security_descriptor **ppdesc) +{ + SHADOW_NEXT(GET_NT_ACL, + (handle, cpath ?: path, security_info, ppdesc), + NTSTATUS); +} + +static int +onefs_shadow_copy_chmod_acl(vfs_handle_struct *handle, const char *path, + mode_t mode) +{ + SHADOW_NEXT(CHMOD_ACL, + (handle, cpath ?: path, mode), + int); +} + +static SMB_ACL_T +onefs_shadow_copy_sys_acl_get_file(vfs_handle_struct *handle, + const char *path, SMB_ACL_TYPE_T type) +{ + SHADOW_NEXT(SYS_ACL_GET_FILE, + (handle, cpath ?: path, type), + SMB_ACL_T); +} + +static int +onefs_shadow_copy_sys_acl_set_file(vfs_handle_struct *handle, const char *path, + SMB_ACL_TYPE_T type, SMB_ACL_T theacl) +{ + SHADOW_NEXT(SYS_ACL_SET_FILE, + (handle, cpath ?: path, type, theacl), + int); +} + +static int +onefs_shadow_copy_sys_acl_delete_def_file(vfs_handle_struct *handle, + const char *path) +{ + SHADOW_NEXT(SYS_ACL_DELETE_DEF_FILE, + (handle, cpath ?: path), + int); +} + +static ssize_t +onefs_shadow_copy_getxattr(vfs_handle_struct *handle, const char *path, + const char *name, void *value, size_t size) +{ + SHADOW_NEXT(GETXATTR, + (handle, cpath ?: path, name, value, size), + ssize_t); +} + +static ssize_t +onefs_shadow_copy_lgetxattr(vfs_handle_struct *handle, const char *path, + const char *name, void *value, size_t size) +{ + SHADOW_NEXT(LGETXATTR, + (handle, cpath ?: path, name, value, size), + ssize_t); +} + +static ssize_t +onefs_shadow_copy_listxattr(vfs_handle_struct *handle, const char *path, + char *list, size_t size) +{ + SHADOW_NEXT(LISTXATTR, + (handle, cpath ?: path, list, size), + ssize_t); +} + +static ssize_t +onefs_shadow_copy_llistxattr(vfs_handle_struct *handle, const char *path, + char *list, size_t size) +{ + SHADOW_NEXT(LLISTXATTR, + (handle, cpath ?: path, list, size), + ssize_t); +} + +static int +onefs_shadow_copy_removexattr(vfs_handle_struct *handle, const char *path, + const char *name) +{ + SHADOW_NEXT(REMOVEXATTR, + (handle, cpath ?: path, name), + int); +} + +static int +onefs_shadow_copy_lremovexattr(vfs_handle_struct *handle, const char *path, + const char *name) +{ + SHADOW_NEXT(LREMOVEXATTR, + (handle, cpath ?: path, name), + int); +} + +static int +onefs_shadow_copy_setxattr(vfs_handle_struct *handle, const char *path, + const char *name, const void *value, size_t size, + int flags) +{ + SHADOW_NEXT(SETXATTR, + (handle, cpath ?: path, name, value, size, flags), + int); +} + +static int +onefs_shadow_copy_lsetxattr(vfs_handle_struct *handle, const char *path, + const char *name, const void *value, size_t size, + int flags) +{ + SHADOW_NEXT(LSETXATTR, + (handle, cpath ?: path, name, value, size, flags), + int); +} + +static bool +onefs_shadow_copy_is_offline(struct vfs_handle_struct *handle, + const char *path, SMB_STRUCT_STAT *sbuf) +{ + SHADOW_NEXT(IS_OFFLINE, + (handle, cpath ?: path, sbuf), + bool); +} + +static int +onefs_shadow_copy_set_offline(struct vfs_handle_struct *handle, + const char *path) +{ + SHADOW_NEXT(SET_OFFLINE, + (handle, cpath ?: path), + int); +} + +/* VFS operations structure */ + +static vfs_op_tuple onefs_shadow_copy_ops[] = { + + /* Disk operations */ + + {SMB_VFS_OP(onefs_shadow_copy_disk_free), SMB_VFS_OP_DISK_FREE, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_get_shadow_copy_data), + SMB_VFS_OP_GET_SHADOW_COPY_DATA, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(onefs_shadow_copy_statvfs), SMB_VFS_OP_STATVFS, + SMB_VFS_LAYER_TRANSPARENT}, + + /* Directory operations */ + + {SMB_VFS_OP(onefs_shadow_copy_opendir), SMB_VFS_OP_OPENDIR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_mkdir), SMB_VFS_OP_MKDIR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_rmdir), SMB_VFS_OP_RMDIR, + SMB_VFS_LAYER_TRANSPARENT}, + + /* File operations */ + + {SMB_VFS_OP(onefs_shadow_copy_open), SMB_VFS_OP_OPEN, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_create_file), SMB_VFS_OP_CREATE_FILE, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_rename), SMB_VFS_OP_RENAME, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_stat), SMB_VFS_OP_STAT, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_stat), SMB_VFS_OP_STAT, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_lstat), SMB_VFS_OP_LSTAT, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_unlink), SMB_VFS_OP_UNLINK, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_chmod), SMB_VFS_OP_CHMOD, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_chown), SMB_VFS_OP_CHOWN, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_lchown), SMB_VFS_OP_LCHOWN, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_chdir), SMB_VFS_OP_CHDIR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_ntimes), SMB_VFS_OP_NTIMES, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_symlink), SMB_VFS_OP_SYMLINK, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_readlink), SMB_VFS_OP_READLINK, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_link), SMB_VFS_OP_LINK, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_mknod), SMB_VFS_OP_MKNOD, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_realpath), SMB_VFS_OP_REALPATH, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_chflags), SMB_VFS_OP_CHFLAGS, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_streaminfo), SMB_VFS_OP_STREAMINFO, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_get_real_filename), + SMB_VFS_OP_GET_REAL_FILENAME, SMB_VFS_LAYER_TRANSPARENT}, + + /* NT File ACL operations */ + + {SMB_VFS_OP(onefs_shadow_copy_get_nt_acl), SMB_VFS_OP_GET_NT_ACL, + SMB_VFS_LAYER_TRANSPARENT}, + + /* POSIX ACL operations */ + + {SMB_VFS_OP(onefs_shadow_copy_chmod_acl), SMB_VFS_OP_CHMOD_ACL, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_sys_acl_get_file), + SMB_VFS_OP_SYS_ACL_GET_FILE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_sys_acl_set_file), + SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_sys_acl_delete_def_file), + SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, SMB_VFS_LAYER_TRANSPARENT}, + + /* EA operations. */ + + {SMB_VFS_OP(onefs_shadow_copy_getxattr), SMB_VFS_OP_GETXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_lgetxattr), SMB_VFS_OP_LGETXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_listxattr), SMB_VFS_OP_LISTXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_llistxattr), SMB_VFS_OP_LLISTXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_removexattr), SMB_VFS_OP_REMOVEXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_lremovexattr), SMB_VFS_OP_LREMOVEXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_setxattr), SMB_VFS_OP_SETXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_lsetxattr), SMB_VFS_OP_LSETXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + + /* offline operations */ + {SMB_VFS_OP(onefs_shadow_copy_is_offline), SMB_VFS_OP_IS_OFFLINE, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_shadow_copy_set_offline), SMB_VFS_OP_SET_OFFLINE, + SMB_VFS_LAYER_TRANSPARENT}, + + {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} +}; + +NTSTATUS vfs_shadow_copy_init(void) +{ + NTSTATUS ret; + + ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, + "onefs_shadow_copy", + onefs_shadow_copy_ops); + + if (!NT_STATUS_IS_OK(ret)) + return ret; + + vfs_onefs_shadow_copy_debug_level = debug_add_class("onefs_shadow_copy"); + + if (vfs_onefs_shadow_copy_debug_level == -1) { + vfs_onefs_shadow_copy_debug_level = DBGC_VFS; + DEBUG(0, ("Couldn't register custom debugging class!\n")); + } else { + DEBUG(10, ("Debug class number of 'onefs_shadow_copy': %d\n", + vfs_onefs_shadow_copy_debug_level)); + } + + return ret; +} -- cgit