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

Annotation of src/sys/fs/sysvbfs/sysvbfs_vnops.c, Revision 1.3.6.7

1.3.6.7 ! yamt        1: /*     $NetBSD: sysvbfs_vnops.c,v 1.3.6.6 2007/12/07 17:32:10 yamt Exp $       */
1.3.6.2   yamt        2:
                      3: /*-
                      4:  * Copyright (c) 2004 The NetBSD Foundation, Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by UCHIYAMA Yasushi.
                      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:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *        This product includes software developed by the NetBSD
                     21:  *        Foundation, Inc. and its contributors.
                     22:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     23:  *    contributors may be used to endorse or promote products derived
                     24:  *    from this software without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     27:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     28:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     29:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     30:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     31:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     32:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     33:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     34:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     35:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     36:  * POSSIBILITY OF SUCH DAMAGE.
                     37:  */
                     38:
                     39: #include <sys/cdefs.h>
1.3.6.7 ! yamt       40: __KERNEL_RCSID(0, "$NetBSD: sysvbfs_vnops.c,v 1.3.6.6 2007/12/07 17:32:10 yamt Exp $");
1.3.6.2   yamt       41:
                     42: #include <sys/param.h>
                     43: #include <sys/kernel.h>
                     44: #include <sys/resource.h>
                     45: #include <sys/vnode.h>
                     46: #include <sys/namei.h>
                     47: #include <sys/dirent.h>
                     48: #include <sys/malloc.h>
                     49: #include <sys/lockf.h>
                     50: #include <sys/unistd.h>
                     51: #include <sys/fcntl.h>
                     52: #include <sys/kauth.h>
                     53:
                     54: #include <fs/sysvbfs/sysvbfs.h>
                     55: #include <fs/sysvbfs/bfs.h>
                     56:
                     57: #ifdef SYSVBFS_VNOPS_DEBUG
                     58: #define        DPRINTF(fmt, args...)   printf(fmt, ##args)
                     59: #else
                     60: #define        DPRINTF(arg...)         ((void)0)
                     61: #endif
                     62: #define        ROUND_SECTOR(x)         (((x) + 511) & ~511)
                     63:
1.3.6.5   yamt       64: MALLOC_JUSTDEFINE(M_SYSVBFS_VNODE, "sysvbfs vnode", "sysvbfs vnode structures");
1.3.6.6   yamt       65: MALLOC_DECLARE(M_BFS);
1.3.6.2   yamt       66:
                     67: int
                     68: sysvbfs_lookup(void *arg)
                     69: {
                     70:        struct vop_lookup_args /* {
                     71:                struct vnode *a_dvp;
                     72:                struct vnode **a_vpp;
                     73:                struct componentname *a_cnp;
                     74:        } */ *a = arg;
                     75:        struct vnode *v = a->a_dvp;
                     76:        struct sysvbfs_node *bnode = v->v_data;
                     77:        struct bfs *bfs = bnode->bmp->bfs;      /* my filesystem */
                     78:        struct vnode *vpp = NULL;
                     79:        struct bfs_dirent *dirent = NULL;
                     80:        struct componentname *cnp = a->a_cnp;
                     81:        int nameiop = cnp->cn_nameiop;
                     82:        const char *name = cnp->cn_nameptr;
                     83:        int namelen = cnp->cn_namelen;
                     84:        int error;
1.3.6.4   yamt       85:        bool islastcn = cnp->cn_flags & ISLASTCN;
1.3.6.2   yamt       86:
                     87:        DPRINTF("%s: %s op=%d %ld\n", __FUNCTION__, name, nameiop,
                     88:            cnp->cn_flags);
                     89:
1.3.6.3   yamt       90:        KASSERT((cnp->cn_flags & ISDOTDOT) == 0);
1.3.6.7 ! yamt       91:        if ((error = VOP_ACCESS(a->a_dvp, VEXEC, cnp->cn_cred)) != 0) {
1.3.6.2   yamt       92:                return error;   /* directory permittion. */
                     93:        }
                     94:
                     95:
                     96:        if (namelen == 1 && name[0] == '.') {   /* "." */
                     97:                VREF(v);
                     98:                *a->a_vpp = v;
                     99:        } else {                                /* Regular file */
                    100:                if (!bfs_dirent_lookup_by_name(bfs, cnp->cn_nameptr,
                    101:                    &dirent)) {
                    102:                        if (nameiop != CREATE && nameiop != RENAME) {
                    103:                                DPRINTF("%s: no such a file. (1)\n",
                    104:                                    __FUNCTION__);
                    105:                                return ENOENT;
                    106:                        }
1.3.6.7 ! yamt      107:                        if ((error = VOP_ACCESS(v, VWRITE, cnp->cn_cred)) != 0)
1.3.6.2   yamt      108:                                return error;
                    109:                        cnp->cn_flags |= SAVENAME;
                    110:                        return EJUSTRETURN;
                    111:                }
                    112:
                    113:                /* Allocate v-node */
1.3.6.3   yamt      114:                if ((error = sysvbfs_vget(v->v_mount, dirent->inode, &vpp)) != 0) {
1.3.6.2   yamt      115:                        DPRINTF("%s: can't get vnode.\n", __FUNCTION__);
                    116:                        return error;
                    117:                }
                    118:                *a->a_vpp = vpp;
                    119:        }
                    120:
                    121:        if (cnp->cn_nameiop != LOOKUP && islastcn)
                    122:                cnp->cn_flags |= SAVENAME;
                    123:
                    124:        return 0;
                    125: }
                    126:
                    127: int
                    128: sysvbfs_create(void *arg)
                    129: {
                    130:        struct vop_create_args /* {
                    131:                struct vnode *a_dvp;
                    132:                struct vnode **a_vpp;
                    133:                struct componentname *a_cnp;
                    134:                struct vattr *a_vap;
                    135:        } */ *a = arg;
                    136:        struct sysvbfs_node *bnode = a->a_dvp->v_data;
                    137:        struct sysvbfs_mount *bmp = bnode->bmp;
                    138:        struct bfs *bfs = bmp->bfs;
                    139:        struct mount *mp = bmp->mountp;
                    140:        struct bfs_dirent *dirent;
                    141:        struct bfs_fileattr attr;
                    142:        struct vattr *va = a->a_vap;
                    143:        kauth_cred_t cr = a->a_cnp->cn_cred;
                    144:        int err = 0;
                    145:
                    146:        DPRINTF("%s: %s\n", __FUNCTION__, a->a_cnp->cn_nameptr);
                    147:        KDASSERT(a->a_vap->va_type == VREG);
                    148:        attr.uid = kauth_cred_geteuid(cr);
                    149:        attr.gid = kauth_cred_getegid(cr);
                    150:        attr.mode = va->va_mode;
                    151:
                    152:        if ((err = bfs_file_create(bfs, a->a_cnp->cn_nameptr, 0, 0, &attr))
                    153:            != 0) {
                    154:                DPRINTF("%s: bfs_file_create failed.\n", __FUNCTION__);
                    155:                goto unlock_exit;
                    156:        }
                    157:
                    158:        if (!bfs_dirent_lookup_by_name(bfs, a->a_cnp->cn_nameptr, &dirent))
                    159:                panic("no dirent for created file.");
                    160:
                    161:        if ((err = sysvbfs_vget(mp, dirent->inode, a->a_vpp)) != 0) {
                    162:                DPRINTF("%s: sysvbfs_vget failed.\n", __FUNCTION__);
                    163:                goto unlock_exit;
                    164:        }
                    165:        bnode = (*a->a_vpp)->v_data;
1.3.6.4   yamt      166:        bnode->update_ctime = true;
                    167:        bnode->update_mtime = true;
                    168:        bnode->update_atime = true;
1.3.6.2   yamt      169:
                    170:  unlock_exit:
                    171:        /* unlock parent directory */
                    172:        vput(a->a_dvp); /* locked at sysvbfs_lookup(); */
                    173:
                    174:        return err;
                    175: }
                    176:
                    177: int
                    178: sysvbfs_open(void *arg)
                    179: {
                    180:        struct vop_open_args /* {
                    181:                struct vnode *a_vp;
                    182:                int  a_mode;
                    183:                kauth_cred_t a_cred;
                    184:        } */ *a = arg;
                    185:        struct vnode *v = a->a_vp;
                    186:        struct sysvbfs_node *bnode = v->v_data;
                    187:        struct bfs_inode *inode = bnode->inode;
                    188:        struct bfs *bfs = bnode->bmp->bfs;
                    189:        struct bfs_dirent *dirent;
                    190:
                    191:        DPRINTF("%s:\n", __FUNCTION__);
                    192:        KDASSERT(v->v_type == VREG || v->v_type == VDIR);
                    193:
                    194:        if (!bfs_dirent_lookup_by_inode(bfs, inode->number, &dirent))
                    195:                return ENOENT;
1.3.6.4   yamt      196:        bnode->update_atime = true;
1.3.6.2   yamt      197:        if ((a->a_mode & FWRITE) && !(a->a_mode & O_APPEND)) {
                    198:                bnode->size = 0;
                    199:        } else {
                    200:                bnode->size = bfs_file_size(inode);
                    201:        }
                    202:        bnode->data_block = inode->start_sector;
                    203:
                    204:        return 0;
                    205: }
                    206:
                    207: int
                    208: sysvbfs_close(void *arg)
                    209: {
                    210:        struct vop_close_args /* {
                    211:                struct vnodeop_desc *a_desc;
                    212:                struct vnode *a_vp;
                    213:                int  a_fflag;
                    214:                kauth_cred_t a_cred;
                    215:        } */ *a = arg;
                    216:        struct vnode *v = a->a_vp;
                    217:        struct sysvbfs_node *bnode = v->v_data;
                    218:        struct bfs_fileattr attr;
                    219:
                    220:        DPRINTF("%s:\n", __FUNCTION__);
                    221:        uvm_vnp_setsize(v, bnode->size);
                    222:
                    223:        memset(&attr, 0xff, sizeof attr);       /* Set VNOVAL all */
                    224:        if (bnode->update_atime)
1.3.6.3   yamt      225:                attr.atime = time_second;
1.3.6.2   yamt      226:        if (bnode->update_ctime)
1.3.6.3   yamt      227:                attr.ctime = time_second;
1.3.6.2   yamt      228:        if (bnode->update_mtime)
1.3.6.3   yamt      229:                attr.mtime = time_second;
1.3.6.2   yamt      230:        bfs_inode_set_attr(bnode->bmp->bfs, bnode->inode, &attr);
                    231:
1.3.6.7 ! yamt      232:        VOP_FSYNC(a->a_vp, a->a_cred, FSYNC_WAIT, 0, 0);
1.3.6.2   yamt      233:
                    234:        return 0;
                    235: }
                    236:
                    237: int
                    238: sysvbfs_access(void *arg)
                    239: {
                    240:        struct vop_access_args /* {
                    241:                struct vnode    *a_vp;
                    242:                int             a_mode;
                    243:                kauth_cred_t    a_cred;
                    244:        } */ *ap = arg;
                    245:        struct vnode *vp = ap->a_vp;
                    246:        struct sysvbfs_node *bnode = vp->v_data;
                    247:        struct bfs_fileattr *attr = &bnode->inode->attr;
                    248:
                    249:        DPRINTF("%s:\n", __FUNCTION__);
                    250:        if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY))
                    251:                return EROFS;
                    252:
                    253:        return vaccess(vp->v_type, attr->mode, attr->uid, attr->gid,
                    254:            ap->a_mode, ap->a_cred);
                    255: }
                    256:
                    257: int
                    258: sysvbfs_getattr(void *v)
                    259: {
                    260:        struct vop_getattr_args /* {
                    261:                struct vnode *a_vp;
                    262:                struct vattr *a_vap;
                    263:                kauth_cred_t a_cred;
                    264:        } */ *ap = v;
                    265:        struct vnode *vp = ap->a_vp;
                    266:        struct sysvbfs_node *bnode = vp->v_data;
                    267:        struct bfs_inode *inode = bnode->inode;
                    268:        struct bfs_fileattr *attr = &inode->attr;
                    269:        struct sysvbfs_mount *bmp = bnode->bmp;
                    270:        struct vattr *vap = ap->a_vap;
                    271:
                    272:        DPRINTF("%s:\n", __FUNCTION__);
                    273:
                    274:        vap->va_type = vp->v_type;
                    275:        vap->va_mode = attr->mode;
                    276:        vap->va_nlink = attr->nlink;
                    277:        vap->va_uid = attr->uid;
                    278:        vap->va_gid = attr->gid;
                    279:        vap->va_fsid = bmp->devvp->v_rdev;
                    280:        vap->va_fileid = inode->number;
                    281:        vap->va_size = bfs_file_size(inode);
                    282:        vap->va_blocksize = BFS_BSIZE;
                    283:        vap->va_atime.tv_sec = attr->atime;
                    284:        vap->va_mtime.tv_sec = attr->mtime;
                    285:        vap->va_ctime.tv_sec = attr->ctime;
                    286:        vap->va_birthtime.tv_sec = 0;
                    287:        vap->va_gen = 1;
                    288:        vap->va_flags = 0;
                    289:        vap->va_rdev = 0;       /* No device file */
                    290:        vap->va_bytes = vap->va_size;
                    291:        vap->va_filerev = 0;
                    292:        vap->va_vaflags = 0;
                    293:
                    294:        return 0;
                    295: }
                    296:
                    297: int
                    298: sysvbfs_setattr(void *arg)
                    299: {
                    300:        struct vop_setattr_args /* {
                    301:                struct vnode *a_vp;
                    302:                struct vattr *a_vap;
                    303:                kauth_cred_t a_cred;
                    304:                struct proc *p;
                    305:        } */ *ap = arg;
                    306:        struct vnode *vp = ap->a_vp;
                    307:        struct vattr *vap = ap->a_vap;
                    308:        struct sysvbfs_node *bnode = vp->v_data;
                    309:        struct bfs_inode *inode = bnode->inode;
                    310:        struct bfs_fileattr *attr = &inode->attr;
                    311:        struct bfs *bfs = bnode->bmp->bfs;
                    312:
                    313:        DPRINTF("%s:\n", __FUNCTION__);
                    314:        if (vp->v_mount->mnt_flag & MNT_RDONLY)
                    315:                return EROFS;
                    316:
                    317:        if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
                    318:            (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
                    319:            (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
                    320:            ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL))
                    321:                return EINVAL;
                    322:
                    323:        if (vap->va_uid != (uid_t)VNOVAL)
                    324:                attr->uid = vap->va_uid;
                    325:        if (vap->va_gid != (uid_t)VNOVAL)
                    326:                attr->gid = vap->va_gid;
                    327:        if (vap->va_mode != (mode_t)VNOVAL)
                    328:                attr->mode = vap->va_mode;
                    329:        if (vap->va_atime.tv_sec != VNOVAL)
                    330:                attr->atime = vap->va_atime.tv_sec;
                    331:        if (vap->va_mtime.tv_sec != VNOVAL)
                    332:                attr->mtime = vap->va_mtime.tv_sec;
                    333:        if (vap->va_ctime.tv_sec != VNOVAL)
                    334:                attr->ctime = vap->va_ctime.tv_sec;
                    335:
                    336:        bfs_inode_set_attr(bfs, inode, attr);
                    337:
                    338:        return 0;
                    339: }
                    340:
                    341: int
                    342: sysvbfs_read(void *arg)
                    343: {
                    344:        struct vop_read_args /* {
                    345:                struct vnode *a_vp;
                    346:                struct uio *a_uio;
                    347:                int a_ioflag;
                    348:                kauth_cred_t a_cred;
                    349:        } */ *a = arg;
                    350:        struct vnode *v = a->a_vp;
                    351:        struct uio *uio = a->a_uio;
                    352:        struct sysvbfs_node *bnode = v->v_data;
                    353:        struct bfs_inode *inode = bnode->inode;
                    354:        vsize_t sz, filesz = bfs_file_size(inode);
                    355:        int err;
                    356:        void *win;
                    357:        const int advice = IO_ADV_DECODE(a->a_ioflag);
                    358:
                    359:        DPRINTF("%s: type=%d\n", __FUNCTION__, v->v_type);
                    360:        if (v->v_type != VREG)
                    361:                return EINVAL;
                    362:
                    363:        while (uio->uio_resid > 0) {
                    364:                if ((sz = MIN(filesz - uio->uio_offset, uio->uio_resid)) == 0)
                    365:                        break;
                    366:
                    367:                win = ubc_alloc(&v->v_uobj, uio->uio_offset, &sz, advice,
                    368:                    UBC_READ);
                    369:                err = uiomove(win, sz, uio);
                    370:                ubc_release(win, 0);
                    371:                if (err)
                    372:                        break;
                    373:                DPRINTF("%s: read %ldbyte\n", __FUNCTION__, sz);
                    374:        }
                    375:
                    376:        return  sysvbfs_update(v, NULL, NULL, UPDATE_WAIT);
                    377: }
                    378:
                    379: int
                    380: sysvbfs_write(void *arg)
                    381: {
                    382:        struct vop_write_args /* {
                    383:                struct vnode *a_vp;
                    384:                struct uio *a_uio;
                    385:                int  a_ioflag;
                    386:                kauth_cred_t a_cred;
                    387:        } */ *a = arg;
                    388:        struct vnode *v = a->a_vp;
                    389:        struct uio *uio = a->a_uio;
                    390:        struct sysvbfs_node *bnode = v->v_data;
                    391:        struct bfs_inode *inode = bnode->inode;
1.3.6.4   yamt      392:        bool extended = false;
1.3.6.2   yamt      393:        vsize_t sz;
                    394:        void *win;
                    395:        int err = 0;
                    396:
                    397:        if (a->a_vp->v_type != VREG)
                    398:                return EISDIR;
                    399:
                    400:        if (a->a_ioflag & IO_APPEND)
                    401:                uio->uio_offset = bnode->size;
                    402:
                    403:        if (uio->uio_resid == 0)
                    404:                return 0;
                    405:
                    406:        if (bnode->size < uio->uio_offset + uio->uio_resid) {
                    407:                bnode->size = uio->uio_offset + uio->uio_resid;
                    408:                uvm_vnp_setsize(v, bnode->size);
1.3.6.4   yamt      409:                extended = true;
1.3.6.2   yamt      410:        }
                    411:
                    412:        while (uio->uio_resid > 0) {
                    413:                sz = uio->uio_resid;
                    414:                win = ubc_alloc(&v->v_uobj, uio->uio_offset, &sz,
                    415:                    UVM_ADV_NORMAL, UBC_WRITE);
                    416:                err = uiomove(win, sz, uio);
                    417:                ubc_release(win, 0);
                    418:                if (err)
                    419:                        break;
                    420:                DPRINTF("%s: write %ldbyte\n", __FUNCTION__, sz);
                    421:        }
                    422:        inode->end_sector = bnode->data_block +
                    423:            (ROUND_SECTOR(bnode->size) >> DEV_BSHIFT) - 1;
                    424:        inode->eof_offset_byte = bnode->data_block * DEV_BSIZE +
                    425:            bnode->size - 1;
1.3.6.4   yamt      426:        bnode->update_mtime = true;
1.3.6.2   yamt      427:
                    428:        VN_KNOTE(v, NOTE_WRITE | (extended ? NOTE_EXTEND : 0));
                    429:
                    430:        return err;
                    431: }
                    432:
                    433: int
                    434: sysvbfs_remove(void *arg)
                    435: {
                    436:        struct vop_remove_args /* {
                    437:                struct vnodeop_desc *a_desc;
                    438:                struct vnode * a_dvp;
                    439:                struct vnode * a_vp;
                    440:                struct componentname * a_cnp;
                    441:        } */ *ap = arg;
                    442:        struct vnode *vp = ap->a_vp;
                    443:        struct vnode *dvp = ap->a_dvp;
                    444:        struct sysvbfs_node *bnode = vp->v_data;
                    445:        struct sysvbfs_mount *bmp = bnode->bmp;
                    446:        struct bfs *bfs = bmp->bfs;
                    447:        int err;
                    448:
                    449:        DPRINTF("%s: delete %s\n", __FUNCTION__, ap->a_cnp->cn_nameptr);
                    450:
                    451:        if (vp->v_type == VDIR)
                    452:                return EPERM;
                    453:
                    454:        if ((err = bfs_file_delete(bfs, ap->a_cnp->cn_nameptr)) != 0)
                    455:                DPRINTF("%s: bfs_file_delete failed.\n", __FUNCTION__);
                    456:
                    457:        VN_KNOTE(ap->a_vp, NOTE_DELETE);
                    458:        VN_KNOTE(ap->a_dvp, NOTE_WRITE);
                    459:        if (dvp == vp)
                    460:                vrele(vp);
                    461:        else
                    462:                vput(vp);
                    463:        vput(dvp);
                    464:
                    465:        return err;
                    466: }
                    467:
                    468: int
                    469: sysvbfs_rename(void *arg)
                    470: {
                    471:        struct vop_rename_args /* {
                    472:                struct vnode *a_fdvp;   from parent-directory v-node
                    473:                struct vnode *a_fvp;    from file v-node
                    474:                struct componentname *a_fcnp;
                    475:                struct vnode *a_tdvp;   to parent-directory
                    476:                struct vnode *a_tvp;    to file v-node
                    477:                struct componentname *a_tcnp;
                    478:        } */ *ap = arg;
                    479:        struct vnode *fvp = ap->a_fvp;
                    480:        struct vnode *tvp = ap->a_tvp;
                    481:        struct sysvbfs_node *bnode = fvp->v_data;
                    482:        struct bfs *bfs = bnode->bmp->bfs;
                    483:        const char *from_name = ap->a_fcnp->cn_nameptr;
                    484:        const char *to_name = ap->a_tcnp->cn_nameptr;
                    485:        int error;
                    486:
                    487:        DPRINTF("%s: %s->%s\n", __FUNCTION__, from_name, to_name);
                    488:        if ((fvp->v_mount != ap->a_tdvp->v_mount) ||
                    489:            (tvp && (fvp->v_mount != tvp->v_mount))) {
                    490:                error = EXDEV;
                    491:                printf("cross-device link\n");
                    492:                goto out;
                    493:        }
                    494:
                    495:        KDASSERT(fvp->v_type == VREG);
1.3.6.4   yamt      496:        KDASSERT(tvp == NULL ? true : tvp->v_type == VREG);
1.3.6.2   yamt      497:
                    498:        error = bfs_file_rename(bfs, from_name, to_name);
                    499:  out:
                    500:        vput(ap->a_tdvp);
1.3.6.3   yamt      501:        if (tvp)
                    502:                vput(ap->a_tvp);  /* locked on entry */
1.3.6.2   yamt      503:        if (ap->a_tdvp != ap->a_fdvp)
                    504:                vrele(ap->a_fdvp);
                    505:        vrele(ap->a_fvp); /* unlocked and refcnt is incremented on entry. */
                    506:
                    507:        return 0;
                    508: }
                    509:
                    510: int
                    511: sysvbfs_readdir(void *v)
                    512: {
                    513:        struct vop_readdir_args /* {
                    514:                struct vnode *a_vp;
                    515:                struct uio *a_uio;
                    516:                kauth_cred_t a_cred;
                    517:                int *a_eofflag;
                    518:                off_t **a_cookies;
                    519:                int *a_ncookies;
                    520:        } */ *ap = v;
                    521:        struct uio *uio = ap->a_uio;
                    522:        struct vnode *vp = ap->a_vp;
                    523:        struct sysvbfs_node *bnode = vp->v_data;
                    524:        struct bfs *bfs = bnode->bmp->bfs;
1.3.6.6   yamt      525:        struct dirent *dp;
1.3.6.2   yamt      526:        struct bfs_dirent *file;
                    527:        int i, n, error;
                    528:
                    529:        DPRINTF("%s: offset=%lld residue=%d\n", __FUNCTION__,
                    530:            uio->uio_offset, uio->uio_resid);
                    531:
                    532:        KDASSERT(vp->v_type == VDIR);
                    533:        KDASSERT(uio->uio_offset >= 0);
                    534:
1.3.6.6   yamt      535:        dp = malloc(sizeof(struct dirent), M_BFS, M_WAITOK | M_ZERO);
                    536:
1.3.6.2   yamt      537:        i = uio->uio_offset / sizeof(struct dirent);
                    538:        n = uio->uio_resid / sizeof(struct dirent);
                    539:        if ((i + n) > bfs->n_dirent)
                    540:                n = bfs->n_dirent - i;
                    541:
                    542:        for (file = &bfs->dirent[i]; i < n; file++) {
                    543:                if (file->inode == 0)
                    544:                        continue;
                    545:                if (i == bfs->max_dirent) {
                    546:                        DPRINTF("%s: file system inconsistent.\n",
                    547:                            __FUNCTION__);
                    548:                        break;
                    549:                }
                    550:                i++;
1.3.6.6   yamt      551:                memset(dp, 0, sizeof(struct dirent));
                    552:                dp->d_fileno = file->inode;
                    553:                dp->d_type = file->inode == BFS_ROOT_INODE ? DT_DIR : DT_REG;
                    554:                dp->d_namlen = strlen(file->name);
                    555:                strncpy(dp->d_name, file->name, BFS_FILENAME_MAXLEN);
                    556:                dp->d_reclen = sizeof(struct dirent);
                    557:                if ((error = uiomove(dp, dp->d_reclen, uio)) != 0) {
1.3.6.2   yamt      558:                        DPRINTF("%s: uiomove failed.\n", __FUNCTION__);
1.3.6.6   yamt      559:                        free(dp, M_BFS);
1.3.6.2   yamt      560:                        return error;
                    561:                }
                    562:        }
                    563:        DPRINTF("%s: %d %d %d\n", __FUNCTION__, i, n, bfs->n_dirent);
1.3.6.6   yamt      564:        *ap->a_eofflag = (i == bfs->n_dirent);
1.3.6.2   yamt      565:
1.3.6.6   yamt      566:        free(dp, M_BFS);
1.3.6.2   yamt      567:        return 0;
                    568: }
                    569:
                    570: int
                    571: sysvbfs_inactive(void *arg)
                    572: {
                    573:        struct vop_inactive_args /* {
                    574:                struct vnode *a_vp;
                    575:        } */ *a = arg;
                    576:        struct vnode *v = a->a_vp;
                    577:
                    578:        DPRINTF("%s:\n", __FUNCTION__);
                    579:        VOP_UNLOCK(v, 0);
1.3.6.7 ! yamt      580:        vrecycle(v, NULL, curlwp);
1.3.6.2   yamt      581:
                    582:        return 0;
                    583: }
                    584:
                    585: int
                    586: sysvbfs_reclaim(void *v)
                    587: {
                    588:        extern struct pool sysvbfs_node_pool;
                    589:        struct vop_reclaim_args /* {
                    590:                struct vnode *a_vp;
                    591:        } */ *ap = v;
                    592:        struct vnode *vp = ap->a_vp;
                    593:        struct sysvbfs_node *bnode = vp->v_data;
                    594:
                    595:        DPRINTF("%s:\n", __FUNCTION__);
                    596:        simple_lock(&mntvnode_slock);
                    597:        LIST_REMOVE(bnode, link);
                    598:        simple_unlock(&mntvnode_slock);
                    599:        cache_purge(vp);
1.3.6.4   yamt      600:        genfs_node_destroy(vp);
1.3.6.2   yamt      601:        pool_put(&sysvbfs_node_pool, bnode);
                    602:        vp->v_data = NULL;
                    603:
                    604:        return 0;
                    605: }
                    606:
                    607: int
                    608: sysvbfs_bmap(void *arg)
                    609: {
                    610:        struct vop_bmap_args /* {
                    611:                struct vnode *a_vp;
                    612:                daddr_t  a_bn;
                    613:                struct vnode **a_vpp;
                    614:                daddr_t *a_bnp;
                    615:                int *a_runp;
                    616:        } */ *a = arg;
                    617:        struct vnode *v = a->a_vp;
                    618:        struct sysvbfs_node *bnode = v->v_data;
                    619:        struct sysvbfs_mount *bmp = bnode->bmp;
                    620:        struct bfs_inode *inode = bnode->inode;
                    621:        daddr_t blk;
                    622:
                    623:        DPRINTF("%s:\n", __FUNCTION__);
1.3.6.3   yamt      624:        /* BFS algorithm is contiguous allocation */
1.3.6.2   yamt      625:        blk = inode->start_sector + a->a_bn;
                    626:
                    627:        if (blk * BFS_BSIZE > bmp->bfs->data_end)
                    628:                return ENOSPC;
                    629:
                    630:        *a->a_vpp = bmp->devvp;
                    631:        *a->a_runp = 0;
                    632:        DPRINTF("%s: %d + %lld\n", __FUNCTION__, inode->start_sector, a->a_bn);
                    633:
                    634:        *a->a_bnp = blk;
                    635:
                    636:
                    637:        return 0;
                    638: }
                    639:
                    640: int
                    641: sysvbfs_strategy(void *arg)
                    642: {
                    643:        struct vop_strategy_args /* {
                    644:                struct vnode *a_vp;
                    645:                struct buf *a_bp;
                    646:        } */ *a = arg;
                    647:        struct buf *b = a->a_bp;
                    648:        struct vnode *v = a->a_vp;
                    649:        struct sysvbfs_node *bnode = v->v_data;
                    650:        struct sysvbfs_mount *bmp = bnode->bmp;
                    651:        int error;
                    652:
                    653:        DPRINTF("%s:\n", __FUNCTION__);
                    654:        KDASSERT(v->v_type == VREG);
                    655:        if (b->b_blkno == b->b_lblkno) {
                    656:                error = VOP_BMAP(v, b->b_lblkno, NULL, &b->b_blkno, NULL);
                    657:                if (error) {
                    658:                        b->b_error = error;
                    659:                        biodone(b);
                    660:                        return error;
                    661:                }
                    662:                if ((long)b->b_blkno == -1)
                    663:                        clrbuf(b);
                    664:        }
                    665:        if ((long)b->b_blkno == -1) {
                    666:                biodone(b);
                    667:                return 0;
                    668:        }
                    669:
                    670:        return VOP_STRATEGY(bmp->devvp, b);
                    671: }
                    672:
                    673: int
                    674: sysvbfs_print(void *v)
                    675: {
                    676:        struct vop_print_args /* {
                    677:                struct vnode *a_vp;
                    678:        } */ *ap = v;
                    679:        struct sysvbfs_node *bnode = ap->a_vp->v_data;
                    680:
                    681:        DPRINTF("%s:\n", __FUNCTION__);
                    682:        bfs_dump(bnode->bmp->bfs);
                    683:
                    684:        return 0;
                    685: }
                    686:
                    687: int
                    688: sysvbfs_advlock(void *v)
                    689: {
                    690:        struct vop_advlock_args /* {
                    691:                struct vnode *a_vp;
                    692:                void *a_id;
                    693:                int a_op;
                    694:                struct flock *a_fl;
                    695:                int a_flags;
                    696:        } */ *ap = v;
                    697:        struct sysvbfs_node *bnode = ap->a_vp->v_data;
                    698:
                    699:        DPRINTF("%s: op=%d\n", __FUNCTION__, ap->a_op);
                    700:
                    701:        return lf_advlock(ap, &bnode->lockf, bfs_file_size(bnode->inode));
                    702: }
                    703:
                    704: int
                    705: sysvbfs_pathconf(void *v)
                    706: {
                    707:        struct vop_pathconf_args /* {
                    708:                struct vnode *a_vp;
                    709:                int a_name;
                    710:                register_t *a_retval;
                    711:        } */ *ap = v;
                    712:        int err = 0;
                    713:
                    714:        DPRINTF("%s:\n", __FUNCTION__);
                    715:
                    716:        switch (ap->a_name) {
                    717:        case _PC_LINK_MAX:
                    718:                *ap->a_retval = 1;
                    719:                break;;
                    720:        case _PC_NAME_MAX:
                    721:                *ap->a_retval = BFS_FILENAME_MAXLEN;
                    722:                break;;
                    723:        case _PC_PATH_MAX:
                    724:                *ap->a_retval = BFS_FILENAME_MAXLEN;
                    725:                break;;
                    726:        case _PC_CHOWN_RESTRICTED:
                    727:                *ap->a_retval = 1;
                    728:                break;;
                    729:        case _PC_NO_TRUNC:
                    730:                *ap->a_retval = 0;
                    731:                break;;
                    732:        case _PC_SYNC_IO:
                    733:                *ap->a_retval = 1;
                    734:                break;;
                    735:        case _PC_FILESIZEBITS:
                    736:                *ap->a_retval = 32;
                    737:                break;;
                    738:        default:
                    739:                err = EINVAL;
                    740:                break;
                    741:        }
                    742:
                    743:        return err;
                    744: }
                    745:
                    746: int
                    747: sysvbfs_fsync(void *v)
                    748: {
                    749:        struct vop_fsync_args /* {
                    750:                struct vnode *a_vp;
                    751:                kauth_cred_t a_cred;
                    752:                int a_flags;
                    753:                off_t offlo;
                    754:                off_t offhi;
                    755:        } */ *ap = v;
                    756:        struct vnode *vp = ap->a_vp;
                    757:        int error, wait;
                    758:
                    759:        if (ap->a_flags & FSYNC_CACHE) {
                    760:                return EOPNOTSUPP;
                    761:        }
                    762:
                    763:        wait = (ap->a_flags & FSYNC_WAIT) != 0;
                    764:        vflushbuf(vp, wait);
                    765:
                    766:        if ((ap->a_flags & FSYNC_DATAONLY) != 0)
                    767:                error = 0;
                    768:        else
                    769:                error = sysvbfs_update(vp, NULL, NULL, wait ? UPDATE_WAIT : 0);
                    770:
                    771:        return error;
                    772: }
                    773:
                    774: int
                    775: sysvbfs_update(struct vnode *vp, const struct timespec *acc,
                    776:     const struct timespec *mod, int flags)
                    777: {
                    778:        struct sysvbfs_node *bnode = vp->v_data;
                    779:        struct bfs_fileattr attr;
                    780:
                    781:        DPRINTF("%s:\n", __FUNCTION__);
                    782:        memset(&attr, 0xff, sizeof attr);       /* Set VNOVAL all */
                    783:        if (bnode->update_atime) {
1.3.6.3   yamt      784:                attr.atime = acc ? acc->tv_sec : time_second;
1.3.6.4   yamt      785:                bnode->update_atime = false;
1.3.6.2   yamt      786:        }
                    787:        if (bnode->update_ctime) {
1.3.6.3   yamt      788:                attr.ctime = time_second;
1.3.6.4   yamt      789:                bnode->update_ctime = false;
1.3.6.2   yamt      790:        }
                    791:        if (bnode->update_mtime) {
1.3.6.3   yamt      792:                attr.mtime = mod ? mod->tv_sec : time_second;
1.3.6.4   yamt      793:                bnode->update_mtime = false;
1.3.6.2   yamt      794:        }
                    795:        bfs_inode_set_attr(bnode->bmp->bfs, bnode->inode, &attr);
                    796:
                    797:        return 0;
                    798: }

CVSweb <webmaster@jp.NetBSD.org>