4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
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.
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]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <sys/fs_subr.h>
31 #include <sys/errno.h>
33 #include <sys/modctl.h>
34 #include <sys/objfs.h>
35 #include <sys/objfs_impl.h>
37 #include <sys/systm.h>
39 extern int last_module_id
;
41 static const struct vnodeops objfs_ops_root
;
43 static int objfs_root_do_lookup(vnode_t
*, const char *, vnode_t
**, ino64_t
*,
44 cred_t
*, int, int *, pathname_t
*);
45 static int objfs_root_do_readdir(vnode_t
*, void *, int *,
46 offset_t
*, offset_t
*, void *, int);
49 objfs_create_root(vfs_t
*vfsp
)
51 vnode_t
*vp
= gfs_root_create(sizeof (objfs_rootnode_t
), vfsp
,
52 &objfs_ops_root
, OBJFS_INO_ROOT
, NULL
, NULL
, OBJFS_NAME_MAX
,
53 objfs_root_do_readdir
, objfs_root_do_lookup
);
60 objfs_root_getattr(vnode_t
*vp
, vattr_t
*vap
, int flags
, cred_t
*cr
,
65 vap
->va_nodeid
= gfs_file_inode(vp
);
66 vap
->va_nlink
= objfs_nobjs() + 2;
67 vap
->va_size
= vap
->va_nlink
;
68 vap
->va_atime
.tv_sec
= vp
->v_vfsp
->vfs_mtime
;
69 vap
->va_atime
.tv_nsec
= 0;
70 vap
->va_mtime
= vap
->va_ctime
= vap
->va_atime
;
71 return (objfs_common_getattr(vp
, vap
));
76 objfs_root_do_lookup(vnode_t
*vp
, const char *nm
, vnode_t
**vpp
, ino64_t
*inop
,
77 cred_t
*cr
, int flags
, int *deflags
, pathname_t
*rpnp
)
83 * Run through all the loaded modules on the system looking for
84 * a matching module name.
86 mutex_enter(&mod_lock
);
90 strcmp(nm
, mp
->mod_modname
) == 0) {
92 * We drop mod_lock in order to do allocations,
93 * as modctls are persistent.
95 mutex_exit(&mod_lock
);
96 *vpp
= objfs_create_odirnode(vp
, mp
);
97 *inop
= OBJFS_INO_ODIR(mp
->mod_id
);
98 mutex_enter(&mod_lock
);
102 } while ((mp
= mp
->mod_next
) != &modules
);
103 mutex_exit(&mod_lock
);
110 objfs_root_do_readdir(vnode_t
*vp
, void *dp
, int *eofp
,
111 offset_t
*offp
, offset_t
*nextp
, void *data
, int flags
)
113 struct modctl
**mpp
= data
;
114 struct modctl
*mp
= *mpp
;
115 struct dirent64
*odp
= dp
;
117 ASSERT(!(flags
& V_RDDIR_ENTFLAGS
));
119 mutex_enter(&mod_lock
);
122 if (*offp
>= last_module_id
) {
124 mutex_exit(&mod_lock
);
129 * Find the appropriate modctl
131 while (mp
->mod_id
< *offp
) {
133 ASSERT(mp
!= &modules
);
136 while (!mp
->mod_loaded
&& mp
!= &modules
)
139 if (mp
== &modules
&& *offp
!= 0) {
141 mutex_exit(&mod_lock
);
146 * The modctl will not change, as they are persistent.
148 mutex_exit(&mod_lock
);
150 (void) strncpy(odp
->d_name
, mp
->mod_modname
, OBJFS_NAME_MAX
);
151 odp
->d_ino
= OBJFS_INO_ODIR(mp
->mod_id
);
153 *nextp
= mp
->mod_id
+ 1;
160 objfs_root_readdir(vnode_t
*vp
, uio_t
*uiop
, cred_t
*cr
, int *eofp
,
161 caller_context_t
*ct
, int flags
)
163 struct modctl
*mp
= &modules
;
165 return (gfs_dir_readdir(vp
, uiop
, eofp
, &mp
, cr
, ct
, flags
));
168 static const struct vnodeops objfs_ops_root
= {
169 .vnop_name
= "objfs root directory",
170 .vop_open
= objfs_dir_open
,
171 .vop_close
= objfs_common_close
,
172 .vop_ioctl
= fs_inval
,
173 .vop_getattr
= objfs_root_getattr
,
174 .vop_access
= objfs_dir_access
,
175 .vop_readdir
= objfs_root_readdir
,
176 .vop_lookup
= gfs_vop_lookup
,
178 .vop_inactive
= gfs_vop_inactive
,