vfs_vops.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  1. /* $OpenBSD: vfs_vops.c,v 1.14 2015/07/19 16:21:11 beck Exp $ */
  2. /*
  3. * Copyright (c) 2010 Thordur I. Bjornsson <thib@openbsd.org>
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. *
  17. * Copyright (c) 1992, 1993
  18. * The Regents of the University of California. All rights reserved.
  19. *
  20. * Redistribution and use in source and binary forms, with or without
  21. * modification, are permitted provided that the following conditions
  22. * are met:
  23. * 1. Redistributions of source code must retain the above copyright
  24. * notice, this list of conditions and the following disclaimer.
  25. * 2. Redistributions in binary form must reproduce the above copyright
  26. * notice, this list of conditions and the following disclaimer in the
  27. * documentation and/or other materials provided with the distribution.
  28. * 3. Neither the name of the University nor the names of its contributors
  29. * may be used to endorse or promote products derived from this software
  30. * without specific prior written permission.
  31. *
  32. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS AS IS'' AND
  33. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  34. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  35. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  36. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  37. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  38. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  40. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  41. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  42. * SUCH DAMAGE.
  43. */
  44. #include <sys/param.h>
  45. #include <sys/vnode.h>
  46. #include <sys/unistd.h>
  47. #include <sys/systm.h>
  48. #ifdef VFSLCKDEBUG
  49. #include <sys/systm.h> /* for panic() */
  50. #define ASSERT_VP_ISLOCKED(vp) do { \
  51. if (((vp)->v_flag & VLOCKSWORK) && !VOP_ISLOCKED(vp)) { \
  52. VOP_PRINT(vp); \
  53. panic("vp not locked"); \
  54. } \
  55. } while (0)
  56. #else
  57. #define ASSERT_VP_ISLOCKED(vp) /* nothing */
  58. #endif
  59. int
  60. VOP_ISLOCKED(struct vnode *vp)
  61. {
  62. struct vop_islocked_args a;
  63. a.a_vp = vp;
  64. if (vp->v_op->vop_islocked == NULL)
  65. return (EOPNOTSUPP);
  66. return ((vp->v_op->vop_islocked)(&a));
  67. }
  68. int
  69. VOP_LOOKUP(struct vnode *dvp, struct vnode **vpp,
  70. struct componentname *cnp)
  71. {
  72. struct vop_lookup_args a;
  73. a.a_dvp = dvp;
  74. a.a_vpp = vpp;
  75. a.a_cnp = cnp;
  76. if (dvp->v_op->vop_lookup == NULL)
  77. return (EOPNOTSUPP);
  78. return ((dvp->v_op->vop_lookup)(&a));
  79. }
  80. int
  81. VOP_CREATE(struct vnode *dvp, struct vnode **vpp,
  82. struct componentname *cnp, struct vattr *vap)
  83. {
  84. struct vop_create_args a;
  85. a.a_dvp = dvp;
  86. a.a_vpp = vpp;
  87. a.a_cnp = cnp;
  88. a.a_vap = vap;
  89. ASSERT_VP_ISLOCKED(dvp);
  90. if (dvp->v_op->vop_create == NULL)
  91. return (EOPNOTSUPP);
  92. return ((dvp->v_op->vop_create)(&a));
  93. }
  94. int
  95. VOP_MKNOD(struct vnode *dvp, struct vnode **vpp,
  96. struct componentname *cnp, struct vattr *vap)
  97. {
  98. struct vop_mknod_args a;
  99. a.a_dvp = dvp;
  100. a.a_vpp = vpp;
  101. a.a_cnp = cnp;
  102. a.a_vap = vap;
  103. ASSERT_VP_ISLOCKED(dvp);
  104. if (dvp->v_op->vop_mknod == NULL)
  105. return (EOPNOTSUPP);
  106. return ((dvp->v_op->vop_mknod)(&a));
  107. }
  108. int
  109. VOP_OPEN(struct vnode *vp, int mode, struct ucred *cred, struct proc *p)
  110. {
  111. struct vop_open_args a;
  112. a.a_vp = vp;
  113. a.a_mode = mode;
  114. a.a_cred = cred;
  115. a.a_p = p;
  116. if (vp->v_op->vop_open == NULL)
  117. return (EOPNOTSUPP);
  118. return ((vp->v_op->vop_open)(&a));
  119. }
  120. int
  121. VOP_CLOSE(struct vnode *vp, int fflag, struct ucred *cred, struct proc *p)
  122. {
  123. struct vop_close_args a;
  124. a.a_vp = vp;
  125. a.a_fflag = fflag;
  126. a.a_cred = cred;
  127. a.a_p = p;
  128. ASSERT_VP_ISLOCKED(vp);
  129. if (vp->v_op->vop_close == NULL)
  130. return (EOPNOTSUPP);
  131. return ((vp->v_op->vop_close)(&a));
  132. }
  133. int
  134. VOP_ACCESS(struct vnode *vp, int mode, struct ucred *cred, struct proc *p)
  135. {
  136. struct vop_access_args a;
  137. a.a_vp = vp;
  138. a.a_mode = mode;
  139. a.a_cred = cred;
  140. a.a_p = p;
  141. ASSERT_VP_ISLOCKED(vp);
  142. if (vp->v_op->vop_access == NULL)
  143. return (EOPNOTSUPP);
  144. return ((vp->v_op->vop_access)(&a));
  145. }
  146. int
  147. VOP_GETATTR(struct vnode *vp, struct vattr *vap, struct ucred *cred,
  148. struct proc *p)
  149. {
  150. struct vop_getattr_args a;
  151. a.a_vp = vp;
  152. a.a_vap = vap;
  153. a.a_cred = cred;
  154. a.a_p = p;
  155. if (vp->v_op->vop_getattr == NULL)
  156. return (EOPNOTSUPP);
  157. return ((vp->v_op->vop_getattr)(&a));
  158. }
  159. int
  160. VOP_SETATTR(struct vnode *vp, struct vattr *vap, struct ucred *cred,
  161. struct proc *p)
  162. {
  163. struct vop_setattr_args a;
  164. a.a_vp = vp;
  165. a.a_vap = vap;
  166. a.a_cred = cred;
  167. a.a_p = p;
  168. ASSERT_VP_ISLOCKED(vp);
  169. if (vp->v_op->vop_setattr == NULL)
  170. return (EOPNOTSUPP);
  171. return ((vp->v_op->vop_setattr)(&a));
  172. }
  173. int
  174. VOP_READ(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
  175. {
  176. struct vop_read_args a;
  177. a.a_vp = vp;
  178. a.a_uio = uio;
  179. a.a_ioflag = ioflag;
  180. a.a_cred = cred;
  181. ASSERT_VP_ISLOCKED(vp);
  182. if (vp->v_op->vop_read == NULL)
  183. return (EOPNOTSUPP);
  184. return ((vp->v_op->vop_read)(&a));
  185. }
  186. int
  187. VOP_WRITE(struct vnode *vp, struct uio *uio, int ioflag,
  188. struct ucred *cred)
  189. {
  190. struct vop_write_args a;
  191. a.a_vp = vp;
  192. a.a_uio = uio;
  193. a.a_ioflag = ioflag;
  194. a.a_cred = cred;
  195. ASSERT_VP_ISLOCKED(vp);
  196. if (vp->v_op->vop_write == NULL)
  197. return (EOPNOTSUPP);
  198. return ((vp->v_op->vop_write)(&a));
  199. }
  200. int
  201. VOP_IOCTL(struct vnode *vp, u_long command, void *data, int fflag,
  202. struct ucred *cred, struct proc *p)
  203. {
  204. struct vop_ioctl_args a;
  205. a.a_vp = vp;
  206. a.a_command = command;
  207. a.a_data = data;
  208. a.a_fflag = fflag;
  209. a.a_cred = cred;
  210. a.a_p = p;
  211. if (vp->v_op->vop_ioctl == NULL)
  212. return (EOPNOTSUPP);
  213. return ((vp->v_op->vop_ioctl)(&a));
  214. }
  215. int
  216. VOP_POLL(struct vnode *vp, int fflag, int events, struct proc *p)
  217. {
  218. struct vop_poll_args a;
  219. a.a_vp = vp;
  220. a.a_fflag = fflag;
  221. a.a_events = events;
  222. a.a_p = p;
  223. if (vp->v_op->vop_poll == NULL)
  224. return (EOPNOTSUPP);
  225. return ((vp->v_op->vop_poll)(&a));
  226. }
  227. int
  228. VOP_KQFILTER(struct vnode *vp, struct knote *kn)
  229. {
  230. struct vop_kqfilter_args a;
  231. a.a_vp = vp;
  232. a.a_kn = kn;
  233. if (vp->v_op->vop_kqfilter == NULL)
  234. return (EOPNOTSUPP);
  235. return ((vp->v_op->vop_kqfilter)(&a));
  236. }
  237. int
  238. VOP_REVOKE(struct vnode *vp, int flags)
  239. {
  240. struct vop_revoke_args a;
  241. a.a_vp = vp;
  242. a.a_flags = flags;
  243. if (vp->v_op->vop_revoke == NULL)
  244. return (EOPNOTSUPP);
  245. return ((vp->v_op->vop_revoke)(&a));
  246. }
  247. int
  248. VOP_FSYNC(struct vnode *vp, struct ucred *cred, int waitfor,
  249. struct proc *p)
  250. {
  251. struct vop_fsync_args a;
  252. a.a_vp = vp;
  253. a.a_cred = cred;
  254. a.a_waitfor = waitfor;
  255. a.a_p = p;
  256. ASSERT_VP_ISLOCKED(vp);
  257. if (vp->v_op->vop_fsync == NULL)
  258. return (EOPNOTSUPP);
  259. return ((vp->v_op->vop_fsync)(&a));
  260. }
  261. int
  262. VOP_REMOVE(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
  263. {
  264. struct vop_remove_args a;
  265. a.a_dvp = dvp;
  266. a.a_vp = vp;
  267. a.a_cnp = cnp;
  268. ASSERT_VP_ISLOCKED(dvp);
  269. ASSERT_VP_ISLOCKED(vp);
  270. if (dvp->v_op->vop_remove == NULL)
  271. return (EOPNOTSUPP);
  272. return ((dvp->v_op->vop_remove)(&a));
  273. }
  274. int
  275. VOP_LINK(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
  276. {
  277. struct vop_link_args a;
  278. a.a_dvp = dvp;
  279. a.a_vp = vp;
  280. a.a_cnp = cnp;
  281. ASSERT_VP_ISLOCKED(dvp);
  282. if (dvp->v_op->vop_link == NULL)
  283. return (EOPNOTSUPP);
  284. return ((dvp->v_op->vop_link)(&a));
  285. }
  286. int
  287. VOP_RENAME(struct vnode *fdvp, struct vnode *fvp,
  288. struct componentname *fcnp, struct vnode *tdvp, struct vnode *tvp,
  289. struct componentname *tcnp)
  290. {
  291. struct vop_rename_args a;
  292. a.a_fdvp = fdvp;
  293. a.a_fvp = fvp;
  294. a.a_fcnp = fcnp;
  295. a.a_tdvp = tdvp;
  296. a.a_tvp = tvp;
  297. a.a_tcnp = tcnp;
  298. ASSERT_VP_ISLOCKED(tdvp);
  299. if (fdvp->v_op->vop_rename == NULL)
  300. return (EOPNOTSUPP);
  301. return ((fdvp->v_op->vop_rename)(&a));
  302. }
  303. int
  304. VOP_MKDIR(struct vnode *dvp, struct vnode **vpp,
  305. struct componentname *cnp, struct vattr *vap)
  306. {
  307. struct vop_mkdir_args a;
  308. a.a_dvp = dvp;
  309. a.a_vpp = vpp;
  310. a.a_cnp = cnp;
  311. a.a_vap = vap;
  312. ASSERT_VP_ISLOCKED(dvp);
  313. if (dvp->v_op->vop_mkdir == NULL)
  314. return (EOPNOTSUPP);
  315. return ((dvp->v_op->vop_mkdir)(&a));
  316. }
  317. int
  318. VOP_RMDIR(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
  319. {
  320. struct vop_rmdir_args a;
  321. a.a_dvp = dvp;
  322. a.a_vp = vp;
  323. a.a_cnp = cnp;
  324. ASSERT_VP_ISLOCKED(dvp);
  325. ASSERT_VP_ISLOCKED(vp);
  326. if (dvp->v_op->vop_rmdir == NULL)
  327. return (EOPNOTSUPP);
  328. return ((dvp->v_op->vop_rmdir)(&a));
  329. }
  330. int
  331. VOP_SYMLINK(struct vnode *dvp, struct vnode **vpp,
  332. struct componentname *cnp, struct vattr *vap, char *target)
  333. {
  334. struct vop_symlink_args a;
  335. a.a_dvp = dvp;
  336. a.a_vpp = vpp;
  337. a.a_cnp = cnp;
  338. a.a_vap = vap;
  339. a.a_target = target;
  340. ASSERT_VP_ISLOCKED(dvp);
  341. if (dvp->v_op->vop_symlink == NULL)
  342. return (EOPNOTSUPP);
  343. return ((dvp->v_op->vop_symlink)(&a));
  344. }
  345. int
  346. VOP_READDIR(struct vnode *vp, struct uio *uio, struct ucred *cred,
  347. int *eofflag)
  348. {
  349. struct vop_readdir_args a;
  350. a.a_vp = vp;
  351. a.a_uio = uio;
  352. a.a_cred = cred;
  353. a.a_eofflag = eofflag;
  354. ASSERT_VP_ISLOCKED(vp);
  355. if (vp->v_op->vop_readdir == NULL)
  356. return (EOPNOTSUPP);
  357. return ((vp->v_op->vop_readdir)(&a));
  358. }
  359. int
  360. VOP_READLINK(struct vnode *vp, struct uio *uio, struct ucred *cred)
  361. {
  362. struct vop_readlink_args a;
  363. a.a_vp = vp;
  364. a.a_uio = uio;
  365. a.a_cred = cred;
  366. ASSERT_VP_ISLOCKED(vp);
  367. if (vp->v_op->vop_readlink == NULL)
  368. return (EOPNOTSUPP);
  369. return ((vp->v_op->vop_readlink)(&a));
  370. }
  371. int
  372. VOP_ABORTOP(struct vnode *dvp, struct componentname *cnp)
  373. {
  374. struct vop_abortop_args a;
  375. a.a_dvp = dvp;
  376. a.a_cnp = cnp;
  377. if (dvp->v_op->vop_abortop == NULL)
  378. return (EOPNOTSUPP);
  379. return ((dvp->v_op->vop_abortop)(&a));
  380. }
  381. int
  382. VOP_INACTIVE(struct vnode *vp, struct proc *p)
  383. {
  384. struct vop_inactive_args a;
  385. a.a_vp = vp;
  386. a.a_p = p;
  387. ASSERT_VP_ISLOCKED(vp);
  388. if (vp->v_op->vop_inactive == NULL)
  389. return (EOPNOTSUPP);
  390. return ((vp->v_op->vop_inactive)(&a));
  391. }
  392. int
  393. VOP_RECLAIM(struct vnode *vp, struct proc *p)
  394. {
  395. struct vop_reclaim_args a;
  396. a.a_vp = vp;
  397. a.a_p = p;
  398. if (vp->v_op->vop_reclaim == NULL)
  399. return (EOPNOTSUPP);
  400. return ((vp->v_op->vop_reclaim)(&a));
  401. }
  402. int
  403. VOP_LOCK(struct vnode *vp, int flags, struct proc *p)
  404. {
  405. struct vop_lock_args a;
  406. a.a_vp = vp;
  407. a.a_flags = flags;
  408. a.a_p = p;
  409. if (vp->v_op->vop_lock == NULL)
  410. return (EOPNOTSUPP);
  411. return ((vp->v_op->vop_lock)(&a));
  412. }
  413. int
  414. VOP_UNLOCK(struct vnode *vp, int flags, struct proc *p)
  415. {
  416. struct vop_unlock_args a;
  417. a.a_vp = vp;
  418. a.a_flags = flags;
  419. a.a_p = p;
  420. if (vp->v_op->vop_unlock == NULL)
  421. return (EOPNOTSUPP);
  422. return ((vp->v_op->vop_unlock)(&a));
  423. }
  424. int
  425. VOP_BMAP(struct vnode *vp, daddr_t bn, struct vnode **vpp,
  426. daddr_t *bnp, int *runp)
  427. {
  428. struct vop_bmap_args a;
  429. a.a_vp = vp;
  430. a.a_bn = bn;
  431. a.a_vpp = vpp;
  432. a.a_bnp = bnp;
  433. a.a_runp = runp;
  434. ASSERT_VP_ISLOCKED(vp);
  435. if (vp->v_op->vop_bmap == NULL)
  436. return (EOPNOTSUPP);
  437. return ((vp->v_op->vop_bmap)(&a));
  438. }
  439. int
  440. VOP_PRINT(struct vnode *vp)
  441. {
  442. struct vop_print_args a;
  443. a.a_vp = vp;
  444. if (vp->v_op->vop_print == NULL)
  445. return (EOPNOTSUPP);
  446. return ((vp->v_op->vop_print)(&a));
  447. }
  448. int
  449. VOP_PATHCONF(struct vnode *vp, int name, register_t *retval)
  450. {
  451. struct vop_pathconf_args a;
  452. /*
  453. * Handle names that are constant across filesystem
  454. */
  455. switch (name) {
  456. case _PC_PATH_MAX:
  457. *retval = PATH_MAX;
  458. return (0);
  459. case _PC_PIPE_BUF:
  460. *retval = PIPE_BUF;
  461. return (0);
  462. case _PC_ASYNC_IO:
  463. case _PC_PRIO_IO:
  464. case _PC_SYNC_IO:
  465. *retval = 0;
  466. return (0);
  467. }
  468. a.a_vp = vp;
  469. a.a_name = name;
  470. a.a_retval = retval;
  471. ASSERT_VP_ISLOCKED(vp);
  472. if (vp->v_op->vop_pathconf == NULL)
  473. return (EOPNOTSUPP);
  474. return ((vp->v_op->vop_pathconf)(&a));
  475. }
  476. int
  477. VOP_ADVLOCK(struct vnode *vp, void *id, int op, struct flock *fl, int flags)
  478. {
  479. struct vop_advlock_args a;
  480. a.a_vp = vp;
  481. a.a_id = id;
  482. a.a_op = op;
  483. a.a_fl = fl;
  484. a.a_flags = flags;
  485. if (vp->v_op->vop_advlock == NULL)
  486. return (EOPNOTSUPP);
  487. return ((vp->v_op->vop_advlock)(&a));
  488. }
  489. int
  490. VOP_REALLOCBLKS(struct vnode *vp, struct cluster_save *buflist)
  491. {
  492. struct vop_reallocblks_args a;
  493. a.a_vp = vp;
  494. a.a_buflist = buflist;
  495. ASSERT_VP_ISLOCKED(vp);
  496. if (vp->v_op->vop_reallocblks == NULL)
  497. return (EOPNOTSUPP);
  498. return ((vp->v_op->vop_reallocblks)(&a));
  499. }
  500. int
  501. VOP_STRATEGY(struct buf *bp)
  502. {
  503. struct vop_strategy_args a;
  504. a.a_bp = bp;
  505. if ((ISSET(bp->b_flags, B_BC)) && (!ISSET(bp->b_flags, B_DMA)))
  506. panic("Non dma reachable buffer passed to VOP_STRATEGY");
  507. if (bp->b_vp->v_op->vop_strategy == NULL)
  508. return (EOPNOTSUPP);
  509. return ((bp->b_vp->v_op->vop_strategy)(&a));
  510. }
  511. int
  512. VOP_BWRITE(struct buf *bp)
  513. {
  514. struct vop_bwrite_args a;
  515. a.a_bp = bp;
  516. if (bp->b_vp->v_op->vop_bwrite == NULL)
  517. return (EOPNOTSUPP);
  518. return ((bp->b_vp->v_op->vop_bwrite)(&a));
  519. }