Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/fs/dev/sdev_ipnetops.c
+++ new/usr/src/uts/common/fs/dev/sdev_ipnetops.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 /*
27 27 * vnode ops for the /dev/ipnet directory
28 28 * The lookup is based on the ipnetif nodes held
29 29 * in the ipnet module. We also override readdir
30 30 * in order to delete ipnet nodes no longer in use.
31 31 */
32 32
33 33 #include <sys/types.h>
34 34 #include <sys/param.h>
35 35 #include <sys/sysmacros.h>
36 36 #include <sys/sunndi.h>
37 37 #include <fs/fs_subr.h>
38 38 #include <sys/fs/dv_node.h>
39 39 #include <sys/fs/sdev_impl.h>
40 40 #include <sys/policy.h>
41 41 #include <inet/ipnet.h>
42 42 #include <sys/zone.h>
43 43
44 44 struct vnodeops *devipnet_vnodeops;
45 45
46 46 static void
47 47 devipnet_fill_vattr(struct vattr *vap, dev_t dev)
48 48 {
49 49 timestruc_t now;
50 50
51 51 *vap = sdev_vattr_chr;
52 52 vap->va_rdev = dev;
53 53 vap->va_mode |= 0666;
54 54
55 55 gethrestime(&now);
56 56 vap->va_atime = now;
57 57 vap->va_mtime = now;
58 58 vap->va_ctime = now;
59 59 }
60 60
61 61 /*
62 62 * Check if an ipnet sdev_node is still valid.
63 63 */
64 64 int
65 65 devipnet_validate(struct sdev_node *dv)
66 66 {
67 67 dev_t dev;
68 68
69 69 dev = ipnet_if_getdev(dv->sdev_name, getzoneid());
70 70 if (dev == (dev_t)-1)
71 71 return (SDEV_VTOR_INVALID);
72 72 if (getminor(SDEVTOV(dv)->v_rdev) != getminor(dev))
73 73 return (SDEV_VTOR_STALE);
74 74 return (SDEV_VTOR_VALID);
75 75 }
76 76
77 77 /*
78 78 * This callback is invoked from devname_lookup_func() to create
79 79 * an ipnet entry when the node is not found in the cache.
80 80 */
81 81 /*ARGSUSED*/
82 82 static int
83 83 devipnet_create_rvp(struct sdev_node *ddv, char *nm,
84 84 void **arg, cred_t *cred, void *whatever, char *whichever)
85 85 {
86 86 dev_t dev;
87 87 struct vattr *vap = (struct vattr *)arg;
88 88 int err = 0;
89 89
90 90 if ((dev = ipnet_if_getdev(nm, getzoneid())) == (dev_t)-1)
91 91 err = ENOENT;
92 92 else
93 93 devipnet_fill_vattr(vap, dev);
94 94
95 95 return (err);
96 96 }
97 97
98 98 /*
99 99 * Lookup for /dev/ipnet directory
100 100 * If the entry does not exist, the devipnet_create_rvp() callback
101 101 * is invoked to create it. Nodes do not persist across reboot.
102 102 */
103 103 /*ARGSUSED3*/
104 104 static int
105 105 devipnet_lookup(struct vnode *dvp, char *nm, struct vnode **vpp,
106 106 struct pathname *pnp, int flags, struct vnode *rdir, struct cred *cred,
107 107 caller_context_t *ct, int *direntflags, pathname_t *realpnp)
108 108 {
109 109 struct sdev_node *sdvp = VTOSDEV(dvp);
110 110 struct sdev_node *dv;
111 111 struct vnode *rvp = NULL;
112 112 int error;
113 113
114 114 error = devname_lookup_func(sdvp, nm, vpp, cred, devipnet_create_rvp,
115 115 SDEV_VATTR);
116 116
117 117 if (error == 0) {
118 118 switch ((*vpp)->v_type) {
119 119 case VCHR:
120 120 dv = VTOSDEV(VTOS(*vpp)->s_realvp);
121 121 ASSERT(VOP_REALVP(SDEVTOV(dv), &rvp, NULL) == ENOSYS);
122 122 break;
123 123 case VDIR:
124 124 dv = VTOSDEV(*vpp);
125 125 break;
126 126 default:
127 127 cmn_err(CE_PANIC, "devipnet_lookup: Unsupported node "
128 128 "type: %p: %d", (void *)(*vpp), (*vpp)->v_type);
129 129 break;
130 130 }
131 131 ASSERT(SDEV_HELD(dv));
132 132 }
133 133
134 134 return (error);
135 135 }
136 136
137 137 static void
138 138 devipnet_filldir_entry(const char *name, void *arg, dev_t dev)
139 139 {
140 140 struct sdev_node *ddv = arg;
141 141 struct vattr vattr;
142 142 struct sdev_node *dv;
143 143
144 144 ASSERT(RW_WRITE_HELD(&ddv->sdev_contents));
145 145
146 146 if ((dv = sdev_cache_lookup(ddv, (char *)name)) == NULL) {
147 147 devipnet_fill_vattr(&vattr, dev);
148 148 if (sdev_mknode(ddv, (char *)name, &dv, &vattr, NULL, NULL,
149 149 kcred, SDEV_READY) != 0)
150 150 return;
151 151 }
152 152 SDEV_SIMPLE_RELE(dv);
153 153 }
154 154
155 155 static void
156 156 devipnet_filldir(struct sdev_node *ddv)
157 157 {
158 158 sdev_node_t *dv, *next;
159 159
160 160 ASSERT(RW_READ_HELD(&ddv->sdev_contents));
161 161 if (rw_tryupgrade(&ddv->sdev_contents) == NULL) {
162 162 rw_exit(&ddv->sdev_contents);
163 163 rw_enter(&ddv->sdev_contents, RW_WRITER);
164 164 /*
165 165 * We've been made a zombie while we weren't looking. We'll bail
166 166 * if that's the case.
167 167 */
168 168 if (ddv->sdev_state == SDEV_ZOMBIE) {
169 169 rw_exit(&ddv->sdev_contents);
170 170 return;
171 171 }
172 172 }
173 173
174 174 for (dv = SDEV_FIRST_ENTRY(ddv); dv; dv = next) {
175 175 next = SDEV_NEXT_ENTRY(ddv, dv);
176 176
177 177 /* validate and prune only ready nodes */
178 178 if (dv->sdev_state != SDEV_READY)
179 179 continue;
180 180 switch (devipnet_validate(dv)) {
181 181 case SDEV_VTOR_VALID:
182 182 case SDEV_VTOR_SKIP:
183 183 continue;
184 184 case SDEV_VTOR_INVALID:
185 185 case SDEV_VTOR_STALE:
186 186 sdcmn_err12(("devipnet_filldir: destroy invalid "
187 187 "node: %s(%p)\n", dv->sdev_name, (void *)dv));
188 188 break;
189 189 }
190 190
191 191 if (SDEVTOV(dv)->v_count > 0)
192 192 continue;
193 193 SDEV_HOLD(dv);
194 194 /* remove the cache node */
195 195 (void) sdev_cache_update(ddv, &dv, dv->sdev_name,
196 196 SDEV_CACHE_DELETE);
197 197 SDEV_RELE(dv);
198 198 }
199 199
200 200 ipnet_walk_if(devipnet_filldir_entry, ddv, getzoneid());
201 201
202 202 rw_downgrade(&ddv->sdev_contents);
203 203 }
204 204
205 205 /*
206 206 * Display all instantiated ipnet device nodes.
207 207 */
208 208 /* ARGSUSED */
209 209 static int
210 210 devipnet_readdir(struct vnode *dvp, struct uio *uiop, struct cred *cred,
211 211 int *eofp, caller_context_t *ct, int flags)
212 212 {
213 213 struct sdev_node *sdvp = VTOSDEV(dvp);
214 214
215 215 if (uiop->uio_offset == 0)
↓ open down ↓ |
215 lines elided |
↑ open up ↑ |
216 216 devipnet_filldir(sdvp);
217 217
218 218 return (devname_readdir_func(dvp, uiop, cred, eofp, 0));
219 219 }
220 220
221 221 /*
222 222 * We override lookup and readdir to build entries based on the
223 223 * in kernel ipnet table.
224 224 */
225 225 const fs_operation_def_t devipnet_vnodeops_tbl[] = {
226 - VOPNAME_READDIR, { .vop_readdir = devipnet_readdir },
227 - VOPNAME_LOOKUP, { .vop_lookup = devipnet_lookup },
228 - VOPNAME_CREATE, { .error = fs_nosys },
229 - VOPNAME_REMOVE, { .error = fs_nosys },
230 - VOPNAME_MKDIR, { .error = fs_nosys },
231 - VOPNAME_RMDIR, { .error = fs_nosys },
232 - VOPNAME_SYMLINK, { .error = fs_nosys },
233 - VOPNAME_SETSECATTR, { .error = fs_nosys },
234 - NULL, NULL
226 + { VOPNAME_READDIR, { .vop_readdir = devipnet_readdir } },
227 + { VOPNAME_LOOKUP, { .vop_lookup = devipnet_lookup } },
228 + { VOPNAME_CREATE, { .error = fs_nosys } },
229 + { VOPNAME_REMOVE, { .error = fs_nosys } },
230 + { VOPNAME_MKDIR, { .error = fs_nosys } },
231 + { VOPNAME_RMDIR, { .error = fs_nosys } },
232 + { VOPNAME_SYMLINK, { .error = fs_nosys } },
233 + { VOPNAME_SETSECATTR, { .error = fs_nosys } },
234 + { NULL, { NULL } }
235 235 };
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX