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