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