openblt

a hobby OS from the late 90s
git clone http://frotz.net/git/openblt.git
Log | Files | Refs | LICENSE

file.c (5319B)


      1 /* $Id: //depot/blt/srv/vfs/drivers/ffs/file.c#2 $
      2 **
      3 ** Copyright 1999 Sidney Cammeresi
      4 ** All rights reserved.
      5 **
      6 ** Redistribution and use in source and binary forms, with or without
      7 ** modification, are permitted provided that the following conditions
      8 ** are met:
      9 ** 1. Redistributions of source code must retain the above copyright
     10 **    notice, this list of conditions, and the following disclaimer.
     11 ** 2. Redistributions in binary form must reproduce the above copyright
     12 **    notice, this list of conditions, and the following disclaimer in the
     13 **    documentation and/or other materials provided with the distribution.
     14 ** 3. The name of the author may not be used to endorse or promote products
     15 **    derived from this software without specific prior written permission.
     16 **
     17 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19 ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 */
     28 
     29 #include <stdio.h>
     30 #include <stdlib.h>
     31 #include <string.h>
     32 #include "vfs-int.h"
     33 
     34 #ifndef VFS_SANDBOX
     35 #include <blt/blkdev.h>
     36 #else
     37 #include "../../sandbox/blkdev.h"
     38 #endif
     39 
     40 #include "ffs.h"
     41 #include "ffs-blt.h"
     42 #include "dinode.h"
     43 
     44 int ffs_open (struct vnode *vnode, void **cookie)
     45 {
     46 	struct ffs_super_data *data;
     47 	struct ffs_dinode *inode;
     48 	struct ffs_cookie *fc;
     49 
     50 #ifdef FFS_DEBUG
     51 	printf ("ffs_open %lld\n", vnode->v_vnid);
     52 #endif
     53 	data = vnode->v_sb->sb_data;
     54 	inode = vnode->v_data;
     55 	fc = malloc (sizeof (struct ffs_cookie));
     56 	*cookie = fc;
     57 	return 0;
     58 }
     59 
     60 int ffs_close (struct vnode *vnode, void *cookie)
     61 {
     62 #ifdef FFS_DEBUG
     63 	printf ("ffs_close %lld\n", vnode->v_vnid);
     64 #endif
     65 	return 0;
     66 }
     67 
     68 void ffs_free_cookie (void *cookie)
     69 {
     70 #ifdef FFS_DEBUG
     71 	printf ("ffs_free_cookie\n");
     72 #endif
     73 	free (cookie);
     74 }
     75 
     76 static inline int32 ffs_fbtofsb (struct ffs_super *fs, blkdev_t *dev,
     77 	struct ffs_dinode *di, uint32 fb)
     78 {
     79 	int32 *buf, res;
     80 
     81 	if (fb < NDADDR)
     82 		return di->di_db[fb];
     83 	else if ((fb -= NDADDR) < NINDIR (fs))
     84 	{
     85 		buf = malloc (BLKSIZE);
     86 		blk_read (dev, buf, fsbtodb (fs, di->di_ib[0]), BLKSIZE / dev->blksize);
     87 		res = buf[fb];
     88 		free (buf);
     89 		return res;
     90 	}
     91 	else if ((fb -= NINDIR (fs)) < NINDIR (fs) * NINDIR (fs))
     92 	{
     93 		printf ("ffs: doubly indirect blocks unsupported.\n");
     94 		return 0;
     95 	}
     96 	else if ((fb -= NINDIR (fs) * NINDIR (fs)) < NINDIR (fs) * NINDIR (fs) *
     97 		NINDIR (fs))
     98 	{
     99 		printf ("ffs: trebly indirect blocks unsupported.\n");
    100 		return 0;
    101 	}
    102 	else
    103 		return -1;
    104 }
    105 
    106 int ffs_read (struct vnode *vnode, char *buf, size_t count, off_t pos,
    107 	size_t *numbytes, void *cookie)
    108 {
    109 	char *temp;
    110 	int i, block;
    111 	off_t offset, len;
    112 	struct ffs_super *fs;
    113 	struct ffs_super_data *data;
    114 	struct ffs_dinode *di;
    115 
    116 #ifdef FFS_DEBUG
    117 	printf ("ffs_read %lld %d\n", pos, count);
    118 #endif
    119 	*numbytes = 0;
    120 	if (!count)
    121 		return 0;
    122 	data = vnode->v_sb->sb_data;
    123 	fs = data->sbbuf;
    124 	di = vnode->v_data;
    125 	if (pos >= di->di_size)
    126 		return 0;
    127 	if (pos + count > di->di_size)
    128 		count = di->di_size - pos;
    129 	temp = malloc (BLKSIZE);
    130 
    131 	/*
    132 	 * if we are not starting at a block boundary, first read up to the
    133 	 * next block boundary.
    134 	 */
    135 	if ((offset = pos % BLKSIZE)) 
    136 	{
    137 		block = ffs_fbtofsb (fs, data->dev, di, pos / BLKSIZE);
    138 		len = (count < (BLKSIZE - offset)) ? count : (BLKSIZE - offset);
    139 		blk_read (data->dev, temp, fsbtodb (fs, block), BLKSIZE /
    140 			data->dev->blksize);
    141 		memcpy (buf, temp + offset, len);
    142 		*numbytes += len, pos += len;
    143 #ifdef FFS_DEBUG
    144 		printf ("ffs_read: (1) %lld\n", len);
    145 #endif
    146 	}
    147 	if (*numbytes == count)
    148 		goto done;
    149 
    150 	/*
    151 	 * now we are block-aligned; read whole blocks at a time until we have
    152 	 * less than a full block to go.
    153 	 */
    154 	for (i = 0; i < ((count - *numbytes) / BLKSIZE); i++, *numbytes += BLKSIZE,
    155 		pos += BLKSIZE)
    156 	{
    157 		block = ffs_fbtofsb (fs, data->dev, di, pos / BLKSIZE);
    158 		blk_read (data->dev, temp, fsbtodb (fs, block), BLKSIZE /
    159 			data->dev->blksize);
    160 		memcpy (buf + *numbytes, temp, BLKSIZE);
    161 #ifdef FFS_DEBUG
    162 		printf ("ffs_read: (2) #%d\n", i);
    163 #endif
    164 	}
    165 	if (*numbytes == count)
    166 		goto done;
    167 
    168 	/*
    169 	 * read in the next block and copy as much as we need.
    170 	 */
    171 	block = ffs_fbtofsb (fs, data->dev, di, pos / BLKSIZE);
    172 	blk_read (data->dev, temp, fsbtodb (fs, block), BLKSIZE /
    173 		data->dev->blksize);
    174 	memcpy (buf + *numbytes, temp, len = count - *numbytes);
    175 	*numbytes += len, pos += len;
    176 #ifdef FFS_DEBUG
    177 	printf ("ffs_read: (3) %lld\n", len);
    178 #endif
    179 
    180 done:
    181 	free (temp);
    182 	return 0;
    183 }
    184 
    185 int ffs_rstat (struct vnode *vnode, struct stat *buf)
    186 {
    187 	struct ffs_dinode *di;
    188 #ifdef FFS_DEBUG
    189 	printf ("ffs_rstat %lld\n", vnode->v_vnid);
    190 #endif
    191 
    192 	di = vnode->v_data;
    193 	buf->st_ino = vnode->v_vnid;
    194 	buf->st_nlink = di->di_nlink;
    195 	buf->st_uid = di->di_uid;
    196 	buf->st_gid = di->di_gid;
    197 	buf->st_size = di->di_size;
    198 	buf->st_blocks = di->di_blocks;
    199 	return 0;
    200 }
    201