Print this page
5045 use atomic_{inc,dec}_* instead of atomic_add_*
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/fs/sharefs/sharefs_vnops.c
+++ new/usr/src/uts/common/fs/sharefs/sharefs_vnops.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
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 -#pragma ident "%Z%%M% %I% %E% SMI"
28 -
29 27 #include <fs/fs_subr.h>
30 28
31 29 #include <sys/errno.h>
32 30 #include <sys/file.h>
33 31 #include <sys/kmem.h>
34 32 #include <sys/kobj.h>
35 33 #include <sys/cmn_err.h>
36 34 #include <sys/stat.h>
37 35 #include <sys/systm.h>
38 36 #include <sys/sysmacros.h>
39 37 #include <sys/atomic.h>
40 38 #include <sys/vfs.h>
41 39 #include <sys/vfs_opreg.h>
42 40
43 41 #include <sharefs/sharefs.h>
44 42
45 43 /*
46 44 * sharefs_snap_create: create a large character buffer with
47 45 * the shares enumerated.
48 46 */
49 47 static int
50 48 sharefs_snap_create(shnode_t *sft)
51 49 {
52 50 sharetab_t *sht;
53 51 share_t *sh;
54 52 size_t sWritten = 0;
55 53 int iCount = 0;
56 54 char *buf;
57 55
58 56 rw_enter(&sharefs_lock, RW_WRITER);
59 57 rw_enter(&sharetab_lock, RW_READER);
60 58
61 59 if (sft->sharefs_snap) {
62 60 /*
63 61 * Nothing has changed, so no need to grab a new copy!
64 62 */
65 63 if (sft->sharefs_generation == sharetab_generation) {
66 64 rw_exit(&sharetab_lock);
67 65 rw_exit(&sharefs_lock);
68 66 return (0);
69 67 }
70 68
71 69 ASSERT(sft->sharefs_size != 0);
72 70 kmem_free(sft->sharefs_snap, sft->sharefs_size + 1);
73 71 sft->sharefs_snap = NULL;
74 72 }
75 73
76 74 sft->sharefs_size = sharetab_size;
77 75 sft->sharefs_count = sharetab_count;
78 76
79 77 if (sft->sharefs_size == 0) {
80 78 rw_exit(&sharetab_lock);
81 79 rw_exit(&sharefs_lock);
82 80 return (0);
83 81 }
84 82
85 83 sft->sharefs_snap = kmem_zalloc(sft->sharefs_size + 1, KM_SLEEP);
86 84
87 85 buf = sft->sharefs_snap;
88 86
89 87 /*
90 88 * Walk the Sharetab, dumping each entry.
91 89 */
92 90 for (sht = sharefs_sharetab; sht != NULL; sht = sht->s_next) {
93 91 int i;
94 92
95 93 for (i = 0; i < SHARETAB_HASHES; i++) {
96 94 for (sh = sht->s_buckets[i].ssh_sh;
97 95 sh != NULL;
98 96 sh = sh->sh_next) {
99 97 int n;
100 98
101 99 if ((sWritten + sh->sh_size) >
102 100 sft->sharefs_size) {
103 101 goto error_fault;
104 102 }
105 103
106 104 /*
107 105 * Note that sh->sh_size accounts
108 106 * for the field seperators.
109 107 * We need to add one for the EOL
110 108 * marker. And we should note that
111 109 * the space is accounted for in
112 110 * each share by the EOS marker.
113 111 */
114 112 n = snprintf(&buf[sWritten],
115 113 sh->sh_size + 1,
116 114 "%s\t%s\t%s\t%s\t%s\n",
117 115 sh->sh_path,
118 116 sh->sh_res,
119 117 sh->sh_fstype,
120 118 sh->sh_opts,
121 119 sh->sh_descr);
122 120
123 121 if (n != sh->sh_size) {
124 122 goto error_fault;
125 123 }
126 124
127 125 sWritten += n;
128 126 iCount++;
129 127 }
130 128 }
131 129 }
132 130
133 131 /*
134 132 * We want to record the generation number and
135 133 * mtime inside this snapshot.
136 134 */
137 135 gethrestime(&sharetab_snap_time);
138 136 sft->sharefs_snap_time = sharetab_snap_time;
139 137 sft->sharefs_generation = sharetab_generation;
140 138
141 139 ASSERT(iCount == sft->sharefs_count);
142 140
143 141 rw_exit(&sharetab_lock);
144 142 rw_exit(&sharefs_lock);
145 143 return (0);
146 144
147 145 error_fault:
148 146
149 147 kmem_free(sft->sharefs_snap, sft->sharefs_size + 1);
150 148 sft->sharefs_size = 0;
151 149 sft->sharefs_count = 0;
152 150 sft->sharefs_snap = NULL;
153 151 rw_exit(&sharetab_lock);
154 152 rw_exit(&sharefs_lock);
155 153
156 154 return (EFAULT);
157 155 }
158 156
159 157 /* ARGSUSED */
160 158 static int
161 159 sharefs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
162 160 caller_context_t *ct)
163 161 {
164 162 timestruc_t now;
165 163 shnode_t *sft = VTOSH(vp);
166 164
167 165 vap->va_type = VREG;
168 166 vap->va_mode = S_IRUSR | S_IRGRP | S_IROTH;
169 167 vap->va_nodeid = SHAREFS_INO_FILE;
170 168 vap->va_nlink = 1;
171 169
172 170 rw_enter(&sharefs_lock, RW_READER);
173 171
174 172 /*
175 173 * If we get asked about a snapped vnode, then
176 174 * we must report the data in that vnode.
177 175 *
178 176 * Else we report what is currently in the
179 177 * sharetab.
180 178 */
181 179 if (sft->sharefs_real_vp) {
182 180 rw_enter(&sharetab_lock, RW_READER);
183 181 vap->va_size = sharetab_size;
184 182 vap->va_mtime = sharetab_mtime;
185 183 rw_exit(&sharetab_lock);
186 184 } else {
187 185 vap->va_size = sft->sharefs_size;
188 186 vap->va_mtime = sft->sharefs_snap_time;
189 187 }
190 188 rw_exit(&sharefs_lock);
191 189
192 190 gethrestime(&now);
193 191 vap->va_atime = vap->va_ctime = now;
194 192
195 193 vap->va_uid = 0;
196 194 vap->va_gid = 0;
197 195 vap->va_rdev = 0;
198 196 vap->va_blksize = DEV_BSIZE;
199 197 vap->va_nblocks = howmany(vap->va_size, vap->va_blksize);
200 198 vap->va_seq = 0;
201 199 vap->va_fsid = vp->v_vfsp->vfs_dev;
202 200
203 201 return (0);
204 202 }
205 203
206 204 /* ARGSUSED */
207 205 static int
208 206 sharefs_access(vnode_t *vp, int mode, int flags, cred_t *cr,
209 207 caller_context_t *ct)
210 208 {
211 209 if (mode & (VWRITE|VEXEC))
212 210 return (EROFS);
213 211
214 212 return (0);
215 213 }
216 214
217 215 /* ARGSUSED */
218 216 int
219 217 sharefs_open(vnode_t **vpp, int flag, cred_t *cr, caller_context_t *ct)
220 218 {
221 219 vnode_t *vp;
222 220 vnode_t *ovp = *vpp;
223 221 shnode_t *sft;
224 222 int error = 0;
225 223
226 224 if (flag & FWRITE)
227 225 return (EINVAL);
228 226
229 227 /*
230 228 * Create a new sharefs vnode for each operation. In order to
231 229 * avoid locks, we create a snapshot which can not change during
232 230 * reads.
233 231 */
234 232 vp = gfs_file_create(sizeof (shnode_t), NULL, sharefs_ops_data);
235 233
236 234 ((gfs_file_t *)vp->v_data)->gfs_ino = SHAREFS_INO_FILE;
237 235
238 236 /*
239 237 * Hold the parent!
240 238 */
241 239 VFS_HOLD(ovp->v_vfsp);
242 240
243 241 VN_SET_VFS_TYPE_DEV(vp, ovp->v_vfsp, VREG, 0);
244 242
245 243 vp->v_flag |= VROOT | VNOCACHE | VNOMAP | VNOSWAP | VNOMOUNT;
↓ open down ↓ |
207 lines elided |
↑ open up ↑ |
246 244
247 245 *vpp = vp;
248 246 VN_RELE(ovp);
249 247
250 248 sft = VTOSH(vp);
251 249
252 250 /*
253 251 * No need for the lock, no other thread can be accessing
254 252 * this data structure.
255 253 */
256 - atomic_add_32(&sft->sharefs_refs, 1);
254 + atomic_inc_32(&sft->sharefs_refs);
257 255 sft->sharefs_real_vp = 0;
258 256
259 257 /*
260 258 * Since the sharetab could easily change on us whilst we
261 259 * are dumping an extremely huge sharetab, we make a copy
262 260 * of it here and use it to dump instead.
263 261 */
264 262 error = sharefs_snap_create(sft);
265 263
266 264 return (error);
267 265 }
268 266
269 267 /* ARGSUSED */
270 268 int
271 269 sharefs_close(vnode_t *vp, int flag, int count,
272 270 offset_t off, cred_t *cr, caller_context_t *ct)
273 271 {
274 272 shnode_t *sft = VTOSH(vp);
275 273
276 274 if (count > 1)
277 275 return (0);
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
278 276
279 277 rw_enter(&sharefs_lock, RW_WRITER);
280 278 if (vp->v_count == 1) {
281 279 if (sft->sharefs_snap != NULL) {
282 280 kmem_free(sft->sharefs_snap, sft->sharefs_size + 1);
283 281 sft->sharefs_size = 0;
284 282 sft->sharefs_snap = NULL;
285 283 sft->sharefs_generation = 0;
286 284 }
287 285 }
288 - atomic_add_32(&sft->sharefs_refs, -1);
286 + atomic_dec_32(&sft->sharefs_refs);
289 287 rw_exit(&sharefs_lock);
290 288
291 289 return (0);
292 290 }
293 291
294 292 /* ARGSUSED */
295 293 static int
296 294 sharefs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr,
297 295 caller_context_t *ct)
298 296 {
299 297 shnode_t *sft = VTOSH(vp);
300 298 off_t off = uio->uio_offset;
301 299 size_t len = uio->uio_resid;
302 300 int error = 0;
303 301
304 302 rw_enter(&sharefs_lock, RW_READER);
305 303
306 304 /*
307 305 * First check to see if we need to grab a new snapshot.
308 306 */
309 307 if (off == (off_t)0) {
310 308 rw_exit(&sharefs_lock);
311 309 error = sharefs_snap_create(sft);
312 310 if (error) {
313 311 return (EFAULT);
314 312 }
315 313 rw_enter(&sharefs_lock, RW_READER);
316 314 }
317 315
318 316 /* LINTED */
319 317 if (len <= 0 || off >= sft->sharefs_size) {
320 318 rw_exit(&sharefs_lock);
321 319 return (error);
322 320 }
323 321
324 322 if ((size_t)(off + len) > sft->sharefs_size)
325 323 len = sft->sharefs_size - off;
326 324
327 325 if (off < 0 || len > sft->sharefs_size) {
328 326 rw_exit(&sharefs_lock);
329 327 return (EFAULT);
330 328 }
331 329
332 330 if (len != 0) {
333 331 error = uiomove(sft->sharefs_snap + off,
334 332 len, UIO_READ, uio);
335 333 }
336 334
337 335 rw_exit(&sharefs_lock);
338 336 return (error);
339 337 }
340 338
341 339 /* ARGSUSED */
342 340 static void
343 341 sharefs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *tx)
344 342 {
345 343 gfs_file_t *fp = vp->v_data;
346 344 shnode_t *sft;
347 345
348 346 sft = (shnode_t *)gfs_file_inactive(vp);
349 347 if (sft) {
350 348 rw_enter(&sharefs_lock, RW_WRITER);
351 349 if (sft->sharefs_snap != NULL) {
352 350 kmem_free(sft->sharefs_snap, sft->sharefs_size + 1);
353 351 }
354 352
355 353 kmem_free(sft, fp->gfs_size);
356 354 rw_exit(&sharefs_lock);
357 355 }
358 356 }
359 357
360 358 vnode_t *
361 359 sharefs_create_root_file(vfs_t *vfsp)
362 360 {
363 361 vnode_t *vp;
364 362 shnode_t *sft;
365 363
366 364 vp = gfs_root_create_file(sizeof (shnode_t),
367 365 vfsp, sharefs_ops_data, SHAREFS_INO_FILE);
368 366
369 367 sft = VTOSH(vp);
370 368
371 369 sft->sharefs_real_vp = 1;
372 370
373 371 return (vp);
374 372 }
375 373
376 374 const fs_operation_def_t sharefs_tops_data[] = {
377 375 { VOPNAME_OPEN, { .vop_open = sharefs_open } },
378 376 { VOPNAME_CLOSE, { .vop_close = sharefs_close } },
379 377 { VOPNAME_IOCTL, { .error = fs_inval } },
380 378 { VOPNAME_GETATTR, { .vop_getattr = sharefs_getattr } },
381 379 { VOPNAME_ACCESS, { .vop_access = sharefs_access } },
382 380 { VOPNAME_INACTIVE, { .vop_inactive = sharefs_inactive } },
383 381 { VOPNAME_READ, { .vop_read = sharefs_read } },
384 382 { VOPNAME_SEEK, { .vop_seek = fs_seek } },
385 383 { NULL }
386 384 };
↓ open down ↓ |
88 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX