Annotation of prex/usr/server/fs/fatfs/fatfs_vfsops.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/stat.h>
! 33: #include <sys/vnode.h>
! 34: #include <sys/file.h>
! 35: #include <sys/mount.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: static int fatfs_mount (mount_t mp, char *dev, int flags, void *data);
! 48: static int fatfs_unmount(mount_t mp);
! 49: #define fatfs_sync ((vfsop_sync_t)vfs_nullop)
! 50: static int fatfs_vget (mount_t mp, vnode_t vp);
! 51: #define fatfs_statfs ((vfsop_statfs_t)vfs_nullop)
! 52:
! 53: /*
! 54: * File system operations
! 55: */
! 56: struct vfsops fatfs_vfsops = {
! 57: fatfs_mount, /* mount */
! 58: fatfs_unmount, /* unmount */
! 59: fatfs_sync, /* sync */
! 60: fatfs_vget, /* vget */
! 61: fatfs_statfs, /* statfs */
! 62: &fatfs_vnops, /* vnops */
! 63: };
! 64:
! 65: /*
! 66: * Read BIOS parameter block.
! 67: * Return 0 on sucess.
! 68: */
! 69: static int
! 70: fat_read_bpb(struct fatfsmount *fmp)
! 71: {
! 72: struct fat_bpb *bpb;
! 73: size_t size;
! 74: int err;
! 75:
! 76: bpb = malloc(SEC_SIZE);
! 77: if (bpb == NULL)
! 78: return ENOMEM;
! 79:
! 80: /* Read boot sector (block:0) */
! 81: size = SEC_SIZE;
! 82: err = device_read(fmp->dev, bpb, &size, 0);
! 83: if (err) {
! 84: free(bpb);
! 85: return err;
! 86: }
! 87: if (bpb->bytes_per_sector != SEC_SIZE) {
! 88: DPRINTF(("fatfs: invalid sector size\n"));
! 89: free(bpb);
! 90: return EINVAL;
! 91: }
! 92:
! 93: /* Build FAT mount data */
! 94: fmp->fat_start = bpb->hidden_sectors + bpb->reserved_sectors;
! 95: fmp->root_start = fmp->fat_start +
! 96: (bpb->num_of_fats * bpb->sectors_per_fat);
! 97: fmp->data_start =
! 98: fmp->root_start + (bpb->root_entries / DIR_PER_SEC);
! 99: fmp->sec_per_cl = bpb->sectors_per_cluster;
! 100: fmp->cluster_size = bpb->sectors_per_cluster * SEC_SIZE;
! 101: fmp->last_cluster = (bpb->total_sectors - fmp->data_start) /
! 102: bpb->sectors_per_cluster + CL_FIRST;
! 103: fmp->free_scan = CL_FIRST;
! 104:
! 105: if (!strncmp((const char *)bpb->file_sys_id, "FAT12 ", 8)) {
! 106: fmp->fat_type = 12;
! 107: fmp->fat_mask = FAT12_MASK;
! 108: fmp->fat_eof = CL_EOF & FAT12_MASK;
! 109: } else if (!strncmp((const char *)bpb->file_sys_id, "FAT16 ", 8)) {
! 110: fmp->fat_type = 16;
! 111: fmp->fat_mask = FAT16_MASK;
! 112: fmp->fat_eof = CL_EOF & FAT16_MASK;
! 113: } else {
! 114: /* FAT32 is not supported now! */
! 115: DPRINTF(("fatfs: invalid FAT type\n"));
! 116: free(bpb);
! 117: return EINVAL;
! 118: }
! 119: free(bpb);
! 120:
! 121: DPRINTF(("----- FAT info -----\n"));
! 122: DPRINTF(("drive:%x\n", (int)bpb->physical_drive));
! 123: DPRINTF(("total_sectors:%d\n", (int)bpb->total_sectors));
! 124: DPRINTF(("heads :%d\n", (int)bpb->heads));
! 125: DPRINTF(("serial :%x\n", (int)bpb->serial_no));
! 126: DPRINTF(("cluster size:%u sectors\n", (int)fmp->sec_per_cl));
! 127: DPRINTF(("fat_type :FAT%u\n", (int)fmp->fat_type));
! 128: DPRINTF(("fat_eof :0x%x\n\n", (int)fmp->fat_eof));
! 129: return 0;
! 130: }
! 131:
! 132: /*
! 133: * Mount file system.
! 134: */
! 135: static int
! 136: fatfs_mount(mount_t mp, char *dev, int flags, void *data)
! 137: {
! 138: struct fatfsmount *fmp;
! 139: vnode_t vp;
! 140: int err = 0;
! 141:
! 142: DPRINTF(("fatfs_mount device=%s\n", dev));
! 143:
! 144: fmp = malloc(sizeof(struct fatfsmount));
! 145: if (fmp == NULL)
! 146: return ENOMEM;
! 147:
! 148: fmp->dev = mp->m_dev;
! 149: if (fat_read_bpb(fmp) != 0)
! 150: goto err1;
! 151:
! 152: err = ENOMEM;
! 153: fmp->io_buf = malloc(fmp->sec_per_cl * SEC_SIZE);
! 154: if (fmp->io_buf == NULL)
! 155: goto err1;
! 156:
! 157: fmp->fat_buf = malloc(SEC_SIZE * 2);
! 158: if (fmp->fat_buf == NULL)
! 159: goto err2;
! 160:
! 161: fmp->dir_buf = malloc(SEC_SIZE);
! 162: if (fmp->dir_buf == NULL)
! 163: goto err3;
! 164:
! 165: mutex_init(&fmp->lock);
! 166: mp->m_data = fmp;
! 167: vp = mp->m_root;
! 168: vp->v_blkno = CL_ROOT;
! 169: return 0;
! 170: err3:
! 171: free(fmp->fat_buf);
! 172: err2:
! 173: free(fmp->io_buf);
! 174: err1:
! 175: free(fmp);
! 176: return err;
! 177: }
! 178:
! 179: /*
! 180: * Unmount the file system.
! 181: */
! 182: static int
! 183: fatfs_unmount(mount_t mp)
! 184: {
! 185: struct fatfsmount *fmp;
! 186:
! 187: fmp = mp->m_data;
! 188: free(fmp->dir_buf);
! 189: free(fmp->fat_buf);
! 190: free(fmp->io_buf);
! 191: mutex_destroy(&fmp->lock);
! 192: free(fmp);
! 193: return 0;
! 194: }
! 195:
! 196: /*
! 197: * Prepare the FAT specific node and fill the vnode.
! 198: */
! 199: static int
! 200: fatfs_vget(mount_t mp, vnode_t vp)
! 201: {
! 202: struct fatfs_node *np;
! 203:
! 204: np = malloc(sizeof(struct fatfs_node));
! 205: if (np == NULL)
! 206: return ENOMEM;
! 207: vp->v_data = np;
! 208: return 0;
! 209: }
! 210:
CVSweb