PageRenderTime 70ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/netbsd/src/sys/ufs/ufs/ufs_vnops.c

https://bitbucket.org/mischief/oskit
C | 2065 lines | 1436 code | 105 blank | 524 comment | 388 complexity | 741b03f0ae7ca1d6b076130a6a94787f MD5 | raw file
Possible License(s): GPL-2.0
  1. /* $NetBSD: ufs_vnops.c,v 1.18 1996/05/11 18:28:04 mycroft Exp $ */
  2. /*
  3. * Copyright (c) 1982, 1986, 1989, 1993
  4. * The Regents of the University of California. All rights reserved.
  5. * (c) UNIX System Laboratories, Inc.
  6. * All or some portions of this file are derived from material licensed
  7. * to the University of California by American Telephone and Telegraph
  8. * Co. or Unix System Laboratories, Inc. and are reproduced herein with
  9. * the permission of UNIX System Laboratories, Inc.
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions
  13. * are met:
  14. * 1. Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. * 2. Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. * 3. All advertising materials mentioning features or use of this software
  20. * must display the following acknowledgement:
  21. * This product includes software developed by the University of
  22. * California, Berkeley and its contributors.
  23. * 4. Neither the name of the University nor the names of its contributors
  24. * may be used to endorse or promote products derived from this software
  25. * without specific prior written permission.
  26. *
  27. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  28. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  29. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  30. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  31. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  32. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  33. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  34. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  35. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  36. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  37. * SUCH DAMAGE.
  38. *
  39. * @(#)ufs_vnops.c 8.14 (Berkeley) 10/26/94
  40. */
  41. #include <sys/param.h>
  42. #include <sys/systm.h>
  43. #include <sys/namei.h>
  44. #include <sys/resourcevar.h>
  45. #include <sys/kernel.h>
  46. #include <sys/file.h>
  47. #include <sys/stat.h>
  48. #include <sys/buf.h>
  49. #include <sys/proc.h>
  50. #include <sys/conf.h>
  51. #include <sys/mount.h>
  52. #include <sys/vnode.h>
  53. #include <sys/malloc.h>
  54. #include <sys/dirent.h>
  55. #include <sys/lockf.h>
  56. #include <vm/vm.h>
  57. #include <miscfs/specfs/specdev.h>
  58. #include <miscfs/fifofs/fifo.h>
  59. #include <ufs/ufs/quota.h>
  60. #include <ufs/ufs/inode.h>
  61. #include <ufs/ufs/dir.h>
  62. #include <ufs/ufs/ufsmount.h>
  63. #include <ufs/ufs/ufs_extern.h>
  64. static int ufs_chmod __P((struct vnode *, int, struct ucred *, struct proc *));
  65. static int ufs_chown
  66. __P((struct vnode *, uid_t, gid_t, struct ucred *, struct proc *));
  67. union _qcvt {
  68. int64_t qcvt;
  69. int32_t val[2];
  70. };
  71. #define SETHIGH(q, h) { \
  72. union _qcvt tmp; \
  73. tmp.qcvt = (q); \
  74. tmp.val[_QUAD_HIGHWORD] = (h); \
  75. (q) = tmp.qcvt; \
  76. }
  77. #define SETLOW(q, l) { \
  78. union _qcvt tmp; \
  79. tmp.qcvt = (q); \
  80. tmp.val[_QUAD_LOWWORD] = (l); \
  81. (q) = tmp.qcvt; \
  82. }
  83. /*
  84. * Create a regular file
  85. */
  86. int
  87. ufs_create(v)
  88. void *v;
  89. {
  90. struct vop_create_args /* {
  91. struct vnode *a_dvp;
  92. struct vnode **a_vpp;
  93. struct componentname *a_cnp;
  94. struct vattr *a_vap;
  95. } */ *ap = v;
  96. return
  97. ufs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode),
  98. ap->a_dvp, ap->a_vpp, ap->a_cnp);
  99. }
  100. /*
  101. * Mknod vnode call
  102. */
  103. /* ARGSUSED */
  104. int
  105. ufs_mknod(v)
  106. void *v;
  107. {
  108. struct vop_mknod_args /* {
  109. struct vnode *a_dvp;
  110. struct vnode **a_vpp;
  111. struct componentname *a_cnp;
  112. struct vattr *a_vap;
  113. } */ *ap = v;
  114. register struct vattr *vap = ap->a_vap;
  115. register struct vnode **vpp = ap->a_vpp;
  116. register struct inode *ip;
  117. int error;
  118. if ((error =
  119. ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
  120. ap->a_dvp, vpp, ap->a_cnp)) != 0)
  121. return (error);
  122. ip = VTOI(*vpp);
  123. ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
  124. if (vap->va_rdev != VNOVAL) {
  125. /*
  126. * Want to be able to use this to make badblock
  127. * inodes, so don't truncate the dev number.
  128. */
  129. ip->i_rdev = vap->va_rdev;
  130. }
  131. /*
  132. * Remove inode so that it will be reloaded by VFS_VGET and
  133. * checked to see if it is an alias of an existing entry in
  134. * the inode cache.
  135. */
  136. vput(*vpp);
  137. (*vpp)->v_type = VNON;
  138. vgone(*vpp);
  139. *vpp = 0;
  140. return (0);
  141. }
  142. /*
  143. * Open called.
  144. *
  145. * Nothing to do.
  146. */
  147. /* ARGSUSED */
  148. int
  149. ufs_open(v)
  150. void *v;
  151. {
  152. struct vop_open_args /* {
  153. struct vnode *a_vp;
  154. int a_mode;
  155. struct ucred *a_cred;
  156. struct proc *a_p;
  157. } */ *ap = v;
  158. /*
  159. * Files marked append-only must be opened for appending.
  160. */
  161. if ((VTOI(ap->a_vp)->i_flags & APPEND) &&
  162. (ap->a_mode & (FWRITE | O_APPEND)) == FWRITE)
  163. return (EPERM);
  164. return (0);
  165. }
  166. /*
  167. * Close called.
  168. *
  169. * Update the times on the inode.
  170. */
  171. /* ARGSUSED */
  172. int
  173. ufs_close(v)
  174. void *v;
  175. {
  176. struct vop_close_args /* {
  177. struct vnode *a_vp;
  178. int a_fflag;
  179. struct ucred *a_cred;
  180. struct proc *a_p;
  181. } */ *ap = v;
  182. register struct vnode *vp = ap->a_vp;
  183. register struct inode *ip = VTOI(vp);
  184. if (vp->v_usecount > 1 && !(ip->i_flag & IN_LOCKED))
  185. ITIMES(ip, &time, &time);
  186. return (0);
  187. }
  188. int
  189. ufs_access(v)
  190. void *v;
  191. {
  192. struct vop_access_args /* {
  193. struct vnode *a_vp;
  194. int a_mode;
  195. struct ucred *a_cred;
  196. struct proc *a_p;
  197. } */ *ap = v;
  198. register struct vnode *vp = ap->a_vp;
  199. register struct inode *ip = VTOI(vp);
  200. mode_t mode = ap->a_mode;
  201. #ifdef DIAGNOSTIC
  202. if (!VOP_ISLOCKED(vp)) {
  203. vprint("ufs_access: not locked", vp);
  204. panic("ufs_access: not locked");
  205. }
  206. #endif
  207. #ifdef QUOTA
  208. if (mode & VWRITE)
  209. switch (vp->v_type) {
  210. int error;
  211. case VDIR:
  212. case VLNK:
  213. case VREG:
  214. if ((error = getinoquota(ip)) != 0)
  215. return (error);
  216. break;
  217. case VBAD:
  218. case VBLK:
  219. case VCHR:
  220. case VSOCK:
  221. case VFIFO:
  222. case VNON:
  223. break;
  224. }
  225. #endif
  226. /* If immutable bit set, nobody gets to write it. */
  227. if ((mode & VWRITE) && (ip->i_flags & IMMUTABLE))
  228. return (EPERM);
  229. return (vaccess(ip->i_mode, ip->i_uid, ip->i_gid, mode, ap->a_cred));
  230. }
  231. /* ARGSUSED */
  232. int
  233. ufs_getattr(v)
  234. void *v;
  235. {
  236. struct vop_getattr_args /* {
  237. struct vnode *a_vp;
  238. struct vattr *a_vap;
  239. struct ucred *a_cred;
  240. struct proc *a_p;
  241. } */ *ap = v;
  242. register struct vnode *vp = ap->a_vp;
  243. register struct inode *ip = VTOI(vp);
  244. register struct vattr *vap = ap->a_vap;
  245. ITIMES(ip, &time, &time);
  246. /*
  247. * Copy from inode table
  248. */
  249. vap->va_fsid = ip->i_dev;
  250. vap->va_fileid = ip->i_number;
  251. vap->va_mode = ip->i_mode & ~IFMT;
  252. vap->va_nlink = ip->i_nlink;
  253. vap->va_uid = ip->i_uid;
  254. vap->va_gid = ip->i_gid;
  255. vap->va_rdev = (dev_t)ip->i_rdev;
  256. vap->va_size = ip->i_din.di_size;
  257. vap->va_atime.tv_sec = ip->i_atime;
  258. vap->va_atime.tv_nsec = ip->i_atimensec;
  259. vap->va_mtime.tv_sec = ip->i_mtime;
  260. vap->va_mtime.tv_nsec = ip->i_mtimensec;
  261. vap->va_ctime.tv_sec = ip->i_ctime;
  262. vap->va_ctime.tv_nsec = ip->i_ctimensec;
  263. vap->va_flags = ip->i_flags;
  264. vap->va_gen = ip->i_gen;
  265. /* this doesn't belong here */
  266. if (vp->v_type == VBLK)
  267. vap->va_blocksize = BLKDEV_IOSIZE;
  268. else if (vp->v_type == VCHR)
  269. vap->va_blocksize = MAXBSIZE;
  270. else
  271. vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
  272. vap->va_bytes = dbtob(ip->i_blocks);
  273. vap->va_type = vp->v_type;
  274. vap->va_filerev = ip->i_modrev;
  275. return (0);
  276. }
  277. /*
  278. * Set attribute vnode op. called from several syscalls
  279. */
  280. int
  281. ufs_setattr(v)
  282. void *v;
  283. {
  284. struct vop_setattr_args /* {
  285. struct vnode *a_vp;
  286. struct vattr *a_vap;
  287. struct ucred *a_cred;
  288. struct proc *a_p;
  289. } */ *ap = v;
  290. register struct vattr *vap = ap->a_vap;
  291. register struct vnode *vp = ap->a_vp;
  292. register struct inode *ip = VTOI(vp);
  293. register struct ucred *cred = ap->a_cred;
  294. register struct proc *p = ap->a_p;
  295. int error;
  296. /*
  297. * Check for unsettable attributes.
  298. */
  299. if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
  300. (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
  301. (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
  302. ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
  303. return (EINVAL);
  304. }
  305. if (vap->va_flags != VNOVAL) {
  306. if (cred->cr_uid != ip->i_uid &&
  307. (error = suser(cred, &p->p_acflag)))
  308. return (error);
  309. if (cred->cr_uid == 0) {
  310. if ((ip->i_flags & (SF_IMMUTABLE | SF_APPEND)) &&
  311. securelevel > 0)
  312. return (EPERM);
  313. ip->i_flags = vap->va_flags;
  314. } else {
  315. if (ip->i_flags & (SF_IMMUTABLE | SF_APPEND))
  316. return (EPERM);
  317. ip->i_flags &= SF_SETTABLE;
  318. ip->i_flags |= (vap->va_flags & UF_SETTABLE);
  319. }
  320. ip->i_flag |= IN_CHANGE;
  321. if (vap->va_flags & (IMMUTABLE | APPEND))
  322. return (0);
  323. }
  324. if (ip->i_flags & (IMMUTABLE | APPEND))
  325. return (EPERM);
  326. /*
  327. * Go through the fields and update iff not VNOVAL.
  328. */
  329. if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
  330. error = ufs_chown(vp, vap->va_uid, vap->va_gid, cred, p);
  331. if (error)
  332. return (error);
  333. }
  334. if (vap->va_size != VNOVAL) {
  335. if (vp->v_type == VDIR)
  336. return (EISDIR);
  337. error = VOP_TRUNCATE(vp, vap->va_size, 0, cred, p);
  338. if (error)
  339. return (error);
  340. }
  341. ip = VTOI(vp);
  342. if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
  343. if (cred->cr_uid != ip->i_uid &&
  344. (error = suser(cred, &p->p_acflag)) &&
  345. ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
  346. (error = VOP_ACCESS(vp, VWRITE, cred, p))))
  347. return (error);
  348. if (vap->va_atime.tv_sec != VNOVAL)
  349. ip->i_flag |= IN_ACCESS;
  350. if (vap->va_mtime.tv_sec != VNOVAL)
  351. ip->i_flag |= IN_CHANGE | IN_UPDATE;
  352. error = VOP_UPDATE(vp, &vap->va_atime, &vap->va_mtime, 1);
  353. if (error)
  354. return (error);
  355. }
  356. error = 0;
  357. if (vap->va_mode != (mode_t)VNOVAL)
  358. error = ufs_chmod(vp, (int)vap->va_mode, cred, p);
  359. return (error);
  360. }
  361. /*
  362. * Change the mode on a file.
  363. * Inode must be locked before calling.
  364. */
  365. static int
  366. ufs_chmod(vp, mode, cred, p)
  367. register struct vnode *vp;
  368. register int mode;
  369. register struct ucred *cred;
  370. struct proc *p;
  371. {
  372. register struct inode *ip = VTOI(vp);
  373. int error;
  374. if (cred->cr_uid != ip->i_uid &&
  375. (error = suser(cred, &p->p_acflag)))
  376. return (error);
  377. if (cred->cr_uid) {
  378. if (vp->v_type != VDIR && (mode & S_ISTXT))
  379. return (EFTYPE);
  380. if (!groupmember(ip->i_gid, cred) && (mode & ISGID))
  381. return (EPERM);
  382. }
  383. ip->i_mode &= ~ALLPERMS;
  384. ip->i_mode |= (mode & ALLPERMS);
  385. ip->i_flag |= IN_CHANGE;
  386. if ((vp->v_flag & VTEXT) && (ip->i_mode & S_ISTXT) == 0)
  387. (void) vnode_pager_uncache(vp);
  388. return (0);
  389. }
  390. /*
  391. * Perform chown operation on inode ip;
  392. * inode must be locked prior to call.
  393. */
  394. static int
  395. ufs_chown(vp, uid, gid, cred, p)
  396. register struct vnode *vp;
  397. uid_t uid;
  398. gid_t gid;
  399. struct ucred *cred;
  400. struct proc *p;
  401. {
  402. register struct inode *ip = VTOI(vp);
  403. uid_t ouid;
  404. gid_t ogid;
  405. int error = 0;
  406. #ifdef QUOTA
  407. register int i;
  408. long change;
  409. #endif
  410. if (uid == (uid_t)VNOVAL)
  411. uid = ip->i_uid;
  412. if (gid == (gid_t)VNOVAL)
  413. gid = ip->i_gid;
  414. /*
  415. * If we don't own the file, are trying to change the owner
  416. * of the file, or are not a member of the target group,
  417. * the caller must be superuser or the call fails.
  418. */
  419. if ((cred->cr_uid != ip->i_uid || uid != ip->i_uid ||
  420. (gid != ip->i_gid && !groupmember((gid_t)gid, cred))) &&
  421. (error = suser(cred, &p->p_acflag)))
  422. return (error);
  423. ogid = ip->i_gid;
  424. ouid = ip->i_uid;
  425. #ifdef QUOTA
  426. if ((error = getinoquota(ip)) != 0)
  427. return (error);
  428. if (ouid == uid) {
  429. dqrele(vp, ip->i_dquot[USRQUOTA]);
  430. ip->i_dquot[USRQUOTA] = NODQUOT;
  431. }
  432. if (ogid == gid) {
  433. dqrele(vp, ip->i_dquot[GRPQUOTA]);
  434. ip->i_dquot[GRPQUOTA] = NODQUOT;
  435. }
  436. change = ip->i_blocks;
  437. (void) chkdq(ip, -change, cred, CHOWN);
  438. (void) chkiq(ip, -1, cred, CHOWN);
  439. for (i = 0; i < MAXQUOTAS; i++) {
  440. dqrele(vp, ip->i_dquot[i]);
  441. ip->i_dquot[i] = NODQUOT;
  442. }
  443. #endif
  444. ip->i_gid = gid;
  445. ip->i_uid = uid;
  446. #ifdef QUOTA
  447. if ((error = getinoquota(ip)) == 0) {
  448. if (ouid == uid) {
  449. dqrele(vp, ip->i_dquot[USRQUOTA]);
  450. ip->i_dquot[USRQUOTA] = NODQUOT;
  451. }
  452. if (ogid == gid) {
  453. dqrele(vp, ip->i_dquot[GRPQUOTA]);
  454. ip->i_dquot[GRPQUOTA] = NODQUOT;
  455. }
  456. if ((error = chkdq(ip, change, cred, CHOWN)) == 0) {
  457. if ((error = chkiq(ip, 1, cred, CHOWN)) == 0)
  458. goto good;
  459. else
  460. (void) chkdq(ip, -change, cred, CHOWN|FORCE);
  461. }
  462. for (i = 0; i < MAXQUOTAS; i++) {
  463. dqrele(vp, ip->i_dquot[i]);
  464. ip->i_dquot[i] = NODQUOT;
  465. }
  466. }
  467. ip->i_gid = ogid;
  468. ip->i_uid = ouid;
  469. if (getinoquota(ip) == 0) {
  470. if (ouid == uid) {
  471. dqrele(vp, ip->i_dquot[USRQUOTA]);
  472. ip->i_dquot[USRQUOTA] = NODQUOT;
  473. }
  474. if (ogid == gid) {
  475. dqrele(vp, ip->i_dquot[GRPQUOTA]);
  476. ip->i_dquot[GRPQUOTA] = NODQUOT;
  477. }
  478. (void) chkdq(ip, change, cred, FORCE|CHOWN);
  479. (void) chkiq(ip, 1, cred, FORCE|CHOWN);
  480. (void) getinoquota(ip);
  481. }
  482. return (error);
  483. good:
  484. if (getinoquota(ip))
  485. panic("chown: lost quota");
  486. #endif /* QUOTA */
  487. if (ouid != uid || ogid != gid)
  488. ip->i_flag |= IN_CHANGE;
  489. if (ouid != uid && cred->cr_uid != 0)
  490. ip->i_mode &= ~ISUID;
  491. if (ogid != gid && cred->cr_uid != 0)
  492. ip->i_mode &= ~ISGID;
  493. return (0);
  494. }
  495. /* ARGSUSED */
  496. int
  497. ufs_ioctl(v)
  498. void *v;
  499. {
  500. #if 0
  501. struct vop_ioctl_args /* {
  502. struct vnode *a_vp;
  503. u_long a_command;
  504. caddr_t a_data;
  505. int a_fflag;
  506. struct ucred *a_cred;
  507. struct proc *a_p;
  508. } */ *ap = v;
  509. #endif
  510. return (ENOTTY);
  511. }
  512. /* ARGSUSED */
  513. int
  514. ufs_select(v)
  515. void *v;
  516. {
  517. #if 0
  518. struct vop_select_args /* {
  519. struct vnode *a_vp;
  520. int a_which;
  521. int a_fflags;
  522. struct ucred *a_cred;
  523. struct proc *a_p;
  524. } */ *ap = v;
  525. #endif
  526. /*
  527. * We should really check to see if I/O is possible.
  528. */
  529. return (1);
  530. }
  531. /*
  532. * Mmap a file
  533. *
  534. * NB Currently unsupported.
  535. */
  536. /* ARGSUSED */
  537. int
  538. ufs_mmap(v)
  539. void *v;
  540. {
  541. #if 0
  542. struct vop_mmap_args /* {
  543. struct vnode *a_vp;
  544. int a_fflags;
  545. struct ucred *a_cred;
  546. struct proc *a_p;
  547. } */ *ap = v;
  548. #endif
  549. return (EINVAL);
  550. }
  551. /*
  552. * Seek on a file
  553. *
  554. * Nothing to do, so just return.
  555. */
  556. /* ARGSUSED */
  557. int
  558. ufs_seek(v)
  559. void *v;
  560. {
  561. #if 0
  562. struct vop_seek_args /* {
  563. struct vnode *a_vp;
  564. off_t a_oldoff;
  565. off_t a_newoff;
  566. struct ucred *a_cred;
  567. } */ *ap = v;
  568. #endif
  569. return (0);
  570. }
  571. int
  572. ufs_remove(v)
  573. void *v;
  574. {
  575. struct vop_remove_args /* {
  576. struct vnode *a_dvp;
  577. struct vnode *a_vp;
  578. struct componentname *a_cnp;
  579. } */ *ap = v;
  580. register struct inode *ip;
  581. register struct vnode *vp = ap->a_vp;
  582. register struct vnode *dvp = ap->a_dvp;
  583. int error;
  584. if (vp->v_type == VDIR) {
  585. error = EISDIR;
  586. goto out;
  587. }
  588. ip = VTOI(vp);
  589. if ((ip->i_flags & (IMMUTABLE | APPEND)) ||
  590. (VTOI(dvp)->i_flags & APPEND)) {
  591. error = EPERM;
  592. goto out;
  593. }
  594. if ((error = ufs_dirremove(dvp, ap->a_cnp)) == 0) {
  595. ip->i_nlink--;
  596. ip->i_flag |= IN_CHANGE;
  597. }
  598. out:
  599. if (dvp == vp)
  600. vrele(vp);
  601. else
  602. vput(vp);
  603. vput(dvp);
  604. return (error);
  605. }
  606. /*
  607. * link vnode call
  608. */
  609. int
  610. ufs_link(v)
  611. void *v;
  612. {
  613. struct vop_link_args /* {
  614. struct vnode *a_dvp;
  615. struct vnode *a_vp;
  616. struct componentname *a_cnp;
  617. } */ *ap = v;
  618. register struct vnode *dvp = ap->a_dvp;
  619. register struct vnode *vp = ap->a_vp;
  620. register struct componentname *cnp = ap->a_cnp;
  621. register struct inode *ip;
  622. struct timespec ts;
  623. int error;
  624. #ifdef DIAGNOSTIC
  625. if ((cnp->cn_flags & HASBUF) == 0)
  626. panic("ufs_link: no name");
  627. #endif
  628. if (vp->v_type == VDIR) {
  629. VOP_ABORTOP(dvp, cnp);
  630. error = EISDIR;
  631. goto out2;
  632. }
  633. if (dvp->v_mount != vp->v_mount) {
  634. VOP_ABORTOP(dvp, cnp);
  635. error = EXDEV;
  636. goto out2;
  637. }
  638. if (dvp != vp && (error = VOP_LOCK(vp))) {
  639. VOP_ABORTOP(dvp, cnp);
  640. goto out2;
  641. }
  642. ip = VTOI(vp);
  643. if ((nlink_t)ip->i_nlink >= LINK_MAX) {
  644. VOP_ABORTOP(dvp, cnp);
  645. error = EMLINK;
  646. goto out1;
  647. }
  648. if (ip->i_flags & (IMMUTABLE | APPEND)) {
  649. VOP_ABORTOP(dvp, cnp);
  650. error = EPERM;
  651. goto out1;
  652. }
  653. ip->i_nlink++;
  654. ip->i_flag |= IN_CHANGE;
  655. TIMEVAL_TO_TIMESPEC(&time, &ts);
  656. error = VOP_UPDATE(vp, &ts, &ts, 1);
  657. if (!error)
  658. error = ufs_direnter(ip, dvp, cnp);
  659. if (error) {
  660. ip->i_nlink--;
  661. ip->i_flag |= IN_CHANGE;
  662. }
  663. FREE(cnp->cn_pnbuf, M_NAMEI);
  664. out1:
  665. if (dvp != vp)
  666. VOP_UNLOCK(vp);
  667. out2:
  668. vput(dvp);
  669. return (error);
  670. }
  671. /*
  672. * whiteout vnode call
  673. */
  674. int
  675. ufs_whiteout(v)
  676. void *v;
  677. {
  678. struct vop_whiteout_args /* {
  679. struct vnode *a_dvp;
  680. struct componentname *a_cnp;
  681. int a_flags;
  682. } */ *ap = v;
  683. struct vnode *dvp = ap->a_dvp;
  684. struct componentname *cnp = ap->a_cnp;
  685. struct direct newdir;
  686. int error = 0;
  687. switch (ap->a_flags) {
  688. case LOOKUP:
  689. /* 4.4 format directories support whiteout operations */
  690. if (dvp->v_mount->mnt_maxsymlinklen > 0)
  691. return (0);
  692. return (EOPNOTSUPP);
  693. case CREATE:
  694. /* create a new directory whiteout */
  695. #ifdef DIAGNOSTIC
  696. if ((cnp->cn_flags & SAVENAME) == 0)
  697. panic("ufs_whiteout: missing name");
  698. if (dvp->v_mount->mnt_maxsymlinklen <= 0)
  699. panic("ufs_whiteout: old format filesystem");
  700. #endif
  701. newdir.d_ino = WINO;
  702. newdir.d_namlen = cnp->cn_namelen;
  703. bcopy(cnp->cn_nameptr, newdir.d_name, (unsigned)cnp->cn_namelen + 1);
  704. newdir.d_type = DT_WHT;
  705. error = ufs_direnter2(dvp, &newdir, cnp->cn_cred, cnp->cn_proc);
  706. break;
  707. case DELETE:
  708. /* remove an existing directory whiteout */
  709. #ifdef DIAGNOSTIC
  710. if (dvp->v_mount->mnt_maxsymlinklen <= 0)
  711. panic("ufs_whiteout: old format filesystem");
  712. #endif
  713. cnp->cn_flags &= ~DOWHITEOUT;
  714. error = ufs_dirremove(dvp, cnp);
  715. break;
  716. }
  717. if (cnp->cn_flags & HASBUF) {
  718. FREE(cnp->cn_pnbuf, M_NAMEI);
  719. cnp->cn_flags &= ~HASBUF;
  720. }
  721. return (error);
  722. }
  723. /*
  724. * Rename system call.
  725. * rename("foo", "bar");
  726. * is essentially
  727. * unlink("bar");
  728. * link("foo", "bar");
  729. * unlink("foo");
  730. * but ``atomically''. Can't do full commit without saving state in the
  731. * inode on disk which isn't feasible at this time. Best we can do is
  732. * always guarantee the target exists.
  733. *
  734. * Basic algorithm is:
  735. *
  736. * 1) Bump link count on source while we're linking it to the
  737. * target. This also ensure the inode won't be deleted out
  738. * from underneath us while we work (it may be truncated by
  739. * a concurrent `trunc' or `open' for creation).
  740. * 2) Link source to destination. If destination already exists,
  741. * delete it first.
  742. * 3) Unlink source reference to inode if still around. If a
  743. * directory was moved and the parent of the destination
  744. * is different from the source, patch the ".." entry in the
  745. * directory.
  746. */
  747. int
  748. ufs_rename(v)
  749. void *v;
  750. {
  751. struct vop_rename_args /* {
  752. struct vnode *a_fdvp;
  753. struct vnode *a_fvp;
  754. struct componentname *a_fcnp;
  755. struct vnode *a_tdvp;
  756. struct vnode *a_tvp;
  757. struct componentname *a_tcnp;
  758. } */ *ap = v;
  759. struct vnode *tvp = ap->a_tvp;
  760. register struct vnode *tdvp = ap->a_tdvp;
  761. struct vnode *fvp = ap->a_fvp;
  762. register struct vnode *fdvp = ap->a_fdvp;
  763. register struct componentname *tcnp = ap->a_tcnp;
  764. register struct componentname *fcnp = ap->a_fcnp;
  765. register struct inode *ip, *xp, *dp;
  766. struct dirtemplate dirbuf;
  767. struct timespec ts;
  768. int doingdirectory = 0, oldparent = 0, newparent = 0;
  769. int error = 0;
  770. u_char namlen;
  771. #ifdef DIAGNOSTIC
  772. if ((tcnp->cn_flags & HASBUF) == 0 ||
  773. (fcnp->cn_flags & HASBUF) == 0)
  774. panic("ufs_rename: no name");
  775. #endif
  776. /*
  777. * Check for cross-device rename.
  778. */
  779. if ((fvp->v_mount != tdvp->v_mount) ||
  780. (tvp && (fvp->v_mount != tvp->v_mount))) {
  781. error = EXDEV;
  782. abortit:
  783. VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */
  784. if (tdvp == tvp)
  785. vrele(tdvp);
  786. else
  787. vput(tdvp);
  788. if (tvp)
  789. vput(tvp);
  790. VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */
  791. vrele(fdvp);
  792. vrele(fvp);
  793. return (error);
  794. }
  795. /*
  796. * Check if just deleting a link name.
  797. */
  798. if (tvp && ((VTOI(tvp)->i_flags & (IMMUTABLE | APPEND)) ||
  799. (VTOI(tdvp)->i_flags & APPEND))) {
  800. error = EPERM;
  801. goto abortit;
  802. }
  803. if (fvp == tvp) {
  804. if (fvp->v_type == VDIR) {
  805. error = EINVAL;
  806. goto abortit;
  807. }
  808. /* Release destination completely. */
  809. VOP_ABORTOP(tdvp, tcnp);
  810. vput(tdvp);
  811. vput(tvp);
  812. /* Delete source. */
  813. vrele(fdvp);
  814. vrele(fvp);
  815. fcnp->cn_flags &= ~MODMASK;
  816. fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
  817. if ((fcnp->cn_flags & SAVESTART) == 0)
  818. panic("ufs_rename: lost from startdir");
  819. fcnp->cn_nameiop = DELETE;
  820. (void) relookup(fdvp, &fvp, fcnp);
  821. return (VOP_REMOVE(fdvp, fvp, fcnp));
  822. }
  823. if ((error = VOP_LOCK(fvp)) != 0)
  824. goto abortit;
  825. dp = VTOI(fdvp);
  826. ip = VTOI(fvp);
  827. if ((ip->i_flags & (IMMUTABLE | APPEND)) || (dp->i_flags & APPEND)) {
  828. VOP_UNLOCK(fvp);
  829. error = EPERM;
  830. goto abortit;
  831. }
  832. if ((ip->i_mode & IFMT) == IFDIR) {
  833. /*
  834. * Avoid ".", "..", and aliases of "." for obvious reasons.
  835. */
  836. if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') ||
  837. dp == ip || (fcnp->cn_flags&ISDOTDOT) ||
  838. (ip->i_flag & IN_RENAME)) {
  839. VOP_UNLOCK(fvp);
  840. error = EINVAL;
  841. goto abortit;
  842. }
  843. ip->i_flag |= IN_RENAME;
  844. oldparent = dp->i_number;
  845. doingdirectory++;
  846. }
  847. vrele(fdvp);
  848. /*
  849. * When the target exists, both the directory
  850. * and target vnodes are returned locked.
  851. */
  852. dp = VTOI(tdvp);
  853. xp = NULL;
  854. if (tvp)
  855. xp = VTOI(tvp);
  856. /*
  857. * 1) Bump link count while we're moving stuff
  858. * around. If we crash somewhere before
  859. * completing our work, the link count
  860. * may be wrong, but correctable.
  861. */
  862. ip->i_nlink++;
  863. ip->i_flag |= IN_CHANGE;
  864. TIMEVAL_TO_TIMESPEC(&time, &ts);
  865. if ((error = VOP_UPDATE(fvp, &ts, &ts, 1)) != 0) {
  866. VOP_UNLOCK(fvp);
  867. goto bad;
  868. }
  869. /*
  870. * If ".." must be changed (ie the directory gets a new
  871. * parent) then the source directory must not be in the
  872. * directory heirarchy above the target, as this would
  873. * orphan everything below the source directory. Also
  874. * the user must have write permission in the source so
  875. * as to be able to change "..". We must repeat the call
  876. * to namei, as the parent directory is unlocked by the
  877. * call to checkpath().
  878. */
  879. error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred, tcnp->cn_proc);
  880. VOP_UNLOCK(fvp);
  881. if (oldparent != dp->i_number)
  882. newparent = dp->i_number;
  883. if (doingdirectory && newparent) {
  884. if (error) /* write access check above */
  885. goto bad;
  886. if (xp != NULL)
  887. vput(tvp);
  888. if ((error = ufs_checkpath(ip, dp, tcnp->cn_cred)) != 0)
  889. goto out;
  890. if ((tcnp->cn_flags & SAVESTART) == 0)
  891. panic("ufs_rename: lost to startdir");
  892. if ((error = relookup(tdvp, &tvp, tcnp)) != 0)
  893. goto out;
  894. dp = VTOI(tdvp);
  895. xp = NULL;
  896. if (tvp)
  897. xp = VTOI(tvp);
  898. }
  899. /*
  900. * 2) If target doesn't exist, link the target
  901. * to the source and unlink the source.
  902. * Otherwise, rewrite the target directory
  903. * entry to reference the source inode and
  904. * expunge the original entry's existence.
  905. */
  906. if (xp == NULL) {
  907. if (dp->i_dev != ip->i_dev)
  908. panic("rename: EXDEV");
  909. /*
  910. * Account for ".." in new directory.
  911. * When source and destination have the same
  912. * parent we don't fool with the link count.
  913. */
  914. if (doingdirectory && newparent) {
  915. if ((nlink_t)dp->i_nlink >= LINK_MAX) {
  916. error = EMLINK;
  917. goto bad;
  918. }
  919. dp->i_nlink++;
  920. dp->i_flag |= IN_CHANGE;
  921. if ((error = VOP_UPDATE(tdvp, &ts, &ts, 1)) != 0)
  922. goto bad;
  923. }
  924. if ((error = ufs_direnter(ip, tdvp, tcnp)) != 0) {
  925. if (doingdirectory && newparent) {
  926. dp->i_nlink--;
  927. dp->i_flag |= IN_CHANGE;
  928. (void)VOP_UPDATE(tdvp, &ts, &ts, 1);
  929. }
  930. goto bad;
  931. }
  932. vput(tdvp);
  933. } else {
  934. if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev)
  935. panic("rename: EXDEV");
  936. /*
  937. * Short circuit rename(foo, foo).
  938. */
  939. if (xp->i_number == ip->i_number)
  940. panic("rename: same file");
  941. /*
  942. * If the parent directory is "sticky", then the user must
  943. * own the parent directory, or the destination of the rename,
  944. * otherwise the destination may not be changed (except by
  945. * root). This implements append-only directories.
  946. */
  947. if ((dp->i_mode & S_ISTXT) && tcnp->cn_cred->cr_uid != 0 &&
  948. tcnp->cn_cred->cr_uid != dp->i_uid &&
  949. xp->i_uid != tcnp->cn_cred->cr_uid) {
  950. error = EPERM;
  951. goto bad;
  952. }
  953. /*
  954. * Target must be empty if a directory and have no links
  955. * to it. Also, ensure source and target are compatible
  956. * (both directories, or both not directories).
  957. */
  958. if ((xp->i_mode&IFMT) == IFDIR) {
  959. if (!ufs_dirempty(xp, dp->i_number, tcnp->cn_cred) ||
  960. xp->i_nlink > 2) {
  961. error = ENOTEMPTY;
  962. goto bad;
  963. }
  964. if (!doingdirectory) {
  965. error = ENOTDIR;
  966. goto bad;
  967. }
  968. cache_purge(tdvp);
  969. } else if (doingdirectory) {
  970. error = EISDIR;
  971. goto bad;
  972. }
  973. if ((error = ufs_dirrewrite(dp, ip, tcnp)) != 0)
  974. goto bad;
  975. /*
  976. * If the target directory is in the same
  977. * directory as the source directory,
  978. * decrement the link count on the parent
  979. * of the target directory.
  980. */
  981. if (doingdirectory && !newparent) {
  982. dp->i_nlink--;
  983. dp->i_flag |= IN_CHANGE;
  984. }
  985. vput(tdvp);
  986. /*
  987. * Adjust the link count of the target to
  988. * reflect the dirrewrite above. If this is
  989. * a directory it is empty and there are
  990. * no links to it, so we can squash the inode and
  991. * any space associated with it. We disallowed
  992. * renaming over top of a directory with links to
  993. * it above, as the remaining link would point to
  994. * a directory without "." or ".." entries.
  995. */
  996. xp->i_nlink--;
  997. if (doingdirectory) {
  998. if (--xp->i_nlink != 0)
  999. panic("rename: linked directory");
  1000. error = VOP_TRUNCATE(tvp, (off_t)0, IO_SYNC,
  1001. tcnp->cn_cred, tcnp->cn_proc);
  1002. }
  1003. xp->i_flag |= IN_CHANGE;
  1004. vput(tvp);
  1005. xp = NULL;
  1006. }
  1007. /*
  1008. * 3) Unlink the source.
  1009. */
  1010. fcnp->cn_flags &= ~MODMASK;
  1011. fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
  1012. if ((fcnp->cn_flags & SAVESTART) == 0)
  1013. panic("ufs_rename: lost from startdir");
  1014. (void) relookup(fdvp, &fvp, fcnp);
  1015. if (fvp != NULL) {
  1016. xp = VTOI(fvp);
  1017. dp = VTOI(fdvp);
  1018. } else {
  1019. /*
  1020. * From name has disappeared.
  1021. */
  1022. if (doingdirectory)
  1023. panic("rename: lost dir entry");
  1024. vrele(ap->a_fvp);
  1025. return (0);
  1026. }
  1027. /*
  1028. * Ensure that the directory entry still exists and has not
  1029. * changed while the new name has been entered. If the source is
  1030. * a file then the entry may have been unlinked or renamed. In
  1031. * either case there is no further work to be done. If the source
  1032. * is a directory then it cannot have been rmdir'ed; its link
  1033. * count of three would cause a rmdir to fail with ENOTEMPTY.
  1034. * The IRENAME flag ensures that it cannot be moved by another
  1035. * rename.
  1036. */
  1037. if (xp != ip) {
  1038. if (doingdirectory)
  1039. panic("rename: lost dir entry");
  1040. } else {
  1041. /*
  1042. * If the source is a directory with a
  1043. * new parent, the link count of the old
  1044. * parent directory must be decremented
  1045. * and ".." set to point to the new parent.
  1046. */
  1047. if (doingdirectory && newparent) {
  1048. dp->i_nlink--;
  1049. dp->i_flag |= IN_CHANGE;
  1050. error = vn_rdwr(UIO_READ, fvp, (caddr_t)&dirbuf,
  1051. sizeof (struct dirtemplate), (off_t)0,
  1052. UIO_SYSSPACE, IO_NODELOCKED,
  1053. tcnp->cn_cred, (int *)0, (struct proc *)0);
  1054. if (error == 0) {
  1055. # if (BYTE_ORDER == LITTLE_ENDIAN)
  1056. if (fvp->v_mount->mnt_maxsymlinklen <= 0)
  1057. namlen = dirbuf.dotdot_type;
  1058. else
  1059. namlen = dirbuf.dotdot_namlen;
  1060. # else
  1061. namlen = dirbuf.dotdot_namlen;
  1062. # endif
  1063. if (namlen != 2 ||
  1064. dirbuf.dotdot_name[0] != '.' ||
  1065. dirbuf.dotdot_name[1] != '.') {
  1066. ufs_dirbad(xp, (doff_t)12,
  1067. "rename: mangled dir");
  1068. } else {
  1069. dirbuf.dotdot_ino = newparent;
  1070. (void) vn_rdwr(UIO_WRITE, fvp,
  1071. (caddr_t)&dirbuf,
  1072. sizeof (struct dirtemplate),
  1073. (off_t)0, UIO_SYSSPACE,
  1074. IO_NODELOCKED|IO_SYNC,
  1075. tcnp->cn_cred, (int *)0,
  1076. (struct proc *)0);
  1077. cache_purge(fdvp);
  1078. }
  1079. }
  1080. }
  1081. error = ufs_dirremove(fdvp, fcnp);
  1082. if (!error) {
  1083. xp->i_nlink--;
  1084. xp->i_flag |= IN_CHANGE;
  1085. }
  1086. xp->i_flag &= ~IN_RENAME;
  1087. }
  1088. if (dp)
  1089. vput(fdvp);
  1090. if (xp)
  1091. vput(fvp);
  1092. vrele(ap->a_fvp);
  1093. return (error);
  1094. bad:
  1095. if (xp)
  1096. vput(ITOV(xp));
  1097. vput(ITOV(dp));
  1098. out:
  1099. if (doingdirectory)
  1100. ip->i_flag &= ~IN_RENAME;
  1101. if (VOP_LOCK(fvp) == 0) {
  1102. ip->i_nlink--;
  1103. ip->i_flag |= IN_CHANGE;
  1104. vput(fvp);
  1105. } else
  1106. vrele(fvp);
  1107. return (error);
  1108. }
  1109. /*
  1110. * A virgin directory (no blushing please).
  1111. */
  1112. static struct dirtemplate mastertemplate = {
  1113. 0, 12, DT_DIR, 1, ".",
  1114. 0, DIRBLKSIZ - 12, DT_DIR, 2, ".."
  1115. };
  1116. static struct odirtemplate omastertemplate = {
  1117. 0, 12, 1, ".",
  1118. 0, DIRBLKSIZ - 12, 2, ".."
  1119. };
  1120. /*
  1121. * Mkdir system call
  1122. */
  1123. int
  1124. ufs_mkdir(v)
  1125. void *v;
  1126. {
  1127. struct vop_mkdir_args /* {
  1128. struct vnode *a_dvp;
  1129. struct vnode **a_vpp;
  1130. struct componentname *a_cnp;
  1131. struct vattr *a_vap;
  1132. } */ *ap = v;
  1133. register struct vnode *dvp = ap->a_dvp;
  1134. register struct vattr *vap = ap->a_vap;
  1135. register struct componentname *cnp = ap->a_cnp;
  1136. register struct inode *ip, *dp;
  1137. struct vnode *tvp;
  1138. struct dirtemplate dirtemplate, *dtp;
  1139. struct timespec ts;
  1140. int error, dmode;
  1141. #ifdef DIAGNOSTIC
  1142. if ((cnp->cn_flags & HASBUF) == 0)
  1143. panic("ufs_mkdir: no name");
  1144. #endif
  1145. dp = VTOI(dvp);
  1146. if ((nlink_t)dp->i_nlink >= LINK_MAX) {
  1147. error = EMLINK;
  1148. goto out;
  1149. }
  1150. dmode = vap->va_mode & 0777;
  1151. dmode |= IFDIR;
  1152. /*
  1153. * Must simulate part of ufs_makeinode here to acquire the inode,
  1154. * but not have it entered in the parent directory. The entry is
  1155. * made later after writing "." and ".." entries.
  1156. */
  1157. if ((error = VOP_VALLOC(dvp, dmode, cnp->cn_cred, &tvp)) != 0)
  1158. goto out;
  1159. ip = VTOI(tvp);
  1160. ip->i_uid = cnp->cn_cred->cr_uid;
  1161. ip->i_gid = dp->i_gid;
  1162. #ifdef QUOTA
  1163. if ((error = getinoquota(ip)) ||
  1164. (error = chkiq(ip, 1, cnp->cn_cred, 0))) {
  1165. free(cnp->cn_pnbuf, M_NAMEI);
  1166. VOP_VFREE(tvp, ip->i_number, dmode);
  1167. vput(tvp);
  1168. vput(dvp);
  1169. return (error);
  1170. }
  1171. #endif
  1172. ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
  1173. ip->i_mode = dmode;
  1174. tvp->v_type = VDIR; /* Rest init'd in getnewvnode(). */
  1175. ip->i_nlink = 2;
  1176. if (cnp->cn_flags & ISWHITEOUT)
  1177. ip->i_flags |= UF_OPAQUE;
  1178. TIMEVAL_TO_TIMESPEC(&time, &ts);
  1179. error = VOP_UPDATE(tvp, &ts, &ts, 1);
  1180. /*
  1181. * Bump link count in parent directory
  1182. * to reflect work done below. Should
  1183. * be done before reference is created
  1184. * so reparation is possible if we crash.
  1185. */
  1186. dp->i_nlink++;
  1187. dp->i_flag |= IN_CHANGE;
  1188. if ((error = VOP_UPDATE(dvp, &ts, &ts, 1)) != 0)
  1189. goto bad;
  1190. /* Initialize directory with "." and ".." from static template. */
  1191. if (dvp->v_mount->mnt_maxsymlinklen > 0)
  1192. dtp = &mastertemplate;
  1193. else
  1194. dtp = (struct dirtemplate *)&omastertemplate;
  1195. dirtemplate = *dtp;
  1196. dirtemplate.dot_ino = ip->i_number;
  1197. dirtemplate.dotdot_ino = dp->i_number;
  1198. error = vn_rdwr(UIO_WRITE, tvp, (caddr_t)&dirtemplate,
  1199. sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE,
  1200. IO_NODELOCKED|IO_SYNC, cnp->cn_cred, (int *)0, (struct proc *)0);
  1201. if (error) {
  1202. dp->i_nlink--;
  1203. dp->i_flag |= IN_CHANGE;
  1204. goto bad;
  1205. }
  1206. if (DIRBLKSIZ > VFSTOUFS(dvp->v_mount)->um_mountp->mnt_stat.f_bsize)
  1207. panic("ufs_mkdir: blksize"); /* XXX should grow with balloc() */
  1208. else {
  1209. ip->i_size = DIRBLKSIZ;
  1210. ip->i_flag |= IN_CHANGE;
  1211. }
  1212. /* Directory set up, now install it's entry in the parent directory. */
  1213. if ((error = ufs_direnter(ip, dvp, cnp)) != 0) {
  1214. dp->i_nlink--;
  1215. dp->i_flag |= IN_CHANGE;
  1216. }
  1217. bad:
  1218. /*
  1219. * No need to do an explicit VOP_TRUNCATE here, vrele will do this
  1220. * for us because we set the link count to 0.
  1221. */
  1222. if (error) {
  1223. ip->i_nlink = 0;
  1224. ip->i_flag |= IN_CHANGE;
  1225. vput(tvp);
  1226. } else
  1227. *ap->a_vpp = tvp;
  1228. out:
  1229. FREE(cnp->cn_pnbuf, M_NAMEI);
  1230. vput(dvp);
  1231. return (error);
  1232. }
  1233. /*
  1234. * Rmdir system call.
  1235. */
  1236. int
  1237. ufs_rmdir(v)
  1238. void *v;
  1239. {
  1240. struct vop_rmdir_args /* {
  1241. struct vnode *a_dvp;
  1242. struct vnode *a_vp;
  1243. struct componentname *a_cnp;
  1244. } */ *ap = v;
  1245. register struct vnode *vp = ap->a_vp;
  1246. register struct vnode *dvp = ap->a_dvp;
  1247. register struct componentname *cnp = ap->a_cnp;
  1248. register struct inode *ip, *dp;
  1249. int error;
  1250. ip = VTOI(vp);
  1251. dp = VTOI(dvp);
  1252. /*
  1253. * No rmdir "." please.
  1254. */
  1255. if (dp == ip) {
  1256. vrele(dvp);
  1257. vput(vp);
  1258. return (EINVAL);
  1259. }
  1260. /*
  1261. * Verify the directory is empty (and valid).
  1262. * (Rmdir ".." won't be valid since
  1263. * ".." will contain a reference to
  1264. * the current directory and thus be
  1265. * non-empty.)
  1266. */
  1267. error = 0;
  1268. if (ip->i_nlink != 2 ||
  1269. !ufs_dirempty(ip, dp->i_number, cnp->cn_cred)) {
  1270. error = ENOTEMPTY;
  1271. goto out;
  1272. }
  1273. if ((dp->i_flags & APPEND) || (ip->i_flags & (IMMUTABLE | APPEND))) {
  1274. error = EPERM;
  1275. goto out;
  1276. }
  1277. /*
  1278. * Delete reference to directory before purging
  1279. * inode. If we crash in between, the directory
  1280. * will be reattached to lost+found,
  1281. */
  1282. if ((error = ufs_dirremove(dvp, cnp)) != 0)
  1283. goto out;
  1284. dp->i_nlink--;
  1285. dp->i_flag |= IN_CHANGE;
  1286. cache_purge(dvp);
  1287. vput(dvp);
  1288. dvp = NULL;
  1289. /*
  1290. * Truncate inode. The only stuff left
  1291. * in the directory is "." and "..". The
  1292. * "." reference is inconsequential since
  1293. * we're quashing it. The ".." reference
  1294. * has already been adjusted above. We've
  1295. * removed the "." reference and the reference
  1296. * in the parent directory, but there may be
  1297. * other hard links so decrement by 2 and
  1298. * worry about them later.
  1299. */
  1300. ip->i_nlink -= 2;
  1301. error = VOP_TRUNCATE(vp, (off_t)0, IO_SYNC, cnp->cn_cred,
  1302. cnp->cn_proc);
  1303. cache_purge(ITOV(ip));
  1304. out:
  1305. if (dvp)
  1306. vput(dvp);
  1307. vput(vp);
  1308. return (error);
  1309. }
  1310. /*
  1311. * symlink -- make a symbolic link
  1312. */
  1313. int
  1314. ufs_symlink(v)
  1315. void *v;
  1316. {
  1317. struct vop_symlink_args /* {
  1318. struct vnode *a_dvp;
  1319. struct vnode **a_vpp;
  1320. struct componentname *a_cnp;
  1321. struct vattr *a_vap;
  1322. char *a_target;
  1323. } */ *ap = v;
  1324. register struct vnode *vp, **vpp = ap->a_vpp;
  1325. register struct inode *ip;
  1326. int len, error;
  1327. error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp,
  1328. vpp, ap->a_cnp);
  1329. if (error)
  1330. return (error);
  1331. vp = *vpp;
  1332. len = strlen(ap->a_target);
  1333. if (len < vp->v_mount->mnt_maxsymlinklen) {
  1334. ip = VTOI(vp);
  1335. bcopy(ap->a_target, (char *)ip->i_shortlink, len);
  1336. ip->i_size = len;
  1337. ip->i_flag |= IN_CHANGE | IN_UPDATE;
  1338. } else
  1339. error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0,
  1340. UIO_SYSSPACE, IO_NODELOCKED, ap->a_cnp->cn_cred, (int *)0,
  1341. (struct proc *)0);
  1342. vput(vp);
  1343. return (error);
  1344. }
  1345. /*
  1346. * Vnode op for reading directories.
  1347. *
  1348. * The routine below assumes that the on-disk format of a directory
  1349. * is the same as that defined by <sys/dirent.h>. If the on-disk
  1350. * format changes, then it will be necessary to do a conversion
  1351. * from the on-disk format that read returns to the format defined
  1352. * by <sys/dirent.h>.
  1353. */
  1354. int
  1355. ufs_readdir(v)
  1356. void *v;
  1357. {
  1358. struct vop_readdir_args /* {
  1359. struct vnode *a_vp;
  1360. struct uio *a_uio;
  1361. struct ucred *a_cred;
  1362. int *a_eofflag;
  1363. u_long *a_cookies;
  1364. int ncookies;
  1365. } */ *ap = v;
  1366. register struct uio *uio = ap->a_uio;
  1367. int error;
  1368. size_t count, lost;
  1369. off_t off = uio->uio_offset;
  1370. count = uio->uio_resid;
  1371. /* Make sure we don't return partial entries. */
  1372. count -= (uio->uio_offset + count) & (DIRBLKSIZ -1);
  1373. if (count <= 0)
  1374. return (EINVAL);
  1375. lost = uio->uio_resid - count;
  1376. uio->uio_resid = count;
  1377. uio->uio_iov->iov_len = count;
  1378. # if (BYTE_ORDER == LITTLE_ENDIAN)
  1379. if (ap->a_vp->v_mount->mnt_maxsymlinklen > 0) {
  1380. error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred);
  1381. } else {
  1382. struct dirent *dp, *edp;
  1383. struct uio auio;
  1384. struct iovec aiov;
  1385. caddr_t dirbuf;
  1386. int readcnt;
  1387. u_char tmp;
  1388. auio = *uio;
  1389. auio.uio_iov = &aiov;
  1390. auio.uio_iovcnt = 1;
  1391. auio.uio_segflg = UIO_SYSSPACE;
  1392. aiov.iov_len = count;
  1393. MALLOC(dirbuf, caddr_t, count, M_TEMP, M_WAITOK);
  1394. aiov.iov_base = dirbuf;
  1395. error = VOP_READ(ap->a_vp, &auio, 0, ap->a_cred);
  1396. if (error == 0) {
  1397. readcnt = count - auio.uio_resid;
  1398. edp = (struct dirent *)&dirbuf[readcnt];
  1399. for (dp = (struct dirent *)dirbuf; dp < edp; ) {
  1400. tmp = dp->d_namlen;
  1401. dp->d_namlen = dp->d_type;
  1402. dp->d_type = tmp;
  1403. if (dp->d_reclen > 0) {
  1404. dp = (struct dirent *)
  1405. ((char *)dp + dp->d_reclen);
  1406. } else {
  1407. error = EIO;
  1408. break;
  1409. }
  1410. }
  1411. if (dp >= edp)
  1412. error = uiomove(dirbuf, readcnt, uio);
  1413. }
  1414. FREE(dirbuf, M_TEMP);
  1415. }
  1416. # else
  1417. error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred);
  1418. # endif
  1419. if (!error && ap->a_ncookies) {
  1420. register struct dirent *dp;
  1421. register u_long *cookies = ap->a_cookies;
  1422. register int ncookies = ap->a_ncookies;
  1423. /*
  1424. * Only the NFS server and emulations use cookies, and they
  1425. * load the directory block into system space, so we can
  1426. * just look at it directly.
  1427. */
  1428. if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
  1429. panic("ufs_readdir: lost in space");
  1430. dp = (struct dirent *)
  1431. (uio->uio_iov->iov_base - (uio->uio_offset - off));
  1432. while (ncookies-- && off < uio->uio_offset) {
  1433. if (dp->d_reclen == 0)
  1434. break;
  1435. off += dp->d_reclen;
  1436. *(cookies++) = off;
  1437. dp = (struct dirent *)((caddr_t)dp + dp->d_reclen);
  1438. }
  1439. lost += uio->uio_offset - off;
  1440. uio->uio_offset = off;
  1441. }
  1442. uio->uio_resid += lost;
  1443. *ap->a_eofflag = VTOI(ap->a_vp)->i_size <= uio->uio_offset;
  1444. return (error);
  1445. }
  1446. /*
  1447. * Return target name of a symbolic link
  1448. */
  1449. int
  1450. ufs_readlink(v)
  1451. void *v;
  1452. {
  1453. struct vop_readlink_args /* {
  1454. struct vnode *a_vp;
  1455. struct uio *a_uio;
  1456. struct ucred *a_cred;
  1457. } */ *ap = v;
  1458. register struct vnode *vp = ap->a_vp;
  1459. register struct inode *ip = VTOI(vp);
  1460. int isize;
  1461. isize = ip->i_size;
  1462. if (isize < vp->v_mount->mnt_maxsymlinklen ||
  1463. (vp->v_mount->mnt_maxsymlinklen == 0 && ip->i_din.di_blocks == 0)) {
  1464. uiomove((char *)ip->i_shortlink, isize, ap->a_uio);
  1465. return (0);
  1466. }
  1467. return (VOP_READ(vp, ap->a_uio, 0, ap->a_cred));
  1468. }
  1469. /*
  1470. * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually
  1471. * done. If a buffer has been saved in anticipation of a CREATE, delete it.
  1472. */
  1473. /* ARGSUSED */
  1474. int
  1475. ufs_abortop(v)
  1476. void *v;
  1477. {
  1478. struct vop_abortop_args /* {
  1479. struct vnode *a_dvp;
  1480. struct componentname *a_cnp;
  1481. } */ *ap = v;
  1482. if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
  1483. FREE(ap->a_cnp->cn_pnbuf, M_NAMEI);
  1484. return (0);
  1485. }
  1486. /*
  1487. * Lock an inode. If its already locked, set the WANT bit and sleep.
  1488. */
  1489. int
  1490. ufs_lock(v)
  1491. void *v;
  1492. {
  1493. struct vop_lock_args /* {
  1494. struct vnode *a_vp;
  1495. } */ *ap = v;
  1496. register struct vnode *vp = ap->a_vp;
  1497. register struct inode *ip;
  1498. #ifdef DIAGNOSTIC
  1499. struct proc *p = curproc; /* XXX */
  1500. #endif
  1501. start:
  1502. while (vp->v_flag & VXLOCK) {
  1503. vp->v_flag |= VXWANT;
  1504. sleep((caddr_t)vp, PINOD);
  1505. }
  1506. if (vp->v_tag == VT_NON)
  1507. return (ENOENT);
  1508. ip = VTOI(vp);
  1509. if (ip->i_flag & IN_LOCKED) {
  1510. ip->i_flag |= IN_WANTED;
  1511. #ifdef DIAGNOSTIC
  1512. if (p) {
  1513. if (p->p_pid == ip->i_lockholder)
  1514. panic("locking against myself");
  1515. ip->i_lockwaiter = p->p_pid;
  1516. } else
  1517. ip->i_lockwaiter = -1;
  1518. #endif
  1519. (void) sleep((caddr_t)ip, PINOD);
  1520. goto start;
  1521. }
  1522. #ifdef DIAGNOSTIC
  1523. ip->i_lockwaiter = 0;
  1524. if (ip->i_lockholder != 0)
  1525. panic("lockholder (%d) != 0", ip->i_lockholder);
  1526. if (p && p->p_pid == 0)
  1527. printf("locking by process 0\n");
  1528. if (p)
  1529. ip->i_lockholder = p->p_pid;
  1530. else
  1531. ip->i_lockholder = -1;
  1532. #endif
  1533. ip->i_flag |= IN_LOCKED;
  1534. return (0);
  1535. }
  1536. /*
  1537. * Unlock an inode. If WANT bit is on, wakeup.
  1538. */
  1539. int lockcount = 90;
  1540. int
  1541. ufs_unlock(v)
  1542. void *v;
  1543. {
  1544. struct vop_unlock_args /* {
  1545. struct vnode *a_vp;
  1546. } */ *ap = v;
  1547. register struct inode *ip = VTOI(ap->a_vp);
  1548. #ifdef DIAGNOSTIC
  1549. struct proc *p = curproc; /* XXX */
  1550. #endif
  1551. #ifdef DIAGNOSTIC
  1552. if ((ip->i_flag & IN_LOCKED) == 0) {
  1553. vprint("ufs_unlock: unlocked inode", ap->a_vp);
  1554. panic("ufs_unlock NOT LOCKED");
  1555. }
  1556. if (p && p->p_pid != ip->i_lockholder && p->p_pid > -1 &&
  1557. ip->i_lockholder > -1 && lockcount++ < 100)
  1558. panic("unlocker (%d) != lock holder (%d)",
  1559. p->p_pid, ip->i_lockholder);
  1560. ip->i_lockholder = 0;
  1561. #endif
  1562. ip->i_flag &= ~IN_LOCKED;
  1563. if (ip->i_flag & IN_WANTED) {
  1564. ip->i_flag &= ~IN_WANTED;
  1565. wakeup((caddr_t)ip);
  1566. }
  1567. return (0);
  1568. }
  1569. /*
  1570. * Check for a locked inode.
  1571. */
  1572. int
  1573. ufs_islocked(v)
  1574. void *v;
  1575. {
  1576. struct vop_islocked_args /* {
  1577. struct vnode *a_vp;
  1578. } */ *ap = v;
  1579. if (VTOI(ap->a_vp)->i_flag & IN_LOCKED)
  1580. return (1);
  1581. return (0);
  1582. }
  1583. /*
  1584. * Calculate the logical to physical mapping if not done already,
  1585. * then call the device strategy routine.
  1586. */
  1587. int
  1588. ufs_strategy(v)
  1589. void *v;
  1590. {
  1591. struct vop_strategy_args /* {
  1592. struct buf *a_bp;
  1593. } */ *ap = v;
  1594. register struct buf *bp = ap->a_bp;
  1595. register struct vnode *vp = bp->b_vp;
  1596. register struct inode *ip;
  1597. int error;
  1598. ip = VTOI(vp);
  1599. if (vp->v_type == VBLK || vp->v_type == VCHR)
  1600. panic("ufs_strategy: spec");
  1601. if (bp->b_blkno == bp->b_lblkno) {
  1602. error = VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno,
  1603. NULL);
  1604. if (error) {
  1605. bp->b_error = error;
  1606. bp->b_flags |= B_ERROR;
  1607. biodone(bp);
  1608. return (error);
  1609. }
  1610. if ((long)bp->b_blkno == -1)
  1611. clrbuf(bp);
  1612. }
  1613. if ((long)bp->b_blkno == -1) {
  1614. biodone(bp);
  1615. return (0);
  1616. }
  1617. vp = ip->i_devvp;
  1618. bp->b_dev = vp->v_rdev;
  1619. VOCALL (vp->v_op, VOFFSET(vop_strategy), ap);
  1620. return (0);
  1621. }
  1622. /*
  1623. * Print out the contents of an inode.
  1624. */
  1625. int
  1626. ufs_print(v)
  1627. void *v;
  1628. {
  1629. struct vop_print_args /* {
  1630. struct vnode *a_vp;
  1631. } */ *ap = v;
  1632. register struct vnode *vp = ap->a_vp;
  1633. register struct inode *ip = VTOI(vp);
  1634. printf("tag VT_UFS, ino %d, on dev %d, %d", ip->i_number,
  1635. major(ip->i_dev), minor(ip->i_dev));
  1636. #ifdef FIFO
  1637. if (vp->v_type == VFIFO)
  1638. fifo_printinfo(vp);
  1639. #endif /* FIFO */
  1640. printf("%s\n", (ip->i_flag & IN_LOCKED) ? " (LOCKED)" : "");
  1641. if (ip->i_lockholder == 0)
  1642. return (0);
  1643. printf("\towner pid %d", ip->i_lockholder);
  1644. if (ip->i_lockwaiter)
  1645. printf(" waiting pid %d", ip->i_lockwaiter);
  1646. printf("\n");
  1647. return (0);
  1648. }
  1649. /*
  1650. * Read wrapper for special devices.
  1651. */
  1652. int
  1653. ufsspec_read(v)
  1654. void *v;
  1655. {
  1656. struct vop_read_args /* {
  1657. struct vnode *a_vp;
  1658. struct uio *a_uio;
  1659. int a_ioflag;
  1660. struct ucred *a_cred;
  1661. } */ *ap = v;
  1662. /*
  1663. * Set access flag.
  1664. */
  1665. VTOI(ap->a_vp)->i_flag |= IN_ACCESS;
  1666. return (VOCALL (spec_vnodeop_p, VOFFSET(vop_read), ap));
  1667. }
  1668. /*
  1669. * Write wrapper for special devices.
  1670. */
  1671. int
  1672. ufsspec_write(v)
  1673. void *v;
  1674. {
  1675. struct vop_write_args /* {
  1676. struct vnode *a_vp;
  1677. struct uio *a_uio;
  1678. int a_ioflag;
  1679. struct ucred *a_cred;
  1680. } */ *ap = v;
  1681. /*
  1682. * Set update and change flags.
  1683. */
  1684. VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE;
  1685. return (VOCALL (spec_vnodeop_p, VOFFSET(vop_write), ap));
  1686. }
  1687. /*
  1688. * Close wrapper for special devices.
  1689. *
  1690. * Update the times on the inode then do device close.
  1691. */
  1692. int
  1693. ufsspec_close(v)
  1694. void *v;
  1695. {
  1696. struct vop_close_args /* {
  1697. struct vnode *a_vp;
  1698. int a_fflag;
  1699. struct ucred *a_cred;
  1700. struct proc *a_p;
  1701. } */ *ap = v;
  1702. register struct inode *ip = VTOI(ap->a_vp);
  1703. if (ap->a_vp->v_usecount > 1 && !(ip->i_flag & IN_LOCKED))
  1704. ITIMES(ip, &time, &time);
  1705. return (VOCALL (spec_vnodeop_p, VOFFSET(vop_close), ap));
  1706. }
  1707. #ifdef FIFO
  1708. /*
  1709. * Read wrapper for fifo's
  1710. */
  1711. int
  1712. ufsfifo_read(v)
  1713. void *v;
  1714. {
  1715. struct vop_read_args /* {
  1716. struct vnode *a_vp;
  1717. struct uio *a_uio;
  1718. int a_ioflag;
  1719. struct ucred *a_cred;
  1720. } */ *ap = v;
  1721. extern int (**fifo_vnodeop_p) __P((void *));
  1722. /*
  1723. * Set access flag.
  1724. */
  1725. VTOI(ap->a_vp)->i_flag |= IN_ACCESS;
  1726. return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_read), ap));
  1727. }
  1728. /*
  1729. * Write wrapper for fifo's.
  1730. */
  1731. int
  1732. ufsfifo_write(v)
  1733. void *v;
  1734. {
  1735. struct vop_write_args /* {
  1736. struct vnode *a_vp;
  1737. struct uio *a_uio;
  1738. int a_ioflag;
  1739. struct ucred *a_cred;
  1740. } */ *ap = v;
  1741. extern int (**fifo_vnodeop_p) __P((void *));
  1742. /*
  1743. * Set update and change flags.
  1744. */
  1745. VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE;
  1746. return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_write), ap));
  1747. }
  1748. /*
  1749. * Close wrapper for fifo's.
  1750. *
  1751. * Update the times on the inode then do device close.
  1752. */
  1753. int
  1754. ufsfifo_close(v)
  1755. void *v;
  1756. {
  1757. struct vop_close_args /* {
  1758. struct vnode *a_vp;
  1759. int a_fflag;
  1760. struct ucred *a_cred;
  1761. struct proc *a_p;
  1762. } */ *ap = v;
  1763. extern int (**fifo_vnodeop_p) __P((void *));
  1764. register struct inode *ip = VTOI(ap->a_vp);
  1765. if (ap->a_vp->v_usecount > 1 && !(ip->i_flag & IN_LOCKED))
  1766. ITIMES(ip, &time, &time);
  1767. return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_close), ap));
  1768. }
  1769. #endif /* FIFO */
  1770. /*
  1771. * Return POSIX pathconf information applicable to ufs filesystems.
  1772. */
  1773. int
  1774. ufs_pathconf(v)
  1775. void *v;
  1776. {
  1777. struct vop_pathconf_args /* {
  1778. struct vnode *a_vp;
  1779. int a_name;
  1780. register_t *a_retval;
  1781. } */ *ap = v;
  1782. switch (ap->a_name) {
  1783. case _PC_LINK_MAX:
  1784. *ap->a_retval = LINK_MAX;
  1785. return (0);
  1786. case _PC_NAME_MAX:
  1787. *ap->a_retval = NAME_MAX;
  1788. return (0);
  1789. case _PC_PATH_MAX:
  1790. *ap->a_retval = PATH_MAX;
  1791. return (0);
  1792. case _PC_PIPE_BUF:
  1793. *ap->a_retval = PIPE_BUF;
  1794. return (0);
  1795. case _PC_CHOWN_RESTRICTED:
  1796. *ap->a_retval = 1;
  1797. return (0);
  1798. case _PC_NO_TRUNC:
  1799. *ap->a_retval = 1;
  1800. return (0);
  1801. default:
  1802. return (EINVAL);
  1803. }
  1804. /* NOTREACHED */
  1805. }
  1806. /*
  1807. * Advisory record locking support
  1808. */
  1809. int
  1810. ufs_advlock(v)
  1811. void *v;
  1812. {
  1813. struct vop_advlock_args /* {
  1814. struct vnode *a_vp;
  1815. caddr_t a_id;
  1816. int a_op;
  1817. struct flock *a_fl;
  1818. int a_flags;
  1819. } */ *ap = v;
  1820. register struct inode *ip = VTOI(ap->a_vp);
  1821. return (lf_advlock(&ip->i_lockf, ip->i_size, ap->a_id, ap->a_op,
  1822. ap->a_fl, ap->a_flags));
  1823. }
  1824. /*
  1825. * Initialize the vnode associated with a new inode, handle aliased
  1826. * vnodes.
  1827. */
  1828. int
  1829. ufs_vinit(mntp, specops, fifoops, vpp)
  1830. struct mount *mntp;
  1831. int (**specops) __P((void *));
  1832. int (**fifoops) __P((void *));
  1833. struct vnode **vpp;
  1834. {
  1835. struct inode *ip;
  1836. struct vnode *vp, *nvp;
  1837. vp = *vpp;
  1838. ip = VTOI(vp);
  1839. switch(vp->v_type = IFTOVT(ip->i_mode)) {
  1840. case VCHR:
  1841. case VBLK:
  1842. vp->v_op = specops;
  1843. if ((nvp = checkalias(vp, ip->i_rdev, mntp)) != NULL) {
  1844. /*
  1845. * Discard unneeded vnode, but save its inode.
  1846. */
  1847. ufs_ihashrem(ip);
  1848. VOP_UNLOCK(vp);
  1849. nvp->v_data = vp->v_data;
  1850. vp->v_data = NULL;
  1851. vp->v_op = spec_vnodeop_p;
  1852. vrele(vp);
  1853. vgone(vp);
  1854. /*
  1855. * Reinitialize aliased inode.
  1856. */
  1857. vp = nvp;
  1858. ip->i_vnode = vp;
  1859. ufs_ihashins(ip);
  1860. }
  1861. break;
  1862. case VFIFO:
  1863. #ifdef FIFO
  1864. vp->v_op = fifoops;
  1865. break;
  1866. #else
  1867. return (EOPNOTSUPP);
  1868. #endif
  1869. case VNON:
  1870. case VBAD:
  1871. case VSOCK:
  1872. case VLNK:
  1873. case VDIR:
  1874. case VREG:
  1875. break;
  1876. }
  1877. if (ip->i_number == ROOTINO)
  1878. vp->v_flag |= VROOT;
  1879. /*
  1880. * Initialize modrev times
  1881. */
  1882. SETHIGH(ip->i_modrev, mono_time.tv_sec);
  1883. SETLOW(ip->i_modrev, mono_time.tv_usec * 4294);
  1884. *vpp = vp;
  1885. return (0);
  1886. }
  1887. /*
  1888. * Allocate a new inode.
  1889. */
  1890. int
  1891. ufs_makeinode(mode, dvp, vpp, cnp)
  1892. int mode;
  1893. struct vnode *dvp;
  1894. struct vnode **vpp;
  1895. struct componentname *cnp;
  1896. {
  1897. register struct inode *ip, *pdir;
  1898. struct timespec ts;
  1899. struct vnode *tvp;
  1900. int error;
  1901. pdir = VTOI(dvp);
  1902. #ifdef DIAGNOSTIC
  1903. if ((cnp->cn_flags & HASBUF) == 0)
  1904. panic("ufs_makeinode: no name");
  1905. #endif
  1906. *vpp = NULL;
  1907. if ((mode & IFMT) == 0)
  1908. mode |= IFREG;
  1909. if ((error = VOP_VALLOC(dvp, mode, cnp->cn_cred, &tvp)) != 0) {
  1910. free(cnp->cn_pnbuf, M_NAMEI);
  1911. vput(dvp);
  1912. return (error);
  1913. }
  1914. ip = VTOI(tvp);
  1915. ip->i_gid = pdir->i_gid;
  1916. ip->i_uid = cnp->cn_cred->cr_uid;
  1917. #ifdef QUOTA
  1918. if ((error = getinoquota(ip)) ||
  1919. (error = chkiq(ip, 1, cnp->cn_cred, 0))) {
  1920. free(cnp->cn_pnbuf, M_NAMEI);
  1921. VOP_VFREE(tvp, ip->i_number, mode);
  1922. vput(tvp);
  1923. vput(dvp);
  1924. return (error);
  1925. }
  1926. #endif
  1927. ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
  1928. ip->i_mode = mode;
  1929. tvp->v_type = IFTOVT(mode); /* Rest init'd in getnewvnode(). */
  1930. ip->i_nlink = 1;
  1931. if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) &&
  1932. suser(cnp->cn_cred, NULL))
  1933. ip->i_mode &= ~ISGID;
  1934. if (cnp->cn_flags & ISWHITEOUT)
  1935. ip->i_flags |= UF_OPAQUE;
  1936. /*
  1937. * Make sure inode goes to disk before directory entry.
  1938. */
  1939. TIMEVAL_TO_TIMESPEC(&time, &ts);
  1940. if ((error = VOP_UPDATE(tvp, &ts, &ts, 1)) != 0)
  1941. goto bad;
  1942. if ((error = ufs_direnter(ip, dvp, cnp)) != 0)
  1943. goto bad;
  1944. if ((cnp->cn_flags & SAVESTART) == 0)
  1945. FREE(cnp->cn_pnbuf, M_NAMEI);
  1946. vput(dvp);
  1947. *vpp = tvp;
  1948. return (0);
  1949. bad:
  1950. /*
  1951. * Write error occurred trying to update the inode
  1952. * or the directory so must deallocate the inode.
  1953. */
  1954. free(cnp->cn_pnbuf, M_NAMEI);
  1955. vput(dvp);
  1956. ip->i_nlink = 0;
  1957. ip->i_flag |= IN_CHANGE;
  1958. vput(tvp);
  1959. return (error);
  1960. }