[BACK]Return to hfs_vnops.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / fs / hfs

Annotation of src/sys/fs/hfs/hfs_vnops.c, Revision 1.9

1.9     ! ad          1: /*     $NetBSD: hfs_vnops.c,v 1.8 2008/01/25 14:32:12 ad Exp $ */
1.1       dillo       2:
                      3: /*-
                      4:  * Copyright (c) 2005, 2007 The NetBSD Foundation, Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Yevgeny Binder and Dieter Baron.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     20:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     21:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     22:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     23:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     24:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     25:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     26:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     27:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     28:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     29:  * POSSIBILITY OF SUCH DAMAGE.
                     30:  */
                     31:
                     32: /*
                     33:  * Copyright (c) 1992, 1993
                     34:  *     The Regents of the University of California.  All rights reserved.
                     35:  *
                     36:  * This code is derived from software donated to Berkeley by
                     37:  * Jan-Simon Pendry.
                     38:  *
                     39:  * Redistribution and use in source and binary forms, with or without
                     40:  * modification, are permitted provided that the following conditions
                     41:  * are met:
                     42:  * 1. Redistributions of source code must retain the above copyright
                     43:  *    notice, this list of conditions and the following disclaimer.
                     44:  * 2. Redistributions in binary form must reproduce the above copyright
                     45:  *    notice, this list of conditions and the following disclaimer in the
                     46:  *    documentation and/or other materials provided with the distribution.
                     47:  * 3. Neither the name of the University nor the names of its contributors
                     48:  *    may be used to endorse or promote products derived from this software
                     49:  *    without specific prior written permission.
                     50:  *
                     51:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     52:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     53:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     54:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     55:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     56:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     57:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     58:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     59:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     60:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     61:  * SUCH DAMAGE.
                     62:  */
                     63:
                     64: /*
                     65:  * Copyright (c) 1982, 1986, 1989, 1993, 1995
                     66:  *     The Regents of the University of California.  All rights reserved.
                     67:  * (c) UNIX System Laboratories, Inc.
                     68:  * All or some portions of this file are derived from material licensed
                     69:  * to the University of California by American Telephone and Telegraph
                     70:  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
                     71:  * the permission of UNIX System Laboratories, Inc.
                     72:  *
                     73:  * Redistribution and use in source and binary forms, with or without
                     74:  * modification, are permitted provided that the following conditions
                     75:  * are met:
                     76:  * 1. Redistributions of source code must retain the above copyright
                     77:  *    notice, this list of conditions and the following disclaimer.
                     78:  * 2. Redistributions in binary form must reproduce the above copyright
                     79:  *    notice, this list of conditions and the following disclaimer in the
                     80:  *    documentation and/or other materials provided with the distribution.
                     81:  * 3. Neither the name of the University nor the names of its contributors
                     82:  *    may be used to endorse or promote products derived from this software
                     83:  *    without specific prior written permission.
                     84:  *
                     85:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     86:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     87:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     88:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     89:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     90:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     91:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     92:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     93:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     94:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     95:  * SUCH DAMAGE.
                     96:  */
                     97:
                     98:
                     99: /*
                    100:  * Apple HFS+ filesystem
                    101:  */
                    102:
                    103: #include <sys/cdefs.h>
1.9     ! ad        104: __KERNEL_RCSID(0, "$NetBSD: hfs_vnops.c,v 1.8 2008/01/25 14:32:12 ad Exp $");
1.1       dillo     105:
                    106: #ifdef _KERNEL_OPT
                    107: #include "opt_ipsec.h"
                    108: #endif
                    109:
                    110: #include <sys/param.h>
                    111: #include <sys/systm.h>
                    112: #include <sys/kernel.h>
                    113: #include <sys/vmmeter.h>
                    114: #include <sys/time.h>
                    115: #include <sys/proc.h>
                    116: #include <sys/vnode.h>
                    117: #include <sys/malloc.h>
                    118: #include <sys/file.h>
                    119: #include <sys/stat.h>
                    120: #include <sys/mount.h>
                    121: #include <sys/namei.h>
                    122: #include <sys/buf.h>
                    123: #include <sys/dirent.h>
                    124: #include <sys/msgbuf.h>
                    125:
                    126: #include <miscfs/fifofs/fifo.h>
                    127: #include <miscfs/specfs/specdev.h>
                    128:
1.2       dillo     129: #include <fs/hfs/hfs.h>
                    130: #include <fs/hfs/unicode.h>
1.1       dillo     131:
                    132: #include <miscfs/genfs/genfs.h>
                    133:
1.2       dillo     134: int    hfs_vop_lookup          (void *);
                    135: int    hfs_vop_open            (void *);
                    136: int    hfs_vop_close           (void *);
                    137: int    hfs_vop_access          (void *);
                    138: int    hfs_vop_getattr (void *);
                    139: int    hfs_vop_setattr (void *);
                    140: int    hfs_vop_bmap            (void *);
                    141: int    hfs_vop_read            (void *);
                    142: int    hfs_vop_readdir (void *);
                    143: int    hfs_vop_readlink        (void *);
                    144: int    hfs_vop_reclaim (void *);
                    145: int    hfs_vop_print           (void *);
1.1       dillo     146:
                    147:
1.2       dillo     148: int (**hfs_vnodeop_p) (void *);
                    149: const struct vnodeopv_entry_desc hfs_vnodeop_entries[] = {
1.1       dillo     150:        { &vop_default_desc, vn_default_error },
1.2       dillo     151:        { &vop_lookup_desc, hfs_vop_lookup },           /* lookup */
1.1       dillo     152:        { &vop_create_desc, genfs_eopnotsupp },         /* create */
                    153:        { &vop_whiteout_desc, genfs_eopnotsupp },       /* whiteout */
                    154:        { &vop_mknod_desc, genfs_eopnotsupp },          /* mknod */
1.2       dillo     155:        { &vop_open_desc, hfs_vop_open },               /* open */
                    156:        { &vop_close_desc, hfs_vop_close },             /* close */
                    157:        { &vop_access_desc, hfs_vop_access },           /* access */
                    158:        { &vop_getattr_desc, hfs_vop_getattr }, /* getattr */
                    159:        { &vop_setattr_desc, hfs_vop_setattr }, /* setattr */
                    160:        { &vop_read_desc, hfs_vop_read },               /* read */
1.1       dillo     161:        { &vop_write_desc, genfs_eopnotsupp },          /* write */
                    162:        { &vop_ioctl_desc, genfs_eopnotsupp },          /* ioctl */
                    163:        { &vop_fcntl_desc, genfs_fcntl },               /* fcntl */
                    164:        { &vop_poll_desc, genfs_eopnotsupp },           /* poll */
                    165:        { &vop_kqfilter_desc, genfs_kqfilter },         /* kqfilter */
                    166:        { &vop_revoke_desc, genfs_eopnotsupp },         /* revoke */
                    167:        { &vop_mmap_desc, genfs_mmap },                 /* mmap */
                    168:        { &vop_fsync_desc, genfs_nullop },              /* fsync */
                    169:        { &vop_seek_desc, genfs_seek },                 /* seek */
                    170:        { &vop_remove_desc, genfs_eopnotsupp },         /* remove */
                    171:        { &vop_link_desc, genfs_eopnotsupp },           /* link */
                    172:        { &vop_rename_desc, genfs_eopnotsupp },         /* rename */
                    173:        { &vop_mkdir_desc, genfs_eopnotsupp },          /* mkdir */
                    174:        { &vop_rmdir_desc, genfs_eopnotsupp },          /* rmdir */
                    175:        { &vop_symlink_desc, genfs_eopnotsupp },        /* symlink */
1.2       dillo     176:        { &vop_readdir_desc, hfs_vop_readdir }, /* readdir */
                    177:        { &vop_readlink_desc, hfs_vop_readlink },       /* readlink */
1.1       dillo     178:        { &vop_abortop_desc, genfs_abortop },           /* abortop */
                    179:        { &vop_inactive_desc, genfs_eopnotsupp },       /* inactive */
1.2       dillo     180:        { &vop_reclaim_desc, hfs_vop_reclaim }, /* reclaim */
1.1       dillo     181:        { &vop_lock_desc, genfs_lock },                 /* lock */
                    182:        { &vop_unlock_desc, genfs_unlock },             /* unlock */
1.2       dillo     183:        { &vop_bmap_desc, hfs_vop_bmap },               /* bmap */
1.1       dillo     184:        { &vop_strategy_desc, genfs_eopnotsupp },       /* strategy */
1.2       dillo     185:        { &vop_print_desc, hfs_vop_print },             /* print */
1.1       dillo     186:        { &vop_islocked_desc, genfs_islocked },         /* islocked */
                    187:        { &vop_pathconf_desc, genfs_eopnotsupp },       /* pathconf */
                    188:        { &vop_advlock_desc, genfs_eopnotsupp },        /* advlock */
                    189:        { &vop_bwrite_desc, genfs_eopnotsupp },         /* bwrite */
                    190:        { &vop_getpages_desc, genfs_getpages },         /* getpages */
                    191:        { &vop_putpages_desc, genfs_putpages },         /* putpages */
                    192:        { &vop_openextattr_desc, genfs_eopnotsupp },    /* openextattr */
                    193:        { &vop_closeextattr_desc, genfs_eopnotsupp },   /* closeextattr */
                    194:        { &vop_getextattr_desc, genfs_eopnotsupp },     /* getextattr */
                    195:        { &vop_setextattr_desc, genfs_eopnotsupp },     /* setextattr */
                    196:        { &vop_listextattr_desc, genfs_eopnotsupp },    /* listextattr */
                    197:        { &vop_deleteextattr_desc, genfs_eopnotsupp },  /* deleteextattr */
                    198:        { NULL, NULL }
                    199: };
1.2       dillo     200: const struct vnodeopv_desc hfs_vnodeop_opv_desc =
                    201:        { &hfs_vnodeop_p, hfs_vnodeop_entries };
1.1       dillo     202:
1.2       dillo     203: int (**hfs_specop_p) (void *);
                    204: const struct vnodeopv_entry_desc hfs_specop_entries[] = {
1.1       dillo     205:        { &vop_default_desc, vn_default_error },
                    206:        { &vop_lookup_desc, spec_lookup },              /* lookup */
                    207:        { &vop_create_desc, spec_create },              /* create */
                    208:        { &vop_mknod_desc, spec_mknod },                /* mknod */
                    209:        { &vop_open_desc, spec_open },                  /* open */
                    210:        { &vop_close_desc, spec_close },                /* close */
1.2       dillo     211:        { &vop_access_desc, hfs_vop_access },           /* access */
                    212:        { &vop_getattr_desc, hfs_vop_getattr }, /* getattr */
                    213:        { &vop_setattr_desc, hfs_vop_setattr }, /* setattr */
1.1       dillo     214:        { &vop_read_desc, spec_read },                  /* read */
                    215:        { &vop_write_desc, spec_write },                /* write */
                    216:        { &vop_ioctl_desc, spec_ioctl },                /* ioctl */
                    217:        { &vop_fcntl_desc, genfs_fcntl },               /* fcntl */
                    218:        { &vop_poll_desc, spec_poll },                  /* poll */
                    219:        { &vop_kqfilter_desc, spec_kqfilter },          /* kqfilter */
                    220:        { &vop_revoke_desc, spec_revoke },              /* revoke */
                    221:        { &vop_mmap_desc, spec_mmap },                  /* mmap */
                    222:        { &vop_fsync_desc, genfs_nullop },              /* fsync */
                    223:        { &vop_seek_desc, spec_seek },                  /* seek */
                    224:        { &vop_remove_desc, spec_remove },              /* remove */
                    225:        { &vop_link_desc, spec_link },                  /* link */
                    226:        { &vop_rename_desc, spec_rename },              /* rename */
                    227:        { &vop_mkdir_desc, spec_mkdir },                /* mkdir */
                    228:        { &vop_rmdir_desc, spec_rmdir },                /* rmdir */
                    229:        { &vop_symlink_desc, spec_symlink },            /* symlink */
                    230:        { &vop_readdir_desc, spec_readdir },            /* readdir */
                    231:        { &vop_readlink_desc, spec_readlink },          /* readlink */
                    232:        { &vop_abortop_desc, spec_abortop },            /* abortop */
                    233:        { &vop_inactive_desc, genfs_eopnotsupp },       /* inactive */
1.2       dillo     234:        { &vop_reclaim_desc, hfs_vop_reclaim }, /* reclaim */
1.1       dillo     235:        { &vop_lock_desc, genfs_lock },                 /* lock */
                    236:        { &vop_unlock_desc, genfs_unlock },             /* unlock */
                    237:        { &vop_bmap_desc, spec_bmap },                  /* bmap */
                    238:        { &vop_strategy_desc, spec_strategy },          /* strategy */
1.2       dillo     239:        { &vop_print_desc, hfs_vop_print },             /* print */
1.1       dillo     240:        { &vop_islocked_desc, genfs_islocked },         /* islocked */
                    241:        { &vop_pathconf_desc, spec_pathconf },          /* pathconf */
                    242:        { &vop_advlock_desc, spec_advlock },            /* advlock */
                    243:        { &vop_bwrite_desc, vn_bwrite },                /* bwrite */
                    244:        { &vop_getpages_desc, spec_getpages },          /* getpages */
                    245:        { &vop_putpages_desc, spec_putpages },          /* putpages */
                    246: #if 0
                    247:        { &vop_openextattr_desc, ffs_openextattr },     /* openextattr */
                    248:        { &vop_closeextattr_desc, ffs_closeextattr },   /* closeextattr */
                    249:        { &vop_getextattr_desc, ffs_getextattr },       /* getextattr */
                    250:        { &vop_setextattr_desc, ffs_setextattr },       /* setextattr */
                    251:        { &vop_listextattr_desc, ffs_listextattr },     /* listextattr */
                    252:        { &vop_deleteextattr_desc, ffs_deleteextattr }, /* deleteextattr */
                    253: #endif
                    254:        { NULL, NULL }
                    255: };
