[BACK]Return to fatfs_vnops.c CVS log [TXT][DIR] Up to [local] / prex / usr / server / fs / fatfs

Annotation of prex/usr/server/fs/fatfs/fatfs_vnops.c, Revision 1.1.1.1

1.1       nbrk        1: /*
                      2:  * Copyright (c) 2005-2008, 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: #include <prex/prex.h>
                     31:
                     32: #include <sys/vnode.h>
                     33: #include <sys/file.h>
                     34: #include <sys/mount.h>
                     35: #include <sys/dirent.h>
                     36: #include <sys/buf.h>
                     37:
                     38: #include <ctype.h>
                     39: #include <unistd.h>
                     40: #include <errno.h>
                     41: #include <string.h>
                     42: #include <stdlib.h>
                     43: #include <fcntl.h>
                     44:
                     45: #include "fatfs.h"
                     46:
                     47: /*
                     48:  *  Time bits: 15-11 hours (0-23), 10-5 min, 4-0 sec /2
                     49:  *  Date bits: 15-9 year - 1980, 8-5 month, 4-0 day
                     50:  */
                     51: #define TEMP_DATE   0x3021
                     52: #define TEMP_TIME   0
                     53:
                     54: #define fatfs_open     ((vnop_open_t)vop_nullop)
                     55: #define fatfs_close    ((vnop_close_t)vop_nullop)
                     56: static int fatfs_read  (vnode_t, file_t, void *, size_t, size_t *);
                     57: static int fatfs_write (vnode_t, file_t, void *, size_t, size_t *);
                     58: #define fatfs_seek     ((vnop_seek_t)vop_nullop)
                     59: #define fatfs_ioctl    ((vnop_ioctl_t)vop_einval)
                     60: #define fatfs_fsync    ((vnop_fsync_t)vop_nullop)
                     61: static int fatfs_readdir(vnode_t, file_t, struct dirent *);
                     62: static int fatfs_lookup        (vnode_t, char *, vnode_t);
                     63: static int fatfs_create        (vnode_t, char *, mode_t);
                     64: static int fatfs_remove        (vnode_t, vnode_t, char *);
                     65: static int fatfs_rename        (vnode_t, vnode_t, char *, vnode_t, vnode_t, char *);
                     66: static int fatfs_mkdir (vnode_t, char *, mode_t);
                     67: static int fatfs_rmdir (vnode_t, vnode_t, char *);
                     68: static int fatfs_getattr(vnode_t, struct vattr *);
                     69: static int fatfs_setattr(vnode_t, struct vattr *);
                     70: static int fatfs_inactive(vnode_t);
                     71: static int fatfs_truncate(vnode_t);
                     72:
                     73: /*
                     74:  * vnode operations
                     75:  */
                     76: struct vnops fatfs_vnops = {
                     77:        fatfs_open,             /* open */
                     78:        fatfs_close,            /* close */
                     79:        fatfs_read,             /* read */
                     80:        fatfs_write,            /* write */
                     81:        fatfs_seek,             /* seek */
                     82:        fatfs_ioctl,            /* ioctl */
                     83:        fatfs_fsync,            /* fsync */
                     84:        fatfs_readdir,          /* readdir */
                     85:        fatfs_lookup,           /* lookup */
                     86:        fatfs_create,           /* create */
                     87:        fatfs_remove,           /* remove */
                     88:        fatfs_rename,           /* remame */
                     89:        fatfs_mkdir,            /* mkdir */
                     90:        fatfs_rmdir,            /* rmdir */
                     91:        fatfs_getattr,          /* getattr */
                     92:        fatfs_setattr,          /* setattr */
                     93:        fatfs_inactive,         /* inactive */
                     94:        fatfs_truncate,         /* truncate */
                     95: };
                     96:
                     97: /*
                     98:  * Read one cluster to buffer.
                     99:  */
                    100: static int
                    101: fat_read_cluster(struct fatfsmount *fmp, u_long cluster)
                    102: {
                    103:        u_long sec;
                    104:        size_t size;
                    105:
                    106:        sec = cl_to_sec(fmp, cluster);
                    107:        size = fmp->sec_per_cl * SEC_SIZE;
                    108:        return device_read(fmp->dev, fmp->io_buf, &size, sec);
                    109: }
                    110:
                    111: /*
                    112:  * Write one cluster from buffer.
                    113:  */
                    114: static int
                    115: fat_write_cluster(struct fatfsmount *fmp, u_long cluster)
                    116: {
                    117:        u_long sec;
                    118:        size_t size;
                    119:
                    120:        sec = cl_to_sec(fmp, cluster);
                    121:        size = fmp->sec_per_cl * SEC_SIZE;
                    122:        return device_write(fmp->dev, fmp->io_buf, &size, sec);
                    123: }
                    124:
                    125: /*
                    126:  * Lookup vnode for the specified file/directory.
                    127:  * The vnode data will be set properly.
                    128:  */
                    129: static int
                    130: fatfs_lookup(vnode_t dvp, char *name, vnode_t vp)
                    131: {
                    132:        struct fatfsmount *fmp;
                    133:        struct fat_dirent *de;
                    134:        struct fatfs_node *np;
                    135:        int err;
                    136:
                    137:        if (*name == '\0')
                    138:                return ENOENT;
                    139:
                    140:        fmp = vp->v_mount->m_data;
                    141:        mutex_lock(&fmp->lock);
                    142:
                    143:        DPRINTF(("fatfs_lookup: name=%s\n", name));
                    144:
                    145:        np = vp->v_data;
                    146:        err = fatfs_lookup_node(dvp, name, np);
                    147:        if (err) {
                    148:                DPRINTF(("fatfs_lookup: failed!! name=%s\n", name));
                    149:                mutex_unlock(&fmp->lock);
                    150:                return err;
                    151:        }
                    152:        de = &np->dirent;
                    153:        vp->v_type = IS_DIR(de) ? VDIR : VREG;
                    154:        fat_attr_to_mode(de->attr, &vp->v_mode);
                    155:        vp->v_mode = ALLPERMS;
                    156:        vp->v_size = de->size;
                    157:        vp->v_blkno = de->cluster;
                    158:
                    159:        DPRINTF(("fatfs_lookup: cl=%d\n", de->cluster));
                    160:        mutex_unlock(&fmp->lock);
                    161:        return 0;
                    162: }
                    163:
                    164: static int
                    165: fatfs_read(vnode_t vp, file_t fp, void *buf, size_t size, size_t *result)
                    166: {
                    167:        struct fatfsmount *fmp;
                    168:        int nr_read, nr_copy, buf_pos, err;
                    169:        u_long cl, file_pos;
                    170:
                    171:        DPRINTF(("fatfs_read: vp=%x\n", vp));
                    172:
                    173:        *result = 0;
                    174:        fmp = vp->v_mount->m_data;
                    175:
                    176:        if (vp->v_type == VDIR)
                    177:                return EISDIR;
                    178:        if (vp->v_type != VREG)
                    179:                return EINVAL;
                    180:
                    181:        /* Check if current file position is already end of file. */
                    182:        file_pos = fp->f_offset;
                    183:        if (file_pos >= vp->v_size)
                    184:                return 0;
                    185:
                    186:        mutex_lock(&fmp->lock);
                    187:
                    188:        /* Get the actual read size. */
                    189:        if (vp->v_size - file_pos < size)
                    190:                size = vp->v_size - file_pos;
                    191:
                    192:        /* Seek to the cluster for the file offset */
                    193:        err = fat_seek_cluster(fmp, vp->v_blkno, file_pos, &cl);
                    194:        if (err)
                    195:                goto out;
                    196:
                    197:        /* Read and copy data */
                    198:        nr_read = 0;
                    199:        buf_pos = file_pos % fmp->cluster_size;
                    200:        do {
                    201:                if (fat_read_cluster(fmp, cl)) {
                    202:                        err = EIO;
                    203:                        goto out;
                    204:                }
                    205:
                    206:                nr_copy = fmp->cluster_size;
                    207:                if (buf_pos > 0)
                    208:                        nr_copy -= buf_pos;
                    209:                if (buf_pos + size < fmp->cluster_size)
                    210:                        nr_copy = size;
                    211:                memcpy(buf, fmp->io_buf + buf_pos, nr_copy);
                    212:
                    213:                file_pos += nr_copy;
                    214:                nr_read += nr_copy;
                    215:                size -= nr_copy;
                    216:                if (size <= 0)
                    217:                        break;
                    218:
                    219:                err = fat_next_cluster(fmp, cl, &cl);
                    220:                if (err)
                    221:                        goto out;
                    222:
                    223:                buf = (void *)((u_long)buf + nr_copy);
                    224:                buf_pos = 0;
                    225:        } while (!IS_EOFCL(fmp, cl));
                    226:
                    227:        fp->f_offset = file_pos;
                    228:        *result = nr_read;
                    229:        err = 0;
                    230:  out:
                    231:        mutex_unlock(&fmp->lock);
                    232:        return err;
                    233: }
                    234:
                    235: static int
                    236: fatfs_write(vnode_t vp, file_t fp, void *buf, size_t size, size_t *result)
                    237: {
                    238:        struct fatfsmount *fmp;
                    239:        struct fatfs_node *np;
                    240:        struct fat_dirent *de;
                    241:        int nr_copy, nr_write, buf_pos, i, cl_size, err;
                    242:        u_long file_pos, end_pos;
                    243:        u_long cl;
                    244:
                    245:        DPRINTF(("fatfs_write: vp=%x\n", vp));
                    246:
                    247:        *result = 0;
                    248:        fmp = vp->v_mount->m_data;
                    249:
                    250:        if (vp->v_type == VDIR)
                    251:                return EISDIR;
                    252:        if (vp->v_type != VREG)
                    253:                return EINVAL;
                    254:
                    255:        mutex_lock(&fmp->lock);
                    256:
                    257:        /* Check if file position exceeds the end of file. */
                    258:        end_pos = vp->v_size;
                    259:        file_pos = (fp->f_flags & O_APPEND) ? end_pos : fp->f_offset;
                    260:        if (file_pos + size > end_pos) {
                    261:                /* Expand the file size before writing to it */
                    262:                end_pos = file_pos + size;
                    263:                err = fat_expand_file(fmp, vp->v_blkno, end_pos);
                    264:                if (err) {
                    265:                        err = EIO;
                    266:                        goto out;
                    267:                }
                    268:
                    269:                /* Update directory entry */
                    270:                np = vp->v_data;
                    271:                de = &np->dirent;
                    272:                de->size = end_pos;
                    273:                err = fatfs_put_node(fmp, np);
                    274:                if (err)
                    275:                        goto out;
                    276:                vp->v_size = end_pos;
                    277:        }
                    278:
                    279:        /* Seek to the cluster for the file offset */
                    280:        err = fat_seek_cluster(fmp, vp->v_blkno, file_pos, &cl);
                    281:        if (err)
                    282:                goto out;
                    283:
                    284:        buf_pos = file_pos % fmp->cluster_size;
                    285:        cl_size = size / fmp->cluster_size + 1;
                    286:        nr_write = 0;
                    287:        i = 0;
                    288:        do {
                    289:                /* First and last cluster must be read before write */
                    290:                if (i == 0 || i == cl_size) {
                    291:                        if (fat_read_cluster(fmp, cl)) {
                    292:                                err = EIO;
                    293:                                goto out;
                    294:                        }
                    295:                }
                    296:                nr_copy = fmp->cluster_size;
                    297:                if (buf_pos > 0)
                    298:                        nr_copy -= buf_pos;
                    299:                if (buf_pos + size < fmp->cluster_size)
                    300:                        nr_copy = size;
                    301:                memcpy(fmp->io_buf + buf_pos, buf, nr_copy);
                    302:
                    303:                if (fat_write_cluster(fmp, cl)) {
                    304:                        err = EIO;
                    305:                        goto out;
                    306:                }
                    307:                file_pos += nr_copy;
                    308:                nr_write += nr_copy;
                    309:                size -= nr_copy;
                    310:                if (size <= 0)
                    311:                        break;
                    312:
                    313:                err = fat_next_cluster(fmp, cl, &cl);
                    314:                if (err)
                    315:                        goto out;
                    316:
                    317:                buf = (void *)((u_long)buf + nr_copy);
                    318:                buf_pos = 0;
                    319:                i++;
                    320:        } while (!IS_EOFCL(fmp, cl));
                    321:
                    322:        fp->f_offset = file_pos;
                    323:
                    324:        /*
                    325:         * XXX: Todo!
                    326:         *    de.time = ?
                    327:         *    de.date = ?
                    328:         *    if (dirent_set(fp, &de))
                    329:         *        return EIO;
                    330:         */
                    331:        *result = nr_write;
                    332:        err = 0;
                    333:  out:
                    334:        mutex_unlock(&fmp->lock);
                    335:        return err;
                    336: }
                    337:
                    338: static int
                    339: fatfs_readdir(vnode_t vp, file_t fp, struct dirent *dir)
                    340: {
                    341:        struct fatfsmount *fmp;
                    342:        struct fatfs_node np;
                    343:        struct fat_dirent *de;
                    344:        int err;
                    345:
                    346:        fmp = vp->v_mount->m_data;
                    347:        mutex_lock(&fmp->lock);
                    348:
                    349:        err = fatfs_get_node(vp, fp->f_offset, &np);
                    350:        if (err)
                    351:                goto out;
                    352:        de = &np.dirent;
                    353:        fat_restore_name((char *)&de->name, dir->d_name);
                    354:
                    355:        if (de->attr & FA_SUBDIR)
                    356:                dir->d_type = DT_DIR;
                    357:        else if (de->attr & FA_DEVICE)
                    358:                dir->d_type = DT_BLK;
                    359:        else
                    360:                dir->d_type = DT_REG;
                    361:
                    362:        dir->d_fileno = fp->f_offset;
                    363:        dir->d_namlen = strlen(dir->d_name);
                    364:
                    365:        fp->f_offset++;
                    366:        err = 0;
                    367:  out:
                    368:        mutex_unlock(&fmp->lock);
                    369:        return err;
                    370: }
                    371:
                    372: /*
                    373:  * Create empty file.
                    374:  */
                    375: static int
                    376: fatfs_create(vnode_t dvp, char *name, mode_t mode)
                    377: {
                    378:        struct fatfsmount *fmp;
                    379:        struct fatfs_node np;
                    380:        struct fat_dirent *de;
                    381:        u_long cl;
                    382:        int err;
                    383:
                    384:        DPRINTF(("fatfs_create: %s\n", name));
                    385:
                    386:        if (!S_ISREG(mode))
                    387:                return EINVAL;
                    388:
                    389:        if (!fat_valid_name(name))
                    390:                return EINVAL;
                    391:
                    392:        fmp = dvp->v_mount->m_data;
                    393:        mutex_lock(&fmp->lock);
                    394:
                    395:        /* Allocate free cluster for new file. */
                    396:        err = fat_alloc_cluster(fmp, 0, &cl);
                    397:        if (err)
                    398:                goto out;
                    399:
                    400:        de = &np.dirent;
                    401:        memset(de, 0, sizeof(struct fat_dirent));
                    402:        fat_convert_name(name, (char *)de->name);
                    403:        de->cluster = cl;
                    404:        de->time = TEMP_TIME;
                    405:        de->date = TEMP_DATE;
                    406:        fat_mode_to_attr(mode, &de->attr);
                    407:        err = fatfs_add_node(dvp, &np);
                    408:        if (err)
                    409:                goto out;
                    410:        err = fat_set_cluster(fmp, cl, fmp->fat_eof);
                    411:  out:
                    412:        mutex_unlock(&fmp->lock);
                    413:        return err;
                    414: }
                    415:
                    416: static int
                    417: fatfs_remove(vnode_t dvp, vnode_t vp, char *name)
                    418: {
                    419:        struct fatfsmount *fmp;
                    420:        struct fatfs_node np;
                    421:        struct fat_dirent *de;
                    422:        int err;
                    423:
                    424:        if (*name == '\0')
                    425:                return ENOENT;
                    426:
                    427:        fmp = dvp->v_mount->m_data;
                    428:        mutex_lock(&fmp->lock);
                    429:
                    430:        err = fatfs_lookup_node(dvp, name, &np);
                    431:        if (err)
                    432:                goto out;
                    433:        de = &np.dirent;
                    434:        if (IS_DIR(de)) {
                    435:                err = EISDIR;
                    436:                goto out;
                    437:        }
                    438:        if (!IS_FILE(de)) {
                    439:                err = EPERM;
                    440:                goto out;
                    441:        }
                    442:
                    443:        /* Remove clusters */
                    444:        err = fat_free_clusters(fmp, de->cluster);
                    445:        if (err)
                    446:                goto out;
                    447:
                    448:        /* remove directory */
                    449:        de->name[0] = 0xe5;
                    450:        err = fatfs_put_node(fmp, &np);
                    451:  out:
                    452:        mutex_unlock(&fmp->lock);
                    453:        return err;
                    454: }
                    455:
                    456: static int
                    457: fatfs_rename(vnode_t dvp1, vnode_t vp1, char *name1,
                    458:             vnode_t dvp2, vnode_t vp2, char *name2)
                    459: {
                    460:        struct fatfsmount *fmp;
                    461:        struct fatfs_node np1;
                    462:        struct fat_dirent *de1, *de2;
                    463:        int err;
                    464:
                    465:        fmp = dvp1->v_mount->m_data;
                    466:        mutex_lock(&fmp->lock);
                    467:
                    468:        err = fatfs_lookup_node(dvp1, name1, &np1);
                    469:        if (err)
                    470:                goto out;
                    471:        de1 = &np1.dirent;
                    472:
                    473:        if (IS_FILE(de1)) {
                    474:                /* Remove destination file, first */
                    475:                err = fatfs_remove(dvp2, vp1, name2);
                    476:                if (err == EIO)
                    477:                        goto out;
                    478:
                    479:                /* Change file name of directory entry */
                    480:                fat_convert_name(name2, (char *)de1->name);
                    481:
                    482:                /* Same directory ? */
                    483:                if (dvp1 == dvp2) {
                    484:                        /* Change the name of existing file */
                    485:                        err = fatfs_put_node(fmp, &np1);
                    486:                        if (err)
                    487:                                goto out;
                    488:                } else {
                    489:                        /* Create new directory entry */
                    490:                        err = fatfs_add_node(dvp2, &np1);
                    491:                        if (err)
                    492:                                goto out;
                    493:
                    494:                        /* Remove souce file */
                    495:                        err = fatfs_remove(dvp1, vp2, name1);
                    496:                        if (err)
                    497:                                goto out;
                    498:                }
                    499:        } else {
                    500:
                    501:                /* remove destination directory */
                    502:                err = fatfs_rmdir(dvp2, NULL, name2);
                    503:                if (err == EIO)
                    504:                        goto out;
                    505:
                    506:                /* Change file name of directory entry */
                    507:                fat_convert_name(name2, (char *)de1->name);
                    508:
                    509:                /* Same directory ? */
                    510:                if (dvp1 == dvp2) {
                    511:                        /* Change the name of existing directory */
                    512:                        err = fatfs_put_node(fmp, &np1);
                    513:                        if (err)
                    514:                                goto out;
                    515:                } else {
                    516:                        /* Create new directory entry */
                    517:                        err = fatfs_add_node(dvp2, &np1);
                    518:                        if (err)
                    519:                                goto out;
                    520:
                    521:                        /* Update "." and ".." for renamed directory */
                    522:                        if (fat_read_cluster(fmp, de1->cluster)) {
                    523:                                err = EIO;
                    524:                                goto out;
                    525:                        }
                    526:
                    527:                        de2 = (struct fat_dirent *)fmp->io_buf;
                    528:                        de2->cluster = de1->cluster;
                    529:                        de2->time = TEMP_TIME;
                    530:                        de2->date = TEMP_DATE;
                    531:                        de2++;
                    532:                        de2->cluster = dvp2->v_blkno;
                    533:                        de2->time = TEMP_TIME;
                    534:                        de2->date = TEMP_DATE;
                    535:
                    536:                        if (fat_write_cluster(fmp, de1->cluster)) {
                    537:                                err = EIO;
                    538:                                goto out;
                    539:                        }
                    540:
                    541:                        /* Remove souce directory */
                    542:                        err = fatfs_rmdir(dvp1, NULL, name1);
                    543:                        if (err)
                    544:                                goto out;
                    545:                }
                    546:        }
                    547:  out:
                    548:        mutex_unlock(&fmp->lock);
                    549:        return err;
                    550: }
                    551:
                    552: static int
                    553: fatfs_mkdir(vnode_t dvp, char *name, mode_t mode)
                    554: {
                    555:        struct fatfsmount *fmp;
                    556:        struct fatfs_node np;
                    557:        struct fat_dirent *de;
                    558:        u_long cl;
                    559:        int err;
                    560:
                    561:        if (!S_ISDIR(mode))
                    562:                return EINVAL;
                    563:
                    564:        if (!fat_valid_name(name))
                    565:                return ENOTDIR;
                    566:
                    567:        fmp = dvp->v_mount->m_data;
                    568:        mutex_lock(&fmp->lock);
                    569:
                    570:        /* Allocate free cluster for directory data */
                    571:        err = fat_alloc_cluster(fmp, 0, &cl);
                    572:        if (err)
                    573:                goto out;
                    574:
                    575:        memset(&np, 0, sizeof(struct fatfs_node));
                    576:        de = &np.dirent;
                    577:        fat_convert_name(name, (char *)&de->name);
                    578:        de->cluster = cl;
                    579:        de->time = TEMP_TIME;
                    580:        de->date = TEMP_DATE;
                    581:        fat_mode_to_attr(mode, &de->attr);
                    582:        err = fatfs_add_node(dvp, &np);
                    583:        if (err)
                    584:                goto out;
                    585:
                    586:        /* Initialize "." and ".." for new directory */
                    587:        memset(fmp->io_buf, 0, fmp->cluster_size);
                    588:
                    589:        de = (struct fat_dirent *)fmp->io_buf;
                    590:        memcpy(de->name, ".          ", 11);
                    591:        de->attr = FA_SUBDIR;
                    592:        de->cluster = cl;
                    593:        de->time = TEMP_TIME;
                    594:        de->date = TEMP_DATE;
                    595:        de++;
                    596:        memcpy(de->name, "..         ", 11);
                    597:        de->attr = FA_SUBDIR;
                    598:        de->cluster = dvp->v_blkno;
                    599:        de->time = TEMP_TIME;
                    600:        de->date = TEMP_DATE;
                    601:
                    602:        if (fat_write_cluster(fmp, cl)) {
                    603:                err = EIO;
                    604:                goto out;
                    605:        }
                    606:        /* Add eof */
                    607:        err = fat_set_cluster(fmp, cl, fmp->fat_eof);
                    608:  out:
                    609:        mutex_unlock(&fmp->lock);
                    610:        return err;
                    611: }
                    612:
                    613: /*
                    614:  * remove can be done only with empty directory
                    615:  */
                    616: static int
                    617: fatfs_rmdir(vnode_t dvp, vnode_t vp, char *name)
                    618: {
                    619:        struct fatfsmount *fmp;
                    620:        struct fatfs_node np;
                    621:        struct fat_dirent *de;
                    622:        int err;
                    623:
                    624:        if (*name == '\0')
                    625:                return ENOENT;
                    626:
                    627:        fmp = dvp->v_mount->m_data;
                    628:        mutex_lock(&fmp->lock);
                    629:
                    630:        err = fatfs_lookup_node(dvp, name, &np);
                    631:        if (err)
                    632:                goto out;
                    633:
                    634:        de = &np.dirent;
                    635:        if (!IS_DIR(de)) {
                    636:                err = ENOTDIR;
                    637:                goto out;
                    638:        }
                    639:
                    640:        /* Remove clusters */
                    641:        err = fat_free_clusters(fmp, de->cluster);
                    642:        if (err)
                    643:                goto out;
                    644:
                    645:        /* remove directory */
                    646:        de->name[0] = 0xe5;
                    647:
                    648:        err = fatfs_put_node(fmp, &np);
                    649:  out:
                    650:        mutex_unlock(&fmp->lock);
                    651:        return err;
                    652: }
                    653:
                    654: static int
                    655: fatfs_getattr(vnode_t vp, struct vattr *vap)
                    656: {
                    657:        /* XXX */
                    658:        return 0;
                    659: }
                    660:
                    661: static int
                    662: fatfs_setattr(vnode_t vp, struct vattr *vap)
                    663: {
                    664:        /* XXX */
                    665:        return 0;
                    666: }
                    667:
                    668:
                    669: static int
                    670: fatfs_inactive(vnode_t vp)
                    671: {
                    672:
                    673:        free(vp->v_data);
                    674:        return 0;
                    675: }
                    676:
                    677: static int
                    678: fatfs_truncate(vnode_t vp)
                    679: {
                    680:        struct fatfsmount *fmp;
                    681:        struct fatfs_node *np;
                    682:        struct fat_dirent *de;
                    683:        int err;
                    684:
                    685:        fmp = vp->v_mount->m_data;
                    686:        mutex_lock(&fmp->lock);
                    687:
                    688:        np = vp->v_data;
                    689:        de = &np->dirent;
                    690:
                    691:        /* Remove clusters */
                    692:        err = fat_free_clusters(fmp, de->cluster);
                    693:        if (err)
                    694:                goto out;
                    695:
                    696:        de->size = 0;
                    697:
                    698:        err = fatfs_put_node(fmp, np);
                    699:        if (err)
                    700:                goto out;
                    701:
                    702:        vp->v_size = 0;
                    703:  out:
                    704:        mutex_unlock(&fmp->lock);
                    705:        return err;
                    706: }
                    707:
                    708: int
                    709: fatfs_init(void)
                    710: {
                    711:        return 0;
                    712: }

CVSweb