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