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

Annotation of src/sys/fs/udf/udf_vnops.c, Revision 1.10.8.2

1.10.8.2! matt        1: /* $NetBSD: udf_vnops.c,v 1.10.8.1 2007/11/06 23:31:23 matt Exp $ */
1.1       reinoud     2:
                      3: /*
                      4:  * Copyright (c) 2006 Reinoud Zandijk
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *          This product includes software developed for the
                     18:  *          NetBSD Project.  See http://www.NetBSD.org/ for
                     19:  *          information about NetBSD.
                     20:  * 4. The name of the author may not be used to endorse or promote products
                     21:  *    derived from this software without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     25:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     26:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     27:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     28:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     29:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     30:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     31:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     32:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     33:  *
                     34:  */
                     35:
                     36:
                     37: #include <sys/cdefs.h>
                     38: #ifndef lint
1.10.8.2! matt       39: __KERNEL_RCSID(0, "$NetBSD$");
1.1       reinoud    40: #endif /* not lint */
                     41:
                     42:
                     43: #include <sys/param.h>
                     44: #include <sys/systm.h>
                     45: #include <sys/namei.h>
                     46: #include <sys/resourcevar.h>   /* defines plimit structure in proc struct */
                     47: #include <sys/kernel.h>
                     48: #include <sys/file.h>          /* define FWRITE ... */
                     49: #include <sys/stat.h>
                     50: #include <sys/buf.h>
                     51: #include <sys/proc.h>
                     52: #include <sys/mount.h>
                     53: #include <sys/vnode.h>
                     54: #include <sys/signalvar.h>
                     55: #include <sys/malloc.h>
                     56: #include <sys/dirent.h>
                     57: #include <sys/lockf.h>
                     58:
                     59: #include <miscfs/genfs/genfs.h>
                     60: #include <uvm/uvm_extern.h>
                     61:
                     62: #include <fs/udf/ecma167-udf.h>
                     63: #include <fs/udf/udf_mount.h>
                     64: #include "udf.h"
                     65: #include "udf_subr.h"
                     66: #include "udf_bswap.h"
                     67:
                     68:
                     69: #define VTOI(vnode) ((struct udf_node *) vnode->v_data)
                     70:
                     71:
                     72: /* externs */
                     73: extern int prtactive;
                     74:
                     75:
                     76: /* implementations of vnode functions; table follows at end */
                     77: /* --------------------------------------------------------------------- */
                     78:
                     79: int
                     80: udf_inactive(void *v)
                     81: {
                     82:        struct vop_inactive_args /* {
                     83:                struct vnode *a_vp;
                     84:                struct proc *a_p;
                     85:        } */ *ap = v;
                     86:        struct vnode *vp = ap->a_vp;
                     87:
                     88:        if (prtactive && vp->v_usecount != 0)
                     89:                vprint("udf_inactive(): pushing active", vp);
                     90:
                     91:        VOP_UNLOCK(vp, 0);
                     92:
                     93:        DPRINTF(LOCKING, ("udf_inactive called for node %p\n", VTOI(vp)));
                     94:
                     95:        /*
                     96:         * Optionally flush metadata to disc. If the file has not been
                     97:         * referenced anymore in a directory we ought to free up the resources
                     98:         * on disc if applicable.
                     99:         */
                    100:
                    101:        return 0;
                    102: }
                    103:
                    104: /* --------------------------------------------------------------------- */
                    105:
                    106: int
                    107: udf_reclaim(void *v)
                    108: {
                    109:        struct vop_reclaim_args /* {
                    110:                struct vnode *a_vp;
                    111:        } */ *ap = v;
                    112:        struct vnode *vp = ap->a_vp;
                    113:        struct udf_node *node = VTOI(vp);
                    114:
                    115:        if (prtactive && vp->v_usecount != 0)
                    116:                vprint("udf_reclaim(): pushing active", vp);
                    117:
                    118:        /* purge old data from namei */
                    119:        cache_purge(vp);
                    120:
                    121:        DPRINTF(LOCKING, ("udf_reclaim called for node %p\n", node));
                    122:        /* dispose all node knowledge */
                    123:        udf_dispose_node(node);
                    124:
                    125:        return 0;
                    126: }
                    127:
                    128: /* --------------------------------------------------------------------- */
                    129:
                    130: int
                    131: udf_read(void *v)
                    132: {
                    133:        struct vop_read_args /* {
                    134:                struct vnode *a_vp;
                    135:                struct uio *a_uio;
                    136:                int a_ioflag;
1.5       elad      137:                kauth_cred_t a_cred;
1.1       reinoud   138:        } */ *ap = v;
                    139:        struct vnode *vp     = ap->a_vp;
                    140:        struct uio   *uio    = ap->a_uio;
                    141:        int           ioflag = ap->a_ioflag;
                    142:        struct uvm_object    *uobj;
                    143:        struct udf_node      *udf_node = VTOI(vp);
                    144:        struct file_entry    *fe;
                    145:        struct extfile_entry *efe;
                    146:        uint64_t file_size;
                    147:        vsize_t len;
                    148:        void *win;
                    149:        int error;
                    150:        int flags;
                    151:
                    152:        /* XXX how to deal with xtended attributes (files) */
                    153:
                    154:        DPRINTF(READ, ("udf_read called\n"));
                    155:
                    156:        /* can this happen? some filingsystems have this check */
                    157:        if (uio->uio_offset < 0)
                    158:                return EINVAL;
                    159:
                    160:        assert(udf_node);
                    161:        assert(udf_node->fe || udf_node->efe);
                    162:
                    163:        /* TODO set access time */
                    164:
                    165:        /* get directory filesize */
                    166:        if (udf_node->fe) {
                    167:                fe = udf_node->fe;
                    168:                file_size = udf_rw64(fe->inf_len);
                    169:        } else {
                    170:                assert(udf_node->efe);
                    171:                efe = udf_node->efe;
                    172:                file_size = udf_rw64(efe->inf_len);
1.6       christos  173:        }
1.1       reinoud   174:
                    175:        if (vp->v_type == VDIR) {
                    176:                /* protect against rogue programs reading raw directories */
                    177:                if ((ioflag & IO_ALTSEMANTICS) == 0)
                    178:                        return EISDIR;
1.6       christos  179:        }
1.1       reinoud   180:        if (vp->v_type == VREG || vp->v_type == VDIR) {
                    181:                const int advice = IO_ADV_DECODE(ap->a_ioflag);
                    182:
                    183:                /* read contents using buffercache */
                    184:                uobj = &vp->v_uobj;
                    185:                flags = UBC_WANT_UNMAP(vp) ? UBC_UNMAP : 0;
                    186:                error = 0;
                    187:                while (uio->uio_resid > 0) {
                    188:                        /* reached end? */
                    189:                        if (file_size <= uio->uio_offset)
                    190:                                break;
                    191:
                    192:                        /* maximise length to file extremity */
                    193:                        len = MIN(file_size - uio->uio_offset, uio->uio_resid);
                    194:                        if (len == 0)
                    195:                                break;
                    196:
                    197:                        /* ubc, here we come, prepare to trap */
                    198:                        win = ubc_alloc(uobj, uio->uio_offset, &len,
                    199:                                        advice, UBC_READ);
                    200:                        error = uiomove(win, len, uio);
                    201:                        ubc_release(win, flags);
                    202:                        if (error)
                    203:                                break;
                    204:                }
                    205:                /* TODO note access time */
                    206:                return error;
1.6       christos  207:        }
1.1       reinoud   208:
                    209:        return EINVAL;
                    210: }
                    211:
                    212: /* --------------------------------------------------------------------- */
                    213:
                    214: int
                    215: udf_write(void *v)
                    216: {
                    217:        struct vop_write_args /* {
                    218:                struct vnode *a_vp;
                    219:                struct uio *a_uio;
                    220:                int a_ioflag;
1.5       elad      221:                kauth_cred_t a_cred;
1.1       reinoud   222:        } */ *ap = v;
                    223:
                    224:        DPRINTF(NOTIMPL, ("udf_write called\n"));
                    225:        ap = ap;        /* shut up gcc */
                    226:
                    227:        /* TODO implement writing */
                    228:        return EROFS;
                    229: }
                    230:
                    231:
                    232: /* --------------------------------------------------------------------- */
                    233:
                    234: /*
                    235:  * `Special' bmap functionality that translates all incomming requests to
                    236:  * translate to vop_strategy() calls with the same blocknumbers effectively
                    237:  * not translating at all.
                    238:  */
                    239:
                    240: int
                    241: udf_trivial_bmap(void *v)
                    242: {
                    243:        struct vop_bmap_args /* {
                    244:                struct vnode *a_vp;
                    245:                daddr_t a_bn;
                    246:                struct vnode **a_vpp;
                    247:                daddr_t *a_bnp;
                    248:                int *a_runp;
                    249:        } */ *ap = v;
                    250:        struct vnode  *vp  = ap->a_vp;  /* our node     */
                    251:        struct vnode **vpp = ap->a_vpp; /* return node  */
                    252:        daddr_t *bnp  = ap->a_bnp;      /* translated   */
                    253:        daddr_t  bn   = ap->a_bn;       /* origional    */
                    254:        int     *runp = ap->a_runp;
                    255:        struct udf_node *udf_node = VTOI(vp);
                    256:        uint32_t lb_size;
                    257:
                    258:        /* get logical block size */
                    259:        lb_size = udf_rw32(udf_node->ump->logical_vol->lb_size);
                    260:
                    261:        /* could return `-1' to indicate holes/zeros */
                    262:        /* translate 1:1 */
                    263:        *bnp = bn;
                    264:
                    265:        /* set the vnode to read the data from with strategy on itself */
                    266:        if (vpp)
                    267:                *vpp = vp;
                    268:
                    269:        /* set runlength of maximum block size */
                    270:        if (runp)
                    271:                *runp = MAXPHYS / lb_size;      /* or with -1 ? */
                    272:
                    273:        /* return success */
                    274:        return 0;
                    275: }
                    276:
                    277: /* --------------------------------------------------------------------- */
                    278:
                    279: int
                    280: udf_strategy(void *v)
                    281: {
                    282:        struct vop_strategy_args /* {
                    283:                struct vnode *a_vp;
                    284:                struct buf *a_bp;
                    285:        } */ *ap = v;
                    286:        struct vnode *vp = ap->a_vp;
                    287:        struct buf   *bp = ap->a_bp;
                    288:        struct udf_node *udf_node = VTOI(vp);
                    289:        uint32_t lb_size, from, sectors;
                    290:        int error;
                    291:
                    292:        DPRINTF(STRATEGY, ("udf_strategy called\n"));
                    293:
                    294:        /* check if we ought to be here */
                    295:        if (vp->v_type == VBLK || vp->v_type == VCHR)
                    296:                panic("udf_strategy: spec");
                    297:
                    298:        /* only filebuffers ought to be read by this, no descriptors */
                    299:        assert(bp->b_blkno >= 0);
                    300:
                    301:        /* get sector size */
                    302:        lb_size = udf_rw32(udf_node->ump->logical_vol->lb_size);
                    303:
                    304:        /* calculate sector to start from */
                    305:        from = bp->b_blkno;
                    306:
                    307:        /* calculate length to fetch/store in sectors */
                    308:        sectors = bp->b_bcount / lb_size;
                    309:        assert(bp->b_bcount > 0);
                    310:
1.3       snj       311:        /* NEVER assume later that this buffer is already translated */
1.1       reinoud   312:        /* bp->b_lblkno = bp->b_blkno; */
                    313:
                    314:        DPRINTF(STRATEGY, ("\tread vp %p buf %p (blk no %"PRIu64")"
                    315:            ", sector %d for %d sectors\n",
                    316:            vp, bp, bp->b_blkno, from, sectors));
                    317:
1.10      msaitoh   318:        /* check assertions: we OUGHT to always get multiples of this */
1.1       reinoud   319:        assert(sectors * lb_size == bp->b_bcount);
                    320:
                    321:        /* determine mode */
                    322:        error = 0;
                    323:        if (bp->b_flags & B_READ) {
                    324:                /* read buffer from the udf_node, translate vtop on the way*/
                    325:                udf_read_filebuf(udf_node, bp);
                    326:                return bp->b_error;
1.6       christos  327:        }
1.1       reinoud   328:
                    329:        printf("udf_strategy: can't write yet\n");
                    330:        return ENOTSUP;
                    331: }
                    332:
                    333: /* --------------------------------------------------------------------- */
                    334:
                    335: int
                    336: udf_readdir(void *v)
                    337: {
                    338:        struct vop_readdir_args /* {
                    339:                struct vnode *a_vp;
                    340:                struct uio *a_uio;
1.5       elad      341:                kauth_cred_t a_cred;
1.1       reinoud   342:                int *a_eofflag;
                    343:                off_t **a_cookies;
                    344:                int *a_ncookies;
                    345:        } */ *ap = v;
                    346:        struct uio *uio = ap->a_uio;
                    347:        struct vnode *vp = ap->a_vp;
                    348:        struct udf_node *udf_node = VTOI(vp);
                    349:        struct file_entry    *fe;
                    350:        struct extfile_entry *efe;
                    351:        struct fileid_desc *fid;
1.10.8.1  matt      352:        struct dirent *dirent;
1.1       reinoud   353:        uint64_t file_size, diroffset, transoffset;
                    354:        uint32_t lb_size;
                    355:        int error;
                    356:
                    357:        DPRINTF(READDIR, ("udf_readdir called\n"));
                    358:
                    359:        /* This operation only makes sense on directory nodes. */
                    360:        if (vp->v_type != VDIR)
                    361:                return ENOTDIR;
                    362:
                    363:        /* get directory filesize */
                    364:        if (udf_node->fe) {
                    365:                fe = udf_node->fe;
                    366:                file_size = udf_rw64(fe->inf_len);
                    367:        } else {
                    368:                assert(udf_node->efe);
                    369:                efe = udf_node->efe;
                    370:                file_size = udf_rw64(efe->inf_len);
1.6       christos  371:        }
1.1       reinoud   372:
1.10.8.1  matt      373:        dirent = malloc(sizeof(struct dirent), M_UDFTEMP, M_WAITOK | M_ZERO);
                    374:
1.1       reinoud   375:        /*
                    376:         * Add `.' pseudo entry if at offset zero since its not in the fid
                    377:         * stream
                    378:         */
                    379:        if (uio->uio_offset == 0) {
                    380:                DPRINTF(READDIR, ("\t'.' inserted\n"));
1.10.8.1  matt      381:                strcpy(dirent->d_name, ".");
                    382:                dirent->d_fileno = udf_calchash(&udf_node->loc);
                    383:                dirent->d_type = DT_DIR;
                    384:                dirent->d_namlen = strlen(dirent->d_name);
                    385:                dirent->d_reclen = _DIRENT_SIZE(dirent);
                    386:                uiomove(dirent, _DIRENT_SIZE(dirent), uio);
1.1       reinoud   387:
                    388:                /* mark with magic value that we have done the dummy */
                    389:                uio->uio_offset = UDF_DIRCOOKIE_DOT;
1.6       christos  390:        }
1.1       reinoud   391:
                    392:        /* we are called just as long as we keep on pushing data in */
                    393:        error = 0;
                    394:        if ((uio->uio_offset < file_size) &&
                    395:            (uio->uio_resid >= sizeof(struct dirent))) {
                    396:                /* allocate temporary space for fid */
                    397:                lb_size = udf_rw32(udf_node->ump->logical_vol->lb_size);
1.10.8.1  matt      398:                fid = malloc(lb_size, M_UDFTEMP, M_WAITOK);
1.1       reinoud   399:
                    400:                if (uio->uio_offset == UDF_DIRCOOKIE_DOT)
                    401:                        uio->uio_offset = 0;
                    402:
                    403:                diroffset   = uio->uio_offset;
                    404:                transoffset = diroffset;
                    405:                while (diroffset < file_size) {
                    406:                        DPRINTF(READDIR, ("\tread in fid stream\n"));
                    407:                        /* transfer a new fid/dirent */
                    408:                        error = udf_read_fid_stream(vp, &diroffset,
1.10.8.1  matt      409:                                    fid, dirent);
1.1       reinoud   410:                        DPRINTFIF(READDIR, error, ("read error in read fid "
                    411:                            "stream : %d\n", error));
                    412:                        if (error)
                    413:                                break;
                    414:
                    415:                        /*
                    416:                         * If there isn't enough space in the uio to return a
                    417:                         * whole dirent, break off read
                    418:                         */
1.10.8.1  matt      419:                        if (uio->uio_resid < _DIRENT_SIZE(dirent))
1.1       reinoud   420:                                break;
                    421:
                    422:                        /* remember the last entry we transfered */
                    423:                        transoffset = diroffset;
                    424:
                    425:                        /* skip deleted entries */
                    426:                        if (fid->file_char & UDF_FILE_CHAR_DEL)
                    427:                                continue;
                    428:
                    429:                        /* skip not visible files */
                    430:                        if (fid->file_char & UDF_FILE_CHAR_VIS)
                    431:                                continue;
                    432:
                    433:                        /* copy dirent to the caller */
                    434:                        DPRINTF(READDIR, ("\tread dirent `%s', type %d\n",
1.10.8.1  matt      435:                            dirent->d_name, dirent->d_type));
                    436:                        uiomove(dirent, _DIRENT_SIZE(dirent), uio);
1.6       christos  437:                }
1.1       reinoud   438:
                    439:                /* pass on last transfered offset */
                    440:                uio->uio_offset = transoffset;
1.10.8.1  matt      441:                free(fid, M_UDFTEMP);
1.6       christos  442:        }
1.1       reinoud   443:
                    444:        if (ap->a_eofflag)
                    445:                *ap->a_eofflag = (uio->uio_offset == file_size);
                    446:
                    447: #ifdef DEBUG
                    448:        if (udf_verbose & UDF_DEBUG_READDIR) {
                    449:                printf("returning offset %d\n", (uint32_t) uio->uio_offset);
                    450:                if (ap->a_eofflag)
                    451:                        printf("returning EOF ? %d\n", *ap->a_eofflag);
                    452:                if (error)
                    453:                        printf("readdir returning error %d\n", error);
1.6       christos  454:        }
1.1       reinoud   455: #endif
                    456:
1.10.8.1  matt      457:        free(dirent, M_UDFTEMP);
1.1       reinoud   458:        return error;
                    459: }
                    460:
                    461: /* --------------------------------------------------------------------- */
                    462:
                    463: int
                    464: udf_lookup(void *v)
                    465: {
                    466:        struct vop_lookup_args /* {
                    467:                struct vnode *a_dvp;
                    468:                struct vnode **a_vpp;
                    469:                struct componentname *a_cnp;
                    470:        } */ *ap = v;
                    471:        struct vnode *dvp = ap->a_dvp;
                    472:        struct vnode **vpp = ap->a_vpp;
                    473:        struct componentname *cnp = ap->a_cnp;
                    474:        struct udf_node  *dir_node, *res_node;
                    475:        struct udf_mount *ump;
                    476:        struct long_ad    icb_loc;
                    477:        const char *name;
1.8       chs       478:        int namelen, nameiop, islastcn, mounted_ro;
1.1       reinoud   479:        int vnodetp;
                    480:        int error, found;
                    481:
                    482:        dir_node = VTOI(dvp);
                    483:        ump = dir_node->ump;
                    484:        *vpp = NULL;
                    485:
                    486:        DPRINTF(LOOKUP, ("udf_lookup called\n"));
                    487:
                    488:        /* simplify/clarification flags */
                    489:        nameiop     = cnp->cn_nameiop;
                    490:        islastcn    = cnp->cn_flags & ISLASTCN;
                    491:        mounted_ro  = dvp->v_mount->mnt_flag & MNT_RDONLY;
                    492:
                    493:        /* check exec/dirread permissions first */
1.10.8.2! matt      494:        error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred);
1.1       reinoud   495:        if (error)
                    496:                return error;
                    497:
                    498:        DPRINTF(LOOKUP, ("\taccess ok\n"));
                    499:
                    500:        /*
                    501:         * If requesting a modify on the last path element on a read-only
                    502:         * filingsystem, reject lookup; XXX why is this repeated in every FS ?
                    503:         */
                    504:        if (islastcn && mounted_ro && (nameiop == DELETE || nameiop == RENAME))
                    505:                return EROFS;
                    506:
                    507:        DPRINTF(LOOKUP, ("\tlooking up cnp->cn_nameptr '%s'\n",
                    508:            cnp->cn_nameptr));
                    509:        /* look in the nami cache; returns 0 on success!! */
                    510:        error = cache_lookup(dvp, vpp, cnp);
                    511:        if (error >= 0)
                    512:                return error;
                    513:
                    514:        DPRINTF(LOOKUP, ("\tNOT found in cache\n"));
                    515:
                    516:        /*
                    517:         * Obviously, the file is not (anymore) in the namecache, we have to
                    518:         * search for it. There are three basic cases: '.', '..' and others.
                    519:         *
                    520:         * Following the guidelines of VOP_LOOKUP manpage and tmpfs.
                    521:         */
                    522:        error = 0;
                    523:        if ((cnp->cn_namelen == 1) && (cnp->cn_nameptr[0] == '.')) {
                    524:                DPRINTF(LOOKUP, ("\tlookup '.'\n"));
                    525:                /* special case 1 '.' */
                    526:                VREF(dvp);
                    527:                *vpp = dvp;
                    528:                /* done */
                    529:        } else if (cnp->cn_flags & ISDOTDOT) {
                    530:                /* special case 2 '..' */
                    531:                DPRINTF(LOOKUP, ("\tlookup '..'\n"));
                    532:
                    533:                /* first unlock parent */
                    534:                VOP_UNLOCK(dvp, 0);
                    535:
                    536:                /* get our node */
                    537:                name    = "..";
                    538:                namelen = 2;
                    539:                found = udf_lookup_name_in_dir(dvp, name, namelen, &icb_loc);
                    540:                if (!found)
                    541:                        error = ENOENT;
                    542:
                    543:                if (!error) {
                    544:                        DPRINTF(LOOKUP, ("\tfound '..'\n"));
                    545:                        /* try to create/reuse the node */
                    546:                        error = udf_get_node(ump, &icb_loc, &res_node);
                    547:
                    548:                        if (!error) {
                    549:                        DPRINTF(LOOKUP, ("\tnode retrieved/created OK\n"));
                    550:                                *vpp = res_node->vnode;
1.6       christos  551:                        }
                    552:                }
1.1       reinoud   553:
1.8       chs       554:                /* try to relock parent */
                    555:                vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
1.1       reinoud   556:        } else {
                    557:                DPRINTF(LOOKUP, ("\tlookup file\n"));
                    558:                /* all other files */
                    559:                /* lookup filename in the directory; location icb_loc */
                    560:                name    = cnp->cn_nameptr;
                    561:                namelen = cnp->cn_namelen;
                    562:                found = udf_lookup_name_in_dir(dvp, name, namelen, &icb_loc);
                    563:                if (!found) {
                    564:                        DPRINTF(LOOKUP, ("\tNOT found\n"));
                    565:                        /*
                    566:                         * UGH, didn't find name. If we're creating or naming
                    567:                         * on the last name this is OK and we ought to return
                    568:                         * EJUSTRETURN if its allowed to be created.
                    569:                         */
                    570:                        error = ENOENT;
                    571:                        if (islastcn &&
                    572:                                (nameiop == CREATE || nameiop == RENAME))
                    573:                                        error = 0;
                    574:                        if (!error) {
1.10.8.2! matt      575:                                error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred);
1.1       reinoud   576:                                if (!error) {
                    577:                                        /* keep the component name */
                    578:                                        cnp->cn_flags |= SAVENAME;
                    579:                                        error = EJUSTRETURN;
1.6       christos  580:                                }
                    581:                        }
1.1       reinoud   582:                        /* done */
                    583:                } else {
                    584:                        /* try to create/reuse the node */
                    585:                        error = udf_get_node(ump, &icb_loc, &res_node);
                    586:                        if (!error) {
                    587:                                /*
                    588:                                 * If we are not at the last path component
                    589:                                 * and found a non-directory or non-link entry
                    590:                                 * (which may itself be pointing to a
                    591:                                 * directory), raise an error.
                    592:                                 */
                    593:                                vnodetp = res_node->vnode->v_type;
                    594:                                if ((vnodetp != VDIR) && (vnodetp != VLNK)) {
                    595:                                        if (!islastcn)
                    596:                                                error = ENOTDIR;
                    597:                                }
                    598:
1.6       christos  599:                        }
1.1       reinoud   600:                        if (!error) {
                    601:                                *vpp = res_node->vnode;
1.6       christos  602:                        }
                    603:                }
1.1       reinoud   604:        }
                    605:
                    606:        /*
                    607:         * Store result in the cache if requested. If we are creating a file,
                    608:         * the file might not be found and thus putting it into the namecache
                    609:         * might be seen as negative caching.
                    610:         */
                    611:        if (cnp->cn_flags & MAKEENTRY)
                    612:                cache_enter(dvp, *vpp, cnp);
                    613:
                    614:        DPRINTFIF(LOOKUP, error, ("udf_lookup returing error %d\n", error));
                    615:
                    616:        return error;
                    617: }
                    618:
                    619: /* --------------------------------------------------------------------- */
                    620:
                    621: int
                    622: udf_getattr(void *v)
                    623: {
                    624:        struct vop_getattr_args /* {
                    625:                struct vnode *a_vp;
                    626:                struct vattr *a_vap;
1.5       elad      627:                kauth_cred_t a_cred;
1.1       reinoud   628:                struct proc *a_p;
                    629:        } */ *ap = v;
                    630:        struct vnode *vp = ap->a_vp;
                    631:        struct udf_node *udf_node = VTOI(vp);
                    632:        struct udf_mount *ump = udf_node->ump;
                    633:        struct vattr *vap = ap->a_vap;
                    634:        struct file_entry *fe;
                    635:        struct extfile_entry *efe;
                    636:        struct timestamp *atime, *mtime, *attrtime;
                    637:        uint32_t nlink;
                    638:        uint64_t filesize, blkssize;
                    639:        uid_t uid;
                    640:        gid_t gid;
                    641:
                    642:        DPRINTF(CALL, ("udf_getattr called\n"));
                    643:
                    644:        /* get descriptor information */
                    645:        if (udf_node->fe) {
                    646:                fe = udf_node->fe;
                    647:                nlink    = udf_rw16(fe->link_cnt);
                    648:                uid      = (uid_t)udf_rw32(fe->uid);
                    649:                gid      = (gid_t)udf_rw32(fe->gid);
                    650:                filesize = udf_rw64(fe->inf_len);
                    651:                blkssize = udf_rw64(fe->logblks_rec);
                    652:                atime    = &fe->atime;
                    653:                mtime    = &fe->mtime;
                    654:                attrtime = &fe->attrtime;
                    655:        } else {
                    656:                assert(udf_node->efe);
                    657:                efe = udf_node->efe;
                    658:                nlink    = udf_rw16(efe->link_cnt);
                    659:                uid      = (uid_t)udf_rw32(efe->uid);
                    660:                gid      = (gid_t)udf_rw32(efe->gid);
                    661:                filesize = udf_rw64(efe->inf_len);      /* XXX or obj_size? */
                    662:                blkssize = udf_rw64(efe->logblks_rec);
                    663:                atime    = &efe->atime;
                    664:                mtime    = &efe->mtime;
                    665:                attrtime = &efe->attrtime;
1.6       christos  666:        }
1.1       reinoud   667:
                    668:        /* do the uid/gid translation game */
                    669:        if ((uid == (uid_t) -1) && (gid == (gid_t) -1)) {
                    670:                uid = ump->mount_args.anon_uid;
                    671:                gid = ump->mount_args.anon_gid;
1.6       christos  672:        }
1.1       reinoud   673:
                    674:        /* fill in struct vattr with values from the node */
                    675:        VATTR_NULL(vap);
                    676:        vap->va_type      = vp->v_type;
                    677:        vap->va_mode      = udf_getaccessmode(udf_node);
                    678:        vap->va_nlink     = nlink;
                    679:        vap->va_uid       = uid;
                    680:        vap->va_gid       = gid;
                    681:        vap->va_fsid      = vp->v_mount->mnt_stat.f_fsidx.__fsid_val[0];
                    682:        vap->va_fileid    = udf_calchash(&udf_node->loc);   /* inode hash XXX */
                    683:        vap->va_size      = filesize;
                    684:        vap->va_blocksize = udf_node->ump->discinfo.sector_size;  /* wise? */
                    685:
                    686:        /*
                    687:         * BUG-ALERT: UDF doesn't count '.' as an entry, so we'll have to add
                    688:         * 1 to the link count if its a directory we're requested attributes
                    689:         * of.
                    690:         */
                    691:        if (vap->va_type == VDIR)
                    692:                vap->va_nlink++;
                    693:
                    694:        /* access times */
                    695:        udf_timestamp_to_timespec(ump, atime,    &vap->va_atime);
                    696:        udf_timestamp_to_timespec(ump, mtime,    &vap->va_mtime);
                    697:        udf_timestamp_to_timespec(ump, attrtime, &vap->va_ctime);
                    698:
                    699:        vap->va_gen       = 1;          /* no multiple generations yes (!?) */
                    700:        vap->va_flags     = 0;          /* no flags */
                    701:        vap->va_rdev      = udf_node->rdev;
1.9       reinoud   702:        vap->va_bytes     = blkssize * udf_node->ump->discinfo.sector_size;
1.1       reinoud   703:        vap->va_filerev   = 1;          /* TODO file revision numbers? */
                    704:        vap->va_vaflags   = 0;          /* TODO which va_vaflags? */
                    705:
                    706:        return 0;
                    707: }
                    708:
                    709: /* --------------------------------------------------------------------- */
                    710:
                    711: int
                    712: udf_setattr(void *v)
                    713: {
                    714:        struct vop_setattr_args /* {
                    715:                struct vnode *a_vp;
                    716:                struct vattr *a_vap;
1.5       elad      717:                kauth_cred_t a_cred;
1.1       reinoud   718:                struct proc *a_p;
                    719:        } */ *ap = v;
                    720:        struct vnode *vp = ap->a_vp;
                    721:        struct udf_node  *udf_node = VTOI(vp);
                    722:        struct udf_mount *ump = udf_node->ump;
                    723:        struct vattr *vap = ap->a_vap;
                    724:        uid_t uid, nobody_uid;
                    725:        gid_t gid, nobody_gid;
                    726:
                    727:        /* shut up gcc for now */
                    728:        ap = ap;
                    729:        vp = vp;
1.4       mrg       730:        uid = 0;        /* XXX gcc */
                    731:        gid = 0;        /* XXX gcc */
1.1       reinoud   732:        udf_node = udf_node;
                    733:
                    734:        DPRINTF(NOTIMPL, ("udf_setattr called\n"));
                    735:
                    736:        /*
                    737:         * BUG-ALERT: UDF doesn't count '.' as an entry, so we'll have to
                    738:         * subtract 1 to the link count if its a directory we're setting
                    739:         * attributes on. See getattr.
                    740:         */
                    741:        if (vap->va_type == VDIR)
                    742:                vap->va_nlink--;
                    743:
                    744:        /* do the uid/gid translation game */
                    745:        nobody_uid = ump->mount_args.nobody_uid;
                    746:        nobody_gid = ump->mount_args.nobody_gid;
                    747:        if ((uid == nobody_uid) && (gid == nobody_gid)) {
                    748:                uid = (uid_t) -1;
                    749:                gid = (gid_t) -1;
1.6       christos  750:        }
1.1       reinoud   751:
                    752:        /* TODO implement setattr!! NOT IMPLEMENTED yet */
                    753:        return 0;
                    754: }
                    755:
                    756: /* --------------------------------------------------------------------- */
                    757:
                    758: /*
                    759:  * Return POSIX pathconf information for UDF file systems.
                    760:  */
                    761: int
                    762: udf_pathconf(void *v)
                    763: {
                    764:        struct vop_pathconf_args /* {
                    765:                struct vnode *a_vp;
                    766:                int a_name;
                    767:                register_t *a_retval;
                    768:        } */ *ap = v;
                    769:        struct vnode *vp = ap->a_vp;
                    770:        struct udf_node *udf_node = VTOI(vp);
                    771:        uint32_t bits;
                    772:
                    773:        DPRINTF(CALL, ("udf_pathconf called\n"));
                    774:
                    775:        switch (ap->a_name) {
                    776:        case _PC_LINK_MAX:
                    777:                *ap->a_retval = (1<<16)-1;      /* 16 bits */
                    778:                return 0;
                    779:        case _PC_NAME_MAX:
                    780:                *ap->a_retval = NAME_MAX;
                    781:                return 0;
                    782:        case _PC_PATH_MAX:
                    783:                *ap->a_retval = PATH_MAX;
                    784:                return 0;
                    785:        case _PC_PIPE_BUF:
                    786:                *ap->a_retval = PIPE_BUF;
                    787:                return 0;
                    788:        case _PC_CHOWN_RESTRICTED:
                    789:                *ap->a_retval = 1;
                    790:                return 0;
                    791:        case _PC_NO_TRUNC:
                    792:                *ap->a_retval = 1;
                    793:                return 0;
                    794:        case _PC_SYNC_IO:
                    795:                *ap->a_retval = 0;     /* synchronised is off for performance */
                    796:                return 0;
                    797:        case _PC_FILESIZEBITS:
                    798:                bits = 32;
                    799:                if (udf_node)
                    800:                        bits = 32 * vp->v_mount->mnt_dev_bshift;
                    801:                *ap->a_retval = bits;
                    802:                return 0;
1.6       christos  803:        }
1.1       reinoud   804:
                    805:        return EINVAL;
                    806: }
                    807:
                    808:
                    809: /* --------------------------------------------------------------------- */
                    810:
                    811: int
                    812: udf_open(void *v)
                    813: {
                    814:        struct vop_open_args /* {
                    815:                struct vnode *a_vp;
                    816:                int a_mode;
1.5       elad      817:                kauth_cred_t a_cred;
1.1       reinoud   818:                struct proc *a_p;
1.7       christos  819:        } */ *ap = v;
1.1       reinoud   820:
                    821:        DPRINTF(CALL, ("udf_open called\n"));
1.4       mrg       822:        ap = 0;         /* XXX gcc */
1.1       reinoud   823:
                    824:        return 0;
                    825: }
                    826:
                    827:
                    828: /* --------------------------------------------------------------------- */
                    829:
                    830: int
                    831: udf_close(void *v)
                    832: {
                    833:        struct vop_close_args /* {
                    834:                struct vnode *a_vp;
                    835:                int a_fflag;
1.5       elad      836:                kauth_cred_t a_cred;
1.1       reinoud   837:                struct proc *a_p;
                    838:        } */ *ap = v;
                    839:        struct vnode *vp = ap->a_vp;
                    840:        struct udf_node *udf_node = VTOI(vp);
                    841:
                    842:        DPRINTF(CALL, ("udf_close called\n"));
                    843:        udf_node = udf_node;    /* shut up gcc */
                    844:
1.10.8.2! matt      845:        mutex_enter(&vp->v_interlock);
1.1       reinoud   846:                if (vp->v_usecount > 1) {
                    847:                        /* TODO update times */
1.6       christos  848:                }
1.10.8.2! matt      849:        mutex_exit(&vp->v_interlock);
1.1       reinoud   850:
                    851:        return 0;
                    852: }
                    853:
                    854:
                    855: /* --------------------------------------------------------------------- */
                    856:
                    857: int
                    858: udf_access(void *v)
                    859: {
                    860:        struct vop_access_args /* {
                    861:                struct vnode *a_vp;
                    862:                int a_mode;
1.5       elad      863:                kauth_cred_t a_cred;
1.1       reinoud   864:                struct proc *a_p;
                    865:        } */ *ap = v;
                    866:        struct vnode    *vp   = ap->a_vp;
                    867:        mode_t           mode = ap->a_mode;
1.5       elad      868:        kauth_cred_t    cred = ap->a_cred;
1.1       reinoud   869:        struct udf_node *udf_node = VTOI(vp);
                    870:        struct file_entry    *fe;
                    871:        struct extfile_entry *efe;
                    872:        mode_t   node_mode;
                    873:        uid_t uid;
                    874:        gid_t gid;
                    875:
                    876:        DPRINTF(CALL, ("udf_access called\n"));
                    877:
                    878:        /* get access mode to compare to */
                    879:        node_mode = udf_getaccessmode(udf_node);
                    880:
                    881:        /* get uid/gid pair */
                    882:        if (udf_node->fe) {
                    883:                fe = udf_node->fe;
                    884:                uid = (uid_t)udf_rw32(fe->uid);
                    885:                gid = (gid_t)udf_rw32(fe->gid);
                    886:        } else {
                    887:                assert(udf_node->efe);
                    888:                efe = udf_node->efe;
                    889:                uid = (uid_t)udf_rw32(efe->uid);
                    890:                gid = (gid_t)udf_rw32(efe->gid);
1.6       christos  891:        }
1.1       reinoud   892:
                    893:        /* check if we are allowed to write */
                    894:        switch (vp->v_type) {
                    895:        case VDIR:
                    896:        case VLNK:
                    897:        case VREG:
                    898:                /*
                    899:                 * normal nodes: check if we're on a read-only mounted
                    900:                 * filingsystem and bomb out if we're trying to write.
                    901:                 */
                    902:                if ((mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY))
                    903:                        return EROFS;
                    904:                break;
                    905:        case VBLK:
                    906:        case VCHR:
                    907:        case VSOCK:
                    908:        case VFIFO:
                    909:                /*
                    910:                 * special nodes: even on read-only mounted filingsystems
                    911:                 * these are allowed to be written to if permissions allow.
                    912:                 */
                    913:                break;
                    914:        default:
                    915:                /* no idea what this is */
                    916:                return EINVAL;
                    917:        }
                    918:
                    919:        /* TODO support for chflags checking i.e. IMMUTABLE flag */
                    920:
                    921:        /* ask the generic vaccess to advice on security */
                    922:        return vaccess(vp->v_type, node_mode, uid, gid, mode, cred);
                    923: }
                    924:
                    925: /* --------------------------------------------------------------------- */
                    926:
                    927: int
                    928: udf_create(void *v)
                    929: {
                    930:        struct vop_create_args /* {
                    931:                struct vnode *a_dvp;
                    932:                struct vnode **a_vpp;
                    933:                struct componentname *a_cnp;
                    934:                struct vattr *a_vap;
                    935:        } */ *ap = v;
                    936:        struct componentname *cnp = ap->a_cnp;
                    937:
                    938:        DPRINTF(NOTIMPL, ("udf_create called\n"));
                    939:
                    940:        /* error out */
                    941:        PNBUF_PUT(cnp->cn_pnbuf);
                    942:        vput(ap->a_dvp);
                    943:        return ENOTSUP;
                    944: }
                    945:
                    946: /* --------------------------------------------------------------------- */
                    947:
                    948: int
                    949: udf_mknod(void *v)
                    950: {
                    951:        struct vop_mknod_args /* {
                    952:                struct vnode *a_dvp;
                    953:                struct vnode **a_vpp;
                    954:                struct componentname *a_cnp;
                    955:                struct vattr *a_vap;
                    956:        } */ *ap = v;
                    957:
                    958:        DPRINTF(NOTIMPL, ("udf_mknod called\n"));
                    959:
                    960:        /* error out */
                    961:        PNBUF_PUT(ap->a_cnp->cn_pnbuf);
                    962:        vput(ap->a_dvp);
                    963:        return ENOTSUP;
                    964: }
                    965:
                    966: /* --------------------------------------------------------------------- */
                    967:
                    968: int
                    969: udf_remove(void *v)
                    970: {
                    971:        struct vop_remove_args /* {
                    972:                struct vnode *a_dvp;
                    973:                struct vnode *a_vp;
                    974:                struct componentname *a_cnp;
                    975:        } */ *ap = v;
                    976:        struct vnode *dvp = ap->a_dvp;
                    977:        struct vnode *vp  = ap->a_vp;
                    978:
                    979:        DPRINTF(NOTIMPL, ("udf_remove called\n"));
                    980:
                    981:        /* error out */
                    982:        vput(dvp);
                    983:        vput(vp);
                    984:
                    985:        return ENOTSUP;
                    986: }
                    987:
                    988: /* --------------------------------------------------------------------- */
                    989:
                    990: int
                    991: udf_link(void *v)
                    992: {
                    993:        struct vop_link_args /* {
                    994:                struct vnode *a_dvp;
                    995:                struct vnode *a_vp;
                    996:                struct componentname *a_cnp;
                    997:        } */ *ap = v;
                    998:        struct vnode *dvp = ap->a_dvp;
                    999:        struct vnode *vp  = ap->a_vp;
                   1000:        struct componentname *cnp = ap->a_cnp;
                   1001:
                   1002:        DPRINTF(NOTIMPL, ("udf_link called\n"));
                   1003:
                   1004:        /* error out */
                   1005:        /* XXX or just VOP_ABORTOP(dvp, a_cnp); ? */
1.10.8.1  matt     1006:        if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE)
1.1       reinoud  1007:                VOP_UNLOCK(vp, 0);
                   1008:        PNBUF_PUT(cnp->cn_pnbuf);
                   1009:        vput(dvp);
                   1010:
                   1011:        return ENOTSUP;
                   1012: }
                   1013:
                   1014: /* --------------------------------------------------------------------- */
                   1015:
                   1016: int
                   1017: udf_symlink(void *v)
                   1018: {
                   1019:        struct vop_symlink_args /* {
                   1020:                struct vnode *a_dvp;
                   1021:                struct vnode **a_vpp;
                   1022:                struct componentname *a_cnp;
                   1023:                struct vattr *a_vap;
                   1024:                char *a_target;
                   1025:        } */ *ap = v;
                   1026:        struct vnode *dvp = ap->a_dvp;
                   1027:        struct componentname *cnp = ap->a_cnp;
                   1028:
                   1029:        DPRINTF(NOTIMPL, ("udf_symlink called\n"));
                   1030:
                   1031:        /* error out */
                   1032:        VOP_ABORTOP(dvp, cnp);
                   1033:        vput(dvp);
                   1034:
                   1035:        return ENOTSUP;
                   1036: }
                   1037:
                   1038: /* --------------------------------------------------------------------- */
                   1039:
                   1040: int
                   1041: udf_readlink(void *v)
                   1042: {
                   1043:        struct vop_readlink_args /* {
                   1044:                struct vnode *a_vp;
                   1045:                struct uio *a_uio;
1.5       elad     1046:                kauth_cred_t a_cred;
1.1       reinoud  1047:        } */ *ap = v;
                   1048: #ifdef notyet
                   1049:        struct vnode *vp = ap->a_vp;
                   1050:        struct uio *uio = ap->a_uio;
1.5       elad     1051:        kauth_cred_t cred = ap->a_cred;
1.1       reinoud  1052: #endif
                   1053:
                   1054:        ap = ap;        /* shut up gcc */
                   1055:
                   1056:        DPRINTF(NOTIMPL, ("udf_readlink called\n"));
                   1057:
                   1058:        /* TODO read `file' contents and process pathcomponents into a path */
                   1059:        return ENOTSUP;
                   1060: }
                   1061:
                   1062: /* --------------------------------------------------------------------- */
                   1063:
                   1064: int
                   1065: udf_rename(void *v)
                   1066: {
                   1067:        struct vop_rename_args /* {
                   1068:                struct vnode *a_fdvp;
                   1069:                struct vnode *a_fvp;
                   1070:                struct componentname *a_fcnp;
                   1071:                struct vnode *a_tdvp;
                   1072:                struct vnode *a_tvp;
                   1073:                struct componentname *a_tcnp;
                   1074:        } */ *ap = v;
                   1075:        struct vnode *tvp = ap->a_tvp;
                   1076:        struct vnode *tdvp = ap->a_tdvp;
                   1077:        struct vnode *fvp = ap->a_fvp;
                   1078:        struct vnode *fdvp = ap->a_fdvp;
                   1079:
                   1080:        DPRINTF(NOTIMPL, ("udf_rename called\n"));
                   1081:
                   1082:        /* error out */
                   1083:        if (tdvp == tvp)
                   1084:                vrele(tdvp);
                   1085:        else
                   1086:                vput(tdvp);
                   1087:        if (tvp != NULL)
                   1088:                vput(tvp);
                   1089:
                   1090:        /* release source nodes. */
                   1091:        vrele(fdvp);
                   1092:        vrele(fvp);
                   1093:
                   1094:        return ENOTSUP;
                   1095: }
                   1096:
                   1097: /* --------------------------------------------------------------------- */
                   1098:
                   1099: int
                   1100: udf_mkdir(void *v)
                   1101: {
                   1102:        struct vop_mkdir_args /* {
                   1103:                struct vnode *a_dvp;
                   1104:                struct vnode **a_vpp;
                   1105:                struct componentname *a_cnp;
                   1106:                struct vattr *a_vap;
                   1107:        } */ *ap = v;
                   1108:        struct vnode *dvp = ap->a_dvp;
                   1109:        struct componentname *cnp = ap->a_cnp;
                   1110:
                   1111:        DPRINTF(NOTIMPL, ("udf_mkdir called\n"));
                   1112:
                   1113:        /* error out */
                   1114:        PNBUF_PUT(cnp->cn_pnbuf);
                   1115:        vput(dvp);
                   1116:
                   1117:        return ENOTSUP;
                   1118: }
                   1119:
                   1120: /* --------------------------------------------------------------------- */
                   1121:
                   1122: int
                   1123: udf_rmdir(void *v)
                   1124: {
                   1125:        struct vop_rmdir_args /* {
                   1126:                struct vnode *a_dvp;
                   1127:                struct vnode *a_vp;
                   1128:                struct componentname *a_cnp;
                   1129:        } */ *ap = v;
                   1130:        struct vnode *vp = ap->a_vp;
                   1131:        struct vnode *dvp = ap->a_dvp;
                   1132:        struct componentname *cnp = ap->a_cnp;
                   1133:        int error;
                   1134:
                   1135:        cnp = cnp;      /* shut up gcc */
                   1136:
                   1137:        DPRINTF(NOTIMPL, ("udf_rmdir called\n"));
                   1138:
                   1139:        error = ENOTSUP;
                   1140:        /* error out */
                   1141:        if (error != 0) {
                   1142:                vput(dvp);
                   1143:                vput(vp);
                   1144:        }
                   1145:
                   1146:        return error;
                   1147: }
                   1148:
                   1149: /* --------------------------------------------------------------------- */
                   1150:
                   1151: int
                   1152: udf_fsync(void *v)
                   1153: {
                   1154:        struct vop_fsync_args /* {
                   1155:                struct vnode *a_vp;
1.5       elad     1156:                kauth_cred_t a_cred;
1.1       reinoud  1157:                int a_flags;
                   1158:                off_t offlo;
                   1159:                off_t offhi;
                   1160:                struct proc *a_p;
                   1161:        } */ *ap = v;
                   1162:        struct vnode *vp = ap->a_vp;
                   1163:
                   1164:        DPRINTF(NOTIMPL, ("udf_fsync called\n"));
                   1165:
                   1166:        vp = vp;        /* shut up gcc */
                   1167:
                   1168:        return 0;
                   1169: }
                   1170:
                   1171: /* --------------------------------------------------------------------- */
                   1172:
                   1173: int
                   1174: udf_advlock(void *v)
                   1175: {
                   1176:        struct vop_advlock_args /* {
                   1177:                struct vnode *a_vp;
                   1178:                void *a_id;
                   1179:                int a_op;
                   1180:                struct flock *a_fl;
                   1181:                int a_flags;
                   1182:        } */ *ap = v;
                   1183:        struct vnode *vp = ap->a_vp;
                   1184:        struct udf_node *udf_node = VTOI(vp);
                   1185:        struct file_entry    *fe;
                   1186:        struct extfile_entry *efe;
                   1187:        uint64_t file_size;
                   1188:
                   1189:        DPRINTF(LOCKING, ("udf_advlock called\n"));
                   1190:
                   1191:        /* get directory filesize */
                   1192:        if (udf_node->fe) {
                   1193:                fe = udf_node->fe;
                   1194:                file_size = udf_rw64(fe->inf_len);
                   1195:        } else {
                   1196:                assert(udf_node->efe);
                   1197:                efe = udf_node->efe;
                   1198:                file_size = udf_rw64(efe->inf_len);
1.6       christos 1199:        }
1.1       reinoud  1200:
                   1201:        return lf_advlock(ap, &udf_node->lockf, file_size);
                   1202: }
                   1203:
                   1204: /* --------------------------------------------------------------------- */
                   1205:
                   1206:
                   1207: /* Global vfs vnode data structures for udfs */
                   1208: int (**udf_vnodeop_p) __P((void *));
                   1209:
                   1210: const struct vnodeopv_entry_desc udf_vnodeop_entries[] = {
                   1211:        { &vop_default_desc, vn_default_error },
                   1212:        { &vop_lookup_desc, udf_lookup },       /* lookup */
                   1213:        { &vop_create_desc, udf_create },       /* create */    /* TODO */
                   1214:        { &vop_mknod_desc, udf_mknod },         /* mknod */     /* TODO */
                   1215:        { &vop_open_desc, udf_open },           /* open */
                   1216:        { &vop_close_desc, udf_close },         /* close */
                   1217:        { &vop_access_desc, udf_access },       /* access */
                   1218:        { &vop_getattr_desc, udf_getattr },     /* getattr */
                   1219:        { &vop_setattr_desc, udf_setattr },     /* setattr */   /* TODO */
                   1220:        { &vop_read_desc, udf_read },           /* read */
                   1221:        { &vop_write_desc, udf_write },         /* write */     /* WRITE */
                   1222:        { &vop_lease_desc, genfs_lease_check }, /* lease */     /* TODO? */
                   1223:        { &vop_fcntl_desc, genfs_fcntl },       /* fcntl */     /* TODO? */
                   1224:        { &vop_ioctl_desc, genfs_enoioctl },    /* ioctl */     /* TODO? */
                   1225:        { &vop_poll_desc, genfs_poll },         /* poll */      /* TODO/OK? */
                   1226:        { &vop_kqfilter_desc, genfs_kqfilter }, /* kqfilter */  /* ? */
                   1227:        { &vop_revoke_desc, genfs_revoke },     /* revoke */    /* TODO? */
                   1228:        { &vop_mmap_desc, genfs_mmap },         /* mmap */      /* OK? */
                   1229:        { &vop_fsync_desc, udf_fsync },         /* fsync */     /* TODO */
                   1230:        { &vop_seek_desc, genfs_seek },         /* seek */
                   1231:        { &vop_remove_desc, udf_remove },       /* remove */    /* TODO */
                   1232:        { &vop_link_desc, udf_link },           /* link */      /* TODO */
                   1233:        { &vop_rename_desc, udf_rename },       /* rename */    /* TODO */
                   1234:        { &vop_mkdir_desc, udf_mkdir },         /* mkdir */     /* TODO */
                   1235:        { &vop_rmdir_desc, udf_rmdir },         /* rmdir */     /* TODO */
                   1236:        { &vop_symlink_desc, udf_symlink },     /* symlink */   /* TODO */
                   1237:        { &vop_readdir_desc, udf_readdir },     /* readdir */
                   1238:        { &vop_readlink_desc, udf_readlink },   /* readlink */  /* TEST ME */
                   1239:        { &vop_abortop_desc, genfs_abortop },   /* abortop */   /* TODO/OK? */
                   1240:        { &vop_inactive_desc, udf_inactive },   /* inactive */
                   1241:        { &vop_reclaim_desc, udf_reclaim },     /* reclaim */
                   1242:        { &vop_lock_desc, genfs_lock },         /* lock */
                   1243:        { &vop_unlock_desc, genfs_unlock },     /* unlock */
                   1244:        { &vop_bmap_desc, udf_trivial_bmap },   /* bmap */      /* 1:1 bmap */
                   1245:        { &vop_strategy_desc, udf_strategy },   /* strategy */
                   1246: /*     { &vop_print_desc, udf_print }, */      /* print */
                   1247:        { &vop_islocked_desc, genfs_islocked }, /* islocked */
                   1248:        { &vop_pathconf_desc, udf_pathconf },   /* pathconf */
                   1249:        { &vop_advlock_desc, udf_advlock },     /* advlock */   /* TEST ME */
                   1250:        { &vop_bwrite_desc, vn_bwrite },        /* bwrite */    /* ->strategy */
                   1251:        { &vop_getpages_desc, genfs_getpages }, /* getpages */
                   1252:        { &vop_putpages_desc, genfs_putpages }, /* putpages */
                   1253:        { NULL, NULL }
                   1254: };
                   1255:
                   1256:
                   1257: const struct vnodeopv_desc udf_vnodeop_opv_desc = {
                   1258:        &udf_vnodeop_p, udf_vnodeop_entries
                   1259: };
                   1260:

CVSweb <webmaster@jp.NetBSD.org>