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 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 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 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 * 130 getvfs(fsid_t *fsid) 131 { 132 return (rootvfs); 133 } 134 135 vfsops_t * 136 vfs_getops(vfs_t *vfsp) 137 { 138 return (vfsp->vfs_op); 139 } 140 141 /* ARGSUSED */ 142 struct vfssw * 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 152 vfs_unrefvfssw(struct vfssw *vswp) 153 { 154 } 155 156 /* ARGSUSED */ 157 int 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 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 * 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 203 vfs_hold(vfs_t *vfsp) 204 { 205 } 206 207 /* ARGSUSED */ 208 void 209 vfs_rele(vfs_t *vfsp) 210 { 211 } 212 213 /* ARGSUSED */ 214 int 215 vfs_lock(vfs_t *vfsp) 216 { 217 return (0); 218 } 219 220 /* ARGSUSED */ 221 int 222 vfs_rlock(vfs_t *vfsp) 223 { 224 return (0); 225 } 226 227 /* ARGSUSED */ 228 void 229 vfs_lock_wait(vfs_t *vfsp) 230 { 231 } 232 233 /* ARGSUSED */ 234 void 235 vfs_rlock_wait(vfs_t *vfsp) 236 { 237 } 238 239 /* ARGSUSED */ 240 void 241 vfs_unlock(vfs_t *vfsp) 242 { 243 } 244 245 246 static u_longlong_t fs_caller_id; 247 u_longlong_t 248 fs_new_caller_id(void) 249 { 250 return (++fs_caller_id); 251 } 252 253 static sysid_t lm_sysid; 254 sysid_t 255 lm_alloc_sysidt(void) 256 { 257 return (++lm_sysid); 258 } 259 260 /* ARGSUSED */ 261 void 262 lm_free_sysidt(sysid_t id) 263 { 264 } 265