1.2       dillo     256: const struct vnodeopv_desc hfs_specop_opv_desc =
                    257:        { &hfs_specop_p, hfs_specop_entries };
1.1       dillo     258:
1.2       dillo     259: int (**hfs_fifoop_p) (void *);
                    260: const struct vnodeopv_entry_desc hfs_fifoop_entries[] = {
1.1       dillo     261:        { &vop_default_desc, vn_default_error },
                    262:        { &vop_lookup_desc, fifo_lookup },              /* lookup */
                    263:        { &vop_create_desc, fifo_create },              /* create */
                    264:        { &vop_mknod_desc, fifo_mknod },                /* mknod */
                    265:        { &vop_open_desc, fifo_open },                  /* open */
                    266:        { &vop_close_desc, fifo_close },                /* close */
1.2       dillo     267:        { &vop_access_desc, hfs_vop_access },           /* access */
                    268:        { &vop_getattr_desc, hfs_vop_getattr }, /* getattr */
                    269:        { &vop_setattr_desc, hfs_vop_setattr }, /* setattr */
1.1       dillo     270:        { &vop_read_desc, fifo_read },                  /* read */
                    271:        { &vop_write_desc, fifo_write },                /* write */
                    272:        { &vop_ioctl_desc, fifo_ioctl },                /* ioctl */
                    273:        { &vop_fcntl_desc, genfs_fcntl },               /* fcntl */
                    274:        { &vop_poll_desc, fifo_poll },                  /* poll */
                    275:        { &vop_kqfilter_desc, fifo_kqfilter },          /* kqfilter */
                    276:        { &vop_revoke_desc, fifo_revoke },              /* revoke */
                    277:        { &vop_mmap_desc, fifo_mmap },                  /* mmap */
                    278:        { &vop_fsync_desc, fifo_fsync },                /* fsync */
                    279:        { &vop_seek_desc, fifo_seek },                  /* seek */
                    280:        { &vop_remove_desc, fifo_remove },              /* remove */
                    281:        { &vop_link_desc, fifo_link },                  /* link */
                    282:        { &vop_rename_desc, fifo_rename },              /* rename */
                    283:        { &vop_mkdir_desc, fifo_mkdir },                /* mkdir */
                    284:        { &vop_rmdir_desc, fifo_rmdir },                /* rmdir */
                    285:        { &vop_symlink_desc, fifo_symlink },            /* symlink */
                    286:        { &vop_readdir_desc, fifo_readdir },            /* readdir */
                    287:        { &vop_readlink_desc, fifo_readlink },          /* readlink */
                    288:        { &vop_abortop_desc, fifo_abortop },            /* abortop */
                    289:        { &vop_inactive_desc, genfs_eopnotsupp },       /* inactive */
1.2       dillo     290:        { &vop_reclaim_desc, hfs_vop_reclaim }, /* reclaim */
1.1       dillo     291:        { &vop_lock_desc, genfs_lock },                 /* lock */
                    292:        { &vop_unlock_desc, genfs_unlock },             /* unlock */
                    293:        { &vop_bmap_desc, fifo_bmap },                  /* bmap */
                    294:        { &vop_strategy_desc, fifo_strategy },          /* strategy */
1.2       dillo     295:        { &vop_print_desc, hfs_vop_print },             /* print */
1.1       dillo     296:        { &vop_islocked_desc, genfs_islocked },         /* islocked */
                    297:        { &vop_pathconf_desc, fifo_pathconf },          /* pathconf */
                    298:        { &vop_advlock_desc, fifo_advlock },            /* advlock */
                    299:        { &vop_bwrite_desc, vn_bwrite },                /* bwrite */
                    300:        { &vop_putpages_desc, fifo_putpages },          /* putpages */
                    301: #if 0
                    302:        { &vop_openextattr_desc, ffs_openextattr },     /* openextattr */
                    303:        { &vop_closeextattr_desc, ffs_closeextattr },   /* closeextattr */
                    304:        { &vop_getextattr_desc, ffs_getextattr },       /* getextattr */
                    305:        { &vop_setextattr_desc, ffs_setextattr },       /* setextattr */
                    306:        { &vop_listextattr_desc, ffs_listextattr },     /* listextattr */
                    307:        { &vop_deleteextattr_desc, ffs_deleteextattr }, /* deleteextattr */
                    308: #endif
                    309:        { NULL, NULL }
                    310: };
1.2       dillo     311: const struct vnodeopv_desc hfs_fifoop_opv_desc =
                    312:        { &hfs_fifoop_p, hfs_fifoop_entries };
1.1       dillo     313:
                    314: int
1.2       dillo     315: hfs_vop_lookup(void *v)
1.1       dillo     316: {
                    317:        struct vop_lookup_args /* {
                    318:                struct vnode * a_dvp;
                    319:                struct vnode ** a_vpp;
                    320:                struct componentname * a_cnp;
                    321:        } */ *ap = v;
                    322:        struct buf *bp;                 /* a buffer of directory entries */
                    323:        struct componentname *cnp;
1.2       dillo     324:        struct hfsnode *dp;     /* hfsnode for directory being searched */
1.1       dillo     325:        kauth_cred_t cred;
                    326:        struct vnode **vpp;             /* resultant vnode */
                    327:        struct vnode *pdp;              /* saved dp during symlink work */
                    328:        struct vnode *tdp;              /* returned by VFS_VGET */
                    329:        struct vnode *vdp;              /* vnode for directory being searched */
1.2       dillo     330:        hfs_catalog_key_t key;  /* hfs+ catalog search key for requested child */
                    331:        hfs_catalog_keyed_record_t rec; /* catalog record of requested child */
1.1       dillo     332:        unichar_t* unicn;               /* name of component, in Unicode */
                    333:        const char *pname;
                    334:        int error;
                    335:        int flags;
1.2       dillo     336:        int result;                             /* result of libhfs operations */
1.1       dillo     337:
1.2       dillo     338: #ifdef HFS_DEBUG
                    339:        printf("VOP = hfs_vop_lookup()\n");
                    340: #endif /* HFS_DEBUG */
1.1       dillo     341:
                    342:        bp = NULL;
                    343:        cnp = ap->a_cnp;
                    344:        cred = cnp->cn_cred;
                    345:        vdp = ap->a_dvp;
                    346:        dp = VTOH(vdp);
                    347:        error = 0;
                    348:        pname = cnp->cn_nameptr;
                    349:        result = 0;
                    350:        unicn = NULL;
                    351:        vpp = ap->a_vpp;
                    352:        *vpp = NULL;
                    353:
                    354:        flags = cnp->cn_flags;
                    355:
                    356:
                    357:        /*
                    358:         * Check accessiblity of directory.
                    359:         */
1.5       pooka     360:        if ((error = VOP_ACCESS(vdp, VEXEC, cred)) != 0)
1.1       dillo     361:                return error;
                    362:
                    363:        if ((flags & ISLASTCN) && (vdp->v_mount->mnt_flag & MNT_RDONLY) &&
                    364:            (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
                    365:                return EROFS;
                    366:
                    367:        /*
                    368:         * We now have a segment name to search for, and a directory to search.
                    369:         *
                    370:         * Before tediously performing a linear scan of the directory,
                    371:         * check the name cache to see if the directory/name pair
                    372:         * we are looking for is known already.
                    373:         */
                    374: /* XXX Cache disabled until we can make sure it works. */
                    375: /*     if ((error = cache_lookup(vdp, vpp, cnp)) >= 0)
                    376:                return error; */
                    377:
                    378:
                    379: /*     if (cnp->cn_namelen == 1 && *pname == '.') {
                    380:                *vpp = vdp;
                    381:                VREF(vdp);
                    382:                return (0);
                    383:        }*/
                    384:
                    385:        pdp = vdp;
                    386:        if (flags & ISDOTDOT) {
                    387: /*printf("DOTDOT ");*/
                    388:                VOP_UNLOCK(pdp, 0);     /* race to get the inode */
                    389:                error = VFS_VGET(vdp->v_mount, dp->h_parent, &tdp);
1.4       pooka     390:                vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY);
                    391:                if (error != 0)
1.1       dillo     392:                        goto error;
                    393:                *vpp = tdp;
                    394: /*     } else if (dp->h_rec.cnid == rec.file.cnid) {*/
                    395:        } else if (cnp->cn_namelen == 1 && pname[0] == '.') {
                    396: /*printf("DOT ");*/
                    397:                VREF(vdp);      /* we want ourself, ie "." */
                    398:                *vpp = vdp;
                    399:        } else {
1.2       dillo     400:                hfs_callback_args cbargs;
1.1       dillo     401:                uint8_t len;
                    402:
1.2       dillo     403:                hfslib_init_cbargs(&cbargs);
1.1       dillo     404:
                    405:                /* XXX: when decomposing, string could grow
                    406:                   and we have to handle overflow */
                    407:                unicn = malloc(cnp->cn_namelen*sizeof(unicn[0]), M_TEMP, M_WAITOK);
                    408:                len = utf8_to_utf16(unicn, cnp->cn_namelen,
                    409:                                    cnp->cn_nameptr, cnp->cn_namelen, 0, NULL);
                    410:                /* XXX: check conversion errors? */
1.2       dillo     411:                if (hfslib_make_catalog_key(VTOH(vdp)->h_rec.cnid, len, unicn,
1.1       dillo     412:                        &key) == 0) {
1.2       dillo     413: /*printf("ERROR in hfslib_make_catalog_key\n");*/
1.1       dillo     414:                        error = EINVAL;
                    415:                        goto error;
                    416:                }
                    417:
1.2       dillo     418:                result = hfslib_find_catalog_record_with_key(&dp->h_hmp->hm_vol, &key,
1.1       dillo     419:                        &rec, &cbargs);
                    420:                if (result > 0) {
                    421:                        error = EINVAL;
                    422:                        goto error;
                    423:                }
                    424:                if (result < 0) {
                    425:                        if (cnp->cn_nameiop == CREATE)
                    426:                                error = EROFS;
                    427:                        else
                    428:                                error = ENOENT;
                    429:                        goto error;
                    430:                }
                    431:
1.2       dillo     432:                if (rec.file.user_info.file_type == HFS_HARD_LINK_FILE_TYPE
1.1       dillo     433:                    && rec.file.user_info.file_creator
1.2       dillo     434:                    == HFS_HFSLUS_CREATOR) {
                    435:                        if (hfslib_get_hardlink(&dp->h_hmp->hm_vol,
1.1       dillo     436:                                         rec.file.bsd.special.inode_num,
                    437:                                         &rec, &cbargs) != 0) {
                    438:                                error = EINVAL;
                    439:                                goto error;
                    440:                        }
                    441:                }
                    442:
1.2       dillo     443:                if (rec.type == HFS_REC_FILE
1.1       dillo     444:                    && strcmp(cnp->cn_nameptr+cnp->cn_namelen, "/rsrc") == 0
                    445:                    && rec.file.rsrc_fork.logical_size > 0) {
                    446:                    /* advance namei next pointer to end of stirng */
                    447:                    cnp->cn_consume = 5;
                    448:                    cnp->cn_flags &= ~REQUIREDIR; /* XXX: needed? */
1.2       dillo     449:                    error = hfs_vget_internal(vdp->v_mount, rec.file.cnid,
                    450:                        HFS_RSRCFORK, &tdp);
1.1       dillo     451:                }
                    452:                else
                    453:                        error = VFS_VGET(vdp->v_mount, rec.file.cnid, &tdp);
                    454:                if (error != 0)
                    455:                        goto error;
                    456:                *vpp = tdp;
                    457:        }
                    458: /*printf("\n");*/
                    459:        /*
                    460:         * Insert name into cache if appropriate.
                    461:         */
                    462: /* XXX Cache disabled until we can make sure it works. */
                    463: /*     if (cnp->cn_flags & MAKEENTRY)
                    464:                cache_enter(vdp, *vpp, cnp);*/
                    465:
                    466:        error = 0;
                    467:
                    468:        /* FALLTHROUGH */
                    469: error:
                    470:        if (unicn != NULL)
                    471:                free(unicn, M_TEMP);
                    472:
                    473:        return error;
                    474: }
                    475:
                    476: int
1.2       dillo     477: hfs_vop_open(void *v)
1.1       dillo     478: {
                    479: #if 0
                    480:        struct vop_open_args /* {
                    481:                struct vnode *a_vp;
                    482:                int a_mode;
                    483:                kauth_cred_t a_cred;
                    484:        } */ *ap = v;
1.2       dillo     485:        struct hfsnode *hn = VTOH(ap->a_vp);
1.1       dillo     486: #endif
1.2       dillo     487: #ifdef HFS_DEBUG
                    488:        printf("VOP = hfs_vop_open()\n");
                    489: #endif /* HFS_DEBUG */
1.1       dillo     490:
                    491:        /*
                    492:         * XXX This is a good place to read and cache the file's extents to avoid
                    493:         * XXX doing it upon every read/write. Must however keep the cache in sync
                    494:         * XXX when the file grows/shrinks. (So would that go in vop_truncate?)
                    495:         */
                    496:
                    497:        return 0;
                    498: }
                    499:
                    500: int
1.2       dillo     501: hfs_vop_close(void *v)
1.1       dillo     502: {
                    503: #if 0
                    504:        struct vop_close_args /* {
                    505:                struct vnode *a_vp;
                    506:                int a_fflag;
                    507:                kauth_cred_t a_cred;
                    508:        } */ *ap = v;
1.2       dillo     509:        struct hfsnode *hn = VTOH(ap->a_vp);
1.1       dillo     510: #endif
1.2       dillo     511: #ifdef HFS_DEBUG
                    512:        printf("VOP = hfs_vop_close()\n");
                    513: #endif /* HFS_DEBUG */
1.1       dillo     514:
                    515:        /* Release extents cache here. */
                    516:
                    517:        return 0;
                    518: }
                    519:
                    520: int
1.2       dillo     521: hfs_vop_access(void *v)
1.1       dillo     522: {
                    523:        struct vop_access_args /* {
                    524:                struct vnode *a_vp;
                    525:                int a_mode;
                    526:                kauth_cred_t a_cred;
                    527:        } */ *ap = v;
                    528:        struct vattr va;
                    529:        int error;
                    530:
1.2       dillo     531: #ifdef HFS_DEBUG
                    532:        printf("VOP = hfs_vop_access()\n");
                    533: #endif /* HFS_DEBUG */
1.1       dillo     534:
                    535:        /*
                    536:         * Disallow writes on files, directories, and symlinks
                    537:         * since we have no write support yet.
                    538:         */
                    539:
                    540:        if (ap->a_mode & VWRITE) {
                    541:                switch (ap->a_vp->v_type) {
                    542:                case VDIR:
                    543:                case VLNK:
                    544:                case VREG:
                    545:                        return EROFS;
                    546:                default:
                    547:                        break;
                    548:                }
                    549:        }
                    550:
1.5       pooka     551:        if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred)) != 0)
1.1       dillo     552:                return error;
                    553:
                    554:        return vaccess(va.va_type, va.va_mode, va.va_uid, va.va_gid,
                    555:            ap->a_mode, ap->a_cred);
                    556: }
                    557:
                    558: int
