[BACK]Return to vfs_syscalls.c CVS log [TXT][DIR] Up to [local] / prex-old / usr / server / fs / vfs

Annotation of prex-old/usr/server/fs/vfs/vfs_syscalls.c, Revision 1.1.1.1.2.1

1.1       nbrk        1: /*
                      2:  * Copyright (c) 2005-2007, Kohsuke Ohtani
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  * 3. Neither the name of the author nor the names of any co-contributors
                     14:  *    may be used to endorse or promote products derived from this software
                     15:  *    without specific prior written permission.
                     16:  *
                     17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     18:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     19:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     20:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     21:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     22:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     23:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     24:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     25:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     26:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     27:  * SUCH DAMAGE.
                     28:  */
                     29:
                     30: /*
1.1.1.1.2.1! nbrk       31:  * vfs_syscalls.c - everything in this file is a routine implementing
        !            32:  *                  a VFS system call.
1.1       nbrk       33:  */
                     34:
                     35: #include <prex/prex.h>
                     36: #include <sys/stat.h>
                     37: #include <sys/vnode.h>
                     38: #include <sys/file.h>
                     39: #include <sys/mount.h>
                     40: #include <sys/dirent.h>
                     41: #include <sys/list.h>
                     42: #include <sys/buf.h>
                     43:
                     44: #include <limits.h>
                     45: #include <unistd.h>
                     46: #include <stdlib.h>
                     47: #include <string.h>
                     48: #include <stdio.h>
                     49: #include <errno.h>
                     50: #include <fcntl.h>
                     51:
                     52: #include "vfs.h"
                     53:
                     54: int
1.1.1.1.2.1! nbrk       55: sys_open(char *path, int flags, mode_t mode, file_t *pfp)
1.1       nbrk       56: {
                     57:        vnode_t vp, dvp;
                     58:        file_t fp;
                     59:        char *filename;
                     60:        int err;
                     61:
1.1.1.1.2.1! nbrk       62:        DPRINTF(VFSDB_SYSCALL, ("sys_open: path=%s flags=%x mode=%x\n",
        !            63:                                path, flags, mode));
1.1       nbrk       64:
                     65:        flags = FFLAGS(flags);
1.1.1.1.2.1! nbrk       66:        if  ((flags & (FREAD | FWRITE)) == 0)
        !            67:                return EINVAL;
1.1       nbrk       68:        if (flags & O_CREAT) {
                     69:                err = namei(path, &vp);
                     70:                if (err == ENOENT) {
                     71:                        /* Create new file. */
                     72:                        if ((err = lookup(path, &dvp, &filename)) != 0)
                     73:                                return err;
                     74:                        if (dvp->v_mount->m_flags & MNT_RDONLY) {
                     75:                                vput(dvp);
                     76:                                return EROFS;
                     77:                        }
                     78:                        mode &= ~S_IFMT;
                     79:                        mode |= S_IFREG;
                     80:                        err = VOP_CREATE(dvp, filename, mode);
                     81:                        vput(dvp);
                     82:                        if (err)
                     83:                                return err;
                     84:                        if ((err = namei(path, &vp)) != 0)
                     85:                                return err;
                     86:                        flags &= ~O_TRUNC;
                     87:                } else if (err) {
                     88:                        return err;
                     89:                } else {
                     90:                        /* File already exits */
                     91:                        if (flags & O_EXCL) {
                     92:                                vput(vp);
                     93:                                return EEXIST;
                     94:                        }
                     95:                        flags &= ~O_CREAT;
                     96:                }
                     97:        } else {
                     98:                /* Open */
                     99:                if ((err = namei(path, &vp)) != 0)
                    100:                        return err;
                    101:        }
                    102:        if ((flags & O_CREAT) == 0) {
                    103:                if (flags & FWRITE || flags & O_TRUNC) {
                    104:                        if (vp->v_mount->m_flags & MNT_RDONLY) {
                    105:                                vput(vp);
                    106:                                return EROFS;
                    107:                        }
                    108:                        if (vp->v_type == VDIR) {
                    109:                                /* Openning directory with writable. */
                    110:                                vput(vp);
                    111:                                return EISDIR;
                    112:                        }
                    113:                }
                    114:        }
                    115:        if (flags & O_TRUNC) {
                    116:                if (!(flags & FWRITE) || (vp->v_type != VREG)) {
                    117:                        vput(vp);
                    118:                        return EINVAL;
                    119:                }
                    120:        }
                    121:        /* Process truncate request */
                    122:        if (flags & O_TRUNC) {
                    123:                if ((err = VOP_TRUNCATE(vp)) != 0) {
                    124:                        vput(vp);
                    125:                        return err;
                    126:                }
                    127:        }
                    128:        /* Setup file structure */
                    129:        if (!(fp = malloc(sizeof(struct file)))) {
                    130:                vput(vp);
                    131:                return ENOMEM;
                    132:        }
                    133:        /* Request to file system */
1.1.1.1.2.1! nbrk      134:        if ((err = VOP_OPEN(vp, flags)) != 0) {
1.1       nbrk      135:                free(fp);
                    136:                vput(vp);
                    137:                return err;
                    138:        }
                    139:        memset(fp, 0, sizeof(struct file));
                    140:        fp->f_vnode = vp;
                    141:        fp->f_flags = flags;
                    142:        fp->f_offset = 0;
                    143:        fp->f_count = 1;
1.1.1.1.2.1! nbrk      144:        *pfp = fp;
1.1       nbrk      145:        vn_unlock(vp);
                    146:        return 0;
                    147: }
                    148:
                    149: int
                    150: sys_close(file_t fp)
                    151: {
                    152:        vnode_t vp;
                    153:        int err;
                    154:
1.1.1.1.2.1! nbrk      155:        DPRINTF(VFSDB_SYSCALL, ("sys_close: fp=%x\n", (u_int)fp));
1.1       nbrk      156:
                    157:        vp = fp->f_vnode;
                    158:        if (--fp->f_count > 0) {
                    159:                vrele(vp);
                    160:                return 0;
                    161:        }
                    162:        vn_lock(vp);
                    163:        if ((err = VOP_CLOSE(vp, fp)) != 0) {
                    164:                vn_unlock(vp);
                    165:                return err;
                    166:        }
                    167:        vput(vp);
                    168:        free(fp);
                    169:        return 0;
                    170: }
                    171:
                    172: int
                    173: sys_read(file_t fp, void *buf, size_t size, size_t *count)
                    174: {
                    175:        vnode_t vp;
                    176:        int err;
                    177:
1.1.1.1.2.1! nbrk      178:        DPRINTF(VFSDB_SYSCALL, ("sys_read: fp=%x buf=%x size=%d\n",
        !           179:                                (u_int)fp, (u_int)buf, size));
1.1       nbrk      180:
                    181:        if ((fp->f_flags & FREAD) == 0)
                    182:                return EPERM;
                    183:        if (size == 0) {
                    184:                *count = 0;
                    185:                return 0;
                    186:        }
                    187:        vp = fp->f_vnode;
                    188:        vn_lock(vp);
                    189:        err = VOP_READ(vp, fp, buf, size, count);
                    190:        vn_unlock(vp);
                    191:        return err;
                    192: }
                    193:
                    194: int
                    195: sys_write(file_t fp, void *buf, size_t size, size_t *count)
                    196: {
                    197:        vnode_t vp;
                    198:        int err;
                    199:
1.1.1.1.2.1! nbrk      200:        DPRINTF(VFSDB_SYSCALL, ("sys_write: fp=%x buf=%x size=%d\n",
        !           201:                                (u_int)fp, (u_int)buf, size));
1.1       nbrk      202:
                    203:        if (size == 0) {
                    204:                *count = 0;
                    205:                return 0;
                    206:        }
                    207:        vp = fp->f_vnode;
                    208:        vn_lock(vp);
                    209:        err = VOP_WRITE(vp, fp, buf, size, count);
                    210:        vn_unlock(vp);
                    211:        return err;
                    212: }
                    213:
                    214: int
                    215: sys_lseek(file_t fp, off_t off, int type, off_t *origin)
                    216: {
                    217:        vnode_t vp;
                    218:
1.1.1.1.2.1! nbrk      219:        DPRINTF(VFSDB_SYSCALL, ("sys_seek: fp=%x off=%d type=%d\n",
        !           220:                                (u_int)fp, (u_int)off, type));
1.1       nbrk      221:
                    222:        vp = fp->f_vnode;
                    223:        vn_lock(vp);
                    224:        switch (type) {
                    225:        case SEEK_SET:
                    226:                if (off < 0)
                    227:                        off = 0;
                    228:                if (off > (off_t)vp->v_size)
                    229:                        off = vp->v_size;
                    230:                break;
                    231:        case SEEK_CUR:
                    232:                if (fp->f_offset + off > (off_t)vp->v_size)
                    233:                        off = vp->v_size;
                    234:                else if (fp->f_offset + off < 0)
                    235:                        off = 0;
                    236:                else
                    237:                        off = fp->f_offset + off;
                    238:                break;
                    239:        case SEEK_END:
                    240:                if (off > 0)
                    241:                        off = vp->v_size;
                    242:                else if ((int)vp->v_size + off < 0)
                    243:                        off = 0;
                    244:                else
                    245:                        off = vp->v_size + off;
                    246:                break;
                    247:        default:
                    248:                vn_unlock(vp);
                    249:                return EINVAL;
                    250:        }
                    251:        /* Request to check the file offset */
                    252:        if (VOP_SEEK(vp, fp, fp->f_offset, off) != 0) {
                    253:                vn_unlock(vp);
                    254:                return EINVAL;
                    255:        }
                    256:        *origin = off;
                    257:        fp->f_offset = off;
                    258:        vn_unlock(vp);
                    259:        return 0;
                    260: }
                    261:
                    262: int
1.1.1.1.2.1! nbrk      263: sys_ioctl(file_t fp, u_long request, void *buf)
1.1       nbrk      264: {
                    265:        vnode_t vp;
                    266:        int err;
                    267:
1.1.1.1.2.1! nbrk      268:        DPRINTF(VFSDB_SYSCALL, ("sys_ioctl: fp=%x request=%x\n", fp, request));
1.1       nbrk      269:
                    270:        if ((fp->f_flags & (FREAD | FWRITE)) == 0)
                    271:                return EBADF;
                    272:
                    273:        vp = fp->f_vnode;
                    274:        vn_lock(vp);
1.1.1.1.2.1! nbrk      275:        err = VOP_IOCTL(vp, fp, request, buf);
1.1       nbrk      276:        vn_unlock(vp);
                    277:        return err;
                    278: }
                    279:
                    280: int
                    281: sys_fsync(file_t fp)
                    282: {
                    283:        vnode_t vp;
                    284:        int err;
                    285:
1.1.1.1.2.1! nbrk      286:        DPRINTF(VFSDB_SYSCALL, ("sys_fsync: fp=%x\n", fp));
1.1       nbrk      287:
                    288:        if ((fp->f_flags & FREAD) == 0)
                    289:                return EBADF;
                    290:
                    291:        vp = fp->f_vnode;
                    292:        vn_lock(vp);
                    293:        err = VOP_FSYNC(vp, fp);
                    294:        vn_unlock(vp);
                    295:        return err;
                    296: }
                    297:
                    298: int
                    299: sys_fstat(file_t fp, struct stat *st)
                    300: {
                    301:        vnode_t vp;
1.1.1.1.2.1! nbrk      302:        int err = 0;
1.1       nbrk      303:
1.1.1.1.2.1! nbrk      304:        DPRINTF(VFSDB_SYSCALL, ("sys_fstat: fp=%x\n", fp));
1.1       nbrk      305:
                    306:        vp = fp->f_vnode;
                    307:        vn_lock(vp);
1.1.1.1.2.1! nbrk      308:        err = vn_stat(vp, st);
1.1       nbrk      309:        vn_unlock(vp);
1.1.1.1.2.1! nbrk      310:        return err;
1.1       nbrk      311: }
                    312:
                    313: /*
                    314:  * Return 0 if directory is empty
                    315:  */
                    316: static int
                    317: check_dir_empty(char *path)
                    318: {
                    319:        int err;
                    320:        file_t fp;
                    321:        struct dirent dir;
                    322:
                    323:        if ((err = sys_opendir(path, &fp)) != 0)
                    324:                return err;
                    325:        do {
                    326:                err = sys_readdir(fp, &dir);
                    327:                if (err)
                    328:                        break;
                    329:        } while (!strcmp(dir.d_name, ".") || !strcmp(dir.d_name, ".."));
                    330:
                    331:        sys_closedir(fp);
                    332:
                    333:        if (err == ENOENT)
                    334:                return 0;
                    335:        else if (err == 0)
                    336:                return EEXIST;
                    337:        return err;
                    338: }
                    339:
                    340: int
                    341: sys_opendir(char *path, file_t *file)
                    342: {
                    343:        vnode_t dvp;
                    344:        file_t fp;
                    345:        int err;
                    346:
1.1.1.1.2.1! nbrk      347:        DPRINTF(VFSDB_SYSCALL, ("sys_opendir: path=%s\n", path));
1.1       nbrk      348:
                    349:        if ((err = sys_open(path, O_RDONLY, 0, &fp)) != 0)
                    350:                return err;
                    351:
                    352:        dvp = fp->f_vnode;
                    353:        vn_lock(dvp);
                    354:        if (dvp->v_type != VDIR) {
                    355:                vn_unlock(dvp);
                    356:                sys_close(fp);
                    357:                return ENOTDIR;
                    358:        }
                    359:        vn_unlock(dvp);
                    360:
                    361:        *file = fp;
                    362:        return 0;
                    363: }
                    364:
                    365: int
                    366: sys_closedir(file_t fp)
                    367: {
                    368:        vnode_t dvp;
                    369:        int err;
                    370:
1.1.1.1.2.1! nbrk      371:        DPRINTF(VFSDB_SYSCALL, ("sys_closedir: fp=%x\n", fp));
1.1       nbrk      372:
                    373:        dvp = fp->f_vnode;
                    374:        vn_lock(dvp);
                    375:        if (dvp->v_type != VDIR) {
                    376:                vn_unlock(dvp);
                    377:                return EBADF;
                    378:        }
                    379:        vn_unlock(dvp);
                    380:        err = sys_close(fp);
                    381:        return err;
                    382: }
                    383:
                    384: int
                    385: sys_readdir(file_t fp, struct dirent *dir)
                    386: {
                    387:        vnode_t dvp;
                    388:        int err;
                    389:
1.1.1.1.2.1! nbrk      390:        DPRINTF(VFSDB_SYSCALL, ("sys_readdir: fp=%x\n", fp));
1.1       nbrk      391:
                    392:        dvp = fp->f_vnode;
                    393:        vn_lock(dvp);
                    394:        if (dvp->v_type != VDIR) {
                    395:                vn_unlock(dvp);
                    396:                return ENOTDIR;
                    397:        }
                    398:        err = VOP_READDIR(dvp, fp, dir);
                    399:        vn_unlock(dvp);
                    400:        return err;
                    401: }
                    402:
                    403: int
                    404: sys_rewinddir(file_t fp)
                    405: {
                    406:        vnode_t dvp;
                    407:
                    408:        dvp = fp->f_vnode;
                    409:        vn_lock(dvp);
                    410:        if (dvp->v_type != VDIR) {
                    411:                vn_unlock(dvp);
                    412:                return EINVAL;
                    413:        }
                    414:        fp->f_offset = 0;
                    415:        vn_unlock(dvp);
                    416:        return 0;
                    417: }
                    418:
                    419: int
                    420: sys_seekdir(file_t fp, long loc)
                    421: {
                    422:        vnode_t dvp;
                    423:
                    424:        dvp = fp->f_vnode;
                    425:        vn_lock(dvp);
                    426:        if (dvp->v_type != VDIR) {
                    427:                vn_unlock(dvp);
                    428:                return EINVAL;
                    429:        }
                    430:        fp->f_offset = (off_t)loc;
                    431:        vn_unlock(dvp);
                    432:        return 0;
                    433: }
                    434:
                    435: int
                    436: sys_telldir(file_t fp, long *loc)
                    437: {
                    438:        vnode_t dvp;
                    439:
                    440:        dvp = fp->f_vnode;
                    441:        vn_lock(dvp);
                    442:        if (dvp->v_type != VDIR) {
                    443:                vn_unlock(dvp);
                    444:                return EINVAL;
                    445:        }
                    446:        *loc = (long)fp->f_offset;
                    447:        vn_unlock(dvp);
                    448:        return 0;
                    449: }
                    450:
                    451: int
                    452: sys_mkdir(char *path, mode_t mode)
                    453: {
                    454:        char *name;
                    455:        vnode_t vp, dvp;
                    456:        int err;
                    457:
1.1.1.1.2.1! nbrk      458:        DPRINTF(VFSDB_SYSCALL, ("sys_mkdir: path=%s mode=%d\n", path, mode));
1.1       nbrk      459:
                    460:        if ((err = namei(path, &vp)) == 0) {
                    461:                /* File already exists */
                    462:                vput(vp);
                    463:                return EEXIST;
                    464:        }
                    465:        /* Notice: vp is invalid here! */
                    466:
                    467:        if ((err = lookup(path, &dvp, &name)) != 0) {
                    468:                /* Directory already exists */
                    469:                return err;
                    470:        }
                    471:        if (dvp->v_mount->m_flags & MNT_RDONLY) {
                    472:                err = EROFS;
                    473:                goto out;
                    474:        }
                    475:        mode &= ~S_IFMT;
                    476:        mode |= S_IFDIR;
                    477:
                    478:        err = VOP_MKDIR(dvp, name, mode);
                    479:  out:
                    480:        vput(dvp);
                    481:        return err;
                    482: }
                    483:
                    484: int
                    485: sys_rmdir(char *path)
                    486: {
                    487:        vnode_t vp, dvp;
                    488:        int err;
                    489:        char *name;
                    490:
1.1.1.1.2.1! nbrk      491:        DPRINTF(VFSDB_SYSCALL, ("sys_rmdir: path=%s\n", path));
1.1       nbrk      492:
                    493:        if ((err = check_dir_empty(path)) != 0)
                    494:                return err;
                    495:        if ((err = namei(path, &vp)) != 0)
                    496:                return err;
                    497:
                    498:        if (vp->v_mount->m_flags & MNT_RDONLY) {
                    499:                err = EROFS;
                    500:                goto out;
                    501:        }
                    502:        if (vp->v_type != VDIR) {
                    503:                err = ENOTDIR;
                    504:                goto out;
                    505:        }
                    506:        if (vp->v_flags & VROOT || vcount(vp) >= 2) {
                    507:                err = EBUSY;
                    508:                goto out;
                    509:        }
                    510:        if ((err = lookup(path, &dvp, &name)) != 0)
                    511:                goto out;
                    512:
                    513:        err = VOP_RMDIR(dvp, vp, name);
                    514:        vn_unlock(vp);
                    515:        vgone(vp);
                    516:        vput(dvp);
                    517:        return err;
                    518:
                    519:  out:
                    520:        vput(vp);
                    521:        return err;
                    522: }
                    523:
                    524: int
                    525: sys_mknod(char *path, mode_t mode)
                    526: {
                    527:        char *name;
                    528:        vnode_t vp, dvp;
                    529:        int err;
                    530:
1.1.1.1.2.1! nbrk      531:        DPRINTF(VFSDB_SYSCALL, ("sys_mknod: path=%s mode=%d\n", path, mode));
        !           532:
        !           533:        switch (mode & S_IFMT) {
        !           534:        case S_IFREG:
        !           535:        case S_IFDIR:
        !           536:        case S_IFIFO:
        !           537:        case S_IFSOCK:
        !           538:                /* OK */
        !           539:                break;
        !           540:        default:
        !           541:                return EINVAL;
        !           542:        }
1.1       nbrk      543:
                    544:        if ((err = namei(path, &vp)) == 0) {
                    545:                vput(vp);
                    546:                return EEXIST;
                    547:        }
                    548:
                    549:        if ((err = lookup(path, &dvp, &name)) != 0)
                    550:                return err;
                    551:
1.1.1.1.2.1! nbrk      552:        if (dvp->v_mount->m_flags & MNT_RDONLY) {
        !           553:                err = EROFS;
        !           554:                goto out;
        !           555:        }
1.1       nbrk      556:        if (S_ISDIR(mode))
                    557:                err = VOP_MKDIR(dvp, name, mode);
                    558:        else
                    559:                err = VOP_CREATE(dvp, name, mode);
1.1.1.1.2.1! nbrk      560:  out:
1.1       nbrk      561:        vput(dvp);
                    562:        return err;
                    563: }
                    564:
                    565: int
                    566: sys_rename(char *src, char *dest)
                    567: {
                    568:        vnode_t vp1, vp2 = 0, dvp1, dvp2;
                    569:        char *sname, *dname;
                    570:        int err;
                    571:        size_t len;
                    572:        char root[] = "/";
                    573:
1.1.1.1.2.1! nbrk      574:        DPRINTF(VFSDB_SYSCALL, ("sys_rename: src=%s dest=%s\n", src, dest));
1.1       nbrk      575:
                    576:        if ((err = namei(src, &vp1)) != 0)
                    577:                return err;
                    578:        if (vp1->v_mount->m_flags & MNT_RDONLY) {
                    579:                err = EROFS;
                    580:                goto err1;
                    581:        }
                    582:        /* If source and dest are the same, do nothing */
                    583:        if (!strncmp(src, dest, PATH_MAX))
                    584:                goto err1;
                    585:
                    586:        /* Check if target is directory of source */
                    587:        len = strlen(dest);
                    588:        if (!strncmp(src, dest, len)) {
                    589:                err = EINVAL;
                    590:                goto err1;
                    591:        }
                    592:        /* Is the source busy ? */
                    593:        if (vcount(vp1) >= 2) {
                    594:                err = EBUSY;
                    595:                goto err1;
                    596:        }
                    597:        /* Check type of source & target */
                    598:        err = namei(dest, &vp2);
                    599:        if (err == 0) {
                    600:                /* target exists */
                    601:                if (vp1->v_type == VDIR && vp2->v_type != VDIR) {
                    602:                        err = ENOTDIR;
                    603:                        goto err2;
                    604:                } else if (vp1->v_type != VDIR && vp2->v_type == VDIR) {
                    605:                        err = EISDIR;
                    606:                        goto err2;
                    607:                }
                    608:                if (vp2->v_type == VDIR && check_dir_empty(dest)) {
                    609:                        err = EEXIST;
                    610:                        goto err2;
                    611:                }
                    612:
                    613:                if (vcount(vp2) >= 2) {
                    614:                        err = EBUSY;
                    615:                        goto err2;
                    616:                }
                    617:        }
                    618:
                    619:        dname = strrchr(dest, '/');
                    620:        if (dname == NULL) {
                    621:                err = ENOTDIR;
                    622:                goto err2;
                    623:        }
                    624:        if (dname == dest)
                    625:                dest = root;
                    626:
                    627:        *dname = 0;
                    628:        dname++;
                    629:
                    630:        if ((err = lookup(src, &dvp1, &sname)) != 0)
                    631:                goto err2;
                    632:
                    633:        if ((err = namei(dest, &dvp2)) != 0)
                    634:                goto err3;
                    635:
                    636:        /* The source and dest must be same file system */
                    637:        if (dvp1->v_mount != dvp2->v_mount) {
                    638:                err = EXDEV;
                    639:                goto err4;
                    640:        }
                    641:        err = VOP_RENAME(dvp1, vp1, sname, dvp2, vp2, dname);
                    642:  err4:
                    643:        vput(dvp2);
                    644:  err3:
                    645:        vput(dvp1);
                    646:  err2:
                    647:        if (vp2)
                    648:                vput(vp2);
                    649:  err1:
                    650:        vput(vp1);
                    651:        return err;
                    652: }
                    653:
                    654: int
                    655: sys_unlink(char *path)
                    656: {
                    657:        char *name;
                    658:        vnode_t vp, dvp;
                    659:        int err;
                    660:
1.1.1.1.2.1! nbrk      661:        DPRINTF(VFSDB_SYSCALL, ("sys_unlink: path=%s\n", path));
1.1       nbrk      662:
                    663:        if ((err = namei(path, &vp)) != 0)
                    664:                return err;
                    665:
                    666:        if (vp->v_mount->m_flags & MNT_RDONLY) {
                    667:                err = EROFS;
                    668:                goto out;
                    669:        }
                    670:        if (vp->v_type == VDIR) {
                    671:                err = EPERM;
                    672:                goto out;
                    673:        }
                    674:        if (vp->v_flags & VROOT || vcount(vp) >= 2) {
                    675:                err = EBUSY;
                    676:                goto out;
                    677:        }
                    678:        if ((err = lookup(path, &dvp, &name)) != 0)
                    679:                goto out;
                    680:
                    681:        err = VOP_REMOVE(dvp, vp, name);
                    682:
                    683:        vn_unlock(vp);
                    684:        vgone(vp);
                    685:        vput(dvp);
                    686:        return 0;
                    687:  out:
                    688:        vput(vp);
                    689:        return err;
                    690: }
                    691:
                    692: int
                    693: sys_access(char *path, int mode)
                    694: {
                    695:        vnode_t vp;
                    696:        int err;
                    697:
1.1.1.1.2.1! nbrk      698:        DPRINTF(VFSDB_SYSCALL, ("sys_access: path=%s\n", path));
1.1       nbrk      699:
                    700:        if ((err = namei(path, &vp)) != 0)
                    701:                return err;
                    702:
                    703:        err = EACCES;
                    704:        if ((mode & X_OK) && (vp->v_mode & 0111) == 0)
                    705:                goto out;
                    706:        if ((mode & W_OK) && (vp->v_mode & 0222) == 0)
                    707:                goto out;
                    708:        if ((mode & R_OK) && (vp->v_mode & 0444) == 0)
                    709:                goto out;
                    710:        err = 0;
                    711:  out:
1.1.1.1.2.1! nbrk      712:        vput(vp);
        !           713:        return err;
        !           714: }
        !           715:
        !           716: int
        !           717: sys_stat(char *path, struct stat *st)
        !           718: {
        !           719:        vnode_t vp;
        !           720:        int err;
        !           721:
        !           722:        if ((err = namei(path, &vp)) != 0)
        !           723:                return err;
        !           724:        err = vn_stat(vp, st);
1.1       nbrk      725:        vput(vp);
                    726:        return err;
                    727: }

CVSweb