488 }
489
490 return (fs_pathconf(vp, cmd, valp, cr, ct));
491 }
492
493 static const fs_operation_def_t zfsctl_tops_root[] = {
494 { VOPNAME_OPEN, { .vop_open = zfsctl_common_open } },
495 { VOPNAME_CLOSE, { .vop_close = zfsctl_common_close } },
496 { VOPNAME_IOCTL, { .error = fs_inval } },
497 { VOPNAME_GETATTR, { .vop_getattr = zfsctl_root_getattr } },
498 { VOPNAME_ACCESS, { .vop_access = zfsctl_common_access } },
499 { VOPNAME_READDIR, { .vop_readdir = gfs_vop_readdir } },
500 { VOPNAME_LOOKUP, { .vop_lookup = zfsctl_root_lookup } },
501 { VOPNAME_SEEK, { .vop_seek = fs_seek } },
502 { VOPNAME_INACTIVE, { .vop_inactive = gfs_vop_inactive } },
503 { VOPNAME_PATHCONF, { .vop_pathconf = zfsctl_pathconf } },
504 { VOPNAME_FID, { .vop_fid = zfsctl_common_fid } },
505 { NULL }
506 };
507
508 static int
509 zfsctl_snapshot_zname(vnode_t *vp, const char *name, int len, char *zname)
510 {
511 objset_t *os = ((zfsvfs_t *)((vp)->v_vfsp->vfs_data))->z_os;
512
513 if (snapshot_namecheck(name, NULL, NULL) != 0)
514 return (SET_ERROR(EILSEQ));
515 dmu_objset_name(os, zname);
516 if (strlen(zname) + 1 + strlen(name) >= len)
517 return (SET_ERROR(ENAMETOOLONG));
518 (void) strcat(zname, "@");
519 (void) strcat(zname, name);
520 return (0);
521 }
522
523 static int
524 zfsctl_unmount_snap(zfs_snapentry_t *sep, int fflags, cred_t *cr)
525 {
526 vnode_t *svp = sep->se_root;
527 int error;
|
488 }
489
490 return (fs_pathconf(vp, cmd, valp, cr, ct));
491 }
492
493 static const fs_operation_def_t zfsctl_tops_root[] = {
494 { VOPNAME_OPEN, { .vop_open = zfsctl_common_open } },
495 { VOPNAME_CLOSE, { .vop_close = zfsctl_common_close } },
496 { VOPNAME_IOCTL, { .error = fs_inval } },
497 { VOPNAME_GETATTR, { .vop_getattr = zfsctl_root_getattr } },
498 { VOPNAME_ACCESS, { .vop_access = zfsctl_common_access } },
499 { VOPNAME_READDIR, { .vop_readdir = gfs_vop_readdir } },
500 { VOPNAME_LOOKUP, { .vop_lookup = zfsctl_root_lookup } },
501 { VOPNAME_SEEK, { .vop_seek = fs_seek } },
502 { VOPNAME_INACTIVE, { .vop_inactive = gfs_vop_inactive } },
503 { VOPNAME_PATHCONF, { .vop_pathconf = zfsctl_pathconf } },
504 { VOPNAME_FID, { .vop_fid = zfsctl_common_fid } },
505 { NULL }
506 };
507
508 /*
509 * Gets the full dataset name that corresponds to the given snapshot name
510 * Example:
511 * zfsctl_snapshot_zname("snap1") -> "mypool/myfs@snap1"
512 */
513 static int
514 zfsctl_snapshot_zname(vnode_t *vp, const char *name, int len, char *zname)
515 {
516 objset_t *os = ((zfsvfs_t *)((vp)->v_vfsp->vfs_data))->z_os;
517
518 if (snapshot_namecheck(name, NULL, NULL) != 0)
519 return (SET_ERROR(EILSEQ));
520 dmu_objset_name(os, zname);
521 if (strlen(zname) + 1 + strlen(name) >= len)
522 return (SET_ERROR(ENAMETOOLONG));
523 (void) strcat(zname, "@");
524 (void) strcat(zname, name);
525 return (0);
526 }
527
528 static int
529 zfsctl_unmount_snap(zfs_snapentry_t *sep, int fflags, cred_t *cr)
530 {
531 vnode_t *svp = sep->se_root;
532 int error;
|