1.2       dillo     559: hfs_vop_getattr(void *v)
1.1       dillo     560: {
                    561:        struct vop_getattr_args /* {
                    562:                struct vnode    *a_vp;
                    563:                struct vattr    *a_vap;
                    564:                struct ucred    *a_cred;
                    565:        } */ *ap = v;
                    566:        struct vnode    *vp;
1.2       dillo     567:        struct hfsnode  *hp;
1.1       dillo     568:        struct vattr    *vap;
1.2       dillo     569:        hfs_bsd_data_t *bsd;
                    570:        hfs_fork_t     *fork;
1.1       dillo     571:
1.2       dillo     572: #ifdef HFS_DEBUG
                    573:        printf("VOP = hfs_vop_getattr()\n");
                    574: #endif /* HFS_DEBUG */
1.1       dillo     575:
                    576:        vp = ap->a_vp;
                    577:        hp = VTOH(vp);
                    578:        vap = ap->a_vap;
                    579:
                    580:        vattr_null(vap);
                    581:
                    582:        /*
                    583:         * XXX Cannot trust permissions/modes/flags stored in an HFS+ catalog record
                    584:         * XXX record those values are not set on files created under Mac OS 9.
                    585:         */
                    586:        vap->va_type = ap->a_vp->v_type;
1.2       dillo     587:        if (hp->h_rec.rec_type == HFS_REC_FILE) {
                    588:                if (hp->h_fork == HFS_RSRCFORK)
1.1       dillo     589:                        fork = &hp->h_rec.file.rsrc_fork;
                    590:                else
                    591:                        fork = &hp->h_rec.file.data_fork;
                    592:                vap->va_fileid = hp->h_rec.file.cnid;
                    593:                bsd = &hp->h_rec.file.bsd;
1.2       dillo     594:                vap->va_bytes = fork->total_blocks * HFS_BLOCKSIZE(vp);
1.1       dillo     595:                vap->va_size = fork->logical_size;
1.2       dillo     596:                hfs_time_to_timespec(hp->h_rec.file.date_created, &vap->va_ctime);
                    597:                hfs_time_to_timespec(hp->h_rec.file.date_content_mod, &vap->va_mtime);
                    598:                hfs_time_to_timespec(hp->h_rec.file.date_accessed, &vap->va_atime);
1.1       dillo     599:                vap->va_nlink = 1;
                    600:        }
1.2       dillo     601:        else if (hp->h_rec.rec_type == HFS_REC_FLDR) {
1.1       dillo     602:                vap->va_fileid = hp->h_rec.folder.cnid;
                    603:                bsd = &hp->h_rec.folder.bsd;
                    604:                vap->va_size = 512; /* XXX Temporary */
                    605:                vap->va_bytes = 512; /* XXX Temporary */
1.2       dillo     606:                hfs_time_to_timespec(hp->h_rec.folder.date_created, &vap->va_ctime);
                    607:                hfs_time_to_timespec(hp->h_rec.folder.date_content_mod,&vap->va_mtime);
                    608:                hfs_time_to_timespec(hp->h_rec.folder.date_accessed, &vap->va_atime);
1.1       dillo     609:                vap->va_nlink = 2; /* XXX */
                    610:        }
                    611:        else {
1.2       dillo     612:                printf("hfslus: hfs_vop_getattr(): invalid record type %i",
1.1       dillo     613:                        hp->h_rec.rec_type);
                    614:                return EINVAL;
                    615:        }
                    616:
                    617:        if ((bsd->file_mode & S_IFMT) == 0) {
                    618:                /* no bsd permissions recorded, use default values */
1.2       dillo     619:                if (hp->h_rec.rec_type == HFS_REC_FILE)
                    620:                        vap->va_mode = (S_IFREG | HFS_DEFAULT_FILE_MODE);
1.1       dillo     621:                else
1.2       dillo     622:                        vap->va_mode = (S_IFDIR | HFS_DEFAULT_DIR_MODE);
                    623:                vap->va_uid = HFS_DEFAULT_UID;
                    624:                vap->va_gid = HFS_DEFAULT_GID;
1.1       dillo     625:        }
                    626:        else {
                    627:                vap->va_mode = bsd->file_mode;
                    628:                vap->va_uid = bsd->owner_id;
                    629:                vap->va_gid = bsd->group_id;
                    630:                if ((vap->va_mode & S_IFMT) == S_IFCHR
                    631:                    || (vap->va_mode & S_IFMT) == S_IFBLK) {
                    632:                        vap->va_rdev
1.2       dillo     633:                            = HFS_CONVERT_RDEV(bsd->special.raw_device);
1.1       dillo     634:                }
                    635:                else if (bsd->special.link_count != 0) {
                    636:                    /* XXX: only if in metadata directory */
                    637:                    vap->va_nlink = bsd->special.link_count;
                    638:                }
                    639:        }
                    640:
                    641:        vap->va_fsid = hp->h_dev;
                    642:        vap->va_blocksize = hp->h_hmp->hm_vol.vh.block_size;
                    643:        vap->va_gen = 1;
                    644:        vap->va_flags = 0;
                    645:
                    646:        return 0;
                    647: }
                    648:
                    649: int
