Prex Home / Browse Source - Prex Version: 0.9.0

root/usr/server/fs/fatfs/fatfs_vfsops.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fat_read_bpb
  2. fatfs_mount
  3. fatfs_unmount
  4. fatfs_vget

   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 <sys/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 error;
  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         error = device_read(fmp->dev, bpb, &size, 0);
  83         if (error) {
  84                 free(bpb);
  85                 return error;
  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 error = 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         error = 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 error;
 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 

/* [<][>][^][v][top][bottom][index][help] */