| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: rumpfs.c,v 1.116 2013/06/12 12:14:35 pooka Exp $ */ | | 1 | /* $NetBSD: rumpfs.c,v 1.117 2013/06/14 05:54:04 pooka Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2009, 2010, 2011 Antti Kantee. All Rights Reserved. | | 4 | * Copyright (c) 2009, 2010, 2011 Antti Kantee. All Rights Reserved. |
5 | * | | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | | 6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | | 7 | * modification, are permitted provided that the following conditions |
8 | * are met: | | 8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright | | 9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. | | 10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright | | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the | | 12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. | | 13 | * documentation and/or other materials provided with the distribution. |
14 | * | | 14 | * |
| @@ -16,27 +16,27 @@ | | | @@ -16,27 +16,27 @@ |
16 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | | 16 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | | 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | | 18 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | | 20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
21 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 21 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
22 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 22 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
23 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 23 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
24 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 24 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
25 | * SUCH DAMAGE. | | 25 | * SUCH DAMAGE. |
26 | */ | | 26 | */ |
27 | | | 27 | |
28 | #include <sys/cdefs.h> | | 28 | #include <sys/cdefs.h> |
29 | __KERNEL_RCSID(0, "$NetBSD: rumpfs.c,v 1.116 2013/06/12 12:14:35 pooka Exp $"); | | 29 | __KERNEL_RCSID(0, "$NetBSD: rumpfs.c,v 1.117 2013/06/14 05:54:04 pooka Exp $"); |
30 | | | 30 | |
31 | #include <sys/param.h> | | 31 | #include <sys/param.h> |
32 | #include <sys/atomic.h> | | 32 | #include <sys/atomic.h> |
33 | #include <sys/buf.h> | | 33 | #include <sys/buf.h> |
34 | #include <sys/dirent.h> | | 34 | #include <sys/dirent.h> |
35 | #include <sys/errno.h> | | 35 | #include <sys/errno.h> |
36 | #include <sys/filedesc.h> | | 36 | #include <sys/filedesc.h> |
37 | #include <sys/fcntl.h> | | 37 | #include <sys/fcntl.h> |
38 | #include <sys/kauth.h> | | 38 | #include <sys/kauth.h> |
39 | #include <sys/malloc.h> | | 39 | #include <sys/malloc.h> |
40 | #include <sys/module.h> | | 40 | #include <sys/module.h> |
41 | #include <sys/mount.h> | | 41 | #include <sys/mount.h> |
42 | #include <sys/namei.h> | | 42 | #include <sys/namei.h> |
| @@ -1264,83 +1264,86 @@ rump_vop_open(void *v) | | | @@ -1264,83 +1264,86 @@ rump_vop_open(void *v) |
1264 | RUMPUSER_OPEN_RDONLY, &rn->rn_readfd); | | 1264 | RUMPUSER_OPEN_RDONLY, &rn->rn_readfd); |
1265 | } | | 1265 | } |
1266 | | | 1266 | |
1267 | if (mode & FWRITE) { | | 1267 | if (mode & FWRITE) { |
1268 | if (rn->rn_writefd != -1) | | 1268 | if (rn->rn_writefd != -1) |
1269 | return 0; | | 1269 | return 0; |
1270 | error = rumpuser_open(rn->rn_hostpath, | | 1270 | error = rumpuser_open(rn->rn_hostpath, |
1271 | RUMPUSER_OPEN_WRONLY, &rn->rn_writefd); | | 1271 | RUMPUSER_OPEN_WRONLY, &rn->rn_writefd); |
1272 | } | | 1272 | } |
1273 | | | 1273 | |
1274 | return error; | | 1274 | return error; |
1275 | } | | 1275 | } |
1276 | | | 1276 | |
1277 | /* simple readdir. event omits dotstuff and periods */ | | 1277 | /* simple readdir. even omits dotstuff and periods */ |
1278 | static int | | 1278 | static int |
1279 | rump_vop_readdir(void *v) | | 1279 | rump_vop_readdir(void *v) |
1280 | { | | 1280 | { |
1281 | struct vop_readdir_args /* { | | 1281 | struct vop_readdir_args /* { |
1282 | struct vnode *a_vp; | | 1282 | struct vnode *a_vp; |
1283 | struct uio *a_uio; | | 1283 | struct uio *a_uio; |
1284 | kauth_cred_t a_cred; | | 1284 | kauth_cred_t a_cred; |
1285 | int *a_eofflag; | | 1285 | int *a_eofflag; |
1286 | off_t **a_cookies; | | 1286 | off_t **a_cookies; |
1287 | int *a_ncookies; | | 1287 | int *a_ncookies; |
1288 | } */ *ap = v; | | 1288 | } */ *ap = v; |
1289 | struct vnode *vp = ap->a_vp; | | 1289 | struct vnode *vp = ap->a_vp; |
1290 | struct uio *uio = ap->a_uio; | | 1290 | struct uio *uio = ap->a_uio; |
1291 | struct rumpfs_node *rnd = vp->v_data; | | 1291 | struct rumpfs_node *rnd = vp->v_data; |
1292 | struct rumpfs_dent *rdent; | | 1292 | struct rumpfs_dent *rdent; |
| | | 1293 | struct dirent *dentp = NULL; |
1293 | unsigned i; | | 1294 | unsigned i; |
1294 | int rv = 0; | | 1295 | int rv = 0; |
1295 | | | 1296 | |
1296 | /* seek to current entry */ | | 1297 | /* seek to current entry */ |
1297 | for (i = 0, rdent = LIST_FIRST(&rnd->rn_dir); | | 1298 | for (i = 0, rdent = LIST_FIRST(&rnd->rn_dir); |
1298 | (i < uio->uio_offset) && rdent; | | 1299 | (i < uio->uio_offset) && rdent; |
1299 | i++, rdent = LIST_NEXT(rdent, rd_entries)) | | 1300 | i++, rdent = LIST_NEXT(rdent, rd_entries)) |
1300 | continue; | | 1301 | continue; |
1301 | if (!rdent) | | 1302 | if (!rdent) |
1302 | goto out; | | 1303 | goto out; |
1303 | | | 1304 | |
1304 | /* copy entries */ | | 1305 | /* copy entries */ |
| | | 1306 | dentp = kmem_alloc(sizeof(*dentp), KM_SLEEP); |
1305 | for (; rdent && uio->uio_resid > 0; | | 1307 | for (; rdent && uio->uio_resid > 0; |
1306 | rdent = LIST_NEXT(rdent, rd_entries), i++) { | | 1308 | rdent = LIST_NEXT(rdent, rd_entries), i++) { |
1307 | struct dirent dent; | | 1309 | strlcpy(dentp->d_name, rdent->rd_name, sizeof(dentp->d_name)); |
1308 | | | 1310 | dentp->d_namlen = strlen(dentp->d_name); |
1309 | strlcpy(dent.d_name, rdent->rd_name, sizeof(dent.d_name)); | | 1311 | dentp->d_reclen = _DIRENT_RECLEN(dentp, dentp->d_namlen); |
1310 | dent.d_namlen = strlen(dent.d_name); | | | |
1311 | dent.d_reclen = _DIRENT_RECLEN(&dent, dent.d_namlen); | | | |
1312 | | | 1312 | |
1313 | if (__predict_false(RDENT_ISWHITEOUT(rdent))) { | | 1313 | if (__predict_false(RDENT_ISWHITEOUT(rdent))) { |
1314 | dent.d_fileno = INO_WHITEOUT; | | 1314 | dentp->d_fileno = INO_WHITEOUT; |
1315 | dent.d_type = DT_WHT; | | 1315 | dentp->d_type = DT_WHT; |
1316 | } else { | | 1316 | } else { |
1317 | dent.d_fileno = rdent->rd_node->rn_va.va_fileid; | | 1317 | dentp->d_fileno = rdent->rd_node->rn_va.va_fileid; |
1318 | dent.d_type = vtype2dt(rdent->rd_node->rn_va.va_type); | | 1318 | dentp->d_type = vtype2dt(rdent->rd_node->rn_va.va_type); |
1319 | } | | 1319 | } |
1320 | | | 1320 | |
1321 | if (uio->uio_resid < dent.d_reclen) { | | 1321 | if (uio->uio_resid < dentp->d_reclen) { |
1322 | i--; | | 1322 | i--; |
1323 | break; | | 1323 | break; |
1324 | } | | 1324 | } |
1325 | | | 1325 | |
1326 | rv = uiomove(&dent, dent.d_reclen, uio); | | 1326 | rv = uiomove(dentp, dentp->d_reclen, uio); |
1327 | if (rv) { | | 1327 | if (rv) { |
1328 | i--; | | 1328 | i--; |
1329 | break; | | 1329 | break; |
1330 | } | | 1330 | } |
1331 | } | | 1331 | } |
| | | 1332 | kmem_free(dentp, sizeof(*dentp)); |
| | | 1333 | dentp = NULL; |
1332 | | | 1334 | |
1333 | out: | | 1335 | out: |
| | | 1336 | KASSERT(dentp == NULL); |
1334 | if (ap->a_cookies) { | | 1337 | if (ap->a_cookies) { |
1335 | *ap->a_ncookies = 0; | | 1338 | *ap->a_ncookies = 0; |
1336 | *ap->a_cookies = NULL; | | 1339 | *ap->a_cookies = NULL; |
1337 | } | | 1340 | } |
1338 | if (rdent) | | 1341 | if (rdent) |
1339 | *ap->a_eofflag = 0; | | 1342 | *ap->a_eofflag = 0; |
1340 | else | | 1343 | else |
1341 | *ap->a_eofflag = 1; | | 1344 | *ap->a_eofflag = 1; |
1342 | uio->uio_offset = i; | | 1345 | uio->uio_offset = i; |
1343 | | | 1346 | |
1344 | return rv; | | 1347 | return rv; |
1345 | } | | 1348 | } |
1346 | | | 1349 | |