1.2       dillo     650: hfs_vop_setattr(void *v)
1.1       dillo     651: {
                    652:        struct vop_setattr_args /* {
                    653:                struct vnode    *a_vp;
                    654:                struct vattr    *a_vap;
                    655:                kauth_cred_t    a_cred;
                    656:        } */ *ap = v;
                    657:        struct vattr    *vap;
                    658:        struct vnode    *vp;
                    659:
                    660:        vap = ap->a_vap;
                    661:        vp = ap->a_vp;
                    662:
                    663:        /*
                    664:         * Check for unsettable attributes.
                    665:         */
                    666:        if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
                    667:            (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
                    668:            (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
                    669:            ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
                    670:                return EINVAL;
                    671:        }
                    672:
                    673:        /* XXX: needs revisiting for write support */
                    674:        if (vap->va_flags != VNOVAL
                    675:            || vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL
                    676:            || vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL
                    677:            || vap->va_birthtime.tv_sec != VNOVAL) {
                    678:                return EROFS;
                    679:        }
                    680:
                    681:        if (vap->va_size != VNOVAL) {
                    682:                /*
                    683:                 * Disallow write attempts on read-only file systems;
                    684:                 * unless the file is a socket, fifo, or a block or
                    685:                 * character device resident on the file system.
                    686:                 */
                    687:                switch (vp->v_type) {
                    688:                case VDIR:
                    689:                        return EISDIR;
                    690:                case VCHR:
                    691:                case VBLK:
                    692:                case VFIFO:
                    693:                        break;
                    694:                case VREG:
                    695:                         return EROFS;
                    696:                default:
                    697:                        return EOPNOTSUPP;
                    698:                }
                    699:        }
                    700:
                    701:        return 0;
                    702: }
                    703:
                    704: int
1.2       dillo     705: hfs_vop_bmap(void *v)
1.1       dillo     706: {
                    707:        struct vop_bmap_args /* {
                    708:                struct vnode *a_vp;
                    709:                daddr_t  a_bn;
                    710:                struct vnode **a_vpp;
                    711:                daddr_t *a_bnp;
                    712:                int *a_runp;
                    713:        } */ *ap = v;
                    714:        struct vnode *vp;
1.2       dillo     715:        struct hfsnode *hp;
1.1       dillo     716:        daddr_t lblkno;
1.2       dillo     717:        hfs_callback_args cbargs;
                    718:        hfs_libcb_argsread argsread;
                    719:        hfs_extent_descriptor_t *extents;
1.1       dillo     720:        uint16_t numextents, i;
                    721:        int bshift;
                    722:
                    723:        vp = ap->a_vp;
                    724:        hp = VTOH(vp);
                    725:        lblkno = ap->a_bn;
                    726:        bshift = vp->v_mount->mnt_fs_bshift;
                    727:
                    728:        /*
                    729:         * Check for underlying vnode requests and ensure that logical
                    730:         * to physical mapping is requested.
                    731:         */
                    732:        if (ap->a_vpp != NULL)
                    733:                *ap->a_vpp = hp->h_devvp;
                    734:        if (ap->a_bnp == NULL)
                    735:                return (0);
                    736:
1.2       dillo     737:        hfslib_init_cbargs(&cbargs);
1.1       dillo     738:        argsread.cred = NULL;
                    739:        argsread.l = NULL;
                    740:        cbargs.read = &argsread;
                    741:
1.2       dillo     742:        numextents = hfslib_get_file_extents(&hp->h_hmp->hm_vol,
1.1       dillo     743:            hp->h_rec.cnid, hp->h_fork, &extents, &cbargs);
                    744:
                    745:        /* XXX: is this correct for 0-length files? */
                    746:        if (numextents == 0)
                    747:                return EBADF;
                    748:
                    749:        for (i=0; i<numextents; i++) {
                    750:                if (lblkno < extents[i].block_count)
                    751:                        break;
                    752:                lblkno -= extents[i].block_count;
                    753:        }
                    754:
                    755:        if (i == numextents) {
                    756:                /* XXX: block number past EOF */
                    757:                i--;
                    758:                lblkno += extents[i].block_count;
                    759:        }
                    760:
                    761:        *ap->a_bnp = ((extents[i].start_block + lblkno)
1.3       dillo     762:                      << (bshift-DEV_BSHIFT))
                    763:            + (hp->h_hmp->hm_vol.offset >> DEV_BSHIFT);
1.1       dillo     764:
                    765:        if (ap->a_runp) {
                    766:                int nblk;
                    767:
                    768:                nblk = extents[i].block_count - lblkno - 1;
                    769:                if (nblk <= 0)
                    770:                        *ap->a_runp = 0;
                    771:                else if (nblk > MAXBSIZE >> bshift)
                    772:                        *ap->a_runp = (MAXBSIZE >> bshift) - 1;
                    773:                else
                    774:                        *ap->a_runp = nblk;
                    775:
                    776:        }
                    777:
1.2       dillo     778:        free(extents, /*M_HFSMNT*/ M_TEMP);
1.1       dillo     779:
                    780:        return 0;
                    781: }
                    782:
                    783: int
1.2       dillo     784: hfs_vop_read(void *v)
1.1       dillo     785: {
                    786:        struct vop_read_args /* {
                    787:                struct vnode *a_vp;
                    788:                struct uio *a_uio;
                    789:                int a_ioflag;
                    790:                kauth_cred_t a_cred;
                    791:        } */ *ap = v;
                    792:        struct vnode *vp;
1.2       dillo     793:        struct hfsnode *hp;
1.1       dillo     794:        struct uio *uio;
                    795:        uint64_t fsize; /* logical size of file */
                    796:        int advice;
                    797:         int error;
                    798:
                    799:        vp = ap->a_vp;
                    800:        hp = VTOH(vp);
                    801:        uio = ap->a_uio;
1.2       dillo     802:        if (hp->h_fork == HFS_RSRCFORK)
1.1       dillo     803:                fsize = hp->h_rec.file.rsrc_fork.logical_size;
                    804:        else
                    805:                fsize = hp->h_rec.file.data_fork.logical_size;
                    806:        error = 0;
                    807:        advice = IO_ADV_DECODE(ap->a_ioflag);
                    808:
                    809:         if (uio->uio_offset < 0)
                    810:                 return EINVAL;
                    811:
                    812:         if (uio->uio_resid == 0 || uio->uio_offset >= fsize)
                    813:                 return 0;
                    814:
                    815:         if (vp->v_type != VREG && vp->v_type != VLNK)
                    816:                return EINVAL;
                    817:
                    818:        error = 0;
                    819:        while (uio->uio_resid > 0 && error == 0) {
                    820:                int flags;
                    821:                vsize_t len;
                    822:                void *win;
                    823:
                    824:                len = MIN(uio->uio_resid, fsize - uio->uio_offset);
                    825:                if (len == 0)
                    826:                        break;
                    827:
                    828:                win = ubc_alloc(&vp->v_uobj, uio->uio_offset, &len,
                    829:                                advice, UBC_READ);
                    830:                error = uiomove(win, len, uio);
                    831:                flags = UBC_WANT_UNMAP(vp) ? UBC_UNMAP : 0;
                    832:                ubc_release(win, flags);
                    833:        }
                    834:
                    835:         return error;
                    836: }
                    837:
                    838: int
1.2       dillo     839: hfs_vop_readdir(void *v)
1.1       dillo     840: {
                    841: struct vop_readdir_args /* {
                    842:                struct vnode *a_vp;
                    843:                struct uio *a_uio;
                    844:                kauth_cred_t a_cred;
                    845:                int *a_eofflag;
                    846:                off_t **a_cookies;
                    847:                int a_*ncookies;
                    848:        } */ *ap = v;
                    849:
1.2       dillo     850: #ifdef HFS_DEBUG
                    851:        printf("VOP = hfs_vop_readdir()\n");
                    852: #endif /* HFS_DEBUG */
1.1       dillo     853:
                    854:        struct dirent curent; /* the dirent entry we're currently constructing */
1.2       dillo     855:        struct hfsnode *hp;
                    856:        hfs_catalog_keyed_record_t *children;
                    857:        hfs_unistr255_t *childnames;
                    858:        hfs_callback_args cbargs;
                    859:        hfs_libcb_argsread argsread;
1.1       dillo     860:        struct uio *uio;
                    861:        off_t bufoff; /* current position in buffer relative to start of dirents */
                    862:        uint32_t numchildren;
                    863:        uint32_t curchild; /* index of child we're currently stuffing into dirent */
                    864:        size_t namlen;
                    865:        int error;
                    866:        int i; /* dummy variable */
                    867:
                    868:        bufoff = 0;
                    869:        children = NULL;
                    870:        error = 0;
                    871:        numchildren = 0;
                    872:        hp = VTOH(ap->a_vp);
                    873:        uio = ap->a_uio;
                    874:
                    875:        if (uio->uio_offset < 0)
                    876:                return EINVAL;
                    877:        if (ap->a_eofflag != NULL)
                    878:                *ap->a_eofflag = 0;
                    879:
                    880: /* XXX Inform that we don't support NFS, for now. */
                    881: /*     if(ap->a_eofflag != NULL || ap->a_cookies != NULL || ap->a_ncookies != NULL)
                    882:                return EOPNOTSUPP;*/
                    883: /*printf("READDIR uio: offset=%i, resid=%i\n",
                    884: (int)uio->uio_offset, (int)uio->uio_resid);*/
1.2       dillo     885:        hfslib_init_cbargs(&cbargs);
1.1       dillo     886:        argsread.cred = ap->a_cred;
                    887:        argsread.l = NULL;
                    888:        cbargs.read = &argsread;
                    889:
                    890:        /* XXX Should we cache this? */
1.2       dillo     891:        if (hfslib_get_directory_contents(&hp->h_hmp->hm_vol, hp->h_rec.cnid,
1.1       dillo     892:                &children, &childnames, &numchildren, &cbargs) != 0) {
                    893: /*printf("NOENT\n");*/
                    894:                error = ENOENT;
                    895:                goto error;
                    896:        }
                    897:
                    898: /*printf("numchildren = %i\n", numchildren);*/
                    899:        for (curchild = 0; curchild < numchildren && uio->uio_resid>0; curchild++) {
                    900:                namlen = utf16_to_utf8(curent.d_name, MAXNAMLEN,
                    901:                                       childnames[curchild].unicode,
                    902:                                       childnames[curchild].length,
                    903:                                       0, NULL);
                    904:                /* XXX: check conversion errors? */
                    905:                if (namlen > MAXNAMLEN) {
                    906:                        /* XXX: how to handle name too long? */
                    907:                        continue;
                    908:                }
                    909:                curent.d_namlen = namlen;
                    910:                curent.d_reclen = _DIRENT_SIZE(&curent);
                    911:
                    912:                /* Skip to desired dirent. */
                    913:                if ((bufoff += curent.d_reclen) - curent.d_reclen < uio->uio_offset)
                    914:                        continue;
                    915:
                    916:                /* Make sure we don't return partial entries. */
                    917:                if (uio->uio_resid < curent.d_reclen) {
                    918: /*printf("PARTIAL ENTRY\n");*/
                    919:                        if (ap->a_eofflag != NULL)
                    920:                                *ap->a_eofflag = 1;
                    921:                        break;
                    922:                }
                    923:
                    924:                curent.d_fileno = children[curchild].file.cnid;
1.2       dillo     925:                switch (hfs_catalog_keyed_record_vtype(children+curchild)) {
1.1       dillo     926:                case VREG:
                    927:                        curent.d_type = DT_REG;
                    928:                        break;
                    929:                case VDIR:
                    930:                        curent.d_type = DT_DIR;
                    931:                        break;
                    932:                case VBLK:
                    933:                        curent.d_type = DT_BLK;
                    934:                        break;
                    935:                case VCHR:
                    936:                        curent.d_type = DT_CHR;
                    937:                        break;
                    938:                case VLNK:
                    939:                        curent.d_type = DT_LNK;
                    940:                        break;
                    941:                case VSOCK:
                    942:                        curent.d_type = DT_SOCK;
                    943:                        break;
                    944:                case VFIFO:
                    945:                        curent.d_type = DT_FIFO;
                    946:                        break;
                    947:                default:
                    948:                        curent.d_type = DT_UNKNOWN;
                    949:                        break;
                    950:                }
                    951: /*printf("curchildname = %s\t\t", curchildname);*/
                    952:                /* pad curent.d_name to aligned byte boundary */
                    953:                 for (i=curent.d_namlen;
                    954:                      i<curent.d_reclen-_DIRENT_NAMEOFF(&curent); i++)
                    955:                         curent.d_name[i] = 0;
                    956:
                    957: /*printf("curent.d_name = %s\n", curent.d_name);*/
                    958:
                    959:                if ((error = uiomove(&curent, curent.d_reclen, uio)) != 0)
                    960:                        goto error;
                    961:        }
                    962:
                    963:
                    964:        /* FALLTHROUGH */
                    965:
                    966: error:
                    967:        if (numchildren > 0) {
                    968:                if (children != NULL)
                    969:                        free(children, M_TEMP);
                    970:                if (childnames != NULL)
                    971:                        free(childnames, M_TEMP);
                    972:        }
                    973:
                    974: /*if (error)
                    975: printf("ERROR = %i\n", error);*/
                    976:        return error;
                    977: }
                    978:
                    979: int
1.2       dillo     980: hfs_vop_readlink(void *v) {
1.1       dillo     981:        struct vop_readlink_args /* {
                    982:                struct vnode *a_vp;
                    983:                struct uio *a_uio;
                    984:                kauth_cred_t a_cred;
                    985:        } */ *ap = v;
                    986:
                    987:        return VOP_READ(ap->a_vp, ap->a_uio, 0, ap->a_cred);
                    988: }
                    989:
                    990: int
1.2       dillo     991: hfs_vop_reclaim(void *v)
1.1       dillo     992: {
                    993:        struct vop_reclaim_args /* {
                    994:                struct vnode *a_vp;
                    995:        } */ *ap = v;
                    996:        struct vnode *vp;
1.2       dillo     997:        struct hfsnode *hp;
                    998:        struct hfsmount *hmp;
1.1       dillo     999:
1.2       dillo    1000: #ifdef HFS_DEBUG
                   1001:        printf("VOP = hfs_vop_reclaim()\n");
                   1002: #endif /* HFS_DEBUG */
1.1       dillo    1003:
                   1004:        vp = ap->a_vp;
                   1005:        hp = VTOH(vp);
                   1006:        hmp = hp->h_hmp;
                   1007:
1.2       dillo    1008:        /* Remove the hfsnode from its hash chain. */
                   1009:        hfs_nhashremove(hp);
1.1       dillo    1010:
                   1011:        /* Purge name lookup cache. */
                   1012:        cache_purge(vp);
                   1013:
                   1014:        /* Decrement the reference count to the volume's device. */
                   1015:        if (hp->h_devvp) {
                   1016:                vrele(hp->h_devvp);
                   1017:                hp->h_devvp = 0;
                   1018:        }
                   1019:
                   1020:        genfs_node_destroy(vp);
                   1021:        FREE(vp->v_data, M_TEMP);
                   1022:        vp->v_data = 0;
                   1023:
                   1024:        return 0;
                   1025: }
                   1026:
                   1027: int
1.2       dillo    1028: hfs_vop_print(void *v)
1.1       dillo    1029: {
                   1030:        struct vop_print_args /* {
                   1031:                struct vnode    *a_vp;
                   1032:        } */ *ap = v;
                   1033:        struct vnode    *vp;
1.2       dillo    1034:        struct hfsnode  *hp;
1.1       dillo    1035:
1.2       dillo    1036: #ifdef HFS_DEBUG
                   1037:        printf("VOP = hfs_vop_print()\n");
                   1038: #endif /* HFS_DEBUG */
1.1       dillo    1039:
                   1040:        vp = ap->a_vp;
                   1041:        hp = VTOH(vp);
                   1042:
                   1043:        printf("dummy = %X\n", (unsigned)hp->dummy);
                   1044:        printf("\n");
                   1045:
                   1046:        return 0;
                   1047: }

CVSweb <webmaster@jp.NetBSD.org>