HardenedBSD src tree https://hardenedbsd.org/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1848 lines
42 KiB

  1. /* $NetBSD: tmpfs_vnops.c,v 1.39 2007/07/23 15:41:01 jmmv Exp $ */
  2. /*-
  3. * SPDX-License-Identifier: BSD-2-Clause-NetBSD
  4. *
  5. * Copyright (c) 2005, 2006 The NetBSD Foundation, Inc.
  6. * All rights reserved.
  7. *
  8. * This code is derived from software contributed to The NetBSD Foundation
  9. * by Julio M. Merino Vidal, developed as part of Google's Summer of Code
  10. * 2005 program.
  11. *
  12. * Redistribution and use in source and binary forms, with or without
  13. * modification, are permitted provided that the following conditions
  14. * are met:
  15. * 1. Redistributions of source code must retain the above copyright
  16. * notice, this list of conditions and the following disclaimer.
  17. * 2. Redistributions in binary form must reproduce the above copyright
  18. * notice, this list of conditions and the following disclaimer in the
  19. * documentation and/or other materials provided with the distribution.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  22. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  23. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  24. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  25. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  26. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  27. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  28. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  29. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  30. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  31. * POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. /*
  34. * tmpfs vnode interface.
  35. */
  36. #include <sys/cdefs.h>
  37. __FBSDID("$FreeBSD$");
  38. #include <sys/param.h>
  39. #include <sys/systm.h>
  40. #include <sys/dirent.h>
  41. #include <sys/fcntl.h>
  42. #include <sys/limits.h>
  43. #include <sys/lockf.h>
  44. #include <sys/lock.h>
  45. #include <sys/mount.h>
  46. #include <sys/namei.h>
  47. #include <sys/priv.h>
  48. #include <sys/proc.h>
  49. #include <sys/rwlock.h>
  50. #include <sys/sched.h>
  51. #include <sys/stat.h>
  52. #include <sys/sysctl.h>
  53. #include <sys/unistd.h>
  54. #include <sys/vnode.h>
  55. #include <vm/vm.h>
  56. #include <vm/vm_param.h>
  57. #include <vm/vm_object.h>
  58. #include <fs/tmpfs/tmpfs_vnops.h>
  59. #include <fs/tmpfs/tmpfs.h>
  60. SYSCTL_DECL(_vfs_tmpfs);
  61. static volatile int tmpfs_rename_restarts;
  62. SYSCTL_INT(_vfs_tmpfs, OID_AUTO, rename_restarts, CTLFLAG_RD,
  63. __DEVOLATILE(int *, &tmpfs_rename_restarts), 0,
  64. "Times rename had to restart due to lock contention");
  65. static struct tmpfs_extattr_list_entry *tmpfs_node_has_extattr(
  66. struct tmpfs_node *, int, const char *);
  67. static int tmpfs_extattr_set(struct vnode *, int, const char *,
  68. struct uio *, struct ucred *, struct thread *);
  69. static int tmpfs_extattr_get(struct vnode *, int, const char *,
  70. struct uio *, size_t *, struct ucred *, struct thread *);
  71. static int tmpfs_listextattr(struct vop_listextattr_args *);
  72. static int tmpfs_extattr_list(struct vnode *, int, struct uio *,
  73. size_t *, struct ucred *, struct thread *);
  74. static int
  75. tmpfs_vn_get_ino_alloc(struct mount *mp, void *arg, int lkflags,
  76. struct vnode **rvp)
  77. {
  78. return (tmpfs_alloc_vp(mp, arg, lkflags, rvp));
  79. }
  80. static int
  81. tmpfs_lookup1(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp)
  82. {
  83. struct tmpfs_dirent *de;
  84. struct tmpfs_node *dnode, *pnode;
  85. struct tmpfs_mount *tm;
  86. int error;
  87. dnode = VP_TO_TMPFS_DIR(dvp);
  88. *vpp = NULLVP;
  89. /* Check accessibility of requested node as a first step. */
  90. error = vn_dir_check_exec(dvp, cnp);
  91. if (error != 0)
  92. goto out;
  93. /* We cannot be requesting the parent directory of the root node. */
  94. MPASS(IMPLIES(dnode->tn_type == VDIR &&
  95. dnode->tn_dir.tn_parent == dnode,
  96. !(cnp->cn_flags & ISDOTDOT)));
  97. TMPFS_ASSERT_LOCKED(dnode);
  98. if (dnode->tn_dir.tn_parent == NULL) {
  99. error = ENOENT;
  100. goto out;
  101. }
  102. if (cnp->cn_flags & ISDOTDOT) {
  103. tm = VFS_TO_TMPFS(dvp->v_mount);
  104. pnode = dnode->tn_dir.tn_parent;
  105. tmpfs_ref_node(pnode);
  106. error = vn_vget_ino_gen(dvp, tmpfs_vn_get_ino_alloc,
  107. pnode, cnp->cn_lkflags, vpp);
  108. tmpfs_free_node(tm, pnode);
  109. if (error != 0)
  110. goto out;
  111. } else if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
  112. VREF(dvp);
  113. *vpp = dvp;
  114. error = 0;
  115. } else {
  116. de = tmpfs_dir_lookup(dnode, NULL, cnp);
  117. if (de != NULL && de->td_node == NULL)
  118. cnp->cn_flags |= ISWHITEOUT;
  119. if (de == NULL || de->td_node == NULL) {
  120. /*
  121. * The entry was not found in the directory.
  122. * This is OK if we are creating or renaming an
  123. * entry and are working on the last component of
  124. * the path name.
  125. */
  126. if ((cnp->cn_flags & ISLASTCN) &&
  127. (cnp->cn_nameiop == CREATE || \
  128. cnp->cn_nameiop == RENAME ||
  129. (cnp->cn_nameiop == DELETE &&
  130. cnp->cn_flags & DOWHITEOUT &&
  131. cnp->cn_flags & ISWHITEOUT))) {
  132. error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred,
  133. cnp->cn_thread);
  134. if (error != 0)
  135. goto out;
  136. /*
  137. * Keep the component name in the buffer for
  138. * future uses.
  139. */
  140. cnp->cn_flags |= SAVENAME;
  141. error = EJUSTRETURN;
  142. } else
  143. error = ENOENT;
  144. } else {
  145. struct tmpfs_node *tnode;
  146. /*
  147. * The entry was found, so get its associated
  148. * tmpfs_node.
  149. */
  150. tnode = de->td_node;
  151. /*
  152. * If we are not at the last path component and
  153. * found a non-directory or non-link entry (which
  154. * may itself be pointing to a directory), raise
  155. * an error.
  156. */
  157. if ((tnode->tn_type != VDIR &&
  158. tnode->tn_type != VLNK) &&
  159. !(cnp->cn_flags & ISLASTCN)) {
  160. error = ENOTDIR;
  161. goto out;
  162. }
  163. /*
  164. * If we are deleting or renaming the entry, keep
  165. * track of its tmpfs_dirent so that it can be
  166. * easily deleted later.
  167. */
  168. if ((cnp->cn_flags & ISLASTCN) &&
  169. (cnp->cn_nameiop == DELETE ||
  170. cnp->cn_nameiop == RENAME)) {
  171. error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred,
  172. cnp->cn_thread);
  173. if (error != 0)
  174. goto out;
  175. /* Allocate a new vnode on the matching entry. */
  176. error = tmpfs_alloc_vp(dvp->v_mount, tnode,
  177. cnp->cn_lkflags, vpp);
  178. if (error != 0)
  179. goto out;
  180. if ((dnode->tn_mode & S_ISTXT) &&
  181. VOP_ACCESS(dvp, VADMIN, cnp->cn_cred,
  182. cnp->cn_thread) && VOP_ACCESS(*vpp, VADMIN,
  183. cnp->cn_cred, cnp->cn_thread)) {
  184. error = EPERM;
  185. vput(*vpp);
  186. *vpp = NULL;
  187. goto out;
  188. }
  189. cnp->cn_flags |= SAVENAME;
  190. } else {
  191. error = tmpfs_alloc_vp(dvp->v_mount, tnode,
  192. cnp->cn_lkflags, vpp);
  193. if (error != 0)
  194. goto out;
  195. }
  196. }
  197. }
  198. /*
  199. * Store the result of this lookup in the cache. Avoid this if the
  200. * request was for creation, as it does not improve timings on
  201. * emprical tests.
  202. */
  203. if ((cnp->cn_flags & MAKEENTRY) != 0 && tmpfs_use_nc(dvp))
  204. cache_enter(dvp, *vpp, cnp);
  205. out:
  206. /*
  207. * If there were no errors, *vpp cannot be null and it must be
  208. * locked.
  209. */
  210. MPASS(IFF(error == 0, *vpp != NULLVP && VOP_ISLOCKED(*vpp)));
  211. return (error);
  212. }
  213. static int
  214. tmpfs_cached_lookup(struct vop_cachedlookup_args *v)
  215. {
  216. return (tmpfs_lookup1(v->a_dvp, v->a_vpp, v->a_cnp));
  217. }
  218. static int
  219. tmpfs_lookup(struct vop_lookup_args *v)
  220. {
  221. return (tmpfs_lookup1(v->a_dvp, v->a_vpp, v->a_cnp));
  222. }
  223. static int
  224. tmpfs_create(struct vop_create_args *v)
  225. {
  226. struct vnode *dvp = v->a_dvp;
  227. struct vnode **vpp = v->a_vpp;
  228. struct componentname *cnp = v->a_cnp;
  229. struct vattr *vap = v->a_vap;
  230. int error;
  231. MPASS(vap->va_type == VREG || vap->va_type == VSOCK);
  232. error = tmpfs_alloc_file(dvp, vpp, vap, cnp, NULL);
  233. if (error == 0 && (cnp->cn_flags & MAKEENTRY) != 0 && tmpfs_use_nc(dvp))
  234. cache_enter(dvp, *vpp, cnp);
  235. return (error);
  236. }
  237. static int
  238. tmpfs_mknod(struct vop_mknod_args *v)
  239. {
  240. struct vnode *dvp = v->a_dvp;
  241. struct vnode **vpp = v->a_vpp;
  242. struct componentname *cnp = v->a_cnp;
  243. struct vattr *vap = v->a_vap;
  244. if (vap->va_type != VBLK && vap->va_type != VCHR &&
  245. vap->va_type != VFIFO)
  246. return EINVAL;
  247. return tmpfs_alloc_file(dvp, vpp, vap, cnp, NULL);
  248. }
  249. static int
  250. tmpfs_open(struct vop_open_args *v)
  251. {
  252. struct vnode *vp = v->a_vp;
  253. int mode = v->a_mode;
  254. int error;
  255. struct tmpfs_node *node;
  256. MPASS(VOP_ISLOCKED(vp));
  257. node = VP_TO_TMPFS_NODE(vp);
  258. /* The file is still active but all its names have been removed
  259. * (e.g. by a "rmdir $(pwd)"). It cannot be opened any more as
  260. * it is about to die. */
  261. if (node->tn_links < 1)
  262. return (ENOENT);
  263. /* If the file is marked append-only, deny write requests. */
  264. if (node->tn_flags & APPEND && (mode & (FWRITE | O_APPEND)) == FWRITE)
  265. error = EPERM;
  266. else {
  267. error = 0;
  268. /* For regular files, the call below is nop. */
  269. KASSERT(vp->v_type != VREG || (node->tn_reg.tn_aobj->flags &
  270. OBJ_DEAD) == 0, ("dead object"));
  271. vnode_create_vobject(vp, node->tn_size, v->a_td);
  272. }
  273. MPASS(VOP_ISLOCKED(vp));
  274. return error;
  275. }
  276. static int
  277. tmpfs_close(struct vop_close_args *v)
  278. {
  279. struct vnode *vp = v->a_vp;
  280. /* Update node times. */
  281. tmpfs_update(vp);
  282. return (0);
  283. }
  284. int
  285. tmpfs_access(struct vop_access_args *v)
  286. {
  287. struct vnode *vp = v->a_vp;
  288. accmode_t accmode = v->a_accmode;
  289. struct ucred *cred = v->a_cred;
  290. mode_t all_x = S_IXUSR | S_IXGRP | S_IXOTH;
  291. int error;
  292. struct tmpfs_node *node;
  293. MPASS(VOP_ISLOCKED(vp));
  294. node = VP_TO_TMPFS_NODE(vp);
  295. /*
  296. * Common case path lookup.
  297. */
  298. if (__predict_true(accmode == VEXEC && (node->tn_mode & all_x) == all_x))
  299. return (0);
  300. switch (vp->v_type) {
  301. case VDIR:
  302. /* FALLTHROUGH */
  303. case VLNK:
  304. /* FALLTHROUGH */
  305. case VREG:
  306. if (accmode & VWRITE && vp->v_mount->mnt_flag & MNT_RDONLY) {
  307. error = EROFS;
  308. goto out;
  309. }
  310. break;
  311. case VBLK:
  312. /* FALLTHROUGH */
  313. case VCHR:
  314. /* FALLTHROUGH */
  315. case VSOCK:
  316. /* FALLTHROUGH */
  317. case VFIFO:
  318. break;
  319. default:
  320. error = EINVAL;
  321. goto out;
  322. }
  323. if (accmode & VWRITE && node->tn_flags & IMMUTABLE) {
  324. error = EPERM;
  325. goto out;
  326. }
  327. error = vaccess(vp->v_type, node->tn_mode, node->tn_uid,
  328. node->tn_gid, accmode, cred, NULL);
  329. out:
  330. MPASS(VOP_ISLOCKED(vp));
  331. return error;
  332. }
  333. int
  334. tmpfs_getattr(struct vop_getattr_args *v)
  335. {
  336. struct vnode *vp = v->a_vp;
  337. struct vattr *vap = v->a_vap;
  338. vm_object_t obj;
  339. struct tmpfs_node *node;
  340. node = VP_TO_TMPFS_NODE(vp);
  341. tmpfs_update_getattr(vp);
  342. vap->va_type = vp->v_type;
  343. vap->va_mode = node->tn_mode;
  344. vap->va_nlink = node->tn_links;
  345. vap->va_uid = node->tn_uid;
  346. vap->va_gid = node->tn_gid;
  347. vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
  348. vap->va_fileid = node->tn_id;
  349. vap->va_size = node->tn_size;
  350. vap->va_blocksize = PAGE_SIZE;
  351. vap->va_atime = node->tn_atime;
  352. vap->va_mtime = node->tn_mtime;
  353. vap->va_ctime = node->tn_ctime;
  354. vap->va_birthtime = node->tn_birthtime;
  355. vap->va_gen = node->tn_gen;
  356. vap->va_flags = node->tn_flags;
  357. vap->va_rdev = (vp->v_type == VBLK || vp->v_type == VCHR) ?
  358. node->tn_rdev : NODEV;
  359. if (vp->v_type == VREG) {
  360. obj = node->tn_reg.tn_aobj;
  361. vap->va_bytes = (u_quad_t)obj->resident_page_count * PAGE_SIZE;
  362. } else
  363. vap->va_bytes = node->tn_size;
  364. vap->va_filerev = 0;
  365. return 0;
  366. }
  367. int
  368. tmpfs_setattr(struct vop_setattr_args *v)
  369. {
  370. struct vnode *vp = v->a_vp;
  371. struct vattr *vap = v->a_vap;
  372. struct ucred *cred = v->a_cred;
  373. struct thread *td = curthread;
  374. int error;
  375. MPASS(VOP_ISLOCKED(vp));
  376. error = 0;
  377. /* Abort if any unsettable attribute is given. */
  378. if (vap->va_type != VNON ||
  379. vap->va_nlink != VNOVAL ||
  380. vap->va_fsid != VNOVAL ||
  381. vap->va_fileid != VNOVAL ||
  382. vap->va_blocksize != VNOVAL ||
  383. vap->va_gen != VNOVAL ||
  384. vap->va_rdev != VNOVAL ||
  385. vap->va_bytes != VNOVAL)
  386. error = EINVAL;
  387. if (error == 0 && (vap->va_flags != VNOVAL))
  388. error = tmpfs_chflags(vp, vap->va_flags, cred, td);
  389. if (error == 0 && (vap->va_size != VNOVAL))
  390. error = tmpfs_chsize(vp, vap->va_size, cred, td);
  391. if (error == 0 && (vap->va_uid != VNOVAL || vap->va_gid != VNOVAL))
  392. error = tmpfs_chown(vp, vap->va_uid, vap->va_gid, cred, td);
  393. if (error == 0 && (vap->va_mode != (mode_t)VNOVAL))
  394. error = tmpfs_chmod(vp, vap->va_mode, cred, td);
  395. if (error == 0 && ((vap->va_atime.tv_sec != VNOVAL &&
  396. vap->va_atime.tv_nsec != VNOVAL) ||
  397. (vap->va_mtime.tv_sec != VNOVAL &&
  398. vap->va_mtime.tv_nsec != VNOVAL) ||
  399. (vap->va_birthtime.tv_sec != VNOVAL &&
  400. vap->va_birthtime.tv_nsec != VNOVAL)))
  401. error = tmpfs_chtimes(vp, vap, cred, td);
  402. /* Update the node times. We give preference to the error codes
  403. * generated by this function rather than the ones that may arise
  404. * from tmpfs_update. */
  405. tmpfs_update(vp);
  406. MPASS(VOP_ISLOCKED(vp));
  407. return error;
  408. }
  409. static int
  410. tmpfs_read(struct vop_read_args *v)
  411. {
  412. struct vnode *vp;
  413. struct uio *uio;
  414. struct tmpfs_node *node;
  415. vp = v->a_vp;
  416. if (vp->v_type != VREG)
  417. return (EISDIR);
  418. uio = v->a_uio;
  419. if (uio->uio_offset < 0)
  420. return (EINVAL);
  421. node = VP_TO_TMPFS_NODE(vp);
  422. tmpfs_set_status(VFS_TO_TMPFS(vp->v_mount), node, TMPFS_NODE_ACCESSED);
  423. return (uiomove_object(node->tn_reg.tn_aobj, node->tn_size, uio));
  424. }
  425. static int
  426. tmpfs_write(struct vop_write_args *v)
  427. {
  428. struct vnode *vp;
  429. struct uio *uio;
  430. struct tmpfs_node *node;
  431. off_t oldsize;
  432. int error, ioflag;
  433. vp = v->a_vp;
  434. uio = v->a_uio;
  435. ioflag = v->a_ioflag;
  436. error = 0;
  437. node = VP_TO_TMPFS_NODE(vp);
  438. oldsize = node->tn_size;
  439. if (uio->uio_offset < 0 || vp->v_type != VREG)
  440. return (EINVAL);
  441. if (uio->uio_resid == 0)
  442. return (0);
  443. if (ioflag & IO_APPEND)
  444. uio->uio_offset = node->tn_size;
  445. if (uio->uio_offset + uio->uio_resid >
  446. VFS_TO_TMPFS(vp->v_mount)->tm_maxfilesize)
  447. return (EFBIG);
  448. if (vn_rlimit_fsize(vp, uio, uio->uio_td))
  449. return (EFBIG);
  450. if (uio->uio_offset + uio->uio_resid > node->tn_size) {
  451. error = tmpfs_reg_resize(vp, uio->uio_offset + uio->uio_resid,
  452. FALSE);
  453. if (error != 0)
  454. goto out;
  455. }
  456. error = uiomove_object(node->tn_reg.tn_aobj, node->tn_size, uio);
  457. node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_MODIFIED |
  458. TMPFS_NODE_CHANGED;
  459. if (node->tn_mode & (S_ISUID | S_ISGID)) {
  460. if (priv_check_cred(v->a_cred, PRIV_VFS_RETAINSUGID))
  461. node->tn_mode &= ~(S_ISUID | S_ISGID);
  462. }
  463. if (error != 0)
  464. (void)tmpfs_reg_resize(vp, oldsize, TRUE);
  465. out:
  466. MPASS(IMPLIES(error == 0, uio->uio_resid == 0));
  467. MPASS(IMPLIES(error != 0, oldsize == node->tn_size));
  468. return (error);
  469. }
  470. static int
  471. tmpfs_fsync(struct vop_fsync_args *v)
  472. {
  473. struct vnode *vp = v->a_vp;
  474. MPASS(VOP_ISLOCKED(vp));
  475. tmpfs_check_mtime(vp);
  476. tmpfs_update(vp);
  477. return 0;
  478. }
  479. static int
  480. tmpfs_remove(struct vop_remove_args *v)
  481. {
  482. struct vnode *dvp = v->a_dvp;
  483. struct vnode *vp = v->a_vp;
  484. int error;
  485. struct tmpfs_dirent *de;
  486. struct tmpfs_mount *tmp;
  487. struct tmpfs_node *dnode;
  488. struct tmpfs_node *node;
  489. MPASS(VOP_ISLOCKED(dvp));
  490. MPASS(VOP_ISLOCKED(vp));
  491. if (vp->v_type == VDIR) {
  492. error = EISDIR;
  493. goto out;
  494. }
  495. dnode = VP_TO_TMPFS_DIR(dvp);
  496. node = VP_TO_TMPFS_NODE(vp);
  497. tmp = VFS_TO_TMPFS(vp->v_mount);
  498. de = tmpfs_dir_lookup(dnode, node, v->a_cnp);
  499. MPASS(de != NULL);
  500. /* Files marked as immutable or append-only cannot be deleted. */
  501. if ((node->tn_flags & (IMMUTABLE | APPEND | NOUNLINK)) ||
  502. (dnode->tn_flags & APPEND)) {
  503. error = EPERM;
  504. goto out;
  505. }
  506. /* Remove the entry from the directory; as it is a file, we do not
  507. * have to change the number of hard links of the directory. */
  508. tmpfs_dir_detach(dvp, de);
  509. if (v->a_cnp->cn_flags & DOWHITEOUT)
  510. tmpfs_dir_whiteout_add(dvp, v->a_cnp);
  511. /* Free the directory entry we just deleted. Note that the node
  512. * referred by it will not be removed until the vnode is really
  513. * reclaimed. */
  514. tmpfs_free_dirent(tmp, de);
  515. node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED;
  516. error = 0;
  517. out:
  518. return error;
  519. }
  520. static int
  521. tmpfs_link(struct vop_link_args *v)
  522. {
  523. struct vnode *dvp = v->a_tdvp;
  524. struct vnode *vp = v->a_vp;
  525. struct componentname *cnp = v->a_cnp;
  526. int error;
  527. struct tmpfs_dirent *de;
  528. struct tmpfs_node *node;
  529. MPASS(VOP_ISLOCKED(dvp));
  530. MPASS(cnp->cn_flags & HASBUF);
  531. MPASS(dvp != vp); /* XXX When can this be false? */
  532. node = VP_TO_TMPFS_NODE(vp);
  533. /* Ensure that we do not overflow the maximum number of links imposed
  534. * by the system. */
  535. MPASS(node->tn_links <= TMPFS_LINK_MAX);
  536. if (node->tn_links == TMPFS_LINK_MAX) {
  537. error = EMLINK;
  538. goto out;
  539. }
  540. /* We cannot create links of files marked immutable or append-only. */
  541. if (node->tn_flags & (IMMUTABLE | APPEND)) {
  542. error = EPERM;
  543. goto out;
  544. }
  545. /* Allocate a new directory entry to represent the node. */
  546. error = tmpfs_alloc_dirent(VFS_TO_TMPFS(vp->v_mount), node,
  547. cnp->cn_nameptr, cnp->cn_namelen, &de);
  548. if (error != 0)
  549. goto out;
  550. /* Insert the new directory entry into the appropriate directory. */
  551. if (cnp->cn_flags & ISWHITEOUT)
  552. tmpfs_dir_whiteout_remove(dvp, cnp);
  553. tmpfs_dir_attach(dvp, de);
  554. /* vp link count has changed, so update node times. */
  555. node->tn_status |= TMPFS_NODE_CHANGED;
  556. tmpfs_update(vp);
  557. error = 0;
  558. out:
  559. return error;
  560. }
  561. /*
  562. * We acquire all but fdvp locks using non-blocking acquisitions. If we
  563. * fail to acquire any lock in the path we will drop all held locks,
  564. * acquire the new lock in a blocking fashion, and then release it and
  565. * restart the rename. This acquire/release step ensures that we do not
  566. * spin on a lock waiting for release. On error release all vnode locks
  567. * and decrement references the way tmpfs_rename() would do.
  568. */
  569. static int
  570. tmpfs_rename_relock(struct vnode *fdvp, struct vnode **fvpp,
  571. struct vnode *tdvp, struct vnode **tvpp,
  572. struct componentname *fcnp, struct componentname *tcnp)
  573. {
  574. struct vnode *nvp;
  575. struct mount *mp;
  576. struct tmpfs_dirent *de;
  577. int error, restarts = 0;
  578. VOP_UNLOCK(tdvp);
  579. if (*tvpp != NULL && *tvpp != tdvp)
  580. VOP_UNLOCK(*tvpp);
  581. mp = fdvp->v_mount;
  582. relock:
  583. restarts += 1;
  584. error = vn_lock(fdvp, LK_EXCLUSIVE);
  585. if (error)
  586. goto releout;
  587. if (vn_lock(tdvp, LK_EXCLUSIVE | LK_NOWAIT) != 0) {
  588. VOP_UNLOCK(fdvp);
  589. error = vn_lock(tdvp, LK_EXCLUSIVE);
  590. if (error)
  591. goto releout;
  592. VOP_UNLOCK(tdvp);
  593. goto relock;
  594. }
  595. /*
  596. * Re-resolve fvp to be certain it still exists and fetch the
  597. * correct vnode.
  598. */
  599. de = tmpfs_dir_lookup(VP_TO_TMPFS_DIR(fdvp), NULL, fcnp);
  600. if (de == NULL) {
  601. VOP_UNLOCK(fdvp);
  602. VOP_UNLOCK(tdvp);
  603. if ((fcnp->cn_flags & ISDOTDOT) != 0 ||
  604. (fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.'))
  605. error = EINVAL;
  606. else
  607. error = ENOENT;
  608. goto releout;
  609. }
  610. error = tmpfs_alloc_vp(mp, de->td_node, LK_EXCLUSIVE | LK_NOWAIT, &nvp);
  611. if (error != 0) {
  612. VOP_UNLOCK(fdvp);
  613. VOP_UNLOCK(tdvp);
  614. if (error != EBUSY)
  615. goto releout;
  616. error = tmpfs_alloc_vp(mp, de->td_node, LK_EXCLUSIVE, &nvp);
  617. if (error != 0)
  618. goto releout;
  619. VOP_UNLOCK(nvp);
  620. /*
  621. * Concurrent rename race.
  622. */
  623. if (nvp == tdvp) {
  624. vrele(nvp);
  625. error = EINVAL;
  626. goto releout;
  627. }
  628. vrele(*fvpp);
  629. *fvpp = nvp;
  630. goto relock;
  631. }
  632. vrele(*fvpp);
  633. *fvpp = nvp;
  634. VOP_UNLOCK(*fvpp);
  635. /*
  636. * Re-resolve tvp and acquire the vnode lock if present.
  637. */
  638. de = tmpfs_dir_lookup(VP_TO_TMPFS_DIR(tdvp), NULL, tcnp);
  639. /*
  640. * If tvp disappeared we just carry on.
  641. */
  642. if (de == NULL && *tvpp != NULL) {
  643. vrele(*tvpp);
  644. *tvpp = NULL;
  645. }
  646. /*
  647. * Get the tvp ino if the lookup succeeded. We may have to restart
  648. * if the non-blocking acquire fails.
  649. */
  650. if (de != NULL) {
  651. nvp = NULL;
  652. error = tmpfs_alloc_vp(mp, de->td_node,
  653. LK_EXCLUSIVE | LK_NOWAIT, &nvp);
  654. if (*tvpp != NULL)
  655. vrele(*tvpp);
  656. *tvpp = nvp;
  657. if (error != 0) {
  658. VOP_UNLOCK(fdvp);
  659. VOP_UNLOCK(tdvp);
  660. if (error != EBUSY)
  661. goto releout;
  662. error = tmpfs_alloc_vp(mp, de->td_node, LK_EXCLUSIVE,
  663. &nvp);
  664. if (error != 0)
  665. goto releout;
  666. VOP_UNLOCK(nvp);
  667. /*
  668. * fdvp contains fvp, thus tvp (=fdvp) is not empty.
  669. */
  670. if (nvp == fdvp) {
  671. error = ENOTEMPTY;
  672. goto releout;
  673. }
  674. goto relock;
  675. }
  676. }
  677. tmpfs_rename_restarts += restarts;
  678. return (0);
  679. releout:
  680. vrele(fdvp);
  681. vrele(*fvpp);
  682. vrele(tdvp);
  683. if (*tvpp != NULL)
  684. vrele(*tvpp);
  685. tmpfs_rename_restarts += restarts;
  686. return (error);
  687. }
  688. static int
  689. tmpfs_rename(struct vop_rename_args *v)
  690. {
  691. struct vnode *fdvp = v->a_fdvp;
  692. struct vnode *fvp = v->a_fvp;
  693. struct componentname *fcnp = v->a_fcnp;
  694. struct vnode *tdvp = v->a_tdvp;
  695. struct vnode *tvp = v->a_tvp;
  696. struct componentname *tcnp = v->a_tcnp;
  697. char *newname;
  698. struct tmpfs_dirent *de;
  699. struct tmpfs_mount *tmp;
  700. struct tmpfs_node *fdnode;
  701. struct tmpfs_node *fnode;
  702. struct tmpfs_node *tnode;
  703. struct tmpfs_node *tdnode;
  704. int error;
  705. MPASS(VOP_ISLOCKED(tdvp));
  706. MPASS(IMPLIES(tvp != NULL, VOP_ISLOCKED(tvp)));
  707. MPASS(fcnp->cn_flags & HASBUF);
  708. MPASS(tcnp->cn_flags & HASBUF);
  709. /*
  710. * Disallow cross-device renames.
  711. * XXX Why isn't this done by the caller?
  712. */
  713. if (fvp->v_mount != tdvp->v_mount ||
  714. (tvp != NULL && fvp->v_mount != tvp->v_mount)) {
  715. error = EXDEV;
  716. goto out;
  717. }
  718. /* If source and target are the same file, there is nothing to do. */
  719. if (fvp == tvp) {
  720. error = 0;
  721. goto out;
  722. }
  723. /*
  724. * If we need to move the directory between entries, lock the
  725. * source so that we can safely operate on it.
  726. */
  727. if (fdvp != tdvp && fdvp != tvp) {
  728. if (vn_lock(fdvp, LK_EXCLUSIVE | LK_NOWAIT) != 0) {
  729. error = tmpfs_rename_relock(fdvp, &fvp, tdvp, &tvp,
  730. fcnp, tcnp);
  731. if (error != 0)
  732. return (error);
  733. ASSERT_VOP_ELOCKED(fdvp,
  734. "tmpfs_rename: fdvp not locked");
  735. ASSERT_VOP_ELOCKED(tdvp,
  736. "tmpfs_rename: tdvp not locked");
  737. if (tvp != NULL)
  738. ASSERT_VOP_ELOCKED(tvp,
  739. "tmpfs_rename: tvp not locked");
  740. if (fvp == tvp) {
  741. error = 0;
  742. goto out_locked;
  743. }
  744. }
  745. }
  746. tmp = VFS_TO_TMPFS(tdvp->v_mount);
  747. tdnode = VP_TO_TMPFS_DIR(tdvp);
  748. tnode = (tvp == NULL) ? NULL : VP_TO_TMPFS_NODE(tvp);
  749. fdnode = VP_TO_TMPFS_DIR(fdvp);
  750. fnode = VP_TO_TMPFS_NODE(fvp);
  751. de = tmpfs_dir_lookup(fdnode, fnode, fcnp);
  752. /*
  753. * Entry can disappear before we lock fdvp,
  754. * also avoid manipulating '.' and '..' entries.
  755. */
  756. if (de == NULL) {
  757. if ((fcnp->cn_flags & ISDOTDOT) != 0 ||
  758. (fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.'))
  759. error = EINVAL;
  760. else
  761. error = ENOENT;
  762. goto out_locked;
  763. }
  764. MPASS(de->td_node == fnode);
  765. /*
  766. * If re-naming a directory to another preexisting directory
  767. * ensure that the target directory is empty so that its
  768. * removal causes no side effects.
  769. * Kern_rename guarantees the destination to be a directory
  770. * if the source is one.
  771. */
  772. if (tvp != NULL) {
  773. MPASS(tnode != NULL);
  774. if ((tnode->tn_flags & (NOUNLINK | IMMUTABLE | APPEND)) ||
  775. (tdnode->tn_flags & (APPEND | IMMUTABLE))) {
  776. error = EPERM;
  777. goto out_locked;
  778. }
  779. if (fnode->tn_type == VDIR && tnode->tn_type == VDIR) {
  780. if (tnode->tn_size > 0) {
  781. error = ENOTEMPTY;
  782. goto out_locked;
  783. }
  784. } else if (fnode->tn_type == VDIR && tnode->tn_type != VDIR) {
  785. error = ENOTDIR;
  786. goto out_locked;
  787. } else if (fnode->tn_type != VDIR && tnode->tn_type == VDIR) {
  788. error = EISDIR;
  789. goto out_locked;
  790. } else {
  791. MPASS(fnode->tn_type != VDIR &&
  792. tnode->tn_type != VDIR);
  793. }
  794. }
  795. if ((fnode->tn_flags & (NOUNLINK | IMMUTABLE | APPEND))
  796. || (fdnode->tn_flags & (APPEND | IMMUTABLE))) {
  797. error = EPERM;
  798. goto out_locked;
  799. }
  800. /*
  801. * Ensure that we have enough memory to hold the new name, if it
  802. * has to be changed.
  803. */
  804. if (fcnp->cn_namelen != tcnp->cn_namelen ||
  805. bcmp(fcnp->cn_nameptr, tcnp->cn_nameptr, fcnp->cn_namelen) != 0) {
  806. newname = malloc(tcnp->cn_namelen, M_TMPFSNAME, M_WAITOK);
  807. } else
  808. newname = NULL;
  809. /*
  810. * If the node is being moved to another directory, we have to do
  811. * the move.
  812. */
  813. if (fdnode != tdnode) {
  814. /*
  815. * In case we are moving a directory, we have to adjust its
  816. * parent to point to the new parent.
  817. */
  818. if (de->td_node->tn_type == VDIR) {
  819. struct tmpfs_node *n;
  820. /*
  821. * Ensure the target directory is not a child of the
  822. * directory being moved. Otherwise, we'd end up
  823. * with stale nodes.
  824. */
  825. n = tdnode;
  826. /*
  827. * TMPFS_LOCK guaranties that no nodes are freed while
  828. * traversing the list. Nodes can only be marked as
  829. * removed: tn_parent == NULL.
  830. */
  831. TMPFS_LOCK(tmp);
  832. TMPFS_NODE_LOCK(n);
  833. while (n != n->tn_dir.tn_parent) {
  834. struct tmpfs_node *parent;
  835. if (n == fnode) {
  836. TMPFS_NODE_UNLOCK(n);
  837. TMPFS_UNLOCK(tmp);
  838. error = EINVAL;
  839. if (newname != NULL)
  840. free(newname, M_TMPFSNAME);
  841. goto out_locked;
  842. }
  843. parent = n->tn_dir.tn_parent;
  844. TMPFS_NODE_UNLOCK(n);
  845. if (parent == NULL) {
  846. n = NULL;
  847. break;
  848. }
  849. TMPFS_NODE_LOCK(parent);
  850. if (parent->tn_dir.tn_parent == NULL) {
  851. TMPFS_NODE_UNLOCK(parent);
  852. n = NULL;
  853. break;
  854. }
  855. n = parent;
  856. }
  857. TMPFS_UNLOCK(tmp);
  858. if (n == NULL) {
  859. error = EINVAL;
  860. if (newname != NULL)
  861. free(newname, M_TMPFSNAME);
  862. goto out_locked;
  863. }
  864. TMPFS_NODE_UNLOCK(n);
  865. /* Adjust the parent pointer. */
  866. TMPFS_VALIDATE_DIR(fnode);
  867. TMPFS_NODE_LOCK(de->td_node);
  868. de->td_node->tn_dir.tn_parent = tdnode;
  869. TMPFS_NODE_UNLOCK(de->td_node);
  870. /*
  871. * As a result of changing the target of the '..'
  872. * entry, the link count of the source and target
  873. * directories has to be adjusted.
  874. */
  875. TMPFS_NODE_LOCK(tdnode);
  876. TMPFS_ASSERT_LOCKED(tdnode);
  877. tdnode->tn_links++;
  878. TMPFS_NODE_UNLOCK(tdnode);
  879. TMPFS_NODE_LOCK(fdnode);
  880. TMPFS_ASSERT_LOCKED(fdnode);
  881. fdnode->tn_links--;
  882. TMPFS_NODE_UNLOCK(fdnode);
  883. }
  884. }
  885. /*
  886. * Do the move: just remove the entry from the source directory
  887. * and insert it into the target one.
  888. */
  889. tmpfs_dir_detach(fdvp, de);
  890. if (fcnp->cn_flags & DOWHITEOUT)
  891. tmpfs_dir_whiteout_add(fdvp, fcnp);
  892. if (tcnp->cn_flags & ISWHITEOUT)
  893. tmpfs_dir_whiteout_remove(tdvp, tcnp);
  894. /*
  895. * If the name has changed, we need to make it effective by changing
  896. * it in the directory entry.
  897. */
  898. if (newname != NULL) {
  899. MPASS(tcnp->cn_namelen <= MAXNAMLEN);
  900. free(de->ud.td_name, M_TMPFSNAME);
  901. de->ud.td_name = newname;
  902. tmpfs_dirent_init(de, tcnp->cn_nameptr, tcnp->cn_namelen);
  903. fnode->tn_status |= TMPFS_NODE_CHANGED;
  904. tdnode->tn_status |= TMPFS_NODE_MODIFIED;
  905. }
  906. /*
  907. * If we are overwriting an entry, we have to remove the old one
  908. * from the target directory.
  909. */
  910. if (tvp != NULL) {
  911. struct tmpfs_dirent *tde;
  912. /* Remove the old entry from the target directory. */
  913. tde = tmpfs_dir_lookup(tdnode, tnode, tcnp);
  914. tmpfs_dir_detach(tdvp, tde);
  915. /*
  916. * Free the directory entry we just deleted. Note that the
  917. * node referred by it will not be removed until the vnode is
  918. * really reclaimed.
  919. */
  920. tmpfs_free_dirent(VFS_TO_TMPFS(tvp->v_mount), tde);
  921. }
  922. tmpfs_dir_attach(tdvp, de);
  923. if (tmpfs_use_nc(fvp)) {
  924. cache_purge(fvp);
  925. if (tvp != NULL)
  926. cache_purge(tvp);
  927. cache_purge_negative(tdvp);
  928. }
  929. error = 0;
  930. out_locked:
  931. if (fdvp != tdvp && fdvp != tvp)
  932. VOP_UNLOCK(fdvp);
  933. out:
  934. /*
  935. * Release target nodes.
  936. * XXX: I don't understand when tdvp can be the same as tvp, but
  937. * other code takes care of this...
  938. */
  939. if (tdvp == tvp)
  940. vrele(tdvp);
  941. else
  942. vput(tdvp);
  943. if (tvp != NULL)
  944. vput(tvp);
  945. /* Release source nodes. */
  946. vrele(fdvp);
  947. vrele(fvp);
  948. return (error);
  949. }
  950. static int
  951. tmpfs_mkdir(struct vop_mkdir_args *v)
  952. {
  953. struct vnode *dvp = v->a_dvp;
  954. struct vnode **vpp = v->a_vpp;
  955. struct componentname *cnp = v->a_cnp;
  956. struct vattr *vap = v->a_vap;
  957. MPASS(vap->va_type == VDIR);
  958. return tmpfs_alloc_file(dvp, vpp, vap, cnp, NULL);
  959. }
  960. static int
  961. tmpfs_rmdir(struct vop_rmdir_args *v)
  962. {
  963. struct vnode *dvp = v->a_dvp;
  964. struct vnode *vp = v->a_vp;
  965. int error;
  966. struct tmpfs_dirent *de;
  967. struct tmpfs_mount *tmp;
  968. struct tmpfs_node *dnode;
  969. struct tmpfs_node *node;
  970. MPASS(VOP_ISLOCKED(dvp));
  971. MPASS(VOP_ISLOCKED(vp));
  972. tmp = VFS_TO_TMPFS(dvp->v_mount);
  973. dnode = VP_TO_TMPFS_DIR(dvp);
  974. node = VP_TO_TMPFS_DIR(vp);
  975. /* Directories with more than two entries ('.' and '..') cannot be
  976. * removed. */
  977. if (node->tn_size > 0) {
  978. error = ENOTEMPTY;
  979. goto out;
  980. }
  981. if ((dnode->tn_flags & APPEND)
  982. || (node->tn_flags & (NOUNLINK | IMMUTABLE | APPEND))) {
  983. error = EPERM;
  984. goto out;
  985. }
  986. /* This invariant holds only if we are not trying to remove "..".
  987. * We checked for that above so this is safe now. */
  988. MPASS(node->tn_dir.tn_parent == dnode);
  989. /* Get the directory entry associated with node (vp). This was
  990. * filled by tmpfs_lookup while looking up the entry. */
  991. de = tmpfs_dir_lookup(dnode, node, v->a_cnp);
  992. MPASS(TMPFS_DIRENT_MATCHES(de,
  993. v->a_cnp->cn_nameptr,
  994. v->a_cnp->cn_namelen));
  995. /* Check flags to see if we are allowed to remove the directory. */
  996. if ((dnode->tn_flags & APPEND) != 0 ||
  997. (node->tn_flags & (NOUNLINK | IMMUTABLE | APPEND)) != 0) {
  998. error = EPERM;
  999. goto out;
  1000. }
  1001. /* Detach the directory entry from the directory (dnode). */
  1002. tmpfs_dir_detach(dvp, de);
  1003. if (v->a_cnp->cn_flags & DOWHITEOUT)
  1004. tmpfs_dir_whiteout_add(dvp, v->a_cnp);
  1005. /* No vnode should be allocated for this entry from this point */
  1006. TMPFS_NODE_LOCK(node);
  1007. node->tn_links--;
  1008. node->tn_dir.tn_parent = NULL;
  1009. node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED |
  1010. TMPFS_NODE_MODIFIED;
  1011. TMPFS_NODE_UNLOCK(node);
  1012. TMPFS_NODE_LOCK(dnode);
  1013. dnode->tn_links--;
  1014. dnode->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED |
  1015. TMPFS_NODE_MODIFIED;
  1016. TMPFS_NODE_UNLOCK(dnode);
  1017. if (tmpfs_use_nc(dvp)) {
  1018. cache_purge(dvp);
  1019. cache_purge(vp);
  1020. }
  1021. /* Free the directory entry we just deleted. Note that the node
  1022. * referred by it will not be removed until the vnode is really
  1023. * reclaimed. */
  1024. tmpfs_free_dirent(tmp, de);
  1025. /* Release the deleted vnode (will destroy the node, notify
  1026. * interested parties and clean it from the cache). */
  1027. dnode->tn_status |= TMPFS_NODE_CHANGED;
  1028. tmpfs_update(dvp);
  1029. error = 0;
  1030. out:
  1031. return error;
  1032. }
  1033. static int
  1034. tmpfs_symlink(struct vop_symlink_args *v)
  1035. {
  1036. struct vnode *dvp = v->a_dvp;
  1037. struct vnode **vpp = v->a_vpp;
  1038. struct componentname *cnp = v->a_cnp;
  1039. struct vattr *vap = v->a_vap;
  1040. const char *target = v->a_target;
  1041. #ifdef notyet /* XXX FreeBSD BUG: kern_symlink is not setting VLNK */
  1042. MPASS(vap->va_type == VLNK);
  1043. #else
  1044. vap->va_type = VLNK;
  1045. #endif
  1046. return tmpfs_alloc_file(dvp, vpp, vap, cnp, target);
  1047. }
  1048. static int
  1049. tmpfs_readdir(struct vop_readdir_args *va)
  1050. {
  1051. struct vnode *vp;
  1052. struct uio *uio;
  1053. struct tmpfs_mount *tm;
  1054. struct tmpfs_node *node;
  1055. u_long **cookies;
  1056. int *eofflag, *ncookies;
  1057. ssize_t startresid;
  1058. int error, maxcookies;
  1059. vp = va->a_vp;
  1060. uio = va->a_uio;
  1061. eofflag = va->a_eofflag;
  1062. cookies = va->a_cookies;
  1063. ncookies = va->a_ncookies;
  1064. /* This operation only makes sense on directory nodes. */
  1065. if (vp->v_type != VDIR)
  1066. return ENOTDIR;
  1067. maxcookies = 0;
  1068. node = VP_TO_TMPFS_DIR(vp);
  1069. tm = VFS_TO_TMPFS(vp->v_mount);
  1070. startresid = uio->uio_resid;
  1071. /* Allocate cookies for NFS and compat modules. */
  1072. if (cookies != NULL && ncookies != NULL) {
  1073. maxcookies = howmany(node->tn_size,
  1074. sizeof(struct tmpfs_dirent)) + 2;
  1075. *cookies = malloc(maxcookies * sizeof(**cookies), M_TEMP,
  1076. M_WAITOK);
  1077. *ncookies = 0;
  1078. }
  1079. if (cookies == NULL)
  1080. error = tmpfs_dir_getdents(tm, node, uio, 0, NULL, NULL);
  1081. else
  1082. error = tmpfs_dir_getdents(tm, node, uio, maxcookies, *cookies,
  1083. ncookies);
  1084. /* Buffer was filled without hitting EOF. */
  1085. if (error == EJUSTRETURN)
  1086. error = (uio->uio_resid != startresid) ? 0 : EINVAL;
  1087. if (error != 0 && cookies != NULL && ncookies != NULL) {
  1088. free(*cookies, M_TEMP);
  1089. *cookies = NULL;
  1090. *ncookies = 0;
  1091. }
  1092. if (eofflag != NULL)
  1093. *eofflag =
  1094. (error == 0 && uio->uio_offset == TMPFS_DIRCOOKIE_EOF);
  1095. return error;
  1096. }
  1097. static int
  1098. tmpfs_readlink(struct vop_readlink_args *v)
  1099. {
  1100. struct vnode *vp = v->a_vp;
  1101. struct uio *uio = v->a_uio;
  1102. int error;
  1103. struct tmpfs_node *node;
  1104. MPASS(uio->uio_offset == 0);
  1105. MPASS(vp->v_type == VLNK);
  1106. node = VP_TO_TMPFS_NODE(vp);
  1107. error = uiomove(node->tn_link, MIN(node->tn_size, uio->uio_resid),
  1108. uio);
  1109. tmpfs_set_status(VFS_TO_TMPFS(vp->v_mount), node, TMPFS_NODE_ACCESSED);
  1110. return (error);
  1111. }
  1112. static int
  1113. tmpfs_inactive(struct vop_inactive_args *v)
  1114. {
  1115. struct vnode *vp;
  1116. struct tmpfs_node *node;
  1117. vp = v->a_vp;
  1118. node = VP_TO_TMPFS_NODE(vp);
  1119. if (node->tn_links == 0)
  1120. vrecycle(vp);
  1121. else
  1122. tmpfs_check_mtime(vp);
  1123. return (0);
  1124. }
  1125. static int
  1126. tmpfs_need_inactive(struct vop_need_inactive_args *ap)
  1127. {
  1128. struct vnode *vp;
  1129. struct tmpfs_node *node;
  1130. struct vm_object *obj;
  1131. vp = ap->a_vp;
  1132. node = VP_TO_TMPFS_NODE(vp);
  1133. if (node->tn_links == 0)
  1134. goto need;
  1135. if (vp->v_type == VREG) {
  1136. obj = vp->v_object;
  1137. if (obj->generation != obj->cleangeneration)
  1138. goto need;
  1139. }
  1140. return (0);
  1141. need:
  1142. return (1);
  1143. }
  1144. int
  1145. tmpfs_reclaim(struct vop_reclaim_args *v)
  1146. {
  1147. struct vnode *vp = v->a_vp;
  1148. struct tmpfs_mount *tmp;
  1149. struct tmpfs_node *node;
  1150. node = VP_TO_TMPFS_NODE(vp);
  1151. tmp = VFS_TO_TMPFS(vp->v_mount);
  1152. if (vp->v_type == VREG)
  1153. tmpfs_destroy_vobject(vp, node->tn_reg.tn_aobj);
  1154. vp->v_object = NULL;
  1155. if (tmpfs_use_nc(vp))
  1156. cache_purge(vp);
  1157. TMPFS_NODE_LOCK(node);
  1158. tmpfs_free_vp(vp);
  1159. /* If the node referenced by this vnode was deleted by the user,
  1160. * we must free its associated data structures (now that the vnode
  1161. * is being reclaimed). */
  1162. if (node->tn_links == 0 &&
  1163. (node->tn_vpstate & TMPFS_VNODE_ALLOCATING) == 0) {
  1164. node->tn_vpstate = TMPFS_VNODE_DOOMED;
  1165. TMPFS_NODE_UNLOCK(node);
  1166. tmpfs_free_node(tmp, node);
  1167. } else
  1168. TMPFS_NODE_UNLOCK(node);
  1169. MPASS(vp->v_data == NULL);
  1170. return 0;
  1171. }
  1172. int
  1173. tmpfs_print(struct vop_print_args *v)
  1174. {
  1175. struct vnode *vp = v->a_vp;
  1176. struct tmpfs_node *node;
  1177. node = VP_TO_TMPFS_NODE(vp);
  1178. printf("tag VT_TMPFS, tmpfs_node %p, flags 0x%lx, links %jd\n",
  1179. node, node->tn_flags, (uintmax_t)node->tn_links);
  1180. printf("\tmode 0%o, owner %d, group %d, size %jd, status 0x%x\n",
  1181. node->tn_mode, node->tn_uid, node->tn_gid,
  1182. (intmax_t)node->tn_size, node->tn_status);
  1183. if (vp->v_type == VFIFO)
  1184. fifo_printinfo(vp);
  1185. printf("\n");
  1186. return 0;
  1187. }
  1188. int
  1189. tmpfs_pathconf(struct vop_pathconf_args *v)
  1190. {
  1191. struct vnode *vp = v->a_vp;
  1192. int name = v->a_name;
  1193. long *retval = v->a_retval;
  1194. int error;
  1195. error = 0;
  1196. switch (name) {
  1197. case _PC_LINK_MAX:
  1198. *retval = TMPFS_LINK_MAX;
  1199. break;
  1200. case _PC_NAME_MAX:
  1201. *retval = NAME_MAX;
  1202. break;
  1203. case _PC_PIPE_BUF:
  1204. if (vp->v_type == VDIR || vp->v_type == VFIFO)
  1205. *retval = PIPE_BUF;
  1206. else
  1207. error = EINVAL;
  1208. break;
  1209. case _PC_CHOWN_RESTRICTED:
  1210. *retval = 1;
  1211. break;
  1212. case _PC_NO_TRUNC:
  1213. *retval = 1;
  1214. break;
  1215. case _PC_SYNC_IO:
  1216. *retval = 1;
  1217. break;
  1218. case _PC_FILESIZEBITS:
  1219. *retval = 64;
  1220. break;
  1221. default:
  1222. error = vop_stdpathconf(v);
  1223. }
  1224. return error;
  1225. }
  1226. static int
  1227. tmpfs_vptofh(struct vop_vptofh_args *ap)
  1228. /*
  1229. vop_vptofh {
  1230. IN struct vnode *a_vp;
  1231. IN struct fid *a_fhp;
  1232. };
  1233. */
  1234. {
  1235. struct tmpfs_fid_data tfd;
  1236. struct tmpfs_node *node;
  1237. struct fid *fhp;
  1238. node = VP_TO_TMPFS_NODE(ap->a_vp);
  1239. fhp = ap->a_fhp;
  1240. fhp->fid_len = sizeof(tfd);
  1241. /*
  1242. * Copy into fid_data from the stack to avoid unaligned pointer use.
  1243. * See the comment in sys/mount.h on struct fid for details.
  1244. */
  1245. tfd.tfd_id = node->tn_id;
  1246. tfd.tfd_gen = node->tn_gen;
  1247. memcpy(fhp->fid_data, &tfd, fhp->fid_len);
  1248. return (0);
  1249. }
  1250. static int
  1251. tmpfs_whiteout(struct vop_whiteout_args *ap)
  1252. {
  1253. struct vnode *dvp = ap->a_dvp;
  1254. struct componentname *cnp = ap->a_cnp;
  1255. struct tmpfs_dirent *de;
  1256. switch (ap->a_flags) {
  1257. case LOOKUP:
  1258. return (0);
  1259. case CREATE:
  1260. de = tmpfs_dir_lookup(VP_TO_TMPFS_DIR(dvp), NULL, cnp);
  1261. if (de != NULL)
  1262. return (de->td_node == NULL ? 0 : EEXIST);
  1263. return (tmpfs_dir_whiteout_add(dvp, cnp));
  1264. case DELETE:
  1265. tmpfs_dir_whiteout_remove(dvp, cnp);
  1266. return (0);
  1267. default:
  1268. panic("tmpfs_whiteout: unknown op");
  1269. }
  1270. }
  1271. static int
  1272. tmpfs_vptocnp_dir(struct tmpfs_node *tn, struct tmpfs_node *tnp,
  1273. struct tmpfs_dirent **pde)
  1274. {
  1275. struct tmpfs_dir_cursor dc;
  1276. struct tmpfs_dirent *de;
  1277. for (de = tmpfs_dir_first(tnp, &dc); de != NULL;
  1278. de = tmpfs_dir_next(tnp, &dc)) {
  1279. if (de->td_node == tn) {
  1280. *pde = de;
  1281. return (0);
  1282. }
  1283. }
  1284. return (ENOENT);
  1285. }
  1286. static int
  1287. tmpfs_vptocnp_fill(struct vnode *vp, struct tmpfs_node *tn,
  1288. struct tmpfs_node *tnp, char *buf, size_t *buflen, struct vnode **dvp)
  1289. {
  1290. struct tmpfs_dirent *de;
  1291. int error, i;
  1292. error = vn_vget_ino_gen(vp, tmpfs_vn_get_ino_alloc, tnp, LK_SHARED,
  1293. dvp);
  1294. if (error != 0)
  1295. return (error);
  1296. error = tmpfs_vptocnp_dir(tn, tnp, &de);
  1297. if (error == 0) {
  1298. i = *buflen;
  1299. i -= de->td_namelen;
  1300. if (i < 0) {
  1301. error = ENOMEM;
  1302. } else {
  1303. bcopy(de->ud.td_name, buf + i, de->td_namelen);
  1304. *buflen = i;
  1305. }
  1306. }
  1307. if (error == 0) {
  1308. if (vp != *dvp)
  1309. VOP_UNLOCK(*dvp);
  1310. } else {
  1311. if (vp != *dvp)
  1312. vput(*dvp);
  1313. else
  1314. vrele(vp);
  1315. }
  1316. return (error);
  1317. }
  1318. static int
  1319. tmpfs_vptocnp(struct vop_vptocnp_args *ap)
  1320. {
  1321. struct vnode *vp, **dvp;
  1322. struct tmpfs_node *tn, *tnp, *tnp1;
  1323. struct tmpfs_dirent *de;
  1324. struct tmpfs_mount *tm;
  1325. char *buf;
  1326. size_t *buflen;
  1327. int error;
  1328. vp = ap->a_vp;
  1329. dvp = ap->a_vpp;
  1330. buf = ap->a_buf;
  1331. buflen = ap->a_buflen;
  1332. tm = VFS_TO_TMPFS(vp->v_mount);
  1333. tn = VP_TO_TMPFS_NODE(vp);
  1334. if (tn->tn_type == VDIR) {
  1335. tnp = tn->tn_dir.tn_parent;
  1336. if (tnp == NULL)
  1337. return (ENOENT);
  1338. tmpfs_ref_node(tnp);
  1339. error = tmpfs_vptocnp_fill(vp, tn, tn->tn_dir.tn_parent, buf,
  1340. buflen, dvp);
  1341. tmpfs_free_node(tm, tnp);
  1342. return (error);
  1343. }
  1344. restart:
  1345. TMPFS_LOCK(tm);
  1346. LIST_FOREACH_SAFE(tnp, &tm->tm_nodes_used, tn_entries, tnp1) {
  1347. if (tnp->tn_type != VDIR)
  1348. continue;
  1349. TMPFS_NODE_LOCK(tnp);
  1350. tmpfs_ref_node_locked(tnp);
  1351. /*
  1352. * tn_vnode cannot be instantiated while we hold the
  1353. * node lock, so the directory cannot be changed while
  1354. * we iterate over it. Do this to avoid instantiating
  1355. * vnode for directories which cannot point to our
  1356. * node.
  1357. */
  1358. error = tnp->tn_vnode == NULL ? tmpfs_vptocnp_dir(tn, tnp,
  1359. &de) : 0;
  1360. if (error == 0) {
  1361. TMPFS_NODE_UNLOCK(tnp);
  1362. TMPFS_UNLOCK(tm);
  1363. error = tmpfs_vptocnp_fill(vp, tn, tnp, buf, buflen,
  1364. dvp);
  1365. if (error == 0) {
  1366. tmpfs_free_node(tm, tnp);
  1367. return (0);
  1368. }
  1369. if (VN_IS_DOOMED(vp)) {
  1370. tmpfs_free_node(tm, tnp);
  1371. return (ENOENT);
  1372. }
  1373. TMPFS_LOCK(tm);
  1374. TMPFS_NODE_LOCK(tnp);
  1375. }
  1376. if (tmpfs_free_node_locked(tm, tnp, false)) {
  1377. goto restart;
  1378. } else {
  1379. KASSERT(tnp->tn_refcount > 0,
  1380. ("node %p refcount zero", tnp));
  1381. tnp1 = LIST_NEXT(tnp, tn_entries);
  1382. TMPFS_NODE_UNLOCK(tnp);
  1383. }
  1384. }
  1385. TMPFS_UNLOCK(tm);
  1386. return (ENOENT);
  1387. }
  1388. static struct tmpfs_extattr_list_entry *
  1389. tmpfs_node_has_extattr(struct tmpfs_node *node, int attrnamespace,
  1390. const char *name)
  1391. {
  1392. struct tmpfs_extattr_list_entry *entry, *tentry;
  1393. LIST_FOREACH_SAFE(entry, &(node->tn_reg.tn_extattr_list),
  1394. tele_entries, tentry) {
  1395. if (attrnamespace != entry->tele_attrnamespace) {
  1396. continue;
  1397. }
  1398. if (!strcmp(name, entry->tele_attrname)) {
  1399. return (entry);
  1400. }
  1401. }
  1402. return (NULL);
  1403. }
  1404. static int
  1405. tmpfs_getextattr(struct vop_getextattr_args *ap)
  1406. {
  1407. return (tmpfs_extattr_get(ap->a_vp, ap->a_attrnamespace,
  1408. ap->a_name, ap->a_uio, ap->a_size, ap->a_cred, ap->a_td));
  1409. }
  1410. static int
  1411. tmpfs_extattr_get(struct vnode *vp, int attrnamespace, const char *name,
  1412. struct uio *uio, size_t *size, struct ucred *cred, struct thread *td)
  1413. {
  1414. struct tmpfs_extattr_list_entry *attr;
  1415. struct tmpfs_node *node;
  1416. size_t len;
  1417. int error;
  1418. error = 0;
  1419. if (vp->v_type != VREG) {
  1420. return (EOPNOTSUPP);
  1421. }
  1422. node = VP_TO_TMPFS_NODE(vp);
  1423. attr = tmpfs_node_has_extattr(node, attrnamespace, name);
  1424. if (attr == NULL) {
  1425. return (ENOATTR);
  1426. }
  1427. if (size) {
  1428. *size = attr->tele_value_size;
  1429. }
  1430. if (uio != NULL) {
  1431. len = MIN(attr->tele_value_size, uio->uio_resid);
  1432. uio->uio_resid = len;
  1433. uio->uio_offset = 0;
  1434. error = uiomove(attr->tele_value, len, uio);
  1435. }
  1436. return (error);
  1437. }
  1438. static int
  1439. tmpfs_setextattr(struct vop_setextattr_args *ap)
  1440. {
  1441. return (tmpfs_extattr_set(ap->a_vp, ap->a_attrnamespace,
  1442. ap->a_name, ap->a_uio, ap->a_cred, ap->a_td));
  1443. }
  1444. static int
  1445. tmpfs_extattr_set(struct vnode *vp, int attrnamespace, const char *name,
  1446. struct uio *uio, struct ucred *cred, struct thread *td)
  1447. {
  1448. struct tmpfs_extattr_list_entry *attr;
  1449. struct tmpfs_node *node;
  1450. size_t sz;
  1451. if (vp->v_type != VREG) {
  1452. return (EOPNOTSUPP);
  1453. }
  1454. if (uio->uio_resid > TMPFS_EXTATTR_MAXVALUESIZE) {
  1455. return (EINVAL);
  1456. }
  1457. if (strlen(name) == 0) {
  1458. return (EINVAL);
  1459. }
  1460. if (strlen(name) >= TMPFS_EXTATTR_MAXNAME) {
  1461. return (EINVAL);
  1462. }
  1463. node = VP_TO_TMPFS_NODE(vp);
  1464. attr = tmpfs_node_has_extattr(node, attrnamespace, name);
  1465. if (attr == NULL) {
  1466. sz = MIN(TMPFS_EXTATTR_MAXVALUESIZE, uio->uio_resid);
  1467. attr = malloc(sizeof(*attr), M_TEMP, M_WAITOK|M_ZERO);
  1468. memset(attr, 0, sizeof(*attr));
  1469. attr->tele_value = malloc(sz, M_TEMP, M_WAITOK);
  1470. attr->tele_value_size = sz;
  1471. attr->tele_attrnamespace = attrnamespace;
  1472. strncpy(attr->tele_attrname, name,
  1473. sizeof(attr->tele_attrname)-1);
  1474. uiomove(attr->tele_value, sz, uio);
  1475. LIST_INSERT_HEAD(&(node->tn_reg.tn_extattr_list),
  1476. attr, tele_entries);
  1477. }
  1478. return (0);
  1479. }
  1480. static int
  1481. tmpfs_listextattr(struct vop_listextattr_args *ap)
  1482. {
  1483. return tmpfs_extattr_list(ap->a_vp, ap->a_attrnamespace,
  1484. ap->a_uio, ap->a_size, ap->a_cred, ap->a_td);
  1485. }
  1486. static int
  1487. tmpfs_extattr_list(struct vnode *vp, int attrnamespace, struct uio *uio,
  1488. size_t *size, struct ucred *cred, struct thread *td)
  1489. {
  1490. struct tmpfs_extattr_list_entry *attr, *tattr;
  1491. struct tmpfs_node *node;
  1492. size_t namelen;
  1493. int error;
  1494. error = 0;
  1495. if (vp->v_type != VREG) {
  1496. return (EOPNOTSUPP);
  1497. }
  1498. node = VP_TO_TMPFS_NODE(vp);
  1499. if (size) {
  1500. *size = 0;
  1501. }
  1502. LIST_FOREACH_SAFE(attr, &(node->tn_reg.tn_extattr_list),
  1503. tele_entries, tattr) {
  1504. if (attr->tele_attrnamespace != attrnamespace) {
  1505. continue;
  1506. }
  1507. namelen = strlen(attr->tele_attrname);
  1508. if (size) {
  1509. *size += namelen + 1;
  1510. } else if (uio != NULL) {
  1511. error = uiomove(&(attr->tele_attrname), namelen + 1,
  1512. uio);
  1513. }
  1514. if (error) {
  1515. break;
  1516. }
  1517. }
  1518. return (error);
  1519. }
  1520. /*
  1521. * Vnode operations vector used for files stored in a tmpfs file system.
  1522. */
  1523. struct vop_vector tmpfs_vnodeop_entries = {
  1524. .vop_default = &default_vnodeops,
  1525. .vop_lookup = vfs_cache_lookup,
  1526. .vop_cachedlookup = tmpfs_cached_lookup,
  1527. .vop_create = tmpfs_create,
  1528. .vop_mknod = tmpfs_mknod,
  1529. .vop_open = tmpfs_open,
  1530. .vop_close = tmpfs_close,
  1531. .vop_access = tmpfs_access,
  1532. .vop_getattr = tmpfs_getattr,
  1533. .vop_setattr = tmpfs_setattr,
  1534. .vop_getextattr = tmpfs_getextattr,
  1535. .vop_setextattr = tmpfs_setextattr,
  1536. .vop_listextattr = tmpfs_listextattr,
  1537. .vop_read = tmpfs_read,
  1538. .vop_write = tmpfs_write,
  1539. .vop_fsync = tmpfs_fsync,
  1540. .vop_remove = tmpfs_remove,
  1541. .vop_link = tmpfs_link,
  1542. .vop_rename = tmpfs_rename,
  1543. .vop_mkdir = tmpfs_mkdir,
  1544. .vop_rmdir = tmpfs_rmdir,
  1545. .vop_symlink = tmpfs_symlink,
  1546. .vop_readdir = tmpfs_readdir,
  1547. .vop_readlink = tmpfs_readlink,
  1548. .vop_inactive = tmpfs_inactive,
  1549. .vop_need_inactive = tmpfs_need_inactive,
  1550. .vop_reclaim = tmpfs_reclaim,
  1551. .vop_print = tmpfs_print,
  1552. .vop_pathconf = tmpfs_pathconf,
  1553. .vop_vptofh = tmpfs_vptofh,
  1554. .vop_whiteout = tmpfs_whiteout,
  1555. .vop_bmap = VOP_EOPNOTSUPP,
  1556. .vop_vptocnp = tmpfs_vptocnp,
  1557. .vop_lock1 = vop_lock,
  1558. .vop_unlock = vop_unlock,
  1559. .vop_islocked = vop_islocked,
  1560. };
  1561. VFS_VOP_VECTOR_REGISTER(tmpfs_vnodeop_entries);
  1562. /*
  1563. * Same vector for mounts which do not use namecache.
  1564. */
  1565. struct vop_vector tmpfs_vnodeop_nonc_entries = {
  1566. .vop_default = &tmpfs_vnodeop_entries,
  1567. .vop_lookup = tmpfs_lookup,
  1568. };
  1569. VFS_VOP_VECTOR_REGISTER(tmpfs_vnodeop_nonc_entries);