1 /*
2 * Copyright (c) 1982, 1986, 1989, 1993, 1995
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 4. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95
35 */
36
37 #include <sys/cdefs.h>
38 __FBSDID("$FreeBSD: releng/5.3/sys/ufs/ufs/ufs_vnops.c 134621 2004-09-02 01:12:20Z csjp $");
39
40 #include "opt_mac.h"
41 #include "opt_quota.h"
42 #include "opt_suiddir.h"
43 #include "opt_ufs.h"
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/malloc.h>
48 #include <sys/namei.h>
49 #include <sys/kernel.h>
50 #include <sys/fcntl.h>
51 #include <sys/stat.h>
52 #include <sys/bio.h>
53 #include <sys/buf.h>
54 #include <sys/mount.h>
55 #include <sys/unistd.h>
56 #include <sys/vnode.h>
57 #include <sys/dirent.h>
58 #include <sys/lockf.h>
59 #include <sys/event.h>
60 #include <sys/conf.h>
61 #include <sys/acl.h>
62 #include <sys/mac.h>
63
64 #include <machine/mutex.h>
65
66 #include <sys/file.h> /* XXX */
67
68 #include <vm/vm.h>
69 #include <vm/vm_extern.h>
70
71 #include <fs/fifofs/fifo.h>
72
73 #include <ufs/ufs/acl.h>
74 #include <ufs/ufs/extattr.h>
75 #include <ufs/ufs/quota.h>
76 #include <ufs/ufs/inode.h>
77 #include <ufs/ufs/dir.h>
78 #include <ufs/ufs/ufsmount.h>
79 #include <ufs/ufs/ufs_extern.h>
80 #ifdef UFS_DIRHASH
81 #include <ufs/ufs/dirhash.h>
82 #endif
83
84 static int ufs_access(struct vop_access_args *);
85 static int ufs_advlock(struct vop_advlock_args *);
86 static int ufs_chmod(struct vnode *, int, struct ucred *, struct thread *);
87 static int ufs_chown(struct vnode *, uid_t, gid_t, struct ucred *, struct thread *);
88 static int ufs_close(struct vop_close_args *);
89 static int ufs_create(struct vop_create_args *);
90 static int ufs_getattr(struct vop_getattr_args *);
91 static int ufs_link(struct vop_link_args *);
92 static int ufs_makeinode(int mode, struct vnode *, struct vnode **, struct componentname *);
93 static int ufs_mkdir(struct vop_mkdir_args *);
94 static int ufs_mknod(struct vop_mknod_args *);
95 static int ufs_open(struct vop_open_args *);
96 static int ufs_pathconf(struct vop_pathconf_args *);
97 static int ufs_lock(struct vop_lock_args *);
98 static int ufs_print(struct vop_print_args *);
99 static int ufs_readlink(struct vop_readlink_args *);
100 static int ufs_remove(struct vop_remove_args *);
101 static int ufs_rename(struct vop_rename_args *);
102 static int ufs_rmdir(struct vop_rmdir_args *);
103 static int ufs_setattr(struct vop_setattr_args *);
104 static int ufs_strategy(struct vop_strategy_args *);
105 static int ufs_symlink(struct vop_symlink_args *);
106 static int ufs_whiteout(struct vop_whiteout_args *);
107 static int ufsfifo_close(struct vop_close_args *);
108 static int ufsfifo_kqfilter(struct vop_kqfilter_args *);
109 static int ufsfifo_read(struct vop_read_args *);
110 static int ufsfifo_write(struct vop_write_args *);
111 static int ufsspec_close(struct vop_close_args *);
112 static int ufsspec_read(struct vop_read_args *);
113 static int ufsspec_write(struct vop_write_args *);
114 static int filt_ufsread(struct knote *kn, long hint);
115 static int filt_ufswrite(struct knote *kn, long hint);
116 static int filt_ufsvnode(struct knote *kn, long hint);
117 static void filt_ufsdetach(struct knote *kn);
118 static int ufs_kqfilter(struct vop_kqfilter_args *ap);
119
120 union _qcvt {
121 int64_t qcvt;
122 int32_t val[2];
123 };
124 #define SETHIGH(q, h) { \
125 union _qcvt tmp; \
126 tmp.qcvt = (q); \
127 tmp.val[_QUAD_HIGHWORD] = (h); \
128 (q) = tmp.qcvt; \
129 }
130 #define SETLOW(q, l) { \
131 union _qcvt tmp; \
132 tmp.qcvt = (q); \
133 tmp.val[_QUAD_LOWWORD] = (l); \
134 (q) = tmp.qcvt; \
135 }
136
137 /*
138 * A virgin directory (no blushing please).
139 */
140 static struct dirtemplate mastertemplate = {
141 0, 12, DT_DIR, 1, ".",
142 0, DIRBLKSIZ - 12, DT_DIR, 2, ".."
143 };
144 static struct odirtemplate omastertemplate = {
145 0, 12, 1, ".",
146 0, DIRBLKSIZ - 12, 2, ".."
147 };
148
149 void
150 ufs_itimes(vp)
151 struct vnode *vp;
152 {
153 struct inode *ip;
154 struct timespec ts;
155
156 ip = VTOI(vp);
157 if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) == 0)
158 return;
159 if ((vp->v_type == VBLK || vp->v_type == VCHR) && !DOINGSOFTDEP(vp))
160 ip->i_flag |= IN_LAZYMOD;
161 else
162 ip->i_flag |= IN_MODIFIED;
163 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
164 vfs_timestamp(&ts);
165 if (ip->i_flag & IN_ACCESS) {
166 DIP_SET(ip, i_atime, ts.tv_sec);
167 DIP_SET(ip, i_atimensec, ts.tv_nsec);
168 }
169 if (ip->i_flag & IN_UPDATE) {
170 DIP_SET(ip, i_mtime, ts.tv_sec);
171 DIP_SET(ip, i_mtimensec, ts.tv_nsec);
172 ip->i_modrev++;
173 }
174 if (ip->i_flag & IN_CHANGE) {
175 DIP_SET(ip, i_ctime, ts.tv_sec);
176 DIP_SET(ip, i_ctimensec, ts.tv_nsec);
177 }
178 }
179 ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE);
180 }
181
182 /*
183 * Create a regular file
184 */
185 static int
186 ufs_create(ap)
187 struct vop_create_args /* {
188 struct vnode *a_dvp;
189 struct vnode **a_vpp;
190 struct componentname *a_cnp;
191 struct vattr *a_vap;
192 } */ *ap;
193 {
194 int error;
195
196 error =
197 ufs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode),
198 ap->a_dvp, ap->a_vpp, ap->a_cnp);
199 if (error)
200 return (error);
201 VN_KNOTE_UNLOCKED(ap->a_dvp, NOTE_WRITE);
202 return (0);
203 }
204
205 /*
206 * Mknod vnode call
207 */
208 /* ARGSUSED */
209 static int
210 ufs_mknod(ap)
211 struct vop_mknod_args /* {
212 struct vnode *a_dvp;
213 struct vnode **a_vpp;
214 struct componentname *a_cnp;
215 struct vattr *a_vap;
216 } */ *ap;
217 {
218 struct vattr *vap = ap->a_vap;
219 struct vnode **vpp = ap->a_vpp;
220 struct inode *ip;
221 ino_t ino;
222 int error;
223
224 error = ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
225 ap->a_dvp, vpp, ap->a_cnp);
226 if (error)
227 return (error);
228 VN_KNOTE_UNLOCKED(ap->a_dvp, NOTE_WRITE);
229 ip = VTOI(*vpp);
230 ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
231 if (vap->va_rdev != VNOVAL) {
232 /*
233 * Want to be able to use this to make badblock
234 * inodes, so don't truncate the dev number.
235 */
236 DIP_SET(ip, i_rdev, vap->va_rdev);
237 }
238 /*
239 * Remove inode, then reload it through VFS_VGET so it is
240 * checked to see if it is an alias of an existing entry in
241 * the inode cache.
242 */
243 vput(*vpp);
244 (*vpp)->v_type = VNON;
245 ino = ip->i_number; /* Save this before vgone() invalidates ip. */
246 vgone(*vpp);
247 error = VFS_VGET(ap->a_dvp->v_mount, ino, LK_EXCLUSIVE, vpp);
248 if (error) {
249 *vpp = NULL;
250 return (error);
251 }
252 return (0);
253 }
254
255 /*
256 * Open called.
257 *
258 * Nothing to do.
259 */
260 /* ARGSUSED */
261 static int
262 ufs_open(ap)
263 struct vop_open_args /* {
264 struct vnode *a_vp;
265 int a_mode;
266 struct ucred *a_cred;
267 struct thread *a_td;
268 } */ *ap;
269 {
270
271 /*
272 * Files marked append-only must be opened for appending.
273 */
274 if ((VTOI(ap->a_vp)->i_flags & APPEND) &&
275 (ap->a_mode & (FWRITE | O_APPEND)) == FWRITE)
276 return (EPERM);
277 return (0);
278 }
279
280 /*
281 * Close called.
282 *
283 * Update the times on the inode.
284 */
285 /* ARGSUSED */
286 static int
287 ufs_close(ap)
288 struct vop_close_args /* {
289 struct vnode *a_vp;
290 int a_fflag;
291 struct ucred *a_cred;
292 struct thread *a_td;
293 } */ *ap;
294 {
295 struct vnode *vp = ap->a_vp;
296 struct mount *mp;
297
298 VI_LOCK(vp);
299 if (vp->v_usecount > 1) {
300 ufs_itimes(vp);
301 VI_UNLOCK(vp);
302 } else {
303 VI_UNLOCK(vp);
304 /*
305 * If we are closing the last reference to an unlinked
306 * file, then it will be freed by the inactive routine.
307 * Because the freeing causes a the filesystem to be
308 * modified, it must be held up during periods when the
309 * filesystem is suspended.
310 *
311 * XXX - EAGAIN is returned to prevent vn_close from
312 * repeating the vrele operation.
313 */
314 if (vp->v_type == VREG && VTOI(vp)->i_effnlink == 0) {
315 (void) vn_start_write(vp, &mp, V_WAIT);
316 vrele(vp);
317 vn_finished_write(mp);
318 return (EAGAIN);
319 }
320 }
321 return (0);
322 }
323
324 static int
325 ufs_access(ap)
326 struct vop_access_args /* {
327 struct vnode *a_vp;
328 int a_mode;
329 struct ucred *a_cred;
330 struct thread *a_td;
331 } */ *ap;
332 {
333 struct vnode *vp = ap->a_vp;
334 struct inode *ip = VTOI(vp);
335 mode_t mode = ap->a_mode;
336 int error;
337 #ifdef UFS_ACL
338 struct acl *acl;
339 #endif
340
341 /*
342 * Disallow write attempts on read-only filesystems;
343 * unless the file is a socket, fifo, or a block or
344 * character device resident on the filesystem.
345 */
346 if (mode & VWRITE) {
347 switch (vp->v_type) {
348 case VDIR:
349 case VLNK:
350 case VREG:
351 if (vp->v_mount->mnt_flag & MNT_RDONLY)
352 return (EROFS);
353 #ifdef QUOTA
354 if ((error = getinoquota(ip)) != 0)
355 return (error);
356 #endif
357 break;
358 default:
359 break;
360 }
361 }
362
363 /* If immutable bit set, nobody gets to write it. */
364 if ((mode & VWRITE) && (ip->i_flags & (IMMUTABLE | SF_SNAPSHOT)))
365 return (EPERM);
366
367 #ifdef UFS_ACL
368 if ((vp->v_mount->mnt_flag & MNT_ACLS) != 0) {
369 MALLOC(acl, struct acl *, sizeof(*acl), M_ACL, M_WAITOK);
370 error = VOP_GETACL(vp, ACL_TYPE_ACCESS, acl, ap->a_cred,
371 ap->a_td);
372 switch (error) {
373 case EOPNOTSUPP:
374 error = vaccess(vp->v_type, ip->i_mode, ip->i_uid,
375 ip->i_gid, ap->a_mode, ap->a_cred, NULL);
376 break;
377 case 0:
378 error = vaccess_acl_posix1e(vp->v_type, ip->i_uid,
379 ip->i_gid, acl, ap->a_mode, ap->a_cred, NULL);
380 break;
381 default:
382 printf(
383 "ufs_access(): Error retrieving ACL on object (%d).\n",
384 error);
385 /*
386 * XXX: Fall back until debugged. Should
387 * eventually possibly log an error, and return
388 * EPERM for safety.
389 */
390 error = vaccess(vp->v_type, ip->i_mode, ip->i_uid,
391 ip->i_gid, ap->a_mode, ap->a_cred, NULL);
392 }
393 FREE(acl, M_ACL);
394 } else
395 #endif /* !UFS_ACL */
396 error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, ip->i_gid,
397 ap->a_mode, ap->a_cred, NULL);
398 return (error);
399 }
400
401 /* ARGSUSED */
402 static int
403 ufs_getattr(ap)
404 struct vop_getattr_args /* {
405 struct vnode *a_vp;
406 struct vattr *a_vap;
407 struct ucred *a_cred;
408 struct thread *a_td;
409 } */ *ap;
410 {
411 struct vnode *vp = ap->a_vp;
412 struct inode *ip = VTOI(vp);
413 struct vattr *vap = ap->a_vap;
414
415 ufs_itimes(vp);
416 /*
417 * Copy from inode table
418 */
419 vap->va_fsid = dev2udev(ip->i_dev);
420 vap->va_fileid = ip->i_number;
421 vap->va_mode = ip->i_mode & ~IFMT;
422 vap->va_nlink = ip->i_effnlink;
423 vap->va_uid = ip->i_uid;
424 vap->va_gid = ip->i_gid;
425 if (ip->i_ump->um_fstype == UFS1) {
426 vap->va_rdev = ip->i_din1->di_rdev;
427 vap->va_size = ip->i_din1->di_size;
428 vap->va_atime.tv_sec = ip->i_din1->di_atime;
429 vap->va_atime.tv_nsec = ip->i_din1->di_atimensec;
430 vap->va_mtime.tv_sec = ip->i_din1->di_mtime;
431 vap->va_mtime.tv_nsec = ip->i_din1->di_mtimensec;
432 vap->va_ctime.tv_sec = ip->i_din1->di_ctime;
433 vap->va_ctime.tv_nsec = ip->i_din1->di_ctimensec;
434 vap->va_birthtime.tv_sec = 0;
435 vap->va_birthtime.tv_nsec = 0;
436 vap->va_bytes = dbtob((u_quad_t)ip->i_din1->di_blocks);
437 } else {
438 vap->va_rdev = ip->i_din2->di_rdev;
439 vap->va_size = ip->i_din2->di_size;
440 vap->va_atime.tv_sec = ip->i_din2->di_atime;
441 vap->va_atime.tv_nsec = ip->i_din2->di_atimensec;
442 vap->va_mtime.tv_sec = ip->i_din2->di_mtime;
443 vap->va_mtime.tv_nsec = ip->i_din2->di_mtimensec;
444 vap->va_ctime.tv_sec = ip->i_din2->di_ctime;
445 vap->va_ctime.tv_nsec = ip->i_din2->di_ctimensec;
446 vap->va_birthtime.tv_sec = ip->i_din2->di_birthtime;
447 vap->va_birthtime.tv_nsec = ip->i_din2->di_birthnsec;
448 vap->va_bytes = dbtob((u_quad_t)ip->i_din2->di_blocks);
449 }
450 vap->va_flags = ip->i_flags;
451 vap->va_gen = ip->i_gen;
452 vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
453 vap->va_type = IFTOVT(ip->i_mode);
454 vap->va_filerev = ip->i_modrev;
455 return (0);
456 }
457
458 /*
459 * Set attribute vnode op. called from several syscalls
460 */
461 static int
462 ufs_setattr(ap)
463 struct vop_setattr_args /* {
464 struct vnode *a_vp;
465 struct vattr *a_vap;
466 struct ucred *a_cred;
467 struct thread *a_td;
468 } */ *ap;
469 {
470 struct vattr *vap = ap->a_vap;
471 struct vnode *vp = ap->a_vp;
472 struct inode *ip = VTOI(vp);
473 struct ucred *cred = ap->a_cred;
474 struct thread *td = ap->a_td;
475 int error;
476
477 /*
478 * Check for unsettable attributes.
479 */
480 if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
481 (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
482 (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
483 ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
484 return (EINVAL);
485 }
486 if (vap->va_flags != VNOVAL) {
487 if (vp->v_mount->mnt_flag & MNT_RDONLY)
488 return (EROFS);
489 /*
490 * Callers may only modify the file flags on objects they
491 * have VADMIN rights for.
492 */
493 if ((error = VOP_ACCESS(vp, VADMIN, cred, td)))
494 return (error);
495 /*
496 * Unprivileged processes and privileged processes in
497 * jail() are not permitted to unset system flags, or
498 * modify flags if any system flags are set.
499 * Privileged non-jail processes may not modify system flags
500 * if securelevel > 0 and any existing system flags are set.
501 */
502 if (!suser_cred(cred, 0)) {
503 if (ip->i_flags
504 & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) {
505 error = securelevel_gt(cred, 0);
506 if (error)
507 return (error);
508 }
509 /* Snapshot flag cannot be set or cleared */
510 if (((vap->va_flags & SF_SNAPSHOT) != 0 &&
511 (ip->i_flags & SF_SNAPSHOT) == 0) ||
512 ((vap->va_flags & SF_SNAPSHOT) == 0 &&
513 (ip->i_flags & SF_SNAPSHOT) != 0))
514 return (EPERM);
515 ip->i_flags = vap->va_flags;
516 DIP_SET(ip, i_flags, vap->va_flags);
517 } else {
518 if (ip->i_flags
519 & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND) ||
520 (vap->va_flags & UF_SETTABLE) != vap->va_flags)
521 return (EPERM);
522 ip->i_flags &= SF_SETTABLE;
523 ip->i_flags |= (vap->va_flags & UF_SETTABLE);
524 DIP_SET(ip, i_flags, ip->i_flags);
525 }
526 ip->i_flag |= IN_CHANGE;
527 if (vap->va_flags & (IMMUTABLE | APPEND))
528 return (0);
529 }
530 if (ip->i_flags & (IMMUTABLE | APPEND))
531 return (EPERM);
532 /*
533 * Go through the fields and update iff not VNOVAL.
534 */
535 if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
536 if (vp->v_mount->mnt_flag & MNT_RDONLY)
537 return (EROFS);
538 if ((error = ufs_chown(vp, vap->va_uid, vap->va_gid, cred,
539 td)) != 0)
540 return (error);
541 }
542 if (vap->va_size != VNOVAL) {
543 /*
544 * Disallow write attempts on read-only filesystems;
545 * unless the file is a socket, fifo, or a block or
546 * character device resident on the filesystem.
547 */
548 switch (vp->v_type) {
549 case VDIR:
550 return (EISDIR);
551 case VLNK:
552 case VREG:
553 if (vp->v_mount->mnt_flag & MNT_RDONLY)
554 return (EROFS);
555 if ((ip->i_flags & SF_SNAPSHOT) != 0)
556 return (EPERM);
557 break;
558 default:
559 break;
560 }
561 if ((error = UFS_TRUNCATE(vp, vap->va_size, IO_NORMAL,
562 cred, td)) != 0)
563 return (error);
564 }
565 if (vap->va_atime.tv_sec != VNOVAL ||
566 vap->va_mtime.tv_sec != VNOVAL ||
567 vap->va_birthtime.tv_sec != VNOVAL) {
568 if (vp->v_mount->mnt_flag & MNT_RDONLY)
569 return (EROFS);
570 if ((ip->i_flags & SF_SNAPSHOT) != 0)
571 return (EPERM);
572 /*
573 * From utimes(2):
574 * If times is NULL, ... The caller must be the owner of
575 * the file, have permission to write the file, or be the
576 * super-user.
577 * If times is non-NULL, ... The caller must be the owner of
578 * the file or be the super-user.
579 */
580 if ((error = VOP_ACCESS(vp, VADMIN, cred, td)) &&
581 ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
582 (error = VOP_ACCESS(vp, VWRITE, cred, td))))
583 return (error);
584 if (vap->va_atime.tv_sec != VNOVAL)
585 ip->i_flag |= IN_ACCESS;
586 if (vap->va_mtime.tv_sec != VNOVAL)
587 ip->i_flag |= IN_CHANGE | IN_UPDATE;
588 if (vap->va_birthtime.tv_sec != VNOVAL &&
589 ip->i_ump->um_fstype == UFS2)
590 ip->i_flag |= IN_MODIFIED;
591 ufs_itimes(vp);
592 if (vap->va_atime.tv_sec != VNOVAL) {
593 DIP_SET(ip, i_atime, vap->va_atime.tv_sec);
594 DIP_SET(ip, i_atimensec, vap->va_atime.tv_nsec);
595 }
596 if (vap->va_mtime.tv_sec != VNOVAL) {
597 DIP_SET(ip, i_mtime, vap->va_mtime.tv_sec);
598 DIP_SET(ip, i_mtimensec, vap->va_mtime.tv_nsec);
599 }
600 if (vap->va_birthtime.tv_sec != VNOVAL &&
601 ip->i_ump->um_fstype == UFS2) {
602 ip->i_din2->di_birthtime = vap->va_birthtime.tv_sec;
603 ip->i_din2->di_birthnsec = vap->va_birthtime.tv_nsec;
604 }
605 error = UFS_UPDATE(vp, 0);
606 if (error)
607 return (error);
608 }
609 error = 0;
610 if (vap->va_mode != (mode_t)VNOVAL) {
611 if (vp->v_mount->mnt_flag & MNT_RDONLY)
612 return (EROFS);
613 if ((ip->i_flags & SF_SNAPSHOT) != 0 && (vap->va_mode &
614 (S_IXUSR | S_IWUSR | S_IXGRP | S_IWGRP | S_IXOTH | S_IWOTH)))
615 return (EPERM);
616 error = ufs_chmod(vp, (int)vap->va_mode, cred, td);
617 }
618 VN_KNOTE_UNLOCKED(vp, NOTE_ATTRIB);
619 return (error);
620 }
621
622 /*
623 * Change the mode on a file.
624 * Inode must be locked before calling.
625 */
626 static int
627 ufs_chmod(vp, mode, cred, td)
628 struct vnode *vp;
629 int mode;
630 struct ucred *cred;
631 struct thread *td;
632 {
633 struct inode *ip = VTOI(vp);
634 int error;
635
636 /*
637 * To modify the permissions on a file, must possess VADMIN
638 * for that file.
639 */
640 if ((error = VOP_ACCESS(vp, VADMIN, cred, td)))
641 return (error);
642 /*
643 * Privileged processes may set the sticky bit on non-directories,
644 * as well as set the setgid bit on a file with a group that the
645 * process is not a member of. Both of these are allowed in
646 * jail(8).
647 */
648 if (vp->v_type != VDIR && (mode & S_ISTXT)) {
649 if (suser_cred(cred, SUSER_ALLOWJAIL))
650 return (EFTYPE);
651 }
652 if (!groupmember(ip->i_gid, cred) && (mode & ISGID)) {
653 error = suser_cred(cred, SUSER_ALLOWJAIL);
654 if (error)
655 return (error);
656 }
657 ip->i_mode &= ~ALLPERMS;
658 ip->i_mode |= (mode & ALLPERMS);
659 DIP_SET(ip, i_mode, ip->i_mode);
660 ip->i_flag |= IN_CHANGE;
661 return (0);
662 }
663
664 /*
665 * Perform chown operation on inode ip;
666 * inode must be locked prior to call.
667 */
668 static int
669 ufs_chown(vp, uid, gid, cred, td)
670 struct vnode *vp;
671 uid_t uid;
672 gid_t gid;
673 struct ucred *cred;
674 struct thread *td;
675 {
676 struct inode *ip = VTOI(vp);
677 uid_t ouid;
678 gid_t ogid;
679 int error = 0;
680 #ifdef QUOTA
681 int i;
682 ufs2_daddr_t change;
683 #endif
684
685 if (uid == (uid_t)VNOVAL)
686 uid = ip->i_uid;
687 if (gid == (gid_t)VNOVAL)
688 gid = ip->i_gid;
689 /*
690 * To modify the ownership of a file, must possess VADMIN
691 * for that file.
692 */
693 if ((error = VOP_ACCESS(vp, VADMIN, cred, td)))
694 return (error);
695 /*
696 * To change the owner of a file, or change the group of a file
697 * to a group of which we are not a member, the caller must
698 * have privilege.
699 */
700 if ((uid != ip->i_uid ||
701 (gid != ip->i_gid && !groupmember(gid, cred))) &&
702 (error = suser_cred(cred, SUSER_ALLOWJAIL)))
703 return (error);
704 ogid = ip->i_gid;
705 ouid = ip->i_uid;
706 #ifdef QUOTA
707 if ((error = getinoquota(ip)) != 0)
708 return (error);
709 if (ouid == uid) {
710 dqrele(vp, ip->i_dquot[USRQUOTA]);
711 ip->i_dquot[USRQUOTA] = NODQUOT;
712 }
713 if (ogid == gid) {
714 dqrele(vp, ip->i_dquot[GRPQUOTA]);
715 ip->i_dquot[GRPQUOTA] = NODQUOT;
716 }
717 change = DIP(ip, i_blocks);
718 (void) chkdq(ip, -change, cred, CHOWN);
719 (void) chkiq(ip, -1, cred, CHOWN);
720 for (i = 0; i < MAXQUOTAS; i++) {
721 dqrele(vp, ip->i_dquot[i]);
722 ip->i_dquot[i] = NODQUOT;
723 }
724 #endif
725 ip->i_gid = gid;
726 DIP_SET(ip, i_gid, gid);
727 ip->i_uid = uid;
728 DIP_SET(ip, i_uid, uid);
729 #ifdef QUOTA
730 if ((error = getinoquota(ip)) == 0) {
731 if (ouid == uid) {
732 dqrele(vp, ip->i_dquot[USRQUOTA]);
733 ip->i_dquot[USRQUOTA] = NODQUOT;
734 }
735 if (ogid == gid) {
736 dqrele(vp, ip->i_dquot[GRPQUOTA]);
737 ip->i_dquot[GRPQUOTA] = NODQUOT;
738 }
739 if ((error = chkdq(ip, change, cred, CHOWN)) == 0) {
740 if ((error = chkiq(ip, 1, cred, CHOWN)) == 0)
741 goto good;
742 else
743 (void) chkdq(ip, -change, cred, CHOWN|FORCE);
744 }
745 for (i = 0; i < MAXQUOTAS; i++) {
746 dqrele(vp, ip->i_dquot[i]);
747 ip->i_dquot[i] = NODQUOT;
748 }
749 }
750 ip->i_gid = ogid;
751 DIP_SET(ip, i_gid, ogid);
752 ip->i_uid = ouid;
753 DIP_SET(ip, i_uid, ouid);
754 if (getinoquota(ip) == 0) {
755 if (ouid == uid) {
756 dqrele(vp, ip->i_dquot[USRQUOTA]);
757 ip->i_dquot[USRQUOTA] = NODQUOT;
758 }
759 if (ogid == gid) {
760 dqrele(vp, ip->i_dquot[GRPQUOTA]);
761 ip->i_dquot[GRPQUOTA] = NODQUOT;
762 }
763 (void) chkdq(ip, change, cred, FORCE|CHOWN);
764 (void) chkiq(ip, 1, cred, FORCE|CHOWN);
765 (void) getinoquota(ip);
766 }
767 return (error);
768 good:
769 if (getinoquota(ip))
770 panic("ufs_chown: lost quota");
771 #endif /* QUOTA */
772 ip->i_flag |= IN_CHANGE;
773 if (suser_cred(cred, SUSER_ALLOWJAIL) && (ouid != uid || ogid != gid)) {
774 ip->i_mode &= ~(ISUID | ISGID);
775 DIP_SET(ip, i_mode, ip->i_mode);
776 }
777 return (0);
778 }
779
780 static int
781 ufs_remove(ap)
782 struct vop_remove_args /* {
783 struct vnode *a_dvp;
784 struct vnode *a_vp;
785 struct componentname *a_cnp;
786 } */ *ap;
787 {
788 struct inode *ip;
789 struct vnode *vp = ap->a_vp;
790 struct vnode *dvp = ap->a_dvp;
791 int error;
792
793 ip = VTOI(vp);
794 if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) ||
795 (VTOI(dvp)->i_flags & APPEND)) {
796 error = EPERM;
797 goto out;
798 }
799 error = ufs_dirremove(dvp, ip, ap->a_cnp->cn_flags, 0);
800 if (ip->i_nlink <= 0)
801 vp->v_vflag |= VV_NOSYNC;
802 VN_KNOTE_UNLOCKED(vp, NOTE_DELETE);
803 VN_KNOTE_UNLOCKED(dvp, NOTE_WRITE);
804 out:
805 return (error);
806 }
807
808 /*
809 * link vnode call
810 */
811 static int
812 ufs_link(ap)
813 struct vop_link_args /* {
814 struct vnode *a_tdvp;
815 struct vnode *a_vp;
816 struct componentname *a_cnp;
817 } */ *ap;
818 {
819 struct vnode *vp = ap->a_vp;
820 struct vnode *tdvp = ap->a_tdvp;
821 struct componentname *cnp = ap->a_cnp;
822 struct inode *ip;
823 struct direct newdir;
824 int error;
825
826 #ifdef DIAGNOSTIC
827 if ((cnp->cn_flags & HASBUF) == 0)
828 panic("ufs_link: no name");
829 #endif
830 if (tdvp->v_mount != vp->v_mount) {
831 error = EXDEV;
832 goto out;
833 }
834 ip = VTOI(vp);
835 if ((nlink_t)ip->i_nlink >= LINK_MAX) {
836 error = EMLINK;
837 goto out;
838 }
839 if (ip->i_flags & (IMMUTABLE | APPEND)) {
840 error = EPERM;
841 goto out;
842 }
843 ip->i_effnlink++;
844 ip->i_nlink++;
845 DIP_SET(ip, i_nlink, ip->i_nlink);
846 ip->i_flag |= IN_CHANGE;
847 if (DOINGSOFTDEP(vp))
848 softdep_change_linkcnt(ip);
849 error = UFS_UPDATE(vp, !(DOINGSOFTDEP(vp) | DOINGASYNC(vp)));
850 if (!error) {
851 ufs_makedirentry(ip, cnp, &newdir);
852 error = ufs_direnter(tdvp, vp, &newdir, cnp, NULL);
853 }
854
855 if (error) {
856 ip->i_effnlink--;
857 ip->i_nlink--;
858 DIP_SET(ip, i_nlink, ip->i_nlink);
859 ip->i_flag |= IN_CHANGE;
860 if (DOINGSOFTDEP(vp))
861 softdep_change_linkcnt(ip);
862 }
863 out:
864 VN_KNOTE_UNLOCKED(vp, NOTE_LINK);
865 VN_KNOTE_UNLOCKED(tdvp, NOTE_WRITE);
866 return (error);
867 }
868
869 /*
870 * whiteout vnode call
871 */
872 static int
873 ufs_whiteout(ap)
874 struct vop_whiteout_args /* {
875 struct vnode *a_dvp;
876 struct componentname *a_cnp;
877 int a_flags;
878 } */ *ap;
879 {
880 struct vnode *dvp = ap->a_dvp;
881 struct componentname *cnp = ap->a_cnp;
882 struct direct newdir;
883 int error = 0;
884
885 switch (ap->a_flags) {
886 case LOOKUP:
887 /* 4.4 format directories support whiteout operations */
888 if (dvp->v_mount->mnt_maxsymlinklen > 0)
889 return (0);
890 return (EOPNOTSUPP);
891
892 case CREATE:
893 /* create a new directory whiteout */
894 #ifdef DIAGNOSTIC
895 if ((cnp->cn_flags & SAVENAME) == 0)
896 panic("ufs_whiteout: missing name");
897 if (dvp->v_mount->mnt_maxsymlinklen <= 0)
898 panic("ufs_whiteout: old format filesystem");
899 #endif
900
901 newdir.d_ino = WINO;
902 newdir.d_namlen = cnp->cn_namelen;
903 bcopy(cnp->cn_nameptr, newdir.d_name, (unsigned)cnp->cn_namelen + 1);
904 newdir.d_type = DT_WHT;
905 error = ufs_direnter(dvp, NULL, &newdir, cnp, NULL);
906 break;
907
908 case DELETE:
909 /* remove an existing directory whiteout */
910 #ifdef DIAGNOSTIC
911 if (dvp->v_mount->mnt_maxsymlinklen <= 0)
912 panic("ufs_whiteout: old format filesystem");
913 #endif
914
915 cnp->cn_flags &= ~DOWHITEOUT;
916 error = ufs_dirremove(dvp, NULL, cnp->cn_flags, 0);
917 break;
918 default:
919 panic("ufs_whiteout: unknown op");
920 }
921 return (error);
922 }
923
924 /*
925 * Rename system call.
926 * rename("foo", "bar");
927 * is essentially
928 * unlink("bar");
929 * link("foo", "bar");
930 * unlink("foo");
931 * but ``atomically''. Can't do full commit without saving state in the
932 * inode on disk which isn't feasible at this time. Best we can do is
933 * always guarantee the target exists.
934 *
935 * Basic algorithm is:
936 *
937 * 1) Bump link count on source while we're linking it to the
938 * target. This also ensure the inode won't be deleted out
939 * from underneath us while we work (it may be truncated by
940 * a concurrent `trunc' or `open' for creation).
941 * 2) Link source to destination. If destination already exists,
942 * delete it first.
943 * 3) Unlink source reference to inode if still around. If a
944 * directory was moved and the parent of the destination
945 * is different from the source, patch the ".." entry in the
946 * directory.
947 */
948 static int
949 ufs_rename(ap)
950 struct vop_rename_args /* {
951 struct vnode *a_fdvp;
952 struct vnode *a_fvp;
953 struct componentname *a_fcnp;
954 struct vnode *a_tdvp;
955 struct vnode *a_tvp;
956 struct componentname *a_tcnp;
957 } */ *ap;
958 {
959 struct vnode *tvp = ap->a_tvp;
960 struct vnode *tdvp = ap->a_tdvp;
961 struct vnode *fvp = ap->a_fvp;
962 struct vnode *fdvp = ap->a_fdvp;
963 struct componentname *tcnp = ap->a_tcnp;
964 struct componentname *fcnp = ap->a_fcnp;
965 struct thread *td = fcnp->cn_thread;
966 struct inode *ip, *xp, *dp;
967 struct direct newdir;
968 int doingdirectory = 0, oldparent = 0, newparent = 0;
969 int error = 0, ioflag;
970
971 #ifdef DIAGNOSTIC
972 if ((tcnp->cn_flags & HASBUF) == 0 ||
973 (fcnp->cn_flags & HASBUF) == 0)
974 panic("ufs_rename: no name");
975 #endif
976 /*
977 * Check for cross-device rename.
978 */
979 if ((fvp->v_mount != tdvp->v_mount) ||
980 (tvp && (fvp->v_mount != tvp->v_mount))) {
981 error = EXDEV;
982 abortit:
983 if (tdvp == tvp)
984 vrele(tdvp);
985 else
986 vput(tdvp);
987 if (tvp)
988 vput(tvp);
989 vrele(fdvp);
990 vrele(fvp);
991 return (error);
992 }
993
994 if (tvp && ((VTOI(tvp)->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) ||
995 (VTOI(tdvp)->i_flags & APPEND))) {
996 error = EPERM;
997 goto abortit;
998 }
999
1000 /*
1001 * Renaming a file to itself has no effect. The upper layers should
1002 * not call us in that case. Temporarily just warn if they do.
1003 */
1004 if (fvp == tvp) {
1005 printf("ufs_rename: fvp == tvp (can't happen)\n");
1006 error = 0;
1007 goto abortit;
1008 }
1009
1010 if ((error = vn_lock(fvp, LK_EXCLUSIVE, td)) != 0)
1011 goto abortit;
1012 dp = VTOI(fdvp);
1013 ip = VTOI(fvp);
1014 if (ip->i_nlink >= LINK_MAX) {
1015 VOP_UNLOCK(fvp, 0, td);
1016 error = EMLINK;
1017 goto abortit;
1018 }
1019 if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND))
1020 || (dp->i_flags & APPEND)) {
1021 VOP_UNLOCK(fvp, 0, td);
1022 error = EPERM;
1023 goto abortit;
1024 }
1025 if ((ip->i_mode & IFMT) == IFDIR) {
1026 /*
1027 * Avoid ".", "..", and aliases of "." for obvious reasons.
1028 */
1029 if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') ||
1030 dp == ip || (fcnp->cn_flags | tcnp->cn_flags) & ISDOTDOT ||
1031 (ip->i_flag & IN_RENAME)) {
1032 VOP_UNLOCK(fvp, 0, td);
1033 error = EINVAL;
1034 goto abortit;
1035 }
1036 ip->i_flag |= IN_RENAME;
1037 oldparent = dp->i_number;
1038 doingdirectory = 1;
1039 }
1040 VN_KNOTE_UNLOCKED(fdvp, NOTE_WRITE); /* XXX right place? */
1041 vrele(fdvp);
1042
1043 /*
1044 * When the target exists, both the directory
1045 * and target vnodes are returned locked.
1046 */
1047 dp = VTOI(tdvp);
1048 xp = NULL;
1049 if (tvp)
1050 xp = VTOI(tvp);
1051
1052 /*
1053 * 1) Bump link count while we're moving stuff
1054 * around. If we crash somewhere before
1055 * completing our work, the link count
1056 * may be wrong, but correctable.
1057 */
1058 ip->i_effnlink++;
1059 ip->i_nlink++;
1060 DIP_SET(ip, i_nlink, ip->i_nlink);
1061 ip->i_flag |= IN_CHANGE;
1062 if (DOINGSOFTDEP(fvp))
1063 softdep_change_linkcnt(ip);
1064 if ((error = UFS_UPDATE(fvp, !(DOINGSOFTDEP(fvp) |
1065 DOINGASYNC(fvp)))) != 0) {
1066 VOP_UNLOCK(fvp, 0, td);
1067 goto bad;
1068 }
1069
1070 /*
1071 * If ".." must be changed (ie the directory gets a new
1072 * parent) then the source directory must not be in the
1073 * directory heirarchy above the target, as this would
1074 * orphan everything below the source directory. Also
1075 * the user must have write permission in the source so
1076 * as to be able to change "..". We must repeat the call
1077 * to namei, as the parent directory is unlocked by the
1078 * call to checkpath().
1079 */
1080 error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred, tcnp->cn_thread);
1081 VOP_UNLOCK(fvp, 0, td);
1082 if (oldparent != dp->i_number)
1083 newparent = dp->i_number;
1084 if (doingdirectory && newparent) {
1085 if (error) /* write access check above */
1086 goto bad;
1087 if (xp != NULL)
1088 vput(tvp);
1089 error = ufs_checkpath(ip, dp, tcnp->cn_cred);
1090 if (error)
1091 goto out;
1092 if ((tcnp->cn_flags & SAVESTART) == 0)
1093 panic("ufs_rename: lost to startdir");
1094 VREF(tdvp);
1095 error = relookup(tdvp, &tvp, tcnp);
1096 if (error)
1097 goto out;
1098 vrele(tdvp);
1099 dp = VTOI(tdvp);
1100 xp = NULL;
1101 if (tvp)
1102 xp = VTOI(tvp);
1103 }
1104 /*
1105 * 2) If target doesn't exist, link the target
1106 * to the source and unlink the source.
1107 * Otherwise, rewrite the target directory
1108 * entry to reference the source inode and
1109 * expunge the original entry's existence.
1110 */
1111 if (xp == NULL) {
1112 if (dp->i_dev != ip->i_dev)
1113 panic("ufs_rename: EXDEV");
1114 /*
1115 * Account for ".." in new directory.
1116 * When source and destination have the same
1117 * parent we don't fool with the link count.
1118 */
1119 if (doingdirectory && newparent) {
1120 if ((nlink_t)dp->i_nlink >= LINK_MAX) {
1121 error = EMLINK;
1122 goto bad;
1123 }
1124 dp->i_effnlink++;
1125 dp->i_nlink++;
1126 DIP_SET(dp, i_nlink, dp->i_nlink);
1127 dp->i_flag |= IN_CHANGE;
1128 if (DOINGSOFTDEP(tdvp))
1129 softdep_change_linkcnt(dp);
1130 error = UFS_UPDATE(tdvp, !(DOINGSOFTDEP(tdvp) |
1131 DOINGASYNC(tdvp)));
1132 if (error)
1133 goto bad;
1134 }
1135 ufs_makedirentry(ip, tcnp, &newdir);
1136 error = ufs_direnter(tdvp, NULL, &newdir, tcnp, NULL);
1137 if (error) {
1138 if (doingdirectory && newparent) {
1139 dp->i_effnlink--;
1140 dp->i_nlink--;
1141 DIP_SET(dp, i_nlink, dp->i_nlink);
1142 dp->i_flag |= IN_CHANGE;
1143 if (DOINGSOFTDEP(tdvp))
1144 softdep_change_linkcnt(dp);
1145 (void)UFS_UPDATE(tdvp, 1);
1146 }
1147 goto bad;
1148 }
1149 VN_KNOTE_UNLOCKED(tdvp, NOTE_WRITE);
1150 vput(tdvp);
1151 } else {
1152 if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev)
1153 panic("ufs_rename: EXDEV");
1154 /*
1155 * Short circuit rename(foo, foo).
1156 */
1157 if (xp->i_number == ip->i_number)
1158 panic("ufs_rename: same file");
1159 /*
1160 * If the parent directory is "sticky", then the caller
1161 * must possess VADMIN for the parent directory, or the
1162 * destination of the rename. This implements append-only
1163 * directories.
1164 */
1165 if ((dp->i_mode & S_ISTXT) &&
1166 VOP_ACCESS(tdvp, VADMIN, tcnp->cn_cred, td) &&
1167 VOP_ACCESS(tvp, VADMIN, tcnp->cn_cred, td)) {
1168 error = EPERM;
1169 goto bad;
1170 }
1171 /*
1172 * Target must be empty if a directory and have no links
1173 * to it. Also, ensure source and target are compatible
1174 * (both directories, or both not directories).
1175 */
1176 if ((xp->i_mode&IFMT) == IFDIR) {
1177 if ((xp->i_effnlink > 2) ||
1178 !ufs_dirempty(xp, dp->i_number, tcnp->cn_cred)) {
1179 error = ENOTEMPTY;
1180 goto bad;
1181 }
1182 if (!doingdirectory) {
1183 error = ENOTDIR;
1184 goto bad;
1185 }
1186 cache_purge(tdvp);
1187 } else if (doingdirectory) {
1188 error = EISDIR;
1189 goto bad;
1190 }
1191 error = ufs_dirrewrite(dp, xp, ip->i_number,
1192 IFTODT(ip->i_mode),
1193 (doingdirectory && newparent) ? newparent : doingdirectory);
1194 if (error)
1195 goto bad;
1196 if (doingdirectory) {
1197 if (!newparent) {
1198 dp->i_effnlink--;
1199 if (DOINGSOFTDEP(tdvp))
1200 softdep_change_linkcnt(dp);
1201 }
1202 xp->i_effnlink--;
1203 if (DOINGSOFTDEP(tvp))
1204 softdep_change_linkcnt(xp);
1205 }
1206 if (doingdirectory && !DOINGSOFTDEP(tvp)) {
1207 /*
1208 * Truncate inode. The only stuff left in the directory
1209 * is "." and "..". The "." reference is inconsequential
1210 * since we are quashing it. We have removed the "."
1211 * reference and the reference in the parent directory,
1212 * but there may be other hard links. The soft
1213 * dependency code will arrange to do these operations
1214 * after the parent directory entry has been deleted on
1215 * disk, so when running with that code we avoid doing
1216 * them now.
1217 */
1218 if (!newparent) {
1219 dp->i_nlink--;
1220 DIP_SET(dp, i_nlink, dp->i_nlink);
1221 dp->i_flag |= IN_CHANGE;
1222 }
1223 xp->i_nlink--;
1224 DIP_SET(xp, i_nlink, xp->i_nlink);
1225 xp->i_flag |= IN_CHANGE;
1226 ioflag = IO_NORMAL;
1227 if (DOINGASYNC(tvp))
1228 ioflag |= IO_SYNC;
1229 if ((error = UFS_TRUNCATE(tvp, (off_t)0, ioflag,
1230 tcnp->cn_cred, tcnp->cn_thread)) != 0)
1231 goto bad;
1232 }
1233 VN_KNOTE_UNLOCKED(tdvp, NOTE_WRITE);
1234 vput(tdvp);
1235 VN_KNOTE_UNLOCKED(tvp, NOTE_DELETE);
1236 vput(tvp);
1237 xp = NULL;
1238 }
1239
1240 /*
1241 * 3) Unlink the source.
1242 */
1243 fcnp->cn_flags &= ~MODMASK;
1244 fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
1245 if ((fcnp->cn_flags & SAVESTART) == 0)
1246 panic("ufs_rename: lost from startdir");
1247 VREF(fdvp);
1248 error = relookup(fdvp, &fvp, fcnp);
1249 if (error == 0)
1250 vrele(fdvp);
1251 if (fvp != NULL) {
1252 xp = VTOI(fvp);
1253 dp = VTOI(fdvp);
1254 } else {
1255 /*
1256 * From name has disappeared. IN_RENAME is not sufficient
1257 * to protect against directory races due to timing windows,
1258 * so we have to remove the panic. XXX the only real way
1259 * to solve this issue is at a much higher level. By the
1260 * time we hit ufs_rename() it's too late.
1261 */
1262 #if 0
1263 if (doingdirectory)
1264 panic("ufs_rename: lost dir entry");
1265 #endif
1266 vrele(ap->a_fvp);
1267 return (0);
1268 }
1269 /*
1270 * Ensure that the directory entry still exists and has not
1271 * changed while the new name has been entered. If the source is
1272 * a file then the entry may have been unlinked or renamed. In
1273 * either case there is no further work to be done. If the source
1274 * is a directory then it cannot have been rmdir'ed; the IN_RENAME
1275 * flag ensures that it cannot be moved by another rename or removed
1276 * by a rmdir.
1277 */
1278 if (xp != ip) {
1279 /*
1280 * From name resolves to a different inode. IN_RENAME is
1281 * not sufficient protection against timing window races
1282 * so we can't panic here. XXX the only real way
1283 * to solve this issue is at a much higher level. By the
1284 * time we hit ufs_rename() it's too late.
1285 */
1286 #if 0
1287 if (doingdirectory)
1288 panic("ufs_rename: lost dir entry");
1289 #endif
1290 } else {
1291 /*
1292 * If the source is a directory with a
1293 * new parent, the link count of the old
1294 * parent directory must be decremented
1295 * and ".." set to point to the new parent.
1296 */
1297 if (doingdirectory && newparent) {
1298 xp->i_offset = mastertemplate.dot_reclen;
1299 ufs_dirrewrite(xp, dp, newparent, DT_DIR, 0);
1300 cache_purge(fdvp);
1301 }
1302 error = ufs_dirremove(fdvp, xp, fcnp->cn_flags, 0);
1303 xp->i_flag &= ~IN_RENAME;
1304 }
1305 VN_KNOTE_UNLOCKED(fvp, NOTE_RENAME);
1306 if (dp)
1307 vput(fdvp);
1308 if (xp)
1309 vput(fvp);
1310 vrele(ap->a_fvp);
1311 return (error);
1312
1313 bad:
1314 if (xp)
1315 vput(ITOV(xp));
1316 vput(ITOV(dp));
1317 out:
1318 if (doingdirectory)
1319 ip->i_flag &= ~IN_RENAME;
1320 if (vn_lock(fvp, LK_EXCLUSIVE, td) == 0) {
1321 ip->i_effnlink--;
1322 ip->i_nlink--;
1323 DIP_SET(ip, i_nlink, ip->i_nlink);
1324 ip->i_flag |= IN_CHANGE;
1325 ip->i_flag &= ~IN_RENAME;
1326 if (DOINGSOFTDEP(fvp))
1327 softdep_change_linkcnt(ip);
1328 vput(fvp);
1329 } else
1330 vrele(fvp);
1331 return (error);
1332 }
1333
1334 /*
1335 * Mkdir system call
1336 */
1337 static int
1338 ufs_mkdir(ap)
1339 struct vop_mkdir_args /* {
1340 struct vnode *a_dvp;
1341 struct vnode **a_vpp;
1342 struct componentname *a_cnp;
1343 struct vattr *a_vap;
1344 } */ *ap;
1345 {
1346 struct vnode *dvp = ap->a_dvp;
1347 struct vattr *vap = ap->a_vap;
1348 struct componentname *cnp = ap->a_cnp;
1349 struct inode *ip, *dp;
1350 struct vnode *tvp;
1351 struct buf *bp;
1352 struct dirtemplate dirtemplate, *dtp;
1353 struct direct newdir;
1354 #ifdef UFS_ACL
1355 struct acl *acl, *dacl;
1356 #endif
1357 int error, dmode;
1358 long blkoff;
1359
1360 #ifdef DIAGNOSTIC
1361 if ((cnp->cn_flags & HASBUF) == 0)
1362 panic("ufs_mkdir: no name");
1363 #endif
1364 dp = VTOI(dvp);
1365 if ((nlink_t)dp->i_nlink >= LINK_MAX) {
1366 error = EMLINK;
1367 goto out;
1368 }
1369 dmode = vap->va_mode & 0777;
1370 dmode |= IFDIR;
1371 /*
1372 * Must simulate part of ufs_makeinode here to acquire the inode,
1373 * but not have it entered in the parent directory. The entry is
1374 * made later after writing "." and ".." entries.
1375 */
1376 error = UFS_VALLOC(dvp, dmode, cnp->cn_cred, &tvp);
1377 if (error)
1378 goto out;
1379 ip = VTOI(tvp);
1380 ip->i_gid = dp->i_gid;
1381 DIP_SET(ip, i_gid, dp->i_gid);
1382 #ifdef SUIDDIR
1383 {
1384 #ifdef QUOTA
1385 struct ucred ucred, *ucp;
1386 ucp = cnp->cn_cred;
1387 #endif
1388 /*
1389 * If we are hacking owners here, (only do this where told to)
1390 * and we are not giving it TO root, (would subvert quotas)
1391 * then go ahead and give it to the other user.
1392 * The new directory also inherits the SUID bit.
1393 * If user's UID and dir UID are the same,
1394 * 'give it away' so that the SUID is still forced on.
1395 */
1396 if ((dvp->v_mount->mnt_flag & MNT_SUIDDIR) &&
1397 (dp->i_mode & ISUID) && dp->i_uid) {
1398 dmode |= ISUID;
1399 ip->i_uid = dp->i_uid;
1400 DIP_SET(ip, i_uid, dp->i_uid);
1401 #ifdef QUOTA
1402 if (dp->i_uid != cnp->cn_cred->cr_uid) {
1403 /*
1404 * Make sure the correct user gets charged
1405 * for the space.
1406 * Make a dummy credential for the victim.
1407 * XXX This seems to never be accessed out of
1408 * our context so a stack variable is ok.
1409 */
1410 ucred.cr_ref = 1;
1411 ucred.cr_uid = ip->i_uid;
1412 ucred.cr_ngroups = 1;
1413 ucred.cr_groups[0] = dp->i_gid;
1414 ucp = &ucred;
1415 }
1416 #endif
1417 } else {
1418 ip->i_uid = cnp->cn_cred->cr_uid;
1419 DIP_SET(ip, i_uid, ip->i_uid);
1420 }
1421 #ifdef QUOTA
1422 if ((error = getinoquota(ip)) ||
1423 (error = chkiq(ip, 1, ucp, 0))) {
1424 UFS_VFREE(tvp, ip->i_number, dmode);
1425 vput(tvp);
1426 return (error);
1427 }
1428 #endif
1429 }
1430 #else /* !SUIDDIR */
1431 ip->i_uid = cnp->cn_cred->cr_uid;
1432 DIP_SET(ip, i_uid, ip->i_uid);
1433 #ifdef QUOTA
1434 if ((error = getinoquota(ip)) ||
1435 (error = chkiq(ip, 1, cnp->cn_cred, 0))) {
1436 UFS_VFREE(tvp, ip->i_number, dmode);
1437 vput(tvp);
1438 return (error);
1439 }
1440 #endif
1441 #endif /* !SUIDDIR */
1442 ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
1443 #ifdef UFS_ACL
1444 acl = dacl = NULL;
1445 if ((dvp->v_mount->mnt_flag & MNT_ACLS) != 0) {
1446 MALLOC(acl, struct acl *, sizeof(*acl), M_ACL, M_WAITOK);
1447 MALLOC(dacl, struct acl *, sizeof(*dacl), M_ACL, M_WAITOK);
1448
1449 /*
1450 * Retrieve default ACL from parent, if any.
1451 */
1452 error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cnp->cn_cred,
1453 cnp->cn_thread);
1454 switch (error) {
1455 case 0:
1456 /*
1457 * Retrieved a default ACL, so merge mode and ACL if
1458 * necessary. If the ACL is empty, fall through to
1459 * the "not defined or available" case.
1460 */
1461 if (acl->acl_cnt != 0) {
1462 dmode = acl_posix1e_newfilemode(dmode, acl);
1463 ip->i_mode = dmode;
1464 DIP_SET(ip, i_mode, dmode);
1465 *dacl = *acl;
1466 ufs_sync_acl_from_inode(ip, acl);
1467 break;
1468 }
1469 /* FALLTHROUGH */
1470
1471 case EOPNOTSUPP:
1472 /*
1473 * Just use the mode as-is.
1474 */
1475 ip->i_mode = dmode;
1476 DIP_SET(ip, i_mode, dmode);
1477 FREE(acl, M_ACL);
1478 FREE(dacl, M_ACL);
1479 dacl = acl = NULL;
1480 break;
1481
1482 default:
1483 UFS_VFREE(tvp, ip->i_number, dmode);
1484 vput(tvp);
1485 FREE(acl, M_ACL);
1486 FREE(dacl, M_ACL);
1487 return (error);
1488 }
1489 } else {
1490 #endif /* !UFS_ACL */
1491 ip->i_mode = dmode;
1492 DIP_SET(ip, i_mode, dmode);
1493 #ifdef UFS_ACL
1494 }
1495 #endif
1496 tvp->v_type = VDIR; /* Rest init'd in getnewvnode(). */
1497 ip->i_effnlink = 2;
1498 ip->i_nlink = 2;
1499 DIP_SET(ip, i_nlink, 2);
1500 if (DOINGSOFTDEP(tvp))
1501 softdep_change_linkcnt(ip);
1502 if (cnp->cn_flags & ISWHITEOUT) {
1503 ip->i_flags |= UF_OPAQUE;
1504 DIP_SET(ip, i_flags, ip->i_flags);
1505 }
1506
1507 /*
1508 * Bump link count in parent directory to reflect work done below.
1509 * Should be done before reference is created so cleanup is
1510 * possible if we crash.
1511 */
1512 dp->i_effnlink++;
1513 dp->i_nlink++;
1514 DIP_SET(dp, i_nlink, dp->i_nlink);
1515 dp->i_flag |= IN_CHANGE;
1516 if (DOINGSOFTDEP(dvp))
1517 softdep_change_linkcnt(dp);
1518 error = UFS_UPDATE(tvp, !(DOINGSOFTDEP(dvp) | DOINGASYNC(dvp)));
1519 if (error)
1520 goto bad;
1521 #ifdef MAC
1522 if (dvp->v_mount->mnt_flag & MNT_MULTILABEL) {
1523 error = mac_create_vnode_extattr(cnp->cn_cred, dvp->v_mount,
1524 dvp, tvp, cnp);
1525 if (error)
1526 goto bad;
1527 }
1528 #endif
1529 #ifdef UFS_ACL
1530 if (acl != NULL) {
1531 /*
1532 * XXX: If we abort now, will Soft Updates notify the extattr
1533 * code that the EAs for the file need to be released?
1534 */
1535 error = VOP_SETACL(tvp, ACL_TYPE_ACCESS, acl, cnp->cn_cred,
1536 cnp->cn_thread);
1537 if (error == 0)
1538 error = VOP_SETACL(tvp, ACL_TYPE_DEFAULT, dacl,
1539 cnp->cn_cred, cnp->cn_thread);
1540 switch (error) {
1541 case 0:
1542 break;
1543
1544 case EOPNOTSUPP:
1545 /*
1546 * XXX: This should not happen, as EOPNOTSUPP above
1547 * was supposed to free acl.
1548 */
1549 printf("ufs_mkdir: VOP_GETACL() but no VOP_SETACL()\n");
1550 /*
1551 panic("ufs_mkdir: VOP_GETACL() but no VOP_SETACL()");
1552 */
1553 break;
1554
1555 default:
1556 FREE(acl, M_ACL);
1557 FREE(dacl, M_ACL);
1558 goto bad;
1559 }
1560 FREE(acl, M_ACL);
1561 FREE(dacl, M_ACL);
1562 }
1563 #endif /* !UFS_ACL */
1564
1565 /*
1566 * Initialize directory with "." and ".." from static template.
1567 */
1568 if (dvp->v_mount->mnt_maxsymlinklen > 0
1569 )
1570 dtp = &mastertemplate;
1571 else
1572 dtp = (struct dirtemplate *)&omastertemplate;
1573 dirtemplate = *dtp;
1574 dirtemplate.dot_ino = ip->i_number;
1575 dirtemplate.dotdot_ino = dp->i_number;
1576 if ((error = UFS_BALLOC(tvp, (off_t)0, DIRBLKSIZ, cnp->cn_cred,
1577 BA_CLRBUF, &bp)) != 0)
1578 goto bad;
1579 ip->i_size = DIRBLKSIZ;
1580 DIP_SET(ip, i_size, DIRBLKSIZ);
1581 ip->i_flag |= IN_CHANGE | IN_UPDATE;
1582 vnode_pager_setsize(tvp, (u_long)ip->i_size);
1583 bcopy((caddr_t)&dirtemplate, (caddr_t)bp->b_data, sizeof dirtemplate);
1584 if (DOINGSOFTDEP(tvp)) {
1585 /*
1586 * Ensure that the entire newly allocated block is a
1587 * valid directory so that future growth within the
1588 * block does not have to ensure that the block is
1589 * written before the inode.
1590 */
1591 blkoff = DIRBLKSIZ;
1592 while (blkoff < bp->b_bcount) {
1593 ((struct direct *)
1594 (bp->b_data + blkoff))->d_reclen = DIRBLKSIZ;
1595 blkoff += DIRBLKSIZ;
1596 }
1597 }
1598 if ((error = UFS_UPDATE(tvp, !(DOINGSOFTDEP(tvp) |
1599 DOINGASYNC(tvp)))) != 0) {
1600 (void)bwrite(bp);
1601 goto bad;
1602 }
1603 /*
1604 * Directory set up, now install its entry in the parent directory.
1605 *
1606 * If we are not doing soft dependencies, then we must write out the
1607 * buffer containing the new directory body before entering the new
1608 * name in the parent. If we are doing soft dependencies, then the
1609 * buffer containing the new directory body will be passed to and
1610 * released in the soft dependency code after the code has attached
1611 * an appropriate ordering dependency to the buffer which ensures that
1612 * the buffer is written before the new name is written in the parent.
1613 */
1614 if (DOINGASYNC(dvp))
1615 bdwrite(bp);
1616 else if (!DOINGSOFTDEP(dvp) && ((error = bwrite(bp))))
1617 goto bad;
1618 ufs_makedirentry(ip, cnp, &newdir);
1619 error = ufs_direnter(dvp, tvp, &newdir, cnp, bp);
1620
1621 bad:
1622 if (error == 0) {
1623 VN_KNOTE_UNLOCKED(dvp, NOTE_WRITE | NOTE_LINK);
1624 *ap->a_vpp = tvp;
1625 } else {
1626 dp->i_effnlink--;
1627 dp->i_nlink--;
1628 DIP_SET(dp, i_nlink, dp->i_nlink);
1629 dp->i_flag |= IN_CHANGE;
1630 if (DOINGSOFTDEP(dvp))
1631 softdep_change_linkcnt(dp);
1632 /*
1633 * No need to do an explicit VOP_TRUNCATE here, vrele will
1634 * do this for us because we set the link count to 0.
1635 */
1636 ip->i_effnlink = 0;
1637 ip->i_nlink = 0;
1638 DIP_SET(ip, i_nlink, 0);
1639 ip->i_flag |= IN_CHANGE;
1640 if (DOINGSOFTDEP(tvp))
1641 softdep_change_linkcnt(ip);
1642 vput(tvp);
1643 }
1644 out:
1645 return (error);
1646 }
1647
1648 /*
1649 * Rmdir system call.
1650 */
1651 static int
1652 ufs_rmdir(ap)
1653 struct vop_rmdir_args /* {
1654 struct vnode *a_dvp;
1655 struct vnode *a_vp;
1656 struct componentname *a_cnp;
1657 } */ *ap;
1658 {
1659 struct vnode *vp = ap->a_vp;
1660 struct vnode *dvp = ap->a_dvp;
1661 struct componentname *cnp = ap->a_cnp;
1662 struct inode *ip, *dp;
1663 int error, ioflag;
1664
1665 ip = VTOI(vp);
1666 dp = VTOI(dvp);
1667
1668 /*
1669 * Do not remove a directory that is in the process of being renamed.
1670 * Verify the directory is empty (and valid). Rmdir ".." will not be
1671 * valid since ".." will contain a reference to the current directory
1672 * and thus be non-empty. Do not allow the removal of mounted on
1673 * directories (this can happen when an NFS exported filesystem
1674 * tries to remove a locally mounted on directory).
1675 */
1676 error = 0;
1677 if (ip->i_flag & IN_RENAME) {
1678 error = EINVAL;
1679 goto out;
1680 }
1681 if (ip->i_effnlink != 2 ||
1682 !ufs_dirempty(ip, dp->i_number, cnp->cn_cred)) {
1683 error = ENOTEMPTY;
1684 goto out;
1685 }
1686 if ((dp->i_flags & APPEND)
1687 || (ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND))) {
1688 error = EPERM;
1689 goto out;
1690 }
1691 if (vp->v_mountedhere != 0) {
1692 error = EINVAL;
1693 goto out;
1694 }
1695 /*
1696 * Delete reference to directory before purging
1697 * inode. If we crash in between, the directory
1698 * will be reattached to lost+found,
1699 */
1700 dp->i_effnlink--;
1701 ip->i_effnlink--;
1702 if (DOINGSOFTDEP(vp)) {
1703 softdep_change_linkcnt(dp);
1704 softdep_change_linkcnt(ip);
1705 }
1706 error = ufs_dirremove(dvp, ip, cnp->cn_flags, 1);
1707 if (error) {
1708 dp->i_effnlink++;
1709 ip->i_effnlink++;
1710 if (DOINGSOFTDEP(vp)) {
1711 softdep_change_linkcnt(dp);
1712 softdep_change_linkcnt(ip);
1713 }
1714 goto out;
1715 }
1716 VN_KNOTE_UNLOCKED(dvp, NOTE_WRITE | NOTE_LINK);
1717 cache_purge(dvp);
1718 /*
1719 * Truncate inode. The only stuff left in the directory is "." and
1720 * "..". The "." reference is inconsequential since we are quashing
1721 * it. The soft dependency code will arrange to do these operations
1722 * after the parent directory entry has been deleted on disk, so
1723 * when running with that code we avoid doing them now.
1724 */
1725 if (!DOINGSOFTDEP(vp)) {
1726 dp->i_nlink--;
1727 DIP_SET(dp, i_nlink, dp->i_nlink);
1728 dp->i_flag |= IN_CHANGE;
1729 ip->i_nlink--;
1730 DIP_SET(ip, i_nlink, ip->i_nlink);
1731 ip->i_flag |= IN_CHANGE;
1732 ioflag = IO_NORMAL;
1733 if (DOINGASYNC(vp))
1734 ioflag |= IO_SYNC;
1735 error = UFS_TRUNCATE(vp, (off_t)0, ioflag, cnp->cn_cred,
1736 cnp->cn_thread);
1737 }
1738 cache_purge(vp);
1739 #ifdef UFS_DIRHASH
1740 /* Kill any active hash; i_effnlink == 0, so it will not come back. */
1741 if (ip->i_dirhash != NULL)
1742 ufsdirhash_free(ip);
1743 #endif
1744 out:
1745 VN_KNOTE_UNLOCKED(vp, NOTE_DELETE);
1746 return (error);
1747 }
1748
1749 /*
1750 * symlink -- make a symbolic link
1751 */
1752 static int
1753 ufs_symlink(ap)
1754 struct vop_symlink_args /* {
1755 struct vnode *a_dvp;
1756 struct vnode **a_vpp;
1757 struct componentname *a_cnp;
1758 struct vattr *a_vap;
1759 char *a_target;
1760 } */ *ap;
1761 {
1762 struct vnode *vp, **vpp = ap->a_vpp;
1763 struct inode *ip;
1764 int len, error;
1765
1766 error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp,
1767 vpp, ap->a_cnp);
1768 if (error)
1769 return (error);
1770 VN_KNOTE_UNLOCKED(ap->a_dvp, NOTE_WRITE);
1771 vp = *vpp;
1772 len = strlen(ap->a_target);
1773 if (len < vp->v_mount->mnt_maxsymlinklen) {
1774 ip = VTOI(vp);
1775 bcopy(ap->a_target, SHORTLINK(ip), len);
1776 ip->i_size = len;
1777 DIP_SET(ip, i_size, len);
1778 ip->i_flag |= IN_CHANGE | IN_UPDATE;
1779 } else
1780 error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0,
1781 UIO_SYSSPACE, IO_NODELOCKED | IO_NOMACCHECK,
1782 ap->a_cnp->cn_cred, NOCRED, (int *)0, (struct thread *)0);
1783 if (error)
1784 vput(vp);
1785 return (error);
1786 }
1787
1788 /*
1789 * Vnode op for reading directories.
1790 *
1791 * The routine below assumes that the on-disk format of a directory
1792 * is the same as that defined by <sys/dirent.h>. If the on-disk
1793 * format changes, then it will be necessary to do a conversion
1794 * from the on-disk format that read returns to the format defined
1795 * by <sys/dirent.h>.
1796 */
1797 int
1798 ufs_readdir(ap)
1799 struct vop_readdir_args /* {
1800 struct vnode *a_vp;
1801 struct uio *a_uio;
1802 struct ucred *a_cred;
1803 int *a_eofflag;
1804 int *ncookies;
1805 u_long **a_cookies;
1806 } */ *ap;
1807 {
1808 struct uio *uio = ap->a_uio;
1809 int error;
1810 size_t count, lost;
1811 off_t off;
1812
1813 if (ap->a_ncookies != NULL)
1814 /*
1815 * Ensure that the block is aligned. The caller can use
1816 * the cookies to determine where in the block to start.
1817 */
1818 uio->uio_offset &= ~(DIRBLKSIZ - 1);
1819 off = uio->uio_offset;
1820 count = uio->uio_resid;
1821 /* Make sure we don't return partial entries. */
1822 if (count <= ((uio->uio_offset + count) & (DIRBLKSIZ -1)))
1823 return (EINVAL);
1824 count -= (uio->uio_offset + count) & (DIRBLKSIZ -1);
1825 lost = uio->uio_resid - count;
1826 uio->uio_resid = count;
1827 uio->uio_iov->iov_len = count;
1828 # if (BYTE_ORDER == LITTLE_ENDIAN)
1829 if (ap->a_vp->v_mount->mnt_maxsymlinklen > 0) {
1830 error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred);
1831 } else {
1832 struct dirent *dp, *edp;
1833 struct uio auio;
1834 struct iovec aiov;
1835 caddr_t dirbuf;
1836 int readcnt;
1837 u_char tmp;
1838
1839 auio = *uio;
1840 auio.uio_iov = &aiov;
1841 auio.uio_iovcnt = 1;
1842 auio.uio_segflg = UIO_SYSSPACE;
1843 aiov.iov_len = count;
1844 MALLOC(dirbuf, caddr_t, count, M_TEMP, M_WAITOK);
1845 aiov.iov_base = dirbuf;
1846 error = VOP_READ(ap->a_vp, &auio, 0, ap->a_cred);
1847 if (error == 0) {
1848 readcnt = count - auio.uio_resid;
1849 edp = (struct dirent *)&dirbuf[readcnt];
1850 for (dp = (struct dirent *)dirbuf; dp < edp; ) {
1851 tmp = dp->d_namlen;
1852 dp->d_namlen = dp->d_type;
1853 dp->d_type = tmp;
1854 if (dp->d_reclen > 0) {
1855 dp = (struct dirent *)
1856 ((char *)dp + dp->d_reclen);
1857 } else {
1858 error = EIO;
1859 break;
1860 }
1861 }
1862 if (dp >= edp)
1863 error = uiomove(dirbuf, readcnt, uio);
1864 }
1865 FREE(dirbuf, M_TEMP);
1866 }
1867 # else
1868 error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred);
1869 # endif
1870 if (!error && ap->a_ncookies != NULL) {
1871 struct dirent* dpStart;
1872 struct dirent* dpEnd;
1873 struct dirent* dp;
1874 int ncookies;
1875 u_long *cookies;
1876 u_long *cookiep;
1877
1878 if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
1879 panic("ufs_readdir: unexpected uio from NFS server");
1880 dpStart = (struct dirent *)
1881 ((char *)uio->uio_iov->iov_base - (uio->uio_offset - off));
1882 dpEnd = (struct dirent *) uio->uio_iov->iov_base;
1883 for (dp = dpStart, ncookies = 0;
1884 dp < dpEnd;
1885 dp = (struct dirent *)((caddr_t) dp + dp->d_reclen))
1886 ncookies++;
1887 MALLOC(cookies, u_long *, ncookies * sizeof(u_long), M_TEMP,
1888 M_WAITOK);
1889 for (dp = dpStart, cookiep = cookies;
1890 dp < dpEnd;
1891 dp = (struct dirent *)((caddr_t) dp + dp->d_reclen)) {
1892 off += dp->d_reclen;
1893 *cookiep++ = (u_long) off;
1894 }
1895 *ap->a_ncookies = ncookies;
1896 *ap->a_cookies = cookies;
1897 }
1898 uio->uio_resid += lost;
1899 if (ap->a_eofflag)
1900 *ap->a_eofflag = VTOI(ap->a_vp)->i_size <= uio->uio_offset;
1901 return (error);
1902 }
1903
1904 /*
1905 * Return target name of a symbolic link
1906 */
1907 static int
1908 ufs_readlink(ap)
1909 struct vop_readlink_args /* {
1910 struct vnode *a_vp;
1911 struct uio *a_uio;
1912 struct ucred *a_cred;
1913 } */ *ap;
1914 {
1915 struct vnode *vp = ap->a_vp;
1916 struct inode *ip = VTOI(vp);
1917 doff_t isize;
1918
1919 isize = ip->i_size;
1920 if ((isize < vp->v_mount->mnt_maxsymlinklen) ||
1921 DIP(ip, i_blocks) == 0) { /* XXX - for old fastlink support */
1922 uiomove(SHORTLINK(ip), isize, ap->a_uio);
1923 return (0);
1924 }
1925 return (VOP_READ(vp, ap->a_uio, 0, ap->a_cred));
1926 }
1927
1928 /*
1929 * Calculate the logical to physical mapping if not done already,
1930 * then call the device strategy routine.
1931 *
1932 * In order to be able to swap to a file, the ufs_bmaparray() operation may not
1933 * deadlock on memory. See ufs_bmap() for details.
1934 */
1935 static int
1936 ufs_strategy(ap)
1937 struct vop_strategy_args /* {
1938 struct vnode *a_vp;
1939 struct buf *a_bp;
1940 } */ *ap;
1941 {
1942 struct buf *bp = ap->a_bp;
1943 struct vnode *vp = ap->a_vp;
1944 struct inode *ip;
1945 ufs2_daddr_t blkno;
1946 int error;
1947
1948 KASSERT(ap->a_vp == ap->a_bp->b_vp, ("%s(%p != %p)",
1949 __func__, ap->a_vp, ap->a_bp->b_vp));
1950 ip = VTOI(vp);
1951 if (bp->b_blkno == bp->b_lblkno) {
1952 error = ufs_bmaparray(vp, bp->b_lblkno, &blkno, bp, NULL, NULL);
1953 bp->b_blkno = blkno;
1954 if (error) {
1955 bp->b_error = error;
1956 bp->b_ioflags |= BIO_ERROR;
1957 bufdone(bp);
1958 return (error);
1959 }
1960 if ((long)bp->b_blkno == -1)
1961 vfs_bio_clrbuf(bp);
1962 }
1963 if ((long)bp->b_blkno == -1) {
1964 bufdone(bp);
1965 return (0);
1966 }
1967 vp = ip->i_devvp;
1968 bp->b_dev = vp->v_rdev;
1969 bp->b_iooffset = dbtob(bp->b_blkno);
1970 if (!buf_prewrite(vp, bp))
1971 VOP_SPECSTRATEGY(vp, bp);
1972 return (0);
1973 }
1974
1975 /*
1976 * Snapshots require all lock requests to be exclusive.
1977 */
1978 static int
1979 ufs_lock(ap)
1980 struct vop_lock_args /* {
1981 struct vnode *a_vp;
1982 int a_flags;
1983 struct thread *a_td;
1984 } */ *ap;
1985 {
1986 struct vnode *vp = ap->a_vp;
1987 int flags = ap->a_flags;
1988
1989 if ((VTOI(vp)->i_flags & SF_SNAPSHOT) &&
1990 ((flags & LK_TYPE_MASK) == LK_SHARED)) {
1991 flags &= ~LK_TYPE_MASK;
1992 flags |= LK_EXCLUSIVE;
1993 }
1994 #ifndef DEBUG_LOCKS
1995 return (lockmgr(vp->v_vnlock, flags, VI_MTX(vp), ap->a_td));
1996 #else
1997 return (debuglockmgr(vp->v_vnlock, flags, VI_MTX(vp),
1998 ap->a_td, "vop_stdlock", vp->filename, vp->line));
1999 #endif
2000 }
2001
2002 /*
2003 * Print out the contents of an inode.
2004 */
2005 static int
2006 ufs_print(ap)
2007 struct vop_print_args /* {
2008 struct vnode *a_vp;
2009 } */ *ap;
2010 {
2011 struct vnode *vp = ap->a_vp;
2012 struct inode *ip = VTOI(vp);
2013
2014 printf("\tino %lu, on dev %s (%d, %d)", (u_long)ip->i_number,
2015 devtoname(ip->i_dev), major(ip->i_dev), minor(ip->i_dev));
2016 if (vp->v_type == VFIFO)
2017 fifo_printinfo(vp);
2018 printf("\n");
2019 return (0);
2020 }
2021
2022 /*
2023 * Read wrapper for special devices.
2024 */
2025 static int
2026 ufsspec_read(ap)
2027 struct vop_read_args /* {
2028 struct vnode *a_vp;
2029 struct uio *a_uio;
2030 int a_ioflag;
2031 struct ucred *a_cred;
2032 } */ *ap;
2033 {
2034 int error, resid;
2035 struct inode *ip;
2036 struct uio *uio;
2037
2038 uio = ap->a_uio;
2039 resid = uio->uio_resid;
2040 error = VOCALL(spec_vnodeop_p, VOFFSET(vop_read), ap);
2041 /*
2042 * The inode may have been revoked during the call, so it must not
2043 * be accessed blindly here or in the other wrapper functions.
2044 */
2045 ip = VTOI(ap->a_vp);
2046 if (ip != NULL && (uio->uio_resid != resid || (error == 0 && resid != 0)))
2047 ip->i_flag |= IN_ACCESS;
2048 return (error);
2049 }
2050
2051 /*
2052 * Write wrapper for special devices.
2053 */
2054 static int
2055 ufsspec_write(ap)
2056 struct vop_write_args /* {
2057 struct vnode *a_vp;
2058 struct uio *a_uio;
2059 int a_ioflag;
2060 struct ucred *a_cred;
2061 } */ *ap;
2062 {
2063 int error, resid;
2064 struct inode *ip;
2065 struct uio *uio;
2066
2067 uio = ap->a_uio;
2068 resid = uio->uio_resid;
2069 error = VOCALL(spec_vnodeop_p, VOFFSET(vop_write), ap);
2070 ip = VTOI(ap->a_vp);
2071 if (ip != NULL && (uio->uio_resid != resid || (error == 0 && resid != 0)))
2072 VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE;
2073 return (error);
2074 }
2075
2076 /*
2077 * Close wrapper for special devices.
2078 *
2079 * Update the times on the inode then do device close.
2080 */
2081 static int
2082 ufsspec_close(ap)
2083 struct vop_close_args /* {
2084 struct vnode *a_vp;
2085 int a_fflag;
2086 struct ucred *a_cred;
2087 struct thread *a_td;
2088 } */ *ap;
2089 {
2090 struct vnode *vp = ap->a_vp;
2091
2092 VI_LOCK(vp);
2093 if (vp->v_usecount > 1)
2094 ufs_itimes(vp);
2095 VI_UNLOCK(vp);
2096 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_close), ap));
2097 }
2098
2099 /*
2100 * Read wrapper for fifos.
2101 */
2102 static int
2103 ufsfifo_read(ap)
2104 struct vop_read_args /* {
2105 struct vnode *a_vp;
2106 struct uio *a_uio;
2107 int a_ioflag;
2108 struct ucred *a_cred;
2109 } */ *ap;
2110 {
2111 int error, resid;
2112 struct inode *ip;
2113 struct uio *uio;
2114
2115 uio = ap->a_uio;
2116 resid = uio->uio_resid;
2117 error = VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), ap);
2118 ip = VTOI(ap->a_vp);
2119 if ((ap->a_vp->v_mount->mnt_flag & MNT_NOATIME) == 0 && ip != NULL &&
2120 (uio->uio_resid != resid || (error == 0 && resid != 0)))
2121 ip->i_flag |= IN_ACCESS;
2122 return (error);
2123 }
2124
2125 /*
2126 * Write wrapper for fifos.
2127 */
2128 static int
2129 ufsfifo_write(ap)
2130 struct vop_write_args /* {
2131 struct vnode *a_vp;
2132 struct uio *a_uio;
2133 int a_ioflag;
2134 struct ucred *a_cred;
2135 } */ *ap;
2136 {
2137 int error, resid;
2138 struct inode *ip;
2139 struct uio *uio;
2140
2141 uio = ap->a_uio;
2142 resid = uio->uio_resid;
2143 error = VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), ap);
2144 ip = VTOI(ap->a_vp);
2145 if (ip != NULL && (uio->uio_resid != resid || (error == 0 && resid != 0)))
2146 ip->i_flag |= IN_CHANGE | IN_UPDATE;
2147 return (error);
2148 }
2149
2150 /*
2151 * Close wrapper for fifos.
2152 *
2153 * Update the times on the inode then do device close.
2154 */
2155 static int
2156 ufsfifo_close(ap)
2157 struct vop_close_args /* {
2158 struct vnode *a_vp;
2159 int a_fflag;
2160 struct ucred *a_cred;
2161 struct thread *a_td;
2162 } */ *ap;
2163 {
2164 struct vnode *vp = ap->a_vp;
2165
2166 VI_LOCK(vp);
2167 if (vp->v_usecount > 1)
2168 ufs_itimes(vp);
2169 VI_UNLOCK(vp);
2170 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_close), ap));
2171 }
2172
2173 /*
2174 * Kqfilter wrapper for fifos.
2175 *
2176 * Fall through to ufs kqfilter routines if needed
2177 */
2178 static int
2179 ufsfifo_kqfilter(ap)
2180 struct vop_kqfilter_args *ap;
2181 {
2182 int error;
2183
2184 error = VOCALL(fifo_vnodeop_p, VOFFSET(vop_kqfilter), ap);
2185 if (error)
2186 error = ufs_kqfilter(ap);
2187 return (error);
2188 }
2189
2190 /*
2191 * Return POSIX pathconf information applicable to ufs filesystems.
2192 */
2193 static int
2194 ufs_pathconf(ap)
2195 struct vop_pathconf_args /* {
2196 struct vnode *a_vp;
2197 int a_name;
2198 int *a_retval;
2199 } */ *ap;
2200 {
2201 int error;
2202
2203 error = 0;
2204 switch (ap->a_name) {
2205 case _PC_LINK_MAX:
2206 *ap->a_retval = LINK_MAX;
2207 break;
2208 case _PC_NAME_MAX:
2209 *ap->a_retval = NAME_MAX;
2210 break;
2211 case _PC_PATH_MAX:
2212 *ap->a_retval = PATH_MAX;
2213 break;
2214 case _PC_PIPE_BUF:
2215 *ap->a_retval = PIPE_BUF;
2216 break;
2217 case _PC_CHOWN_RESTRICTED:
2218 *ap->a_retval = 1;
2219 break;
2220 case _PC_NO_TRUNC:
2221 *ap->a_retval = 1;
2222 break;
2223 case _PC_ACL_EXTENDED:
2224 #ifdef UFS_ACL
2225 if (ap->a_vp->v_mount->mnt_flag & MNT_ACLS)
2226 *ap->a_retval = 1;
2227 else
2228 *ap->a_retval = 0;
2229 #else
2230 *ap->a_retval = 0;
2231 #endif
2232 break;
2233 case _PC_ACL_PATH_MAX:
2234 #ifdef UFS_ACL
2235 if (ap->a_vp->v_mount->mnt_flag & MNT_ACLS)
2236 *ap->a_retval = ACL_MAX_ENTRIES;
2237 else
2238 *ap->a_retval = 3;
2239 #else
2240 *ap->a_retval = 3;
2241 #endif
2242 break;
2243 case _PC_MAC_PRESENT:
2244 #ifdef MAC
2245 if (ap->a_vp->v_mount->mnt_flag & MNT_MULTILABEL)
2246 *ap->a_retval = 1;
2247 else
2248 *ap->a_retval = 0;
2249 #else
2250 *ap->a_retval = 0;
2251 #endif
2252 break;
2253 case _PC_ASYNC_IO:
2254 /* _PC_ASYNC_IO should have been handled by upper layers. */
2255 KASSERT(0, ("_PC_ASYNC_IO should not get here"));
2256 error = EINVAL;
2257 break;
2258 case _PC_PRIO_IO:
2259 *ap->a_retval = 0;
2260 break;
2261 case _PC_SYNC_IO:
2262 *ap->a_retval = 0;
2263 break;
2264 case _PC_ALLOC_SIZE_MIN:
2265 *ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_bsize;
2266 break;
2267 case _PC_FILESIZEBITS:
2268 *ap->a_retval = 64;
2269 break;
2270 case _PC_REC_INCR_XFER_SIZE:
2271 *ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize;
2272 break;
2273 case _PC_REC_MAX_XFER_SIZE:
2274 *ap->a_retval = -1; /* means ``unlimited'' */
2275 break;
2276 case _PC_REC_MIN_XFER_SIZE:
2277 *ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize;
2278 break;
2279 case _PC_REC_XFER_ALIGN:
2280 *ap->a_retval = PAGE_SIZE;
2281 break;
2282 case _PC_SYMLINK_MAX:
2283 *ap->a_retval = MAXPATHLEN;
2284 break;
2285
2286 default:
2287 error = EINVAL;
2288 break;
2289 }
2290 return (error);
2291 }
2292
2293 /*
2294 * Advisory record locking support
2295 */
2296 static int
2297 ufs_advlock(ap)
2298 struct vop_advlock_args /* {
2299 struct vnode *a_vp;
2300 caddr_t a_id;
2301 int a_op;
2302 struct flock *a_fl;
2303 int a_flags;
2304 } */ *ap;
2305 {
2306 struct inode *ip = VTOI(ap->a_vp);
2307
2308 return (lf_advlock(ap, &(ip->i_lockf), ip->i_size));
2309 }
2310
2311 /*
2312 * Initialize the vnode associated with a new inode, handle aliased
2313 * vnodes.
2314 */
2315 int
2316 ufs_vinit(mntp, specops, fifoops, vpp)
2317 struct mount *mntp;
2318 vop_t **specops;
2319 vop_t **fifoops;
2320 struct vnode **vpp;
2321 {
2322 struct inode *ip;
2323 struct vnode *vp;
2324 struct timeval tv;
2325
2326 vp = *vpp;
2327 ip = VTOI(vp);
2328 switch(vp->v_type = IFTOVT(ip->i_mode)) {
2329 case VCHR:
2330 case VBLK:
2331 vp->v_op = specops;
2332 vp = addaliasu(vp, DIP(ip, i_rdev));
2333 ip->i_vnode = vp;
2334 break;
2335 case VFIFO:
2336 vp->v_op = fifoops;
2337 break;
2338 default:
2339 break;
2340
2341 }
2342 ASSERT_VOP_LOCKED(vp, "ufs_vinit");
2343 if (ip->i_number == ROOTINO)
2344 vp->v_vflag |= VV_ROOT;
2345 /*
2346 * Initialize modrev times
2347 */
2348 getmicrouptime(&tv);
2349 SETHIGH(ip->i_modrev, tv.tv_sec);
2350 SETLOW(ip->i_modrev, tv.tv_usec * 4294);
2351 *vpp = vp;
2352 return (0);
2353 }
2354
2355 /*
2356 * Allocate a new inode.
2357 * Vnode dvp must be locked.
2358 */
2359 static int
2360 ufs_makeinode(mode, dvp, vpp, cnp)
2361 int mode;
2362 struct vnode *dvp;
2363 struct vnode **vpp;
2364 struct componentname *cnp;
2365 {
2366 struct inode *ip, *pdir;
2367 struct direct newdir;
2368 struct vnode *tvp;
2369 #ifdef UFS_ACL
2370 struct acl *acl;
2371 #endif
2372 int error;
2373
2374 pdir = VTOI(dvp);
2375 #ifdef DIAGNOSTIC
2376 if ((cnp->cn_flags & HASBUF) == 0)
2377 panic("ufs_makeinode: no name");
2378 #endif
2379 *vpp = NULL;
2380 if ((mode & IFMT) == 0)
2381 mode |= IFREG;
2382
2383 error = UFS_VALLOC(dvp, mode, cnp->cn_cred, &tvp);
2384 if (error)
2385 return (error);
2386 ip = VTOI(tvp);
2387 ip->i_gid = pdir->i_gid;
2388 DIP_SET(ip, i_gid, pdir->i_gid);
2389 #ifdef SUIDDIR
2390 {
2391 #ifdef QUOTA
2392 struct ucred ucred, *ucp;
2393 ucp = cnp->cn_cred;
2394 #endif
2395 /*
2396 * If we are not the owner of the directory,
2397 * and we are hacking owners here, (only do this where told to)
2398 * and we are not giving it TO root, (would subvert quotas)
2399 * then go ahead and give it to the other user.
2400 * Note that this drops off the execute bits for security.
2401 */
2402 if ((dvp->v_mount->mnt_flag & MNT_SUIDDIR) &&
2403 (pdir->i_mode & ISUID) &&
2404 (pdir->i_uid != cnp->cn_cred->cr_uid) && pdir->i_uid) {
2405 ip->i_uid = pdir->i_uid;
2406 DIP_SET(ip, i_uid, ip->i_uid);
2407 mode &= ~07111;
2408 #ifdef QUOTA
2409 /*
2410 * Make sure the correct user gets charged
2411 * for the space.
2412 * Quickly knock up a dummy credential for the victim.
2413 * XXX This seems to never be accessed out of our
2414 * context so a stack variable is ok.
2415 */
2416 ucred.cr_ref = 1;
2417 ucred.cr_uid = ip->i_uid;
2418 ucred.cr_ngroups = 1;
2419 ucred.cr_groups[0] = pdir->i_gid;
2420 ucp = &ucred;
2421 #endif
2422 } else {
2423 ip->i_uid = cnp->cn_cred->cr_uid;
2424 DIP_SET(ip, i_uid, ip->i_uid);
2425 }
2426
2427 #ifdef QUOTA
2428 if ((error = getinoquota(ip)) ||
2429 (error = chkiq(ip, 1, ucp, 0))) {
2430 UFS_VFREE(tvp, ip->i_number, mode);
2431 vput(tvp);
2432 return (error);
2433 }
2434 #endif
2435 }
2436 #else /* !SUIDDIR */
2437 ip->i_uid = cnp->cn_cred->cr_uid;
2438 DIP_SET(ip, i_uid, ip->i_uid);
2439 #ifdef QUOTA
2440 if ((error = getinoquota(ip)) ||
2441 (error = chkiq(ip, 1, cnp->cn_cred, 0))) {
2442 UFS_VFREE(tvp, ip->i_number, mode);
2443 vput(tvp);
2444 return (error);
2445 }
2446 #endif
2447 #endif /* !SUIDDIR */
2448 ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
2449 #ifdef UFS_ACL
2450 acl = NULL;
2451 if ((dvp->v_mount->mnt_flag & MNT_ACLS) != 0) {
2452 MALLOC(acl, struct acl *, sizeof(*acl), M_ACL, M_WAITOK);
2453
2454 /*
2455 * Retrieve default ACL for parent, if any.
2456 */
2457 error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cnp->cn_cred,
2458 cnp->cn_thread);
2459 switch (error) {
2460 case 0:
2461 /*
2462 * Retrieved a default ACL, so merge mode and ACL if
2463 * necessary.
2464 */
2465 if (acl->acl_cnt != 0) {
2466 /*
2467 * Two possible ways for default ACL to not
2468 * be present. First, the EA can be
2469 * undefined, or second, the default ACL can
2470 * be blank. If it's blank, fall through to
2471 * the it's not defined case.
2472 */
2473 mode = acl_posix1e_newfilemode(mode, acl);
2474 ip->i_mode = mode;
2475 DIP_SET(ip, i_mode, mode);
2476 ufs_sync_acl_from_inode(ip, acl);
2477 break;
2478 }
2479 /* FALLTHROUGH */
2480
2481 case EOPNOTSUPP:
2482 /*
2483 * Just use the mode as-is.
2484 */
2485 ip->i_mode = mode;
2486 DIP_SET(ip, i_mode, mode);
2487 FREE(acl, M_ACL);
2488 acl = NULL;
2489 break;
2490
2491 default:
2492 UFS_VFREE(tvp, ip->i_number, mode);
2493 vput(tvp);
2494 FREE(acl, M_ACL);
2495 acl = NULL;
2496 return (error);
2497 }
2498 } else {
2499 #endif
2500 ip->i_mode = mode;
2501 DIP_SET(ip, i_mode, mode);
2502 #ifdef UFS_ACL
2503 }
2504 #endif
2505 tvp->v_type = IFTOVT(mode); /* Rest init'd in getnewvnode(). */
2506 ip->i_effnlink = 1;
2507 ip->i_nlink = 1;
2508 DIP_SET(ip, i_nlink, 1);
2509 if (DOINGSOFTDEP(tvp))
2510 softdep_change_linkcnt(ip);
2511 if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) &&
2512 suser_cred(cnp->cn_cred, SUSER_ALLOWJAIL)) {
2513 ip->i_mode &= ~ISGID;
2514 DIP_SET(ip, i_mode, ip->i_mode);
2515 }
2516
2517 if (cnp->cn_flags & ISWHITEOUT) {
2518 ip->i_flags |= UF_OPAQUE;
2519 DIP_SET(ip, i_flags, ip->i_flags);
2520 }
2521
2522 /*
2523 * Make sure inode goes to disk before directory entry.
2524 */
2525 error = UFS_UPDATE(tvp, !(DOINGSOFTDEP(tvp) | DOINGASYNC(tvp)));
2526 if (error)
2527 goto bad;
2528 #ifdef MAC
2529 if (dvp->v_mount->mnt_flag & MNT_MULTILABEL) {
2530 error = mac_create_vnode_extattr(cnp->cn_cred, dvp->v_mount,
2531 dvp, tvp, cnp);
2532 if (error)
2533 goto bad;
2534 }
2535 #endif
2536 #ifdef UFS_ACL
2537 if (acl != NULL) {
2538 /*
2539 * XXX: If we abort now, will Soft Updates notify the extattr
2540 * code that the EAs for the file need to be released?
2541 */
2542 error = VOP_SETACL(tvp, ACL_TYPE_ACCESS, acl, cnp->cn_cred,
2543 cnp->cn_thread);
2544 switch (error) {
2545 case 0:
2546 break;
2547
2548 case EOPNOTSUPP:
2549 /*
2550 * XXX: This should not happen, as EOPNOTSUPP above was
2551 * supposed to free acl.
2552 */
2553 printf("ufs_makeinode: VOP_GETACL() but no "
2554 "VOP_SETACL()\n");
2555 /* panic("ufs_makeinode: VOP_GETACL() but no "
2556 "VOP_SETACL()"); */
2557 break;
2558
2559 default:
2560 FREE(acl, M_ACL);
2561 goto bad;
2562 }
2563 FREE(acl, M_ACL);
2564 }
2565 #endif /* !UFS_ACL */
2566 ufs_makedirentry(ip, cnp, &newdir);
2567 error = ufs_direnter(dvp, tvp, &newdir, cnp, NULL);
2568 if (error)
2569 goto bad;
2570 *vpp = tvp;
2571 return (0);
2572
2573 bad:
2574 /*
2575 * Write error occurred trying to update the inode
2576 * or the directory so must deallocate the inode.
2577 */
2578 ip->i_effnlink = 0;
2579 ip->i_nlink = 0;
2580 DIP_SET(ip, i_nlink, 0);
2581 ip->i_flag |= IN_CHANGE;
2582 if (DOINGSOFTDEP(tvp))
2583 softdep_change_linkcnt(ip);
2584 vput(tvp);
2585 return (error);
2586 }
2587
2588 static struct filterops ufsread_filtops =
2589 { 1, NULL, filt_ufsdetach, filt_ufsread };
2590 static struct filterops ufswrite_filtops =
2591 { 1, NULL, filt_ufsdetach, filt_ufswrite };
2592 static struct filterops ufsvnode_filtops =
2593 { 1, NULL, filt_ufsdetach, filt_ufsvnode };
2594
2595 static int
2596 ufs_kqfilter(ap)
2597 struct vop_kqfilter_args /* {
2598 struct vnode *a_vp;
2599 struct knote *a_kn;
2600 } */ *ap;
2601 {
2602 struct vnode *vp = ap->a_vp;
2603 struct knote *kn = ap->a_kn;
2604
2605 switch (kn->kn_filter) {
2606 case EVFILT_READ:
2607 kn->kn_fop = &ufsread_filtops;
2608 break;
2609 case EVFILT_WRITE:
2610 kn->kn_fop = &ufswrite_filtops;
2611 break;
2612 case EVFILT_VNODE:
2613 kn->kn_fop = &ufsvnode_filtops;
2614 break;
2615 default:
2616 return (1);
2617 }
2618
2619 kn->kn_hook = (caddr_t)vp;
2620
2621 if (vp->v_pollinfo == NULL)
2622 v_addpollinfo(vp);
2623 if (vp->v_pollinfo == NULL)
2624 return ENOMEM;
2625 knlist_add(&vp->v_pollinfo->vpi_selinfo.si_note, kn, 0);
2626
2627 return (0);
2628 }
2629
2630 static void
2631 filt_ufsdetach(struct knote *kn)
2632 {
2633 struct vnode *vp = (struct vnode *)kn->kn_hook;
2634
2635 KASSERT(vp->v_pollinfo != NULL, ("Mising v_pollinfo"));
2636 knlist_remove(&vp->v_pollinfo->vpi_selinfo.si_note, kn, 0);
2637 }
2638
2639 /*ARGSUSED*/
2640 static int
2641 filt_ufsread(struct knote *kn, long hint)
2642 {
2643 struct vnode *vp = (struct vnode *)kn->kn_hook;
2644 struct inode *ip = VTOI(vp);
2645
2646 /*
2647 * filesystem is gone, so set the EOF flag and schedule
2648 * the knote for deletion.
2649 */
2650 if (hint == NOTE_REVOKE) {
2651 kn->kn_flags |= (EV_EOF | EV_ONESHOT);
2652 return (1);
2653 }
2654
2655 kn->kn_data = ip->i_size - kn->kn_fp->f_offset;
2656 return (kn->kn_data != 0);
2657 }
2658
2659 /*ARGSUSED*/
2660 static int
2661 filt_ufswrite(struct knote *kn, long hint)
2662 {
2663
2664 /*
2665 * filesystem is gone, so set the EOF flag and schedule
2666 * the knote for deletion.
2667 */
2668 if (hint == NOTE_REVOKE)
2669 kn->kn_flags |= (EV_EOF | EV_ONESHOT);
2670
2671 kn->kn_data = 0;
2672 return (1);
2673 }
2674
2675 static int
2676 filt_ufsvnode(struct knote *kn, long hint)
2677 {
2678
2679 if (kn->kn_sfflags & hint)
2680 kn->kn_fflags |= hint;
2681 if (hint == NOTE_REVOKE) {
2682 kn->kn_flags |= EV_EOF;
2683 return (1);
2684 }
2685 return (kn->kn_fflags != 0);
2686 }
2687
2688 /* Global vfs data structures for ufs. */
2689 static vop_t **ufs_vnodeop_p;
2690 static struct vnodeopv_entry_desc ufs_vnodeop_entries[] = {
2691 { &vop_default_desc, (vop_t *) vop_defaultop },
2692 { &vop_fsync_desc, (vop_t *) vop_panic },
2693 { &vop_read_desc, (vop_t *) vop_panic },
2694 { &vop_reallocblks_desc, (vop_t *) vop_panic },
2695 { &vop_write_desc, (vop_t *) vop_panic },
2696 { &vop_access_desc, (vop_t *) ufs_access },
2697 { &vop_advlock_desc, (vop_t *) ufs_advlock },
2698 { &vop_lock_desc, (vop_t *) ufs_lock },
2699 { &vop_bmap_desc, (vop_t *) ufs_bmap },
2700 { &vop_cachedlookup_desc, (vop_t *) ufs_lookup },
2701 { &vop_close_desc, (vop_t *) ufs_close },
2702 { &vop_create_desc, (vop_t *) ufs_create },
2703 { &vop_getattr_desc, (vop_t *) ufs_getattr },
2704 { &vop_inactive_desc, (vop_t *) ufs_inactive },
2705 { &vop_link_desc, (vop_t *) ufs_link },
2706 { &vop_lookup_desc, (vop_t *) vfs_cache_lookup },
2707 { &vop_mkdir_desc, (vop_t *) ufs_mkdir },
2708 { &vop_mknod_desc, (vop_t *) ufs_mknod },
2709 { &vop_open_desc, (vop_t *) ufs_open },
2710 { &vop_pathconf_desc, (vop_t *) ufs_pathconf },
2711 { &vop_poll_desc, (vop_t *) vop_stdpoll },
2712 { &vop_kqfilter_desc, (vop_t *) ufs_kqfilter },
2713 { &vop_getwritemount_desc, (vop_t *) vop_stdgetwritemount },
2714 { &vop_print_desc, (vop_t *) ufs_print },
2715 { &vop_readdir_desc, (vop_t *) ufs_readdir },
2716 { &vop_readlink_desc, (vop_t *) ufs_readlink },
2717 { &vop_reclaim_desc, (vop_t *) ufs_reclaim },
2718 { &vop_remove_desc, (vop_t *) ufs_remove },
2719 { &vop_rename_desc, (vop_t *) ufs_rename },
2720 { &vop_rmdir_desc, (vop_t *) ufs_rmdir },
2721 { &vop_setattr_desc, (vop_t *) ufs_setattr },
2722 #ifdef MAC
2723 { &vop_setlabel_desc, (vop_t *) vop_stdsetlabel_ea },
2724 #endif
2725 { &vop_strategy_desc, (vop_t *) ufs_strategy },
2726 { &vop_symlink_desc, (vop_t *) ufs_symlink },
2727 { &vop_whiteout_desc, (vop_t *) ufs_whiteout },
2728 #ifdef UFS_EXTATTR
2729 { &vop_getextattr_desc, (vop_t *) ufs_getextattr },
2730 { &vop_deleteextattr_desc, (vop_t *) ufs_deleteextattr },
2731 { &vop_setextattr_desc, (vop_t *) ufs_setextattr },
2732 #endif
2733 #ifdef UFS_ACL
2734 { &vop_getacl_desc, (vop_t *) ufs_getacl },
2735 { &vop_setacl_desc, (vop_t *) ufs_setacl },
2736 { &vop_aclcheck_desc, (vop_t *) ufs_aclcheck },
2737 #endif
2738 { NULL, NULL }
2739 };
2740 static struct vnodeopv_desc ufs_vnodeop_opv_desc =
2741 { &ufs_vnodeop_p, ufs_vnodeop_entries };
2742
2743 static vop_t **ufs_specop_p;
2744 static struct vnodeopv_entry_desc ufs_specop_entries[] = {
2745 { &vop_default_desc, (vop_t *) spec_vnoperate },
2746 { &vop_fsync_desc, (vop_t *) vop_panic },
2747 { &vop_access_desc, (vop_t *) ufs_access },
2748 { &vop_close_desc, (vop_t *) ufsspec_close },
2749 { &vop_getattr_desc, (vop_t *) ufs_getattr },
2750 { &vop_inactive_desc, (vop_t *) ufs_inactive },
2751 { &vop_print_desc, (vop_t *) ufs_print },
2752 { &vop_read_desc, (vop_t *) ufsspec_read },
2753 { &vop_reclaim_desc, (vop_t *) ufs_reclaim },
2754 { &vop_setattr_desc, (vop_t *) ufs_setattr },
2755 #ifdef MAC
2756 { &vop_setlabel_desc, (vop_t *) vop_stdsetlabel_ea },
2757 #endif
2758 { &vop_write_desc, (vop_t *) ufsspec_write },
2759 #ifdef UFS_EXTATTR
2760 { &vop_getextattr_desc, (vop_t *) ufs_getextattr },
2761 { &vop_deleteextattr_desc, (vop_t *) ufs_deleteextattr },
2762 { &vop_setextattr_desc, (vop_t *) ufs_setextattr },
2763 #endif
2764 #ifdef UFS_ACL
2765 { &vop_getacl_desc, (vop_t *) ufs_getacl },
2766 { &vop_setacl_desc, (vop_t *) ufs_setacl },
2767 { &vop_aclcheck_desc, (vop_t *) ufs_aclcheck },
2768 #endif
2769 {NULL, NULL}
2770 };
2771 static struct vnodeopv_desc ufs_specop_opv_desc =
2772 { &ufs_specop_p, ufs_specop_entries };
2773
2774 static vop_t **ufs_fifoop_p;
2775 static struct vnodeopv_entry_desc ufs_fifoop_entries[] = {
2776 { &vop_default_desc, (vop_t *) fifo_vnoperate },
2777 { &vop_fsync_desc, (vop_t *) vop_panic },
2778 { &vop_access_desc, (vop_t *) ufs_access },
2779 { &vop_close_desc, (vop_t *) ufsfifo_close },
2780 { &vop_getattr_desc, (vop_t *) ufs_getattr },
2781 { &vop_inactive_desc, (vop_t *) ufs_inactive },
2782 { &vop_kqfilter_desc, (vop_t *) ufsfifo_kqfilter },
2783 { &vop_print_desc, (vop_t *) ufs_print },
2784 { &vop_read_desc, (vop_t *) ufsfifo_read },
2785 { &vop_reclaim_desc, (vop_t *) ufs_reclaim },
2786 { &vop_setattr_desc, (vop_t *) ufs_setattr },
2787 #ifdef MAC
2788 { &vop_setlabel_desc, (vop_t *) vop_stdsetlabel_ea },
2789 #endif
2790 { &vop_write_desc, (vop_t *) ufsfifo_write },
2791 #ifdef UFS_EXTATTR
2792 { &vop_getextattr_desc, (vop_t *) ufs_getextattr },
2793 { &vop_deleteextattr_desc, (vop_t *) ufs_deleteextattr },
2794 { &vop_setextattr_desc, (vop_t *) ufs_setextattr },
2795 #endif
2796 #ifdef UFS_ACL
2797 { &vop_getacl_desc, (vop_t *) ufs_getacl },
2798 { &vop_setacl_desc, (vop_t *) ufs_setacl },
2799 { &vop_aclcheck_desc, (vop_t *) ufs_aclcheck },
2800 #endif
2801 { NULL, NULL }
2802 };
2803 static struct vnodeopv_desc ufs_fifoop_opv_desc =
2804 { &ufs_fifoop_p, ufs_fifoop_entries };
2805
2806 VNODEOP_SET(ufs_vnodeop_opv_desc);
2807 VNODEOP_SET(ufs_specop_opv_desc);
2808 VNODEOP_SET(ufs_fifoop_opv_desc);
2809
2810 int
2811 ufs_vnoperate(ap)
2812 struct vop_generic_args /* {
2813 struct vnodeop_desc *a_desc;
2814 } */ *ap;
2815 {
2816 return (VOCALL(ufs_vnodeop_p, ap->a_desc->vdesc_offset, ap));
2817 }
2818
2819 int
2820 ufs_vnoperatefifo(ap)
2821 struct vop_generic_args /* {
2822 struct vnodeop_desc *a_desc;
2823 } */ *ap;
2824 {
2825 return (VOCALL(ufs_fifoop_p, ap->a_desc->vdesc_offset, ap));
2826 }
2827
2828 int
2829 ufs_vnoperatespec(ap)
2830 struct vop_generic_args /* {
2831 struct vnodeop_desc *a_desc;
2832 } */ *ap;
2833 {
2834 return (VOCALL(ufs_specop_p, ap->a_desc->vdesc_offset, ap));
2835 }
Cache object: c95af28a31181eda778beb4ec7042e9f
|