Print this page
NEX-15069 smtorture smb2.create.blob is failed
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15069 smtorture smb2.create.blob is failed
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-6276 SMB sparse file support
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5844 want SMB2 ioctl FSCTL_SRV_COPYCHUNK
NEX-6124 smb_fsop_read/write should allow file != sr->fid_ofile
NEX-6125 smbtorture invalid response with smb2.ioctl
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-6041 Should pass the smbtorture lock tests
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-5312 delete_on_close should be acted on earlier
Reviewed by: Gordon Ross <gwr@nexenta.com>
NEX-4239 smbtorture create failures re. allocation size
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-4083 Upstream changes from illumos 5917 and 5995
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-2831 panic in smb_make_link
NEX-2442 regression with smbtorture test raw.sfileinfo.rename
SMB-122 smbd core dumps in smbd_dc_update / smb_log
SMB-117 Win7 fails to open security properties
SMB-11 SMB2 message parse & dispatch
SMB-12 SMB2 Negotiate Protocol
SMB-13 SMB2 Session Setup
SMB-14 SMB2 Logoff
SMB-15 SMB2 Tree Connect
SMB-16 SMB2 Tree Disconnect
SMB-17 SMB2 Create
SMB-18 SMB2 Close
SMB-19 SMB2 Flush
SMB-20 SMB2 Read
SMB-21 SMB2 Write
SMB-22 SMB2 Lock/Unlock
SMB-23 SMB2 Ioctl
SMB-24 SMB2 Cancel
SMB-25 SMB2 Echo
SMB-26 SMB2 Query Dir
SMB-27 SMB2 Change Notify
SMB-28 SMB2 Query Info
SMB-29 SMB2 Set Info
SMB-30 SMB2 Oplocks
SMB-53 SMB2 Create Context options
(SMB2 code review cleanup 1, 2, 3)
SMB-50 User-mode SMB server
Includes work by these authors:
Thomas Keiser <thomas.keiser@nexenta.com>
Albert Lee <trisk@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/smbsrv/libfksmbsrv/common/fake_vop.c
+++ new/usr/src/lib/smbsrv/libfksmbsrv/common/fake_vop.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
|
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 /*
13 - * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
13 + * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
14 14 */
15 15
16 16 #include <sys/types.h>
17 17 #include <sys/param.h>
18 +#include <sys/systm.h>
18 19 #include <sys/t_lock.h>
19 20 #include <sys/errno.h>
20 21 #include <sys/cred.h>
21 22 #include <sys/user.h>
22 23 #include <sys/uio.h>
23 24 #include <sys/file.h>
24 25 #include <sys/pathname.h>
25 26 #include <sys/vfs.h>
26 27 #include <sys/vnode.h>
27 28 #include <sys/stat.h>
28 29 #include <sys/mode.h>
29 30 #include <sys/kmem.h>
31 +#include <sys/cmn_err.h>
30 32 #include <sys/debug.h>
31 33 #include <sys/atomic.h>
32 34 #include <sys/acl.h>
35 +#include <sys/filio.h>
33 36 #include <sys/flock.h>
34 37 #include <sys/nbmlock.h>
35 38 #include <sys/fcntl.h>
36 39 #include <sys/poll.h>
37 40 #include <sys/time.h>
38 41
39 42 #include <errno.h>
40 43 #include <fcntl.h>
41 44 #include <unistd.h>
42 45
43 46 #include "vncache.h"
44 47
45 48 #define O_RWMASK (O_WRONLY | O_RDWR) /* == 3 */
46 49
47 50 int fop_shrlock_enable = 0;
48 51
49 52 int stat_to_vattr(const struct stat *, vattr_t *);
50 53 int fop__getxvattr(vnode_t *, xvattr_t *);
51 54 int fop__setxvattr(vnode_t *, xvattr_t *);
52 55
56 +static void fake_inactive_xattrdir(vnode_t *);
53 57
54 58 /* ARGSUSED */
55 59 int
56 60 fop_open(
57 61 vnode_t **vpp,
58 62 int mode,
59 63 cred_t *cr,
60 64 caller_context_t *ct)
61 65 {
62 66
63 67 if ((*vpp)->v_type == VREG) {
64 68 if (mode & FREAD)
65 69 atomic_add_32(&((*vpp)->v_rdcnt), 1);
66 70 if (mode & FWRITE)
67 71 atomic_add_32(&((*vpp)->v_wrcnt), 1);
68 72 }
69 73
70 74 /* call to ->vop_open was here */
71 75
72 76 return (0);
73 77 }
74 78
75 79 /* ARGSUSED */
76 80 int
77 81 fop_close(
78 82 vnode_t *vp,
79 83 int flag,
80 84 int count,
81 85 offset_t offset,
82 86 cred_t *cr,
83 87 caller_context_t *ct)
84 88 {
85 89
86 90 /* call to ->vop_close was here */
87 91
88 92 /*
89 93 * Check passed in count to handle possible dups. Vnode counts are only
90 94 * kept on regular files
91 95 */
92 96 if ((vp->v_type == VREG) && (count == 1)) {
93 97 if (flag & FREAD) {
94 98 ASSERT(vp->v_rdcnt > 0);
95 99 atomic_add_32(&(vp->v_rdcnt), -1);
96 100 }
97 101 if (flag & FWRITE) {
98 102 ASSERT(vp->v_wrcnt > 0);
99 103 atomic_add_32(&(vp->v_wrcnt), -1);
100 104 }
101 105 }
102 106 return (0);
103 107 }
104 108
105 109 /* ARGSUSED */
106 110 int
107 111 fop_read(
108 112 vnode_t *vp,
109 113 uio_t *uio,
110 114 int ioflag,
111 115 cred_t *cr,
112 116 caller_context_t *ct)
113 117 {
114 118 struct stat st;
115 119 struct iovec *iov;
116 120 ssize_t resid;
117 121 size_t cnt;
118 122 int n;
119 123
120 124 /*
121 125 * If that caller asks for read beyond end of file,
122 126 * that causes the pread call to block. (Ugh!)
123 127 * Get the file size and return what we can.
124 128 */
125 129 (void) fstat(vp->v_fd, &st);
126 130 resid = uio->uio_resid;
127 131 if ((uio->uio_loffset + resid) > st.st_size)
128 132 resid = st.st_size - uio->uio_loffset;
129 133
130 134 while (resid > 0) {
131 135
132 136 ASSERT(uio->uio_iovcnt > 0);
133 137 iov = uio->uio_iov;
134 138
135 139 if (iov->iov_len == 0) {
136 140 uio->uio_iov++;
137 141 uio->uio_iovcnt--;
138 142 continue;
139 143 }
140 144 cnt = iov->iov_len;
141 145 if (cnt > resid)
142 146 cnt = resid;
143 147
144 148 n = pread(vp->v_fd, iov->iov_base, cnt, uio->uio_loffset);
145 149 if (n < 0)
146 150 return (errno);
147 151
148 152 iov->iov_base += n;
149 153 iov->iov_len -= n;
150 154
151 155 uio->uio_resid -= n;
152 156 uio->uio_loffset += n;
153 157
154 158 resid -= n;
155 159 }
156 160
157 161 return (0);
158 162 }
159 163
160 164 /* ARGSUSED */
161 165 int
162 166 fop_write(
163 167 vnode_t *vp,
164 168 uio_t *uio,
165 169 int ioflag,
166 170 cred_t *cr,
167 171 caller_context_t *ct)
168 172 {
169 173 struct iovec *iov;
170 174 size_t cnt;
171 175 int n;
172 176
173 177 while (uio->uio_resid > 0) {
174 178
175 179 ASSERT(uio->uio_iovcnt > 0);
176 180 iov = uio->uio_iov;
177 181
178 182 if (iov->iov_len == 0) {
179 183 uio->uio_iov++;
180 184 uio->uio_iovcnt--;
181 185 continue;
182 186 }
183 187 cnt = iov->iov_len;
184 188 if (cnt > uio->uio_resid)
185 189 cnt = uio->uio_resid;
186 190
187 191 n = pwrite(vp->v_fd, iov->iov_base, iov->iov_len,
188 192 uio->uio_loffset);
189 193 if (n < 0)
190 194 return (errno);
191 195
192 196 iov->iov_base += n;
193 197 iov->iov_len -= n;
194 198
195 199 uio->uio_resid -= n;
196 200 uio->uio_loffset += n;
197 201 }
198 202
199 203 if (ioflag == FSYNC) {
200 204 (void) fsync(vp->v_fd);
201 205 }
202 206
203 207 return (0);
204 208 }
205 209
206 210 /* ARGSUSED */
|
↓ open down ↓ |
144 lines elided |
↑ open up ↑ |
207 211 int
208 212 fop_ioctl(
209 213 vnode_t *vp,
210 214 int cmd,
211 215 intptr_t arg,
212 216 int flag,
213 217 cred_t *cr,
214 218 int *rvalp,
215 219 caller_context_t *ct)
216 220 {
217 - return (ENOSYS);
221 + off64_t off;
222 + int rv, whence;
223 +
224 + switch (cmd) {
225 + case _FIO_SEEK_DATA:
226 + case _FIO_SEEK_HOLE:
227 + whence = (cmd == _FIO_SEEK_DATA) ? SEEK_DATA : SEEK_HOLE;
228 + bcopy((void *)arg, &off, sizeof (off));
229 + off = lseek(vp->v_fd, off, whence);
230 + if (off == (off64_t)-1) {
231 + rv = errno;
232 + } else {
233 + bcopy(&off, (void *)arg, sizeof (off));
234 + rv = 0;
235 + }
236 + break;
237 +
238 + default:
239 + rv = ENOTTY;
240 + break;
241 + }
242 +
243 + return (rv);
218 244 }
219 245
220 246 /* ARGSUSED */
221 247 int
222 248 fop_setfl(
223 249 vnode_t *vp,
224 250 int oflags,
225 251 int nflags,
226 252 cred_t *cr,
227 253 caller_context_t *ct)
228 254 {
229 255 /* allow any flags? See fs_setfl */
230 256 return (0);
231 257 }
232 258
233 259 /* ARGSUSED */
234 260 int
235 261 fop_getattr(
236 262 vnode_t *vp,
237 263 vattr_t *vap,
238 264 int flags,
239 265 cred_t *cr,
240 266 caller_context_t *ct)
241 267 {
242 268 int error;
243 269 struct stat st;
244 270
245 271 if (fstat(vp->v_fd, &st) == -1)
246 272 return (errno);
247 273 error = stat_to_vattr(&st, vap);
248 274
249 275 if (vap->va_mask & AT_XVATTR)
250 276 (void) fop__getxvattr(vp, (xvattr_t *)vap);
251 277
252 278 return (error);
253 279 }
254 280
|
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
255 281 /* ARGSUSED */
256 282 int
257 283 fop_setattr(
258 284 vnode_t *vp,
259 285 vattr_t *vap,
260 286 int flags,
261 287 cred_t *cr,
262 288 caller_context_t *ct)
263 289 {
264 290 timespec_t times[2];
291 + int err;
265 292
266 293 if (vap->va_mask & AT_SIZE) {
267 - if (ftruncate(vp->v_fd, vap->va_size) == -1)
268 - return (errno);
294 + if (ftruncate(vp->v_fd, vap->va_size) == -1) {
295 + err = errno;
296 + if (err == EBADF)
297 + err = EACCES;
298 + return (err);
299 + }
269 300 }
270 301
271 302 /* AT_MODE or anything else? */
272 303
273 304 if (vap->va_mask & AT_XVATTR)
274 305 (void) fop__setxvattr(vp, (xvattr_t *)vap);
275 306
276 307 if (vap->va_mask & (AT_ATIME | AT_MTIME)) {
277 308 if (vap->va_mask & AT_ATIME) {
278 309 times[0] = vap->va_atime;
279 310 } else {
280 311 times[0].tv_sec = 0;
281 312 times[0].tv_nsec = UTIME_OMIT;
282 313 }
283 314 if (vap->va_mask & AT_MTIME) {
284 315 times[1] = vap->va_mtime;
285 316 } else {
286 317 times[1].tv_sec = 0;
287 318 times[1].tv_nsec = UTIME_OMIT;
288 319 }
289 320
290 321 (void) futimens(vp->v_fd, times);
291 322 }
292 323
293 324 return (0);
294 325 }
295 326
296 327 /* ARGSUSED */
297 328 int
|
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
298 329 fop_access(
299 330 vnode_t *vp,
300 331 int mode,
301 332 int flags,
302 333 cred_t *cr,
303 334 caller_context_t *ct)
304 335 {
305 336 return (0);
306 337 }
307 338
339 +/*
340 + * Conceptually like xattr_dir_lookup()
341 + */
342 +static int
343 +fake_lookup_xattrdir(
344 + vnode_t *dvp,
345 + vnode_t **vpp)
346 +{
347 + int len, fd;
348 + int omode = O_RDWR | O_NOFOLLOW;
349 + vnode_t *vp;
350 +
351 + *vpp = NULL;
352 +
353 + if (dvp->v_type != VDIR && dvp->v_type != VREG)
354 + return (EINVAL);
355 +
356 + /*
357 + * If we're already in sysattr space, don't allow creation
358 + * of another level of sysattrs.
359 + */
360 + if (dvp->v_flag & V_SYSATTR)
361 + return (EINVAL);
362 +
363 + mutex_enter(&dvp->v_lock);
364 + if (dvp->v_xattrdir != NULL) {
365 + *vpp = dvp->v_xattrdir;
366 + VN_HOLD(*vpp);
367 + mutex_exit(&dvp->v_lock);
368 + return (0);
369 + }
370 + mutex_exit(&dvp->v_lock);
371 +
372 + omode = O_RDONLY|O_XATTR;
373 + fd = openat(dvp->v_fd, ".", omode);
374 + if (fd < 0)
375 + return (errno);
376 +
377 + vp = vn_alloc(KM_SLEEP);
378 + vp->v_fd = fd;
379 + vp->v_flag = V_XATTRDIR|V_SYSATTR;
380 + vp->v_type = VDIR;
381 + vp->v_vfsp = dvp->v_vfsp;
382 +
383 + /* Set v_path to parent path + "/@" (like NFS) */
384 + len = strlen(dvp->v_path) + 3;
385 + vp->v_path = kmem_alloc(len, KM_SLEEP);
386 + (void) snprintf(vp->v_path, len, "%s/@", dvp->v_path);
387 +
388 + /*
389 + * Keep a pointer to the parent and a hold on it.
390 + * Both are cleaned up in fake_inactive_xattrdir
391 + */
392 + vp->v_data = dvp;
393 + vn_hold(dvp);
394 +
395 + mutex_enter(&dvp->v_lock);
396 + if (dvp->v_xattrdir == NULL) {
397 + *vpp = dvp->v_xattrdir = vp;
398 + mutex_exit(&dvp->v_lock);
399 + } else {
400 + *vpp = dvp->v_xattrdir;
401 + mutex_exit(&dvp->v_lock);
402 + fake_inactive_xattrdir(vp);
403 + }
404 +
405 + return (0);
406 +}
407 +
308 408 /* ARGSUSED */
309 409 int
310 410 fop_lookup(
311 411 vnode_t *dvp,
312 412 char *name,
313 413 vnode_t **vpp,
314 414 pathname_t *pnp,
315 415 int flags,
316 416 vnode_t *rdir,
317 417 cred_t *cr,
318 418 caller_context_t *ct,
319 419 int *deflags, /* Returned per-dirent flags */
320 420 pathname_t *ppnp) /* Returned case-preserved name in directory */
321 421 {
322 422 int fd;
323 423 int omode = O_RDWR | O_NOFOLLOW;
324 424 vnode_t *vp;
325 425 struct stat st;
326 426
327 427 if (flags & LOOKUP_XATTR)
328 - return (ENOENT);
428 + return (fake_lookup_xattrdir(dvp, vpp));
329 429
330 430 /*
331 431 * If lookup is for "", just return dvp.
332 432 */
333 433 if (name[0] == '\0') {
334 434 vn_hold(dvp);
335 435 *vpp = dvp;
336 436 return (0);
337 437 }
338 438
339 439 if (fstatat(dvp->v_fd, name, &st, AT_SYMLINK_NOFOLLOW) == -1)
340 440 return (errno);
341 441
342 442 vp = vncache_lookup(&st);
343 443 if (vp != NULL) {
344 444 /* lookup gave us a hold */
345 445 *vpp = vp;
346 446 return (0);
347 447 }
348 448
349 449 if (S_ISDIR(st.st_mode))
350 450 omode = O_RDONLY | O_NOFOLLOW;
351 451
352 452 again:
353 453 fd = openat(dvp->v_fd, name, omode, 0);
354 454 if (fd < 0) {
355 455 if ((omode & O_RWMASK) == O_RDWR) {
356 456 omode &= ~O_RWMASK;
357 457 omode |= O_RDONLY;
358 458 goto again;
359 459 }
360 460 return (errno);
361 461 }
362 462
363 463 if (fstat(fd, &st) == -1) {
364 464 (void) close(fd);
365 465 return (errno);
366 466 }
367 467
368 468 vp = vncache_enter(&st, dvp, name, fd);
369 469
370 470 *vpp = vp;
371 471 return (0);
372 472 }
373 473
374 474 /* ARGSUSED */
375 475 int
376 476 fop_create(
377 477 vnode_t *dvp,
378 478 char *name,
379 479 vattr_t *vap,
380 480 vcexcl_t excl,
381 481 int mode,
382 482 vnode_t **vpp,
383 483 cred_t *cr,
384 484 int flags,
385 485 caller_context_t *ct,
386 486 vsecattr_t *vsecp) /* ACL to set during create */
387 487 {
388 488 struct stat st;
389 489 vnode_t *vp;
390 490 int err, fd, omode;
391 491
392 492 /*
393 493 * If creating "", just return dvp.
394 494 */
395 495 if (name[0] == '\0') {
396 496 vn_hold(dvp);
397 497 *vpp = dvp;
398 498 return (0);
399 499 }
400 500
401 501 err = fstatat(dvp->v_fd, name, &st, AT_SYMLINK_NOFOLLOW);
402 502 if (err != 0)
403 503 err = errno;
404 504
405 505 vp = NULL;
406 506 if (err == 0) {
407 507 /* The file already exists. */
408 508 if (excl == EXCL)
409 509 return (EEXIST);
410 510
411 511 vp = vncache_lookup(&st);
412 512 /* vp gained a hold */
413 513 }
414 514
415 515 if (vp == NULL) {
416 516 /*
417 517 * Open it. (may or may not exist)
418 518 */
419 519 omode = O_RDWR | O_CREAT | O_NOFOLLOW;
420 520 if (excl == EXCL)
421 521 omode |= O_EXCL;
422 522 open_again:
423 523 fd = openat(dvp->v_fd, name, omode, mode);
424 524 if (fd < 0) {
425 525 if ((omode & O_RWMASK) == O_RDWR) {
426 526 omode &= ~O_RWMASK;
427 527 omode |= O_RDONLY;
428 528 goto open_again;
429 529 }
430 530 return (errno);
431 531 }
432 532 (void) fstat(fd, &st);
433 533
434 534 vp = vncache_enter(&st, dvp, name, fd);
435 535 /* vp has its initial hold */
436 536 }
437 537
438 538 /* Should have the vp now. */
439 539 if (vp == NULL)
440 540 return (EFAULT);
441 541
442 542 if (vp->v_type == VDIR && vap->va_type != VDIR) {
443 543 vn_rele(vp);
444 544 return (EISDIR);
445 545 }
446 546 if (vp->v_type != VDIR && vap->va_type == VDIR) {
447 547 vn_rele(vp);
448 548 return (ENOTDIR);
449 549 }
450 550
451 551 /*
452 552 * Might need to set attributes.
453 553 */
454 554 (void) fop_setattr(vp, vap, 0, cr, ct);
455 555
456 556 *vpp = vp;
457 557 return (0);
458 558 }
459 559
460 560 /* ARGSUSED */
461 561 int
462 562 fop_remove(
463 563 vnode_t *dvp,
464 564 char *name,
465 565 cred_t *cr,
466 566 caller_context_t *ct,
467 567 int flags)
468 568 {
469 569
470 570 if (unlinkat(dvp->v_fd, name, 0))
471 571 return (errno);
472 572
473 573 return (0);
474 574 }
475 575
476 576 /* ARGSUSED */
477 577 int
478 578 fop_link(
479 579 vnode_t *to_dvp,
480 580 vnode_t *fr_vp,
481 581 char *to_name,
482 582 cred_t *cr,
483 583 caller_context_t *ct,
484 584 int flags)
485 585 {
486 586 int err;
487 587
488 588 /*
489 589 * Would prefer to specify "from" as the combination:
490 590 * (fr_vp->v_fd, NULL) but linkat does not permit it.
491 591 */
492 592 err = linkat(AT_FDCWD, fr_vp->v_path, to_dvp->v_fd, to_name,
493 593 AT_SYMLINK_FOLLOW);
494 594 if (err == -1)
495 595 err = errno;
496 596
497 597 return (err);
498 598 }
499 599
500 600 /* ARGSUSED */
501 601 int
502 602 fop_rename(
503 603 vnode_t *from_dvp,
504 604 char *from_name,
505 605 vnode_t *to_dvp,
506 606 char *to_name,
507 607 cred_t *cr,
508 608 caller_context_t *ct,
509 609 int flags)
510 610 {
511 611 struct stat st;
512 612 vnode_t *vp;
513 613 int err;
514 614
515 615 if (fstatat(from_dvp->v_fd, from_name, &st,
516 616 AT_SYMLINK_NOFOLLOW) == -1)
517 617 return (errno);
518 618
519 619 vp = vncache_lookup(&st);
520 620 if (vp == NULL)
521 621 return (ENOENT);
522 622
523 623 err = renameat(from_dvp->v_fd, from_name, to_dvp->v_fd, to_name);
524 624 if (err == -1)
525 625 err = errno;
526 626 else
527 627 vncache_renamed(vp, to_dvp, to_name);
528 628
529 629 vn_rele(vp);
530 630
531 631 return (err);
532 632 }
533 633
534 634 /* ARGSUSED */
535 635 int
536 636 fop_mkdir(
537 637 vnode_t *dvp,
538 638 char *name,
539 639 vattr_t *vap,
540 640 vnode_t **vpp,
541 641 cred_t *cr,
542 642 caller_context_t *ct,
543 643 int flags,
544 644 vsecattr_t *vsecp) /* ACL to set during create */
545 645 {
546 646 struct stat st;
547 647 int err, fd;
548 648
549 649 mode_t mode = vap->va_mode & 0777;
550 650
551 651 if (mkdirat(dvp->v_fd, name, mode) == -1)
552 652 return (errno);
553 653
554 654 if ((fd = openat(dvp->v_fd, name, O_RDONLY)) == -1)
555 655 return (errno);
556 656 if (fstat(fd, &st) == -1) {
557 657 err = errno;
558 658 (void) close(fd);
559 659 return (err);
560 660 }
561 661
562 662 *vpp = vncache_enter(&st, dvp, name, fd);
563 663
564 664 /*
565 665 * Might need to set attributes.
566 666 */
567 667 (void) fop_setattr(*vpp, vap, 0, cr, ct);
568 668
569 669 return (0);
570 670 }
571 671
572 672 /* ARGSUSED */
573 673 int
574 674 fop_rmdir(
575 675 vnode_t *dvp,
576 676 char *name,
577 677 vnode_t *cdir,
578 678 cred_t *cr,
579 679 caller_context_t *ct,
580 680 int flags)
581 681 {
582 682
583 683 if (unlinkat(dvp->v_fd, name, AT_REMOVEDIR) == -1)
584 684 return (errno);
585 685
586 686 return (0);
587 687 }
588 688
589 689 /* ARGSUSED */
590 690 int
591 691 fop_readdir(
592 692 vnode_t *vp,
593 693 uio_t *uiop,
594 694 cred_t *cr,
595 695 int *eofp,
596 696 caller_context_t *ct,
597 697 int flags)
598 698 {
599 699 struct iovec *iov;
600 700 int cnt;
601 701 int error = 0;
602 702 int fd = vp->v_fd;
603 703
604 704 if (eofp) {
605 705 *eofp = 0;
606 706 }
607 707
608 708 error = lseek(fd, uiop->uio_loffset, SEEK_SET);
609 709 if (error == -1)
610 710 return (errno);
611 711
612 712 ASSERT(uiop->uio_iovcnt > 0);
613 713 iov = uiop->uio_iov;
614 714 if (iov->iov_len < sizeof (struct dirent))
615 715 return (EINVAL);
616 716
617 717 /* LINTED E_BAD_PTR_CAST_ALIGN */
618 718 cnt = getdents(fd, (struct dirent *)(uiop->uio_iov->iov_base),
619 719 uiop->uio_resid);
620 720 if (cnt == -1)
621 721 return (errno);
622 722 if (cnt == 0) {
623 723 if (eofp) {
624 724 *eofp = 1;
625 725 }
626 726 return (ENOENT);
627 727 }
628 728
629 729 iov->iov_base += cnt;
630 730 iov->iov_len -= cnt;
631 731 uiop->uio_resid -= cnt;
632 732 uiop->uio_loffset = lseek(fd, 0LL, SEEK_CUR);
633 733
634 734 return (0);
635 735 }
636 736
637 737 /* ARGSUSED */
638 738 int
639 739 fop_symlink(
640 740 vnode_t *dvp,
641 741 char *linkname,
642 742 vattr_t *vap,
643 743 char *target,
644 744 cred_t *cr,
645 745 caller_context_t *ct,
646 746 int flags)
647 747 {
648 748 return (ENOSYS);
649 749 }
650 750
651 751 /* ARGSUSED */
652 752 int
653 753 fop_readlink(
654 754 vnode_t *vp,
655 755 uio_t *uiop,
656 756 cred_t *cr,
657 757 caller_context_t *ct)
658 758 {
659 759 return (ENOSYS);
660 760 }
661 761
662 762 /* ARGSUSED */
663 763 int
664 764 fop_fsync(
665 765 vnode_t *vp,
666 766 int syncflag,
667 767 cred_t *cr,
668 768 caller_context_t *ct)
669 769 {
670 770
671 771 if (fsync(vp->v_fd) == -1)
672 772 return (errno);
673 773
|
↓ open down ↓ |
335 lines elided |
↑ open up ↑ |
674 774 return (0);
675 775 }
676 776
677 777 /* ARGSUSED */
678 778 void
679 779 fop_inactive(
680 780 vnode_t *vp,
681 781 cred_t *cr,
682 782 caller_context_t *ct)
683 783 {
684 - vncache_inactive(vp);
784 + if (vp->v_flag & V_XATTRDIR) {
785 + fake_inactive_xattrdir(vp);
786 + } else {
787 + vncache_inactive(vp);
788 + }
685 789 }
686 790
791 +/*
792 + * The special xattr directories are not in the vncache AVL, but
793 + * hang off the parent's v_xattrdir field. When vn_rele finds
794 + * an xattr dir at v_count == 1 it calls here, but until we
795 + * take locks on both the parent and the xattrdir, we don't
796 + * know if we're really at the last reference. So in here we
797 + * take both locks, re-check the count, and either bail out
798 + * or proceed with "inactive" vnode cleanup. Part of that
799 + * cleanup includes releasing the hold on the parent and
800 + * clearing the parent's v_xattrdir field, which were
801 + * setup in fake_lookup_xattrdir()
802 + */
803 +static void
804 +fake_inactive_xattrdir(vnode_t *vp)
805 +{
806 + vnode_t *dvp = vp->v_data; /* parent */
807 + mutex_enter(&dvp->v_lock);
808 + mutex_enter(&vp->v_lock);
809 + if (vp->v_count > 1) {
810 + /* new ref. via v_xattrdir */
811 + mutex_exit(&vp->v_lock);
812 + mutex_exit(&dvp->v_lock);
813 + return;
814 + }
815 + ASSERT(dvp->v_xattrdir == vp);
816 + dvp->v_xattrdir = NULL;
817 + mutex_exit(&vp->v_lock);
818 + mutex_exit(&dvp->v_lock);
819 + vn_rele(dvp);
820 + vn_free(vp);
821 +}
822 +
687 823 /* ARGSUSED */
688 824 int
689 825 fop_fid(
690 826 vnode_t *vp,
691 827 fid_t *fidp,
692 828 caller_context_t *ct)
693 829 {
694 830 return (ENOSYS);
695 831 }
696 832
697 833 /* ARGSUSED */
698 834 int
699 835 fop_rwlock(
700 836 vnode_t *vp,
701 837 int write_lock,
702 838 caller_context_t *ct)
703 839 {
704 840 /* See: fs_rwlock */
705 841 return (-1);
706 842 }
707 843
708 844 /* ARGSUSED */
709 845 void
710 846 fop_rwunlock(
711 847 vnode_t *vp,
712 848 int write_lock,
713 849 caller_context_t *ct)
714 850 {
715 851 /* See: fs_rwunlock */
716 852 }
717 853
718 854 /* ARGSUSED */
719 855 int
720 856 fop_seek(
721 857 vnode_t *vp,
722 858 offset_t ooff,
723 859 offset_t *noffp,
724 860 caller_context_t *ct)
725 861 {
726 862 return (ENOSYS);
727 863 }
728 864
729 865 /* ARGSUSED */
730 866 int
731 867 fop_cmp(
732 868 vnode_t *vp1,
733 869 vnode_t *vp2,
734 870 caller_context_t *ct)
735 871 {
736 872 /* See fs_cmp */
737 873 return (vncache_cmp(vp1, vp2));
738 874 }
739 875
740 876 /* ARGSUSED */
741 877 int
|
↓ open down ↓ |
45 lines elided |
↑ open up ↑ |
742 878 fop_frlock(
743 879 vnode_t *vp,
744 880 int cmd,
745 881 flock64_t *bfp,
746 882 int flag,
747 883 offset_t offset,
748 884 struct flk_callback *flk_cbp,
749 885 cred_t *cr,
750 886 caller_context_t *ct)
751 887 {
888 +#if defined(_LP64)
889 + offset_t maxoffset = INT64_MAX;
890 +#elif defined(_ILP32)
891 + /*
892 + * Sadly, the fcntl API enforces 32-bit offsets,
893 + * even though we have _FILE_OFFSET_BITS=64
894 + */
895 + offset_t maxoffset = INT32_MAX;
896 +#else
897 +#error "unsupported env."
898 +#endif
899 +
752 900 /* See fs_frlock */
753 901
754 902 switch (cmd) {
755 903 case F_GETLK:
756 904 case F_SETLK_NBMAND:
757 905 case F_SETLK:
758 906 case F_SETLKW:
759 907 break;
760 908 default:
761 909 return (EINVAL);
762 910 }
763 911
912 + /* We only get SEEK_SET ranges here. */
913 + if (bfp->l_whence != 0)
914 + return (EINVAL);
915 +
916 + /*
917 + * One limitation of using fcntl(2) F_SETLK etc is that
918 + * the real kernel limits the offsets we can use.
919 + * (Maybe the fcntl API should loosen that up?)
920 + * See syscall/fcntl.c:flock_check()
921 + *
922 + * Here in libfksmbsrv we can just ignore such locks,
923 + * or ignore the part that extends beyond maxoffset.
924 + * The SMB layer still keeps track of such locks for
925 + * conflict detection, so not reflecting such locks
926 + * into the real FS layer is OK. Note: this may
927 + * modify the pased bfp->l_len.
928 + */
929 + if (bfp->l_start < 0 || bfp->l_start > maxoffset)
930 + return (0);
931 + if (bfp->l_len < 0 || bfp->l_len > maxoffset)
932 + return (0);
933 + if (bfp->l_len > (maxoffset - bfp->l_start + 1))
934 + bfp->l_len = (maxoffset - bfp->l_start + 1);
935 +
764 936 if (fcntl(vp->v_fd, cmd, bfp) == -1)
765 937 return (errno);
766 938
767 939 return (0);
768 940 }
769 941
770 942 /* ARGSUSED */
771 943 int
772 944 fop_space(
773 945 vnode_t *vp,
774 946 int cmd,
775 947 flock64_t *bfp,
776 948 int flag,
777 949 offset_t offset,
778 950 cred_t *cr,
779 951 caller_context_t *ct)
780 952 {
781 953 /* See fs_frlock */
782 954
783 955 switch (cmd) {
784 956 case F_ALLOCSP:
785 957 case F_FREESP:
786 958 break;
787 959 default:
788 960 return (EINVAL);
789 961 }
790 962
791 963 if (fcntl(vp->v_fd, cmd, bfp) == -1)
792 964 return (errno);
793 965
794 966 return (0);
795 967 }
796 968
797 969 /* ARGSUSED */
798 970 int
799 971 fop_realvp(
800 972 vnode_t *vp,
801 973 vnode_t **vpp,
802 974 caller_context_t *ct)
803 975 {
804 976 return (ENOSYS);
805 977 }
806 978
807 979 /* ARGSUSED */
808 980 int
809 981 fop_getpage(
810 982 vnode_t *vp,
811 983 offset_t off,
812 984 size_t len,
813 985 uint_t *protp,
814 986 struct page **plarr,
815 987 size_t plsz,
816 988 struct seg *seg,
817 989 caddr_t addr,
818 990 enum seg_rw rw,
819 991 cred_t *cr,
820 992 caller_context_t *ct)
821 993 {
822 994 return (ENOSYS);
823 995 }
824 996
825 997 /* ARGSUSED */
826 998 int
827 999 fop_putpage(
828 1000 vnode_t *vp,
829 1001 offset_t off,
830 1002 size_t len,
831 1003 int flags,
832 1004 cred_t *cr,
833 1005 caller_context_t *ct)
834 1006 {
835 1007 return (ENOSYS);
836 1008 }
837 1009
838 1010 /* ARGSUSED */
839 1011 int
840 1012 fop_map(
841 1013 vnode_t *vp,
842 1014 offset_t off,
843 1015 struct as *as,
844 1016 caddr_t *addrp,
845 1017 size_t len,
846 1018 uchar_t prot,
847 1019 uchar_t maxprot,
848 1020 uint_t flags,
849 1021 cred_t *cr,
850 1022 caller_context_t *ct)
851 1023 {
852 1024 return (ENOSYS);
853 1025 }
854 1026
855 1027 /* ARGSUSED */
856 1028 int
857 1029 fop_addmap(
858 1030 vnode_t *vp,
859 1031 offset_t off,
860 1032 struct as *as,
861 1033 caddr_t addr,
862 1034 size_t len,
863 1035 uchar_t prot,
864 1036 uchar_t maxprot,
865 1037 uint_t flags,
866 1038 cred_t *cr,
867 1039 caller_context_t *ct)
868 1040 {
869 1041 return (ENOSYS);
870 1042 }
871 1043
872 1044 /* ARGSUSED */
873 1045 int
874 1046 fop_delmap(
875 1047 vnode_t *vp,
876 1048 offset_t off,
877 1049 struct as *as,
878 1050 caddr_t addr,
879 1051 size_t len,
880 1052 uint_t prot,
881 1053 uint_t maxprot,
882 1054 uint_t flags,
883 1055 cred_t *cr,
884 1056 caller_context_t *ct)
885 1057 {
886 1058 return (ENOSYS);
887 1059 }
888 1060
889 1061 /* ARGSUSED */
890 1062 int
891 1063 fop_poll(
892 1064 vnode_t *vp,
893 1065 short events,
894 1066 int anyyet,
895 1067 short *reventsp,
896 1068 struct pollhead **phpp,
897 1069 caller_context_t *ct)
898 1070 {
899 1071 *reventsp = 0;
900 1072 if (events & POLLIN)
901 1073 *reventsp |= POLLIN;
902 1074 if (events & POLLRDNORM)
903 1075 *reventsp |= POLLRDNORM;
904 1076 if (events & POLLRDBAND)
905 1077 *reventsp |= POLLRDBAND;
906 1078 if (events & POLLOUT)
907 1079 *reventsp |= POLLOUT;
908 1080 if (events & POLLWRBAND)
909 1081 *reventsp |= POLLWRBAND;
910 1082 *phpp = NULL; /* or fake_pollhead? */
911 1083
912 1084 return (0);
913 1085 }
914 1086
915 1087 /* ARGSUSED */
916 1088 int
917 1089 fop_dump(
918 1090 vnode_t *vp,
919 1091 caddr_t addr,
920 1092 offset_t lbdn,
921 1093 offset_t dblks,
922 1094 caller_context_t *ct)
923 1095 {
924 1096 return (ENOSYS);
925 1097 }
926 1098
927 1099 /*
928 1100 * See fs_pathconf
929 1101 */
930 1102 /* ARGSUSED */
931 1103 int
932 1104 fop_pathconf(
933 1105 vnode_t *vp,
934 1106 int cmd,
935 1107 ulong_t *valp,
936 1108 cred_t *cr,
937 1109 caller_context_t *ct)
938 1110 {
939 1111 register ulong_t val;
940 1112 register int error = 0;
941 1113
942 1114 switch (cmd) {
943 1115
944 1116 case _PC_LINK_MAX:
945 1117 val = MAXLINK;
946 1118 break;
947 1119
948 1120 case _PC_MAX_CANON:
949 1121 val = MAX_CANON;
950 1122 break;
951 1123
952 1124 case _PC_MAX_INPUT:
953 1125 val = MAX_INPUT;
954 1126 break;
955 1127
956 1128 case _PC_NAME_MAX:
957 1129 val = MAXNAMELEN;
958 1130 break;
959 1131
960 1132 case _PC_PATH_MAX:
961 1133 case _PC_SYMLINK_MAX:
962 1134 val = MAXPATHLEN;
963 1135 break;
964 1136
965 1137 case _PC_PIPE_BUF:
966 1138 val = PIPE_BUF;
967 1139 break;
968 1140
969 1141 case _PC_NO_TRUNC:
970 1142 val = (ulong_t)-1;
971 1143 break;
972 1144
973 1145 case _PC_VDISABLE:
974 1146 val = _POSIX_VDISABLE;
975 1147 break;
|
↓ open down ↓ |
202 lines elided |
↑ open up ↑ |
976 1148
977 1149 case _PC_CHOWN_RESTRICTED:
978 1150 val = 1; /* chown restricted enabled */
979 1151 break;
980 1152
981 1153 case _PC_FILESIZEBITS:
982 1154 val = (ulong_t)-1; /* large file support */
983 1155 break;
984 1156
985 1157 case _PC_ACL_ENABLED:
986 - val = 0;
1158 + val = _ACL_ACE_ENABLED;
987 1159 break;
988 1160
989 1161 case _PC_CASE_BEHAVIOR:
990 1162 val = _CASE_SENSITIVE;
991 1163 break;
992 1164
993 1165 case _PC_SATTR_ENABLED:
994 1166 case _PC_SATTR_EXISTS:
995 1167 val = 0;
996 1168 break;
997 1169
998 1170 case _PC_ACCESS_FILTERING:
999 1171 val = 0;
1000 1172 break;
1001 1173
1002 1174 default:
1003 1175 error = EINVAL;
1004 1176 break;
1005 1177 }
1006 1178
1007 1179 if (error == 0)
1008 1180 *valp = val;
1009 1181 return (error);
1010 1182 }
1011 1183
1012 1184 /* ARGSUSED */
1013 1185 int
1014 1186 fop_pageio(
1015 1187 vnode_t *vp,
1016 1188 struct page *pp,
1017 1189 u_offset_t io_off,
1018 1190 size_t io_len,
1019 1191 int flags,
1020 1192 cred_t *cr,
1021 1193 caller_context_t *ct)
1022 1194 {
1023 1195 return (ENOSYS);
1024 1196 }
1025 1197
1026 1198 /* ARGSUSED */
1027 1199 int
1028 1200 fop_dumpctl(
1029 1201 vnode_t *vp,
1030 1202 int action,
1031 1203 offset_t *blkp,
1032 1204 caller_context_t *ct)
1033 1205 {
1034 1206 return (ENOSYS);
1035 1207 }
1036 1208
1037 1209 /* ARGSUSED */
1038 1210 void
1039 1211 fop_dispose(
1040 1212 vnode_t *vp,
1041 1213 struct page *pp,
1042 1214 int flag,
1043 1215 int dn,
1044 1216 cred_t *cr,
1045 1217 caller_context_t *ct)
1046 1218 {
1047 1219 }
1048 1220
1049 1221 /* ARGSUSED */
1050 1222 int
1051 1223 fop_setsecattr(
1052 1224 vnode_t *vp,
1053 1225 vsecattr_t *vsap,
1054 1226 int flag,
1055 1227 cred_t *cr,
1056 1228 caller_context_t *ct)
1057 1229 {
1058 1230 return (0);
1059 1231 }
1060 1232
1061 1233 /*
1062 1234 * Fake up just enough of this so we can test get/set SDs.
1063 1235 */
1064 1236 /* ARGSUSED */
1065 1237 int
1066 1238 fop_getsecattr(
1067 1239 vnode_t *vp,
1068 1240 vsecattr_t *vsecattr,
1069 1241 int flag,
1070 1242 cred_t *cr,
1071 1243 caller_context_t *ct)
1072 1244 {
1073 1245
1074 1246 vsecattr->vsa_aclcnt = 0;
1075 1247 vsecattr->vsa_aclentsz = 0;
1076 1248 vsecattr->vsa_aclentp = NULL;
1077 1249 vsecattr->vsa_dfaclcnt = 0; /* Default ACLs are not fabricated */
1078 1250 vsecattr->vsa_dfaclentp = NULL;
1079 1251
1080 1252 if (vsecattr->vsa_mask & (VSA_ACLCNT | VSA_ACL)) {
1081 1253 aclent_t *aclentp;
1082 1254 size_t aclsize;
1083 1255
1084 1256 aclsize = sizeof (aclent_t);
1085 1257 vsecattr->vsa_aclcnt = 1;
1086 1258 vsecattr->vsa_aclentp = kmem_zalloc(aclsize, KM_SLEEP);
1087 1259 aclentp = vsecattr->vsa_aclentp;
1088 1260
1089 1261 aclentp->a_type = OTHER_OBJ;
1090 1262 aclentp->a_perm = 0777;
1091 1263 aclentp->a_id = (gid_t)-1;
1092 1264 aclentp++;
1093 1265 } else if (vsecattr->vsa_mask & (VSA_ACECNT | VSA_ACE)) {
1094 1266 ace_t *acl;
1095 1267
1096 1268 acl = kmem_alloc(sizeof (ace_t), KM_SLEEP);
1097 1269 acl->a_who = (uint32_t)-1;
1098 1270 acl->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
1099 1271 acl->a_flags = ACE_EVERYONE;
1100 1272 acl->a_access_mask = ACE_MODIFY_PERMS;
1101 1273
1102 1274 vsecattr->vsa_aclentp = (void *)acl;
1103 1275 vsecattr->vsa_aclcnt = 1;
1104 1276 vsecattr->vsa_aclentsz = sizeof (ace_t);
1105 1277 }
1106 1278
1107 1279 return (0);
1108 1280 }
1109 1281
1110 1282 /* ARGSUSED */
1111 1283 int
1112 1284 fop_shrlock(
1113 1285 vnode_t *vp,
1114 1286 int cmd,
1115 1287 struct shrlock *shr,
1116 1288 int flag,
1117 1289 cred_t *cr,
1118 1290 caller_context_t *ct)
1119 1291 {
1120 1292
1121 1293 switch (cmd) {
1122 1294 case F_SHARE:
1123 1295 case F_SHARE_NBMAND:
1124 1296 case F_UNSHARE:
1125 1297 break;
1126 1298 default:
1127 1299 return (EINVAL);
1128 1300 }
1129 1301
1130 1302 if (!fop_shrlock_enable)
1131 1303 return (0);
1132 1304
1133 1305 if (fcntl(vp->v_fd, cmd, shr) == -1)
1134 1306 return (errno);
1135 1307
1136 1308 return (0);
1137 1309 }
1138 1310
1139 1311 /* ARGSUSED */
1140 1312 int
1141 1313 fop_vnevent(vnode_t *vp, vnevent_t vnevent, vnode_t *dvp, char *fnm,
1142 1314 caller_context_t *ct)
1143 1315 {
1144 1316 return (ENOSYS);
1145 1317 }
1146 1318
1147 1319 /* ARGSUSED */
1148 1320 int
1149 1321 fop_reqzcbuf(vnode_t *vp, enum uio_rw ioflag, xuio_t *uiop, cred_t *cr,
1150 1322 caller_context_t *ct)
1151 1323 {
1152 1324 return (ENOSYS);
1153 1325 }
1154 1326
1155 1327 /* ARGSUSED */
1156 1328 int
1157 1329 fop_retzcbuf(vnode_t *vp, xuio_t *uiop, cred_t *cr, caller_context_t *ct)
1158 1330 {
1159 1331 return (ENOSYS);
1160 1332 }
1161 1333
1162 1334
1163 1335 /*
1164 1336 * ***************************************************************
1165 1337 * other VOP support
1166 1338 */
1167 1339
1168 1340 /*
1169 1341 * Convert stat(2) formats to vnode types and vice versa. (Knows about
1170 1342 * numerical order of S_IFMT and vnode types.)
1171 1343 */
1172 1344 enum vtype iftovt_tab[] = {
1173 1345 VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON,
1174 1346 VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VNON
1175 1347 };
1176 1348
1177 1349 ushort_t vttoif_tab[] = {
1178 1350 0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, S_IFIFO,
1179 1351 S_IFDOOR, 0, S_IFSOCK, S_IFPORT, 0
1180 1352 };
1181 1353
1182 1354 /*
1183 1355 * stat_to_vattr()
1184 1356 *
1185 1357 * Convert from a stat structure to an vattr structure
1186 1358 * Note: only set fields according to va_mask
1187 1359 */
1188 1360
1189 1361 int
1190 1362 stat_to_vattr(const struct stat *st, vattr_t *vap)
1191 1363 {
1192 1364
1193 1365 if (vap->va_mask & AT_TYPE)
1194 1366 vap->va_type = IFTOVT(st->st_mode);
1195 1367
1196 1368 if (vap->va_mask & AT_MODE)
1197 1369 vap->va_mode = st->st_mode;
1198 1370
1199 1371 if (vap->va_mask & AT_UID)
1200 1372 vap->va_uid = st->st_uid;
1201 1373
1202 1374 if (vap->va_mask & AT_GID)
1203 1375 vap->va_gid = st->st_gid;
1204 1376
1205 1377 if (vap->va_mask & AT_FSID)
1206 1378 vap->va_fsid = st->st_dev;
1207 1379
1208 1380 if (vap->va_mask & AT_NODEID)
1209 1381 vap->va_nodeid = st->st_ino;
1210 1382
1211 1383 if (vap->va_mask & AT_NLINK)
1212 1384 vap->va_nlink = st->st_nlink;
1213 1385
1214 1386 if (vap->va_mask & AT_SIZE)
1215 1387 vap->va_size = (u_offset_t)st->st_size;
1216 1388
1217 1389 if (vap->va_mask & AT_ATIME) {
1218 1390 vap->va_atime.tv_sec = st->st_atim.tv_sec;
1219 1391 vap->va_atime.tv_nsec = st->st_atim.tv_nsec;
1220 1392 }
1221 1393
1222 1394 if (vap->va_mask & AT_MTIME) {
1223 1395 vap->va_mtime.tv_sec = st->st_mtim.tv_sec;
1224 1396 vap->va_mtime.tv_nsec = st->st_mtim.tv_nsec;
1225 1397 }
1226 1398
1227 1399 if (vap->va_mask & AT_CTIME) {
1228 1400 vap->va_ctime.tv_sec = st->st_ctim.tv_sec;
1229 1401 vap->va_ctime.tv_nsec = st->st_ctim.tv_nsec;
1230 1402 }
1231 1403
1232 1404 if (vap->va_mask & AT_RDEV)
1233 1405 vap->va_rdev = st->st_rdev;
1234 1406
1235 1407 if (vap->va_mask & AT_BLKSIZE)
1236 1408 vap->va_blksize = (uint_t)st->st_blksize;
1237 1409
1238 1410
1239 1411 if (vap->va_mask & AT_NBLOCKS)
1240 1412 vap->va_nblocks = (u_longlong_t)st->st_blocks;
1241 1413
1242 1414 if (vap->va_mask & AT_SEQ)
1243 1415 vap->va_seq = 0;
1244 1416
1245 1417 return (0);
1246 1418 }
1247 1419
1248 1420 /* ARGSUSED */
1249 1421 void
1250 1422 flk_init_callback(flk_callback_t *flk_cb,
1251 1423 callb_cpr_t *(*cb_fcn)(flk_cb_when_t, void *), void *cbdata)
1252 1424 {
1253 1425 }
1254 1426
1255 1427 void
1256 1428 vn_hold(vnode_t *vp)
1257 1429 {
1258 1430 mutex_enter(&vp->v_lock);
1259 1431 vp->v_count++;
|
↓ open down ↓ |
263 lines elided |
↑ open up ↑ |
1260 1432 mutex_exit(&vp->v_lock);
1261 1433 }
1262 1434
1263 1435 void
1264 1436 vn_rele(vnode_t *vp)
1265 1437 {
1266 1438 VERIFY3U(vp->v_count, !=, 0);
1267 1439 mutex_enter(&vp->v_lock);
1268 1440 if (vp->v_count == 1) {
1269 1441 mutex_exit(&vp->v_lock);
1270 - vncache_inactive(vp);
1442 + fop_inactive(vp, NULL, NULL);
1271 1443 } else {
1272 1444 vp->v_count--;
1273 1445 mutex_exit(&vp->v_lock);
1274 1446 }
1275 1447 }
1276 1448
1277 1449 int
1278 1450 vn_has_other_opens(
1279 1451 vnode_t *vp,
1280 1452 v_mode_t mode)
1281 1453 {
1282 1454
1283 1455 switch (mode) {
1284 1456 case V_WRITE:
1285 1457 if (vp->v_wrcnt > 1)
1286 1458 return (V_TRUE);
1287 1459 break;
1288 1460 case V_RDORWR:
1289 1461 if ((vp->v_rdcnt > 1) || (vp->v_wrcnt > 1))
1290 1462 return (V_TRUE);
1291 1463 break;
1292 1464 case V_RDANDWR:
1293 1465 if ((vp->v_rdcnt > 1) && (vp->v_wrcnt > 1))
1294 1466 return (V_TRUE);
1295 1467 break;
1296 1468 case V_READ:
1297 1469 if (vp->v_rdcnt > 1)
1298 1470 return (V_TRUE);
1299 1471 break;
1300 1472 }
1301 1473
1302 1474 return (V_FALSE);
1303 1475 }
1304 1476
1305 1477 /*
1306 1478 * vn_is_opened() checks whether a particular file is opened and
1307 1479 * whether the open is for read and/or write.
1308 1480 *
1309 1481 * Vnode counts are only kept on regular files (v_type=VREG).
1310 1482 */
1311 1483 int
1312 1484 vn_is_opened(
1313 1485 vnode_t *vp,
1314 1486 v_mode_t mode)
1315 1487 {
1316 1488
1317 1489 ASSERT(vp != NULL);
1318 1490
1319 1491 switch (mode) {
1320 1492 case V_WRITE:
1321 1493 if (vp->v_wrcnt)
1322 1494 return (V_TRUE);
1323 1495 break;
1324 1496 case V_RDANDWR:
1325 1497 if (vp->v_rdcnt && vp->v_wrcnt)
1326 1498 return (V_TRUE);
1327 1499 break;
1328 1500 case V_RDORWR:
1329 1501 if (vp->v_rdcnt || vp->v_wrcnt)
1330 1502 return (V_TRUE);
1331 1503 break;
1332 1504 case V_READ:
1333 1505 if (vp->v_rdcnt)
1334 1506 return (V_TRUE);
1335 1507 break;
1336 1508 }
1337 1509
1338 1510 return (V_FALSE);
1339 1511 }
1340 1512
1341 1513 /*
1342 1514 * vn_is_mapped() checks whether a particular file is mapped and whether
1343 1515 * the file is mapped read and/or write.
1344 1516 */
1345 1517 /* ARGSUSED */
1346 1518 int
1347 1519 vn_is_mapped(
1348 1520 vnode_t *vp,
1349 1521 v_mode_t mode)
1350 1522 {
1351 1523 return (V_FALSE);
1352 1524 }
|
↓ open down ↓ |
72 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX