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
48static uint64_t vfs_features = VFSFT_XVATTR;
49
50vnode_t *rootdir = NULL;	/* pointer to root inode vnode. */
51
52static struct vfs fake_rootvfs;
53static struct vfsops fake_vfsops;
54struct vfs *rootvfs = NULL;
55static struct vfssw fake_vfssw = {
56	.vsw_name = "fake"	/* see smb_tree.c:smb_mtype[] */
57};
58
59int
60fksmbsrv_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 */
106int
107vfs_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 */
118struct vfs *
119getvfs(fsid_t *fsid)
120{
121	return (rootvfs);
122}
123
124vfsops_t *
125vfs_getops(vfs_t *vfsp)
126{
127	return (vfsp->vfs_op);
128}
129
130/* ARGSUSED */
131struct vfssw *
132vfs_getvfsswbyvfsops(vfsops_t *vfsops)
133{
134	if (vfsops == &fake_vfsops)
135		return (&fake_vfssw);
136	return (NULL);
137}
138
139/* ARGSUSED */
140void
141vfs_unrefvfssw(struct vfssw *vswp)
142{
143}
144
145/* ARGSUSED */
146int
147fsop_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 */
160int
161fsop_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
177refstr_t *
178vfs_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 */
189void
190vfs_hold(vfs_t *vfsp)
191{
192}
193
194/* ARGSUSED */
195void
196vfs_rele(vfs_t *vfsp)
197{
198}
199
200/* ARGSUSED */
201int
202vfs_lock(vfs_t *vfsp)
203{
204	return (0);
205}
206
207/* ARGSUSED */
208int
209vfs_rlock(vfs_t *vfsp)
210{
211	return (0);
212}
213
214/* ARGSUSED */
215void
216vfs_lock_wait(vfs_t *vfsp)
217{
218}
219
220/* ARGSUSED */
221void
222vfs_rlock_wait(vfs_t *vfsp)
223{
224}
225
226/* ARGSUSED */
227void
228vfs_unlock(vfs_t *vfsp)
229{
230}
231
232
233static u_longlong_t fs_caller_id;
234u_longlong_t
235fs_new_caller_id(void)
236{
237	return (++fs_caller_id);
238}
239
240static sysid_t lm_sysid;
241sysid_t
242lm_alloc_sysidt(void)
243{
244	return (++lm_sysid);
245}
246
247/* ARGSUSED */
248void
249lm_free_sysidt(sysid_t id)
250{
251}
252