• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/samba-3.5.8/source3/modules/
1/*
2 * OneFS shadow copy implementation that utilizes the file system's native
3 * snapshot support. This is based on the original shadow copy module from
4 * 2004.
5 *
6 * Copyright (C) Stefan Metzmacher	2003-2004
7 * Copyright (C) Tim Prouty		2009
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "includes.h"
25#include "onefs_shadow_copy.h"
26
27static int vfs_onefs_shadow_copy_debug_level = DBGC_VFS;
28
29#undef DBGC_CLASS
30#define DBGC_CLASS vfs_onefs_shadow_copy_debug_level
31
32#define SHADOW_COPY_PREFIX "@GMT-"
33#define SHADOW_COPY_SAMPLE "@GMT-2004.02.18-15.44.00"
34
35bool
36shadow_copy_match_name(const char *name, char **snap_component)
37{
38	uint32  i = 0;
39	char delim[] = SHADOW_COPY_PREFIX;
40	char* start;
41
42	start = strstr( name, delim );
43
44	/*
45	 * The name could have SHADOW_COPY_PREFIX in it so we need to keep
46	 * trying until we get something that is the full length of the
47	 * SHADOW_COPY_SAMPLE.
48	 */
49	while (start != NULL) {
50
51		DEBUG(10,("Processing %s\n", name));
52
53		/* size / correctness check */
54		*snap_component = start;
55		for ( i = sizeof(SHADOW_COPY_PREFIX);
56		      i < sizeof(SHADOW_COPY_SAMPLE); i++) {
57			if (start[i] == '/') {
58				if (i == sizeof(SHADOW_COPY_SAMPLE) - 1)
59					return true;
60				else
61					break;
62			} else if (start[i] == '\0')
63				return (i == sizeof(SHADOW_COPY_SAMPLE) - 1);
64		}
65
66		start = strstr( start, delim );
67	}
68
69	return false;
70}
71
72static int
73onefs_shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle,
74				       files_struct *fsp,
75				       SHADOW_COPY_DATA *shadow_copy_data,
76				       bool labels)
77{
78	void *p = osc_version_opendir();
79	char *snap_component = NULL;
80	shadow_copy_data->num_volumes = 0;
81	shadow_copy_data->labels = NULL;
82
83	if (!p) {
84		DEBUG(0, ("shadow_copy_get_shadow_copy_data: osc_opendir() "
85			  "failed for [%s]\n",fsp->conn->connectpath));
86		return -1;
87	}
88
89	while (true) {
90		SHADOW_COPY_LABEL *tlabels;
91		char *d;
92
93		d = osc_version_readdir(p);
94		if (d == NULL)
95			break;
96
97		if (!shadow_copy_match_name(d, &snap_component)) {
98			DEBUG(10,("shadow_copy_get_shadow_copy_data: ignore "
99				  "[%s]\n",d));
100			continue;
101		}
102
103		DEBUG(7,("shadow_copy_get_shadow_copy_data: not ignore "
104			 "[%s]\n",d));
105
106		if (!labels) {
107			shadow_copy_data->num_volumes++;
108			continue;
109		}
110
111		tlabels = (SHADOW_COPY_LABEL *)TALLOC_REALLOC(
112			shadow_copy_data->mem_ctx,
113			shadow_copy_data->labels,
114			(shadow_copy_data->num_volumes+1) *
115			sizeof(SHADOW_COPY_LABEL));
116
117		if (tlabels == NULL) {
118			DEBUG(0,("shadow_copy_get_shadow_copy_data: Out of "
119				 "memory\n"));
120			osc_version_closedir(p);
121			return -1;
122		}
123
124		snprintf(tlabels[shadow_copy_data->num_volumes++],
125			 sizeof(*tlabels), "%s",d);
126
127		shadow_copy_data->labels = tlabels;
128	}
129
130	osc_version_closedir(p);
131
132	return 0;
133}
134
135#define SHADOW_NEXT(op, args, rtype) do {			      \
136	char *cpath = NULL;					      \
137	char *snap_component = NULL;				      \
138	rtype ret;						      \
139	if (shadow_copy_match_name(path, &snap_component))	      \
140		cpath = osc_canonicalize_path(path, snap_component); \
141	ret = SMB_VFS_NEXT_ ## op args;				      \
142	SAFE_FREE(cpath);					      \
143	return ret;						      \
144	} while (0)						      \
145
146/*
147 * XXX: Convert osc_canonicalize_path to use talloc instead of malloc.
148 */
149#define SHADOW_NEXT_SMB_FNAME(op, args, rtype) do {		      \
150		char *smb_base_name_tmp = NULL;			      \
151		char *cpath = NULL;				      \
152		char *snap_component = NULL;			      \
153		rtype ret;					      \
154		smb_base_name_tmp = smb_fname->base_name;	      \
155		if (shadow_copy_match_name(smb_fname->base_name,      \
156			&snap_component)) {				\
157			cpath = osc_canonicalize_path(smb_fname->base_name, \
158			    snap_component);				\
159			smb_fname->base_name = cpath;			\
160		}							\
161		ret = SMB_VFS_NEXT_ ## op args;				\
162		smb_fname->base_name = smb_base_name_tmp;		\
163		SAFE_FREE(cpath);					\
164		return ret;						\
165	} while (0)							\
166
167static uint64_t
168onefs_shadow_copy_disk_free(vfs_handle_struct *handle, const char *path,
169			    bool small_query, uint64_t *bsize, uint64_t *dfree,
170			    uint64_t *dsize)
171{
172
173	SHADOW_NEXT(DISK_FREE,
174		    (handle, cpath ?: path, small_query, bsize, dfree, dsize),
175		    uint64_t);
176
177}
178
179static int
180onefs_shadow_copy_statvfs(struct vfs_handle_struct *handle, const char *path,
181			  struct vfs_statvfs_struct *statbuf)
182{
183	SHADOW_NEXT(STATVFS,
184		    (handle, cpath ?: path, statbuf),
185		    int);
186}
187
188static SMB_STRUCT_DIR *
189onefs_shadow_copy_opendir(vfs_handle_struct *handle, const char *path,
190			  const char *mask, uint32_t attr)
191{
192	SHADOW_NEXT(OPENDIR,
193		    (handle, cpath ?: path, mask, attr),
194		    SMB_STRUCT_DIR *);
195}
196
197static int
198onefs_shadow_copy_mkdir(vfs_handle_struct *handle, const char *path,
199			mode_t mode)
200{
201	SHADOW_NEXT(MKDIR,
202		    (handle, cpath ?: path, mode),
203		    int);
204}
205
206static int
207onefs_shadow_copy_rmdir(vfs_handle_struct *handle, const char *path)
208{
209	SHADOW_NEXT(RMDIR,
210		    (handle, cpath ?: path),
211		    int);
212}
213
214static int
215onefs_shadow_copy_open(vfs_handle_struct *handle,
216		       struct smb_filename *smb_fname, files_struct *fsp,
217		       int flags, mode_t mode)
218{
219	SHADOW_NEXT_SMB_FNAME(OPEN,
220			      (handle, smb_fname, fsp, flags, mode),
221			      int);
222}
223
224static NTSTATUS
225onefs_shadow_copy_create_file(vfs_handle_struct *handle,
226			      struct smb_request *req,
227			      uint16_t root_dir_fid,
228			      struct smb_filename *smb_fname,
229			      uint32_t access_mask,
230			      uint32_t share_access,
231			      uint32_t create_disposition,
232			      uint32_t create_options,
233			      uint32_t file_attributes,
234			      uint32_t oplock_request,
235			      uint64_t allocation_size,
236			      struct security_descriptor *sd,
237			      struct ea_list *ea_list,
238			      files_struct **result,
239			      int *pinfo)
240{
241	SHADOW_NEXT_SMB_FNAME(CREATE_FILE,
242			      (handle, req, root_dir_fid, smb_fname,
243				  access_mask, share_access,
244				  create_disposition, create_options,
245				  file_attributes, oplock_request,
246				  allocation_size, sd, ea_list, result, pinfo),
247			      NTSTATUS);
248}
249
250/**
251 * XXX: macro-ize
252 */
253static int
254onefs_shadow_copy_rename(vfs_handle_struct *handle,
255			 const struct smb_filename *smb_fname_src,
256			 const struct smb_filename *smb_fname_dst)
257{
258	char *old_cpath = NULL;
259	char *old_snap_component = NULL;
260	char *new_cpath = NULL;
261	char *new_snap_component = NULL;
262	struct smb_filename *smb_fname_src_tmp = NULL;
263	struct smb_filename *smb_fname_dst_tmp = NULL;
264	NTSTATUS status;
265	int ret = -1;
266
267	status = copy_smb_filename(talloc_tos(), smb_fname_src,
268				   &smb_fname_src_tmp);
269	if (!NT_STATUS_IS_OK(status)) {
270		errno = map_errno_from_nt_status(status);
271		goto out;
272	}
273	status = copy_smb_filename(talloc_tos(), smb_fname_dst,
274				   &smb_fname_dst_tmp);
275	if (!NT_STATUS_IS_OK(status)) {
276		errno = map_errno_from_nt_status(status);
277		goto out;
278	}
279
280	if (shadow_copy_match_name(smb_fname_src_tmp->base_name,
281				   &old_snap_component)) {
282		old_cpath = osc_canonicalize_path(smb_fname_src_tmp->base_name,
283					  old_snap_component);
284		smb_fname_src_tmp->base_name = old_cpath;
285	}
286
287	if (shadow_copy_match_name(smb_fname_dst_tmp->base_name,
288				   &new_snap_component)) {
289		new_cpath = osc_canonicalize_path(smb_fname_dst_tmp->base_name,
290					  new_snap_component);
291		smb_fname_dst_tmp->base_name = new_cpath;
292	}
293
294	ret = SMB_VFS_NEXT_RENAME(handle, smb_fname_src_tmp,
295				  smb_fname_dst_tmp);
296
297 out:
298	SAFE_FREE(old_cpath);
299	SAFE_FREE(new_cpath);
300	TALLOC_FREE(smb_fname_src_tmp);
301	TALLOC_FREE(smb_fname_dst_tmp);
302
303	return ret;
304}
305
306static int
307onefs_shadow_copy_stat(vfs_handle_struct *handle,
308		       struct smb_filename *smb_fname)
309{
310	SHADOW_NEXT_SMB_FNAME(STAT,
311			      (handle, smb_fname),
312			      int);
313}
314
315static int
316onefs_shadow_copy_lstat(vfs_handle_struct *handle,
317			struct smb_filename *smb_fname)
318{
319	SHADOW_NEXT_SMB_FNAME(LSTAT,
320			      (handle, smb_fname),
321			      int);
322}
323
324static int
325onefs_shadow_copy_unlink(vfs_handle_struct *handle,
326			 const struct smb_filename *smb_fname_in)
327{
328	struct smb_filename *smb_fname = NULL;
329	NTSTATUS status;
330
331	status = copy_smb_filename(talloc_tos(), smb_fname_in, &smb_fname);
332	if (!NT_STATUS_IS_OK(status)) {
333		errno = map_errno_from_nt_status(status);
334		return -1;
335	}
336
337	SHADOW_NEXT_SMB_FNAME(UNLINK,
338			      (handle, smb_fname),
339			      int);
340}
341
342static int
343onefs_shadow_copy_chmod(vfs_handle_struct *handle, const char *path,
344			mode_t mode)
345{
346	SHADOW_NEXT(CHMOD,
347		    (handle, cpath ?: path, mode),
348		    int);
349}
350
351static int
352onefs_shadow_copy_chown(vfs_handle_struct *handle, const char *path,
353			uid_t uid, gid_t gid)
354{
355	SHADOW_NEXT(CHOWN,
356		    (handle, cpath ?: path, uid, gid),
357		    int);
358}
359
360static int
361onefs_shadow_copy_lchown(vfs_handle_struct *handle, const char *path,
362			 uid_t uid, gid_t gid)
363{
364	SHADOW_NEXT(LCHOWN,
365		    (handle, cpath ?: path, uid, gid),
366		    int);
367}
368
369static int
370onefs_shadow_copy_chdir(vfs_handle_struct *handle, const char *path)
371{
372	SHADOW_NEXT(CHDIR,
373		    (handle, cpath ?: path),
374		    int);
375}
376
377static int
378onefs_shadow_copy_ntimes(vfs_handle_struct *handle,
379			const struct smb_filename *smb_fname_in,
380			struct smb_file_time *ft)
381{
382	struct smb_filename *smb_fname = NULL;
383	NTSTATUS status;
384
385	status = copy_smb_filename(talloc_tos(), smb_fname_in, &smb_fname);
386	if (!NT_STATUS_IS_OK(status)) {
387		errno = map_errno_from_nt_status(status);
388		return -1;
389	}
390
391	SHADOW_NEXT_SMB_FNAME(NTIMES,
392			      (handle, smb_fname, ft),
393			      int);
394
395}
396
397/**
398 * XXX: macro-ize
399 */
400static int
401onefs_shadow_copy_symlink(vfs_handle_struct *handle,
402    const char *oldpath, const char *newpath)
403{
404	char *old_cpath = NULL;
405	char *old_snap_component = NULL;
406	char *new_cpath = NULL;
407	char *new_snap_component = NULL;
408	bool ret;
409
410	if (shadow_copy_match_name(oldpath, &old_snap_component))
411		old_cpath = osc_canonicalize_path(oldpath, old_snap_component);
412
413	if (shadow_copy_match_name(newpath, &new_snap_component))
414		new_cpath = osc_canonicalize_path(newpath, new_snap_component);
415
416        ret = SMB_VFS_NEXT_SYMLINK(handle, old_cpath ?: oldpath,
417	    new_cpath ?: newpath);
418
419	SAFE_FREE(old_cpath);
420	SAFE_FREE(new_cpath);
421
422	return ret;
423}
424
425static int
426onefs_shadow_copy_readlink(vfs_handle_struct *handle, const char *path,
427			   char *buf, size_t bufsiz)
428{
429	SHADOW_NEXT(READLINK,
430		    (handle, cpath ?: path, buf, bufsiz),
431		    int);
432}
433
434/**
435 * XXX: macro-ize
436 */
437static int
438onefs_shadow_copy_link(vfs_handle_struct *handle, const char *oldpath,
439		       const char *newpath)
440{
441	char *old_cpath = NULL;
442	char *old_snap_component = NULL;
443	char *new_cpath = NULL;
444	char *new_snap_component = NULL;
445	int ret;
446
447	if (shadow_copy_match_name(oldpath, &old_snap_component))
448		old_cpath = osc_canonicalize_path(oldpath, old_snap_component);
449
450	if (shadow_copy_match_name(newpath, &new_snap_component))
451		new_cpath = osc_canonicalize_path(newpath, new_snap_component);
452
453        ret = SMB_VFS_NEXT_LINK(handle, old_cpath ?: oldpath,
454	    new_cpath ?: newpath);
455
456	SAFE_FREE(old_cpath);
457	SAFE_FREE(new_cpath);
458
459	return ret;
460}
461
462static int
463onefs_shadow_copy_mknod(vfs_handle_struct *handle, const char *path,
464			mode_t mode, SMB_DEV_T dev)
465{
466	SHADOW_NEXT(MKNOD,
467		    (handle, cpath ?: path, mode, dev),
468		    int);
469}
470
471static char *
472onefs_shadow_copy_realpath(vfs_handle_struct *handle, const char *path,
473			   char *resolved_path)
474{
475	SHADOW_NEXT(REALPATH,
476		    (handle, cpath ?: path, resolved_path),
477		    char *);
478}
479
480static int onefs_shadow_copy_chflags(struct vfs_handle_struct *handle,
481				     const char *path, unsigned int flags)
482{
483	SHADOW_NEXT(CHFLAGS,
484		    (handle, cpath ?: path, flags),
485		    int);
486}
487
488static NTSTATUS
489onefs_shadow_copy_streaminfo(struct vfs_handle_struct *handle,
490			     struct files_struct *fsp,
491			     const char *path,
492			     TALLOC_CTX *mem_ctx,
493			     unsigned int *num_streams,
494			     struct stream_struct **streams)
495{
496	SHADOW_NEXT(STREAMINFO,
497		    (handle, fsp, cpath ?: path, mem_ctx, num_streams,
498			streams),
499		    NTSTATUS);
500}
501
502static int
503onefs_shadow_copy_get_real_filename(struct vfs_handle_struct *handle,
504				    const char *full_path,
505				    const char *path,
506				    TALLOC_CTX *mem_ctx,
507				    char **found_name)
508{
509	SHADOW_NEXT(GET_REAL_FILENAME,
510		    (handle, full_path, cpath ?: path, mem_ctx, found_name),
511		    int);
512}
513
514static NTSTATUS
515onefs_shadow_copy_get_nt_acl(struct vfs_handle_struct *handle,
516			    const char *path, uint32 security_info,
517			    struct security_descriptor **ppdesc)
518{
519	SHADOW_NEXT(GET_NT_ACL,
520		    (handle, cpath ?: path, security_info, ppdesc),
521		    NTSTATUS);
522}
523
524static int
525onefs_shadow_copy_chmod_acl(vfs_handle_struct *handle, const char *path,
526			    mode_t mode)
527{
528	SHADOW_NEXT(CHMOD_ACL,
529		    (handle, cpath ?: path, mode),
530		    int);
531}
532
533static SMB_ACL_T
534onefs_shadow_copy_sys_acl_get_file(vfs_handle_struct *handle,
535				   const char *path, SMB_ACL_TYPE_T type)
536{
537	SHADOW_NEXT(SYS_ACL_GET_FILE,
538		    (handle, cpath ?: path, type),
539		    SMB_ACL_T);
540}
541
542static int
543onefs_shadow_copy_sys_acl_set_file(vfs_handle_struct *handle, const char *path,
544				   SMB_ACL_TYPE_T type, SMB_ACL_T theacl)
545{
546	SHADOW_NEXT(SYS_ACL_SET_FILE,
547		    (handle, cpath ?: path, type, theacl),
548		    int);
549}
550
551static int
552onefs_shadow_copy_sys_acl_delete_def_file(vfs_handle_struct *handle,
553					  const char *path)
554{
555	SHADOW_NEXT(SYS_ACL_DELETE_DEF_FILE,
556		    (handle, cpath ?: path),
557		    int);
558}
559
560static ssize_t
561onefs_shadow_copy_getxattr(vfs_handle_struct *handle, const char *path,
562			   const char *name, void *value, size_t size)
563{
564	SHADOW_NEXT(GETXATTR,
565		    (handle, cpath ?: path, name, value, size),
566		    ssize_t);
567}
568
569static ssize_t
570onefs_shadow_copy_lgetxattr(vfs_handle_struct *handle, const char *path,
571			    const char *name, void *value, size_t size)
572{
573	SHADOW_NEXT(LGETXATTR,
574		    (handle, cpath ?: path, name, value, size),
575		    ssize_t);
576}
577
578static ssize_t
579onefs_shadow_copy_listxattr(vfs_handle_struct *handle, const char *path,
580			    char *list, size_t size)
581{
582	SHADOW_NEXT(LISTXATTR,
583		    (handle, cpath ?: path, list, size),
584		    ssize_t);
585}
586
587static ssize_t
588onefs_shadow_copy_llistxattr(vfs_handle_struct *handle, const char *path,
589			     char *list, size_t size)
590{
591	SHADOW_NEXT(LLISTXATTR,
592		    (handle, cpath ?: path, list, size),
593		    ssize_t);
594}
595
596static int
597onefs_shadow_copy_removexattr(vfs_handle_struct *handle, const char *path,
598			      const char *name)
599{
600	SHADOW_NEXT(REMOVEXATTR,
601		    (handle, cpath ?: path, name),
602		    int);
603}
604
605static int
606onefs_shadow_copy_lremovexattr(vfs_handle_struct *handle, const char *path,
607			       const char *name)
608{
609	SHADOW_NEXT(LREMOVEXATTR,
610		    (handle, cpath ?: path, name),
611		    int);
612}
613
614static int
615onefs_shadow_copy_setxattr(vfs_handle_struct *handle, const char *path,
616			   const char *name, const void *value, size_t size,
617			   int flags)
618{
619	SHADOW_NEXT(SETXATTR,
620		    (handle, cpath ?: path, name, value, size, flags),
621		    int);
622}
623
624static int
625onefs_shadow_copy_lsetxattr(vfs_handle_struct *handle, const char *path,
626			    const char *name, const void *value, size_t size,
627			    int flags)
628{
629	SHADOW_NEXT(LSETXATTR,
630		    (handle, cpath ?: path, name, value, size, flags),
631		    int);
632}
633
634static bool
635onefs_shadow_copy_is_offline(struct vfs_handle_struct *handle,
636			     const char *path, SMB_STRUCT_STAT *sbuf)
637{
638	SHADOW_NEXT(IS_OFFLINE,
639		    (handle, cpath ?: path, sbuf),
640		    bool);
641}
642
643static int
644onefs_shadow_copy_set_offline(struct vfs_handle_struct *handle,
645			      const char *path)
646{
647	SHADOW_NEXT(SET_OFFLINE,
648		    (handle, cpath ?: path),
649		    int);
650}
651
652/* VFS operations structure */
653
654static struct vfs_fn_pointers onefs_shadow_copy_fns = {
655	.disk_free = onefs_shadow_copy_disk_free,
656	.get_shadow_copy_data = onefs_shadow_copy_get_shadow_copy_data,
657	.statvfs = onefs_shadow_copy_statvfs,
658	.opendir = onefs_shadow_copy_opendir,
659	.mkdir = onefs_shadow_copy_mkdir,
660	.rmdir = onefs_shadow_copy_rmdir,
661	.open = onefs_shadow_copy_open,
662	.create_file = onefs_shadow_copy_create_file,
663	.rename = onefs_shadow_copy_rename,
664	.stat = onefs_shadow_copy_stat,
665	.stat = onefs_shadow_copy_stat,
666	.lstat = onefs_shadow_copy_lstat,
667	.unlink = onefs_shadow_copy_unlink,
668	.chmod = onefs_shadow_copy_chmod,
669	.chown = onefs_shadow_copy_chown,
670	.lchown = onefs_shadow_copy_lchown,
671	.chdir = onefs_shadow_copy_chdir,
672	.ntimes = onefs_shadow_copy_ntimes,
673	.symlink = onefs_shadow_copy_symlink,
674	.vfs_readlink = onefs_shadow_copy_readlink,
675	.link = onefs_shadow_copy_link,
676	.mknod = onefs_shadow_copy_mknod,
677	.realpath = onefs_shadow_copy_realpath,
678	.chflags = onefs_shadow_copy_chflags,
679	.streaminfo = onefs_shadow_copy_streaminfo,
680	.get_real_filename = onefs_shadow_copy_get_real_filename,
681	.get_nt_acl = onefs_shadow_copy_get_nt_acl,
682	.chmod_acl = onefs_shadow_copy_chmod_acl,
683	.sys_acl_get_file = onefs_shadow_copy_sys_acl_get_file,
684	.sys_acl_set_file = onefs_shadow_copy_sys_acl_set_file,
685	.sys_acl_delete_def_file = onefs_shadow_copy_sys_acl_delete_def_file,
686	.getxattr = onefs_shadow_copy_getxattr,
687	.lgetxattr = onefs_shadow_copy_lgetxattr,
688	.listxattr = onefs_shadow_copy_listxattr,
689	.llistxattr = onefs_shadow_copy_llistxattr,
690	.removexattr = onefs_shadow_copy_removexattr,
691	.lremovexattr = onefs_shadow_copy_lremovexattr,
692	.setxattr = onefs_shadow_copy_setxattr,
693	.lsetxattr = onefs_shadow_copy_lsetxattr,
694	.is_offline = onefs_shadow_copy_is_offline,
695	.set_offline = onefs_shadow_copy_set_offline,
696};
697
698NTSTATUS vfs_shadow_copy_init(void)
699{
700	NTSTATUS ret;
701
702	ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
703			       "onefs_shadow_copy",
704			       &onefs_shadow_copy_fns);
705
706	if (!NT_STATUS_IS_OK(ret))
707		return ret;
708
709	vfs_onefs_shadow_copy_debug_level = debug_add_class("onefs_shadow_copy");
710
711	if (vfs_onefs_shadow_copy_debug_level == -1) {
712		vfs_onefs_shadow_copy_debug_level = DBGC_VFS;
713		DEBUG(0, ("Couldn't register custom debugging class!\n"));
714	} else {
715		DEBUG(10, ("Debug class number of 'onefs_shadow_copy': %d\n",
716			   vfs_onefs_shadow_copy_debug_level));
717	}
718
719	return ret;
720}
721