* Simplified in-kernel wrapper calls for extended attribute access. * Both calls pass in a NULL credential, authorizing as "kernel" access. * Set IO_NODELOCKED in ioflg if the vnode is already locked. */
| 2119 | * Set IO_NODELOCKED in ioflg if the vnode is already locked. |
| 2120 | */ |
| 2121 | int |
| 2122 | vn_extattr_get(struct vnode *vp, int ioflg, int attrnamespace, |
| 2123 | const char *attrname, int *buflen, char *buf, struct thread *td) |
| 2124 | { |
| 2125 | struct uio auio; |
| 2126 | struct iovec iov; |
| 2127 | int error; |
| 2128 | |
| 2129 | iov.iov_len = *buflen; |
| 2130 | iov.iov_base = buf; |
| 2131 | |
| 2132 | auio.uio_iov = &iov; |
| 2133 | auio.uio_iovcnt = 1; |
| 2134 | auio.uio_rw = UIO_READ; |
| 2135 | auio.uio_segflg = UIO_SYSSPACE; |
| 2136 | auio.uio_td = td; |
| 2137 | auio.uio_offset = 0; |
| 2138 | auio.uio_resid = *buflen; |
| 2139 | |
| 2140 | if ((ioflg & IO_NODELOCKED) == 0) |
| 2141 | vn_lock(vp, LK_SHARED | LK_RETRY); |
| 2142 | |
| 2143 | ASSERT_VOP_LOCKED(vp, "IO_NODELOCKED with no vp lock held"); |
| 2144 | |
| 2145 | /* authorize attribute retrieval as kernel */ |
| 2146 | error = VOP_GETEXTATTR(vp, attrnamespace, attrname, &auio, NULL, NULL, |
| 2147 | td); |
| 2148 | |
| 2149 | if ((ioflg & IO_NODELOCKED) == 0) |
| 2150 | VOP_UNLOCK(vp); |
| 2151 | |
| 2152 | if (error == 0) { |
| 2153 | *buflen = *buflen - auio.uio_resid; |
| 2154 | } |
| 2155 | |
| 2156 | return (error); |
| 2157 | } |
| 2158 | |
| 2159 | /* |
| 2160 | * XXX failure mode if partially written? |
no test coverage detected