5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
24 * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
25 */
26
27 /*
28 * ZFS control directory (a.k.a. ".zfs")
29 *
30 * This directory provides a common location for all ZFS meta-objects.
31 * Currently, this is only the 'snapshot' directory, but this may expand in the
32 * future. The elements are built using the GFS primitives, as the hierarchy
33 * does not actually exist on disk.
34 *
35 * For 'snapshot', we don't want to have all snapshots always mounted, because
36 * this would take up a huge amount of space in /etc/mnttab. We have three
37 * types of objects:
38 *
39 * ctldir ------> snapshotdir -------> snapshot
40 * |
41 * |
42 * V
43 * mounted fs
44 *
60 * File systems mounted ontop of the GFS nodes '.zfs/snapshot/<snapname>'
61 * (ie: snapshots) are ZFS nodes and have their own unique vfs_t.
62 * However, vnodes within these mounted on file systems have their v_vfsp
63 * fields set to the head filesystem to make NFS happy (see
64 * zfsctl_snapdir_lookup()). We VFS_HOLD the head filesystem's vfs_t
65 * so that it cannot be freed until all snapshots have been unmounted.
66 */
67
68 #include <fs/fs_subr.h>
69 #include <sys/zfs_ctldir.h>
70 #include <sys/zfs_ioctl.h>
71 #include <sys/zfs_vfsops.h>
72 #include <sys/vfs_opreg.h>
73 #include <sys/gfs.h>
74 #include <sys/stat.h>
75 #include <sys/dmu.h>
76 #include <sys/dsl_destroy.h>
77 #include <sys/dsl_deleg.h>
78 #include <sys/mount.h>
79 #include <sys/sunddi.h>
80
81 #include "zfs_namecheck.h"
82
83 typedef struct zfsctl_node {
84 gfs_dir_t zc_gfs_private;
85 uint64_t zc_id;
86 timestruc_t zc_cmtime; /* ctime and mtime, always the same */
87 } zfsctl_node_t;
88
89 typedef struct zfsctl_snapdir {
90 zfsctl_node_t sd_node;
91 kmutex_t sd_lock;
92 avl_tree_t sd_snaps;
93 } zfsctl_snapdir_t;
94
95 typedef struct {
96 char *se_name;
97 vnode_t *se_root;
98 avl_node_t se_node;
99 } zfs_snapentry_t;
724
725 mutex_exit(&sdp->sd_lock);
726
727 return (err);
728 }
729
730 /*
731 * This creates a snapshot under '.zfs/snapshot'.
732 */
733 /* ARGSUSED */
734 static int
735 zfsctl_snapdir_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp,
736 cred_t *cr, caller_context_t *cc, int flags, vsecattr_t *vsecp)
737 {
738 zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data;
739 char name[ZFS_MAX_DATASET_NAME_LEN];
740 int err;
741 static enum symfollow follow = NO_FOLLOW;
742 static enum uio_seg seg = UIO_SYSSPACE;
743
744 if (zfs_component_namecheck(dirname, NULL, NULL) != 0)
745 return (SET_ERROR(EILSEQ));
746
747 dmu_objset_name(zfsvfs->z_os, name);
748
749 *vpp = NULL;
750
751 err = zfs_secpolicy_snapshot_perms(name, cr);
752 if (err != 0)
753 return (err);
754
755 if (err == 0) {
756 err = dmu_objset_snapshot_one(name, dirname);
757 if (err != 0)
758 return (err);
759 err = lookupnameat(dirname, seg, follow, NULL, vpp, dvp);
760 }
761
762 return (err);
763 }
764
853 }
854 mutex_exit(&sdp->sd_lock);
855 ZFS_EXIT(zfsvfs);
856 return (err);
857 }
858
859 /*
860 * The requested snapshot is not currently mounted, look it up.
861 */
862 err = zfsctl_snapshot_zname(dvp, nm, sizeof (snapname), snapname);
863 if (err != 0) {
864 mutex_exit(&sdp->sd_lock);
865 ZFS_EXIT(zfsvfs);
866 /*
867 * handle "ls *" or "?" in a graceful manner,
868 * forcing EILSEQ to ENOENT.
869 * Since shell ultimately passes "*" or "?" as name to lookup
870 */
871 return (err == EILSEQ ? ENOENT : err);
872 }
873 if (dmu_objset_hold(snapname, FTAG, &snap) != 0) {
874 mutex_exit(&sdp->sd_lock);
875 ZFS_EXIT(zfsvfs);
876 return (SET_ERROR(ENOENT));
877 }
878
879 sep = kmem_alloc(sizeof (zfs_snapentry_t), KM_SLEEP);
880 sep->se_name = kmem_alloc(strlen(nm) + 1, KM_SLEEP);
881 (void) strcpy(sep->se_name, nm);
882 *vpp = sep->se_root = zfsctl_snapshot_mknode(dvp, dmu_objset_id(snap));
883 avl_insert(&sdp->sd_snaps, sep, where);
884
885 dmu_objset_rele(snap, FTAG);
886 domount:
887 mountpoint_len = strlen(refstr_value(dvp->v_vfsp->vfs_mntpt)) +
888 strlen("/.zfs/snapshot/") + strlen(nm) + 1;
889 mountpoint = kmem_alloc(mountpoint_len, KM_SLEEP);
890 (void) snprintf(mountpoint, mountpoint_len, "%s/.zfs/snapshot/%s",
891 refstr_value(dvp->v_vfsp->vfs_mntpt), nm);
892
970 ZFS_EXIT(zfsvfs);
971
972 return (error);
973 }
974
975 /* ARGSUSED */
976 static int
977 zfsctl_snapdir_readdir_cb(vnode_t *vp, void *dp, int *eofp,
978 offset_t *offp, offset_t *nextp, void *data, int flags)
979 {
980 zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
981 char snapname[ZFS_MAX_DATASET_NAME_LEN];
982 uint64_t id, cookie;
983 boolean_t case_conflict;
984 int error;
985
986 ZFS_ENTER(zfsvfs);
987
988 cookie = *offp;
989 dsl_pool_config_enter(dmu_objset_pool(zfsvfs->z_os), FTAG);
990 error = dmu_snapshot_list_next(zfsvfs->z_os,
991 sizeof (snapname), snapname, &id, &cookie, &case_conflict);
992 dsl_pool_config_exit(dmu_objset_pool(zfsvfs->z_os), FTAG);
993 if (error) {
994 ZFS_EXIT(zfsvfs);
995 if (error == ENOENT) {
996 *eofp = 1;
997 return (0);
998 }
999 return (error);
1000 }
1001
1002 if (flags & V_RDDIR_ENTFLAGS) {
1003 edirent_t *eodp = dp;
1004
1005 (void) strcpy(eodp->ed_name, snapname);
1006 eodp->ed_ino = ZFSCTL_INO_SNAP(id);
1007 eodp->ed_eflags = case_conflict ? ED_CASE_CONFLICT : 0;
1008 } else {
1009 struct dirent64 *odp = dp;
1010
1011 (void) strcpy(odp->d_name, snapname);
|
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
24 * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
25 * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
26 */
27
28 /*
29 * ZFS control directory (a.k.a. ".zfs")
30 *
31 * This directory provides a common location for all ZFS meta-objects.
32 * Currently, this is only the 'snapshot' directory, but this may expand in the
33 * future. The elements are built using the GFS primitives, as the hierarchy
34 * does not actually exist on disk.
35 *
36 * For 'snapshot', we don't want to have all snapshots always mounted, because
37 * this would take up a huge amount of space in /etc/mnttab. We have three
38 * types of objects:
39 *
40 * ctldir ------> snapshotdir -------> snapshot
41 * |
42 * |
43 * V
44 * mounted fs
45 *
61 * File systems mounted ontop of the GFS nodes '.zfs/snapshot/<snapname>'
62 * (ie: snapshots) are ZFS nodes and have their own unique vfs_t.
63 * However, vnodes within these mounted on file systems have their v_vfsp
64 * fields set to the head filesystem to make NFS happy (see
65 * zfsctl_snapdir_lookup()). We VFS_HOLD the head filesystem's vfs_t
66 * so that it cannot be freed until all snapshots have been unmounted.
67 */
68
69 #include <fs/fs_subr.h>
70 #include <sys/zfs_ctldir.h>
71 #include <sys/zfs_ioctl.h>
72 #include <sys/zfs_vfsops.h>
73 #include <sys/vfs_opreg.h>
74 #include <sys/gfs.h>
75 #include <sys/stat.h>
76 #include <sys/dmu.h>
77 #include <sys/dsl_destroy.h>
78 #include <sys/dsl_deleg.h>
79 #include <sys/mount.h>
80 #include <sys/sunddi.h>
81 #include <sys/autosnap.h>
82
83 #include "zfs_namecheck.h"
84
85 typedef struct zfsctl_node {
86 gfs_dir_t zc_gfs_private;
87 uint64_t zc_id;
88 timestruc_t zc_cmtime; /* ctime and mtime, always the same */
89 } zfsctl_node_t;
90
91 typedef struct zfsctl_snapdir {
92 zfsctl_node_t sd_node;
93 kmutex_t sd_lock;
94 avl_tree_t sd_snaps;
95 } zfsctl_snapdir_t;
96
97 typedef struct {
98 char *se_name;
99 vnode_t *se_root;
100 avl_node_t se_node;
101 } zfs_snapentry_t;
726
727 mutex_exit(&sdp->sd_lock);
728
729 return (err);
730 }
731
732 /*
733 * This creates a snapshot under '.zfs/snapshot'.
734 */
735 /* ARGSUSED */
736 static int
737 zfsctl_snapdir_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp,
738 cred_t *cr, caller_context_t *cc, int flags, vsecattr_t *vsecp)
739 {
740 zfsvfs_t *zfsvfs = dvp->v_vfsp->vfs_data;
741 char name[ZFS_MAX_DATASET_NAME_LEN];
742 int err;
743 static enum symfollow follow = NO_FOLLOW;
744 static enum uio_seg seg = UIO_SYSSPACE;
745
746 if (zfs_component_namecheck(dirname, NULL, NULL) != 0 ||
747 autosnap_check_name(dirname))
748 return (SET_ERROR(EILSEQ));
749
750 dmu_objset_name(zfsvfs->z_os, name);
751
752 *vpp = NULL;
753
754 err = zfs_secpolicy_snapshot_perms(name, cr);
755 if (err != 0)
756 return (err);
757
758 if (err == 0) {
759 err = dmu_objset_snapshot_one(name, dirname);
760 if (err != 0)
761 return (err);
762 err = lookupnameat(dirname, seg, follow, NULL, vpp, dvp);
763 }
764
765 return (err);
766 }
767
856 }
857 mutex_exit(&sdp->sd_lock);
858 ZFS_EXIT(zfsvfs);
859 return (err);
860 }
861
862 /*
863 * The requested snapshot is not currently mounted, look it up.
864 */
865 err = zfsctl_snapshot_zname(dvp, nm, sizeof (snapname), snapname);
866 if (err != 0) {
867 mutex_exit(&sdp->sd_lock);
868 ZFS_EXIT(zfsvfs);
869 /*
870 * handle "ls *" or "?" in a graceful manner,
871 * forcing EILSEQ to ENOENT.
872 * Since shell ultimately passes "*" or "?" as name to lookup
873 */
874 return (err == EILSEQ ? ENOENT : err);
875 }
876
877 if (autosnap_check_name(strchr(snapname, '@'))) {
878 mutex_exit(&sdp->sd_lock);
879 ZFS_EXIT(zfsvfs);
880 return (SET_ERROR(ENOENT));
881 }
882
883 if (dmu_objset_hold(snapname, FTAG, &snap) != 0) {
884 mutex_exit(&sdp->sd_lock);
885 ZFS_EXIT(zfsvfs);
886 return (SET_ERROR(ENOENT));
887 }
888
889 sep = kmem_alloc(sizeof (zfs_snapentry_t), KM_SLEEP);
890 sep->se_name = kmem_alloc(strlen(nm) + 1, KM_SLEEP);
891 (void) strcpy(sep->se_name, nm);
892 *vpp = sep->se_root = zfsctl_snapshot_mknode(dvp, dmu_objset_id(snap));
893 avl_insert(&sdp->sd_snaps, sep, where);
894
895 dmu_objset_rele(snap, FTAG);
896 domount:
897 mountpoint_len = strlen(refstr_value(dvp->v_vfsp->vfs_mntpt)) +
898 strlen("/.zfs/snapshot/") + strlen(nm) + 1;
899 mountpoint = kmem_alloc(mountpoint_len, KM_SLEEP);
900 (void) snprintf(mountpoint, mountpoint_len, "%s/.zfs/snapshot/%s",
901 refstr_value(dvp->v_vfsp->vfs_mntpt), nm);
902
980 ZFS_EXIT(zfsvfs);
981
982 return (error);
983 }
984
985 /* ARGSUSED */
986 static int
987 zfsctl_snapdir_readdir_cb(vnode_t *vp, void *dp, int *eofp,
988 offset_t *offp, offset_t *nextp, void *data, int flags)
989 {
990 zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data;
991 char snapname[ZFS_MAX_DATASET_NAME_LEN];
992 uint64_t id, cookie;
993 boolean_t case_conflict;
994 int error;
995
996 ZFS_ENTER(zfsvfs);
997
998 cookie = *offp;
999 dsl_pool_config_enter(dmu_objset_pool(zfsvfs->z_os), FTAG);
1000 do {
1001 error = dmu_snapshot_list_next(zfsvfs->z_os,
1002 sizeof (snapname), snapname, &id, &cookie, &case_conflict);
1003 } while (error == 0 && autosnap_check_name(snapname));
1004 dsl_pool_config_exit(dmu_objset_pool(zfsvfs->z_os), FTAG);
1005 if (error) {
1006 ZFS_EXIT(zfsvfs);
1007 if (error == ENOENT) {
1008 *eofp = 1;
1009 return (0);
1010 }
1011 return (error);
1012 }
1013
1014 if (flags & V_RDDIR_ENTFLAGS) {
1015 edirent_t *eodp = dp;
1016
1017 (void) strcpy(eodp->ed_name, snapname);
1018 eodp->ed_ino = ZFSCTL_INO_SNAP(id);
1019 eodp->ed_eflags = case_conflict ? ED_CASE_CONFLICT : 0;
1020 } else {
1021 struct dirent64 *odp = dp;
1022
1023 (void) strcpy(odp->d_name, snapname);
|