openblt

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

rootfs.c (5754B)


      1 /* $Id: //depot/blt/srv/vfs/rootfs.c#3 $
      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 <stdlib.h>
     30 #include <stdio.h>
     31 #include <string.h>
     32 #include <errno.h>
     33 #include "vfs-int.h"
     34 #include "rootfs.h"
     35 
     36 static int inode_max = 0;
     37 
     38 static struct vnode_ops rootfs_vnode_ops =
     39 {
     40 	rootfs_read_vnode, rootfs_drop_vnode, NULL, NULL, rootfs_walk, NULL,
     41 	rootfs_mount, rootfs_unmount, NULL, NULL, NULL, NULL,
     42 	NULL, rootfs_mkdir, NULL, NULL, NULL, NULL, NULL, NULL,
     43 	rootfs_opendir, rootfs_closedir, NULL, rootfs_rewinddir, rootfs_readdir,
     44 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
     45 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
     46 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
     47 	NULL, NULL, NULL, NULL
     48 };
     49 
     50 struct fs_type rootfs = { "rootfs", &rootfs_vnode_ops, NULL };
     51 
     52 static struct rootfs_inode *rootfs_inew (const char *name)
     53 {
     54 	struct rootfs_inode *i;
     55 
     56 	i = malloc (sizeof (struct rootfs_inode));
     57 	i->i_ino = inode_max++;
     58 	i->i_name = malloc (strlen (name) + 1);
     59 	strcpy (i->i_name, name);
     60 	i->i_next = NULL;
     61 	return i;
     62 }
     63 
     64 int rootfs_mount (struct superblock *super, const char *data, int silent)
     65 {
     66 	struct rootfs_inode *ri;
     67 
     68 #ifdef ROOTFS_DEBUG
     69 	printf ("rootfs_mount\n");
     70 #endif
     71 	super->sb_data = ri = rootfs_inew (".");
     72 	ri->i_next = rootfs_inew ("..");
     73 	super->sb_root = vget (super, 0);
     74 	return 0;
     75 }
     76 
     77 void rootfs_unmount (struct superblock *super)
     78 {
     79 #ifdef ROOTFS_DEBUG
     80 	printf ("rootfs_unmount\n");
     81 #endif
     82 }
     83 
     84 int rootfs_read_vnode (struct vnode *vnode)
     85 {
     86 	struct rootfs_inode *inode;
     87 
     88 #ifdef ROOTFS_DEBUG
     89 	printf ("rootfs_read_vnode %llx\n", vnode->v_vnid);
     90 #endif
     91 	inode = vnode->v_sb->sb_data;
     92 	while (inode != NULL)
     93 		if (inode->i_ino == vnode->v_vnid)
     94 		{
     95 			vnode->v_data = inode;
     96 			return 0;
     97 		}
     98 		else
     99 			inode = inode->i_next;
    100 	return -1;
    101 }
    102 
    103 void rootfs_drop_vnode (struct vnode *vnode)
    104 {
    105 	vnode->v_data = NULL;
    106 }
    107 
    108 struct vnode *rootfs_walk (struct vnode *parent, const char *path)
    109 {
    110 	struct rootfs_inode *inode;
    111 
    112 #ifdef ROOTFS_DEBUG
    113 	printf ("rootfs_walk %llx %s\n", parent->v_vnid, path);
    114 #endif
    115 	inode = parent->v_data;
    116 	while (inode != NULL)
    117 		if (strcmp (inode->i_name, path))
    118 			inode = inode->i_next;
    119 		else
    120 			return vget (parent->v_sb, inode->i_ino);
    121 	return NULL;
    122 }
    123 
    124 int rootfs_mkdir (struct vnode *parent, const char *name, mode_t mode)
    125 {
    126 	struct rootfs_inode *inode, *p;
    127 
    128 #ifdef ROOTFS_DEBUG
    129 	printf ("rootfs_mkdir %llx %s\n", parent->v_vnid, name);
    130 #endif
    131 	if (parent->v_vnid)
    132 		return -1; /* paranoia */
    133 
    134 	inode = malloc (sizeof (struct rootfs_inode));
    135 	inode->i_ino = inode_max++;
    136 	inode->i_name = malloc (strlen (name) + 1);
    137 	strcpy (inode->i_name, name);
    138 	inode->i_next = NULL;
    139 
    140 	p = parent->v_sb->sb_data;
    141 	while (p->i_next != NULL)
    142 		p = p->i_next;
    143 	p->i_next = inode;
    144 	return 0;
    145 }
    146 
    147 int rootfs_opendir (struct vnode *dir, void **cookie)
    148 {
    149 	struct vfs_dirent_node *head, *p;
    150 	struct rootfs_inode *inode;
    151 	union rootfs_cookie *rc;
    152 
    153 #ifdef ROOTFS_DEBUG
    154 	printf ("rootfs_opendir\n");
    155 #endif
    156 	if (dir->v_vnid)
    157 		return ENOTDIR; /* paranoia */
    158 
    159 	head = NULL;
    160 	inode = dir->v_sb->sb_data;
    161 	while (inode != NULL)
    162 	{
    163 		p = malloc (sizeof (struct vfs_dirent_node));
    164 		p->dirent = malloc (sizeof (struct dirent));
    165 		p->dirent->d_fileno = inode->i_ino;
    166 		p->dirent->d_reclen = sizeof (struct dirent);
    167 		strncpy (p->dirent->d_name, inode->i_name, sizeof (p->dirent->d_name));
    168 
    169 		p->next = head;
    170 		head = p;
    171 		inode = inode->i_next;
    172 	}
    173 
    174 	rc = malloc (sizeof (union rootfs_cookie));
    175 	rc->u_dir.head = rc->u_dir.current = head;
    176 	*cookie = rc;
    177 	return 0;
    178 }
    179 
    180 void rootfs_closedir (struct vnode *dir, void *cookie)
    181 {
    182 #ifdef ROOTFS_DEBUG
    183 	printf ("rootfs_closedir\n");
    184 #endif
    185 }
    186 
    187 int rootfs_rewinddir (struct vnode *dir, void *cookie)
    188 {
    189 	union rootfs_cookie *rc;
    190 
    191 #ifdef ROOTFS_DEBUG
    192 	printf ("rootfs_rewinddir\n");
    193 #endif
    194 
    195 	rc = cookie;
    196 	rc->u_dir.current = rc->u_dir.head;
    197 	return 0;
    198 }
    199 
    200 int rootfs_readdir (struct vnode *dir, struct dirent *dirent, void *cookie)
    201 {
    202 	struct dirent *orig;
    203 	union rootfs_cookie *rc;
    204 
    205 	rc = cookie;
    206 	if (rc->u_dir.current == NULL)
    207 		return 1;
    208 	orig = rc->u_dir.current->dirent;
    209 	dirent->d_fileno = orig->d_fileno;
    210 	dirent->d_reclen = orig->d_reclen;
    211 	strncpy (dirent->d_name, orig->d_name, BLT_MAX_NAME_LENGTH);
    212 	rc->u_dir.current = rc->u_dir.current->next;
    213 #ifdef ROOTFS_DEBUG
    214 	printf ("rootfs_readdir %s\n", dirent->d_name);
    215 #endif
    216 	return 0;
    217 }
    218