|
50 | 50 | zfs_file_open(const char *path, int flags, int mode, zfs_file_t **fpp)
|
51 | 51 | {
|
52 | 52 | struct thread *td;
|
53 |
| - int rc, fd; |
| 53 | + struct vnode *vp; |
| 54 | + struct file *fp; |
| 55 | + struct nameidata nd; |
| 56 | + int error; |
54 | 57 |
|
55 | 58 | td = curthread;
|
56 | 59 | pwd_ensure_dirs();
|
57 |
| - /* 12.x doesn't take a const char * */ |
58 |
| - rc = kern_openat(td, AT_FDCWD, __DECONST(char *, path), |
59 |
| - UIO_SYSSPACE, flags, mode); |
60 |
| - if (rc) |
61 |
| - return (SET_ERROR(rc)); |
62 |
| - fd = td->td_retval[0]; |
63 |
| - td->td_retval[0] = 0; |
64 |
| - if (fget(curthread, fd, &cap_no_rights, fpp)) |
65 |
| - kern_close(td, fd); |
| 60 | + |
| 61 | + KASSERT((flags & (O_EXEC | O_PATH)) == 0, |
| 62 | + ("invalid flags: 0x%x", flags)); |
| 63 | + KASSERT((flags & O_ACCMODE) != O_ACCMODE, |
| 64 | + ("invalid flags: 0x%x", flags)); |
| 65 | + flags = FFLAGS(flags); |
| 66 | + |
| 67 | + error = falloc_noinstall(td, &fp); |
| 68 | + if (error != 0) { |
| 69 | + return (error); |
| 70 | + } |
| 71 | + fp->f_flag = flags & FMASK; |
| 72 | + |
| 73 | +#if __FreeBSD_version >= 1400043 |
| 74 | + NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, path); |
| 75 | +#else |
| 76 | + NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, path, td); |
| 77 | +#endif |
| 78 | + error = vn_open(&nd, &flags, mode, fp); |
| 79 | + if (error != 0) { |
| 80 | + falloc_abort(td, fp); |
| 81 | + return (SET_ERROR(error)); |
| 82 | + } |
| 83 | + NDFREE_PNBUF(&nd); |
| 84 | + vp = nd.ni_vp; |
| 85 | + fp->f_vnode = vp; |
| 86 | + if (fp->f_ops == &badfileops) { |
| 87 | + finit_vnode(fp, flags, NULL, &vnops); |
| 88 | + } |
| 89 | + VOP_UNLOCK(vp); |
| 90 | + if (vp->v_type != VREG) { |
| 91 | + zfs_file_close(fp); |
| 92 | + return (SET_ERROR(EACCES)); |
| 93 | + } |
| 94 | + |
| 95 | + if (flags & O_TRUNC) { |
| 96 | + error = fo_truncate(fp, 0, td->td_ucred, td); |
| 97 | + if (error != 0) { |
| 98 | + zfs_file_close(fp); |
| 99 | + return (SET_ERROR(error)); |
| 100 | + } |
| 101 | + } |
| 102 | + |
| 103 | + *fpp = fp; |
| 104 | + |
66 | 105 | return (0);
|
67 | 106 | }
|
68 | 107 |
|
69 | 108 | void
|
70 | 109 | zfs_file_close(zfs_file_t *fp)
|
71 | 110 | {
|
72 |
| - fo_close(fp, curthread); |
| 111 | + fdrop(fp, curthread); |
73 | 112 | }
|
74 | 113 |
|
75 | 114 | static int
|
@@ -260,7 +299,7 @@ zfs_file_get(int fd)
|
260 | 299 | void
|
261 | 300 | zfs_file_put(zfs_file_t *fp)
|
262 | 301 | {
|
263 |
| - fdrop(fp, curthread); |
| 302 | + zfs_file_close(fp); |
264 | 303 | }
|
265 | 304 |
|
266 | 305 | loff_t
|
|
0 commit comments