[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     ! 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