1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
14  */
15 
16 #include <sys/types.h>
17 #include <sys/param.h>
18 #include <sys/t_lock.h>
19 #include <sys/errno.h>
20 #include <sys/cred.h>
21 #include <sys/user.h>
22 #include <sys/uio.h>
23 #include <sys/file.h>
24 #include <sys/pathname.h>
25 #include <sys/vfs.h>
26 #include <sys/vnode.h>
27 #include <sys/stat.h>
28 #include <sys/mode.h>
29 #include <sys/conf.h>
30 #include <sys/sysmacros.h>
31 #include <sys/cmn_err.h>
32 #include <sys/systm.h>
33 #include <sys/kmem.h>
34 #include <sys/debug.h>
35 #include <sys/acl.h>
36 #include <sys/nbmlock.h>
37 #include <sys/fcntl.h>
38 #include <sys/poll.h>
39 
40 #include <errno.h>
41 #include <fcntl.h>
42 #include <unistd.h>
43 
44 #include "vncache.h"
45 
46 #define	VFTBITS(feature)	((feature) & 0xFFFFFFFFLL)
47 
48 static uint64_t vfs_features = VFSFT_XVATTR;
49 
50 vnode_t *rootdir = NULL;	/* pointer to root inode vnode. */
51 
52 static struct vfs fake_rootvfs;
53 static struct vfsops fake_vfsops;
54 struct vfs *rootvfs = NULL;
55 static struct vfssw fake_vfssw = {
56 	.vsw_name = "fake"	/* see smb_tree.c:smb_mtype[] */
57 };
58 
59 int
fksmbsrv_vfs_init(void)60 fksmbsrv_vfs_init(void)
61 {
62 	struct stat st;
63 	int err, fd;
64 	vnode_t *vp;
65 	char *name = "/";
66 
67 	if (rootvfs == NULL) {
68 		rootvfs = &fake_rootvfs;
69 		rootvfs->vfs_mntpt = refstr_alloc(name);
70 		rootvfs->vfs_fsid.val[0] = 1;
71 		rootvfs->vfs_op = &fake_vfsops;
72 	}
73 
74 	if (rootdir == NULL) {
75 		if (lstat(name, &st) == -1)
76 			return (errno);
77 		fd = open(name, O_RDONLY, 0);
78 		if (fd < 0) {
79 			return (errno);
80 		}
81 		if (fstat(fd, &st) == -1) {
82 			err = errno;
83 			(void) close(fd);
84 			return (err);
85 		}
86 		vp = vncache_enter(&st, NULL, "", fd);
87 		/* extra hold for rootvp */
88 		vn_hold(vp);
89 		rootdir = vp;
90 
91 		/* VFS stuff in global zone struct. */
92 		zone0.zone_rootvp = rootdir;
93 		zone0.zone_rootpath = "/";
94 	}
95 
96 	return (0);
97 
98 }
99 
100 
101 /*
102  * Query a vfs for a feature.
103  * Returns 1 if feature is present, 0 if not
104  */
105 /* ARGSUSED */
106 int
vfs_has_feature(vfs_t * vfsp,vfs_feature_t feature)107 vfs_has_feature(vfs_t *vfsp, vfs_feature_t feature)
108 {
109 	int	ret = 0;
110 
111 	if (vfs_features & VFTBITS(feature))
112 		ret = 1;
113 
114 	return (ret);
115 }
116 
117 /* ARGSUSED */
118 struct vfs *
getvfs(fsid_t * fsid)119 getvfs(fsid_t *fsid)
120 {
121 	return (rootvfs);
122 }
123 
124 vfsops_t *
vfs_getops(vfs_t * vfsp)125 vfs_getops(vfs_t *vfsp)
126 {
127 	return (vfsp->vfs_op);
128 }
129 
130 /* ARGSUSED */
131 struct vfssw *
vfs_getvfsswbyvfsops(vfsops_t * vfsops)132 vfs_getvfsswbyvfsops(vfsops_t *vfsops)
133 {
134 	if (vfsops == &fake_vfsops)
135 		return (&fake_vfssw);
136 	return (NULL);
137 }
138 
139 /* ARGSUSED */
140 void
vfs_unrefvfssw(struct vfssw * vswp)141 vfs_unrefvfssw(struct vfssw *vswp)
142 {
143 }
144 
145 /* ARGSUSED */
146 int
fsop_root(vfs_t * vfsp,vnode_t ** vpp)147 fsop_root(vfs_t *vfsp, vnode_t **vpp)
148 {
149 	vnode_t *vp;
150 
151 	if ((vp = rootdir) == NULL)
152 		return (ENXIO);
153 
154 	vn_hold(vp);
155 	*vpp = vp;
156 	return (0);
157 }
158 
159 /* ARGSUSED */
160 int
fsop_statfs(vfs_t * vfsp,statvfs64_t * sp)161 fsop_statfs(vfs_t *vfsp, statvfs64_t *sp)
162 {
163 	vnode_t *vp;
164 	int rc;
165 
166 	if ((vp = rootdir) == NULL)
167 		return (ENXIO);
168 
169 	rc = fstatvfs64(vp->v_fd, sp);
170 	if (rc == -1) {
171 		rc = errno;
172 	}
173 
174 	return (rc);
175 }
176 
177 refstr_t *
vfs_getmntpoint(const struct vfs * vfsp)178 vfs_getmntpoint(const struct vfs *vfsp)
179 {
180 	refstr_t *mntpt;
181 
182 	mntpt = vfsp->vfs_mntpt;
183 	refstr_hold(mntpt);
184 
185 	return (mntpt);
186 }
187 
188 /* ARGSUSED */
189 void
vfs_hold(vfs_t * vfsp)190 vfs_hold(vfs_t *vfsp)
191 {
192 }
193 
194 /* ARGSUSED */
195 void
vfs_rele(vfs_t * vfsp)196 vfs_rele(vfs_t *vfsp)
197 {
198 }
199 
200 /* ARGSUSED */
201 int
vfs_lock(vfs_t * vfsp)202 vfs_lock(vfs_t *vfsp)
203 {
204 	return (0);
205 }
206 
207 /* ARGSUSED */
208 int
vfs_rlock(vfs_t * vfsp)209 vfs_rlock(vfs_t *vfsp)
210 {
211 	return (0);
212 }
213 
214 /* ARGSUSED */
215 void
vfs_lock_wait(vfs_t * vfsp)216 vfs_lock_wait(vfs_t *vfsp)
217 {
218 }
219 
220 /* ARGSUSED */
221 void
vfs_rlock_wait(vfs_t * vfsp)222 vfs_rlock_wait(vfs_t *vfsp)
223 {
224 }
225 
226 /* ARGSUSED */
227 void
vfs_unlock(vfs_t * vfsp)228 vfs_unlock(vfs_t *vfsp)
229 {
230 }
231 
232 
233 static u_longlong_t fs_caller_id;
234 u_longlong_t
fs_new_caller_id(void)235 fs_new_caller_id(void)
236 {
237 	return (++fs_caller_id);
238 }
239 
240 static sysid_t lm_sysid;
241 sysid_t
lm_alloc_sysidt(void)242 lm_alloc_sysidt(void)
243 {
244 	return (++lm_sysid);
245 }
246 
247 /* ARGSUSED */
248 void
lm_free_sysidt(sysid_t id)249 lm_free_sysidt(sysid_t id)
250 {
251 }
252