ufs.c

Go to the documentation of this file.
00001 /*****************************************************************************************
00002  Copyright (c) 2002-2004 The UbixOS Project
00003  All rights reserved.
00004 
00005  Redistribution and use in source and binary forms, with or without modification, are
00006  permitted provided that the following conditions are met:
00007 
00008  Redistributions of source code must retain the above copyright notice, this list of
00009  conditions, the following disclaimer and the list of authors.  Redistributions in binary
00010  form must reproduce the above copyright notice, this list of conditions, the following
00011  disclaimer and the list of authors in the documentation and/or other materials provided
00012  with the distribution. Neither the name of the UbixOS Project nor the names of its
00013  contributors may be used to endorse or promote products derived from this software
00014  without specific prior written permission.
00015 
00016  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
00017  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00018  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
00019  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00020  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00021  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00022  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
00023  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00024  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025 
00026  $Id: ufs_8c-source.html 88 2016-01-12 00:11:29Z reddawg $
00027 
00028 *****************************************************************************************/
00029 
00030 #include <vfs/vfs.h>
00031 #include <ufs/ufs.h>
00032 #include <ufs/ffs.h>
00033 #include <lib/kprintf.h>
00034 #include <lib/kmalloc.h>
00035 #include <ubixos/kpanic.h>
00036 #include <lib/string.h>
00037 
00038 #define VBLKSHIFT       12
00039 #define VBLKSIZE        (1 << VBLKSHIFT)
00040 #define VBLKMASK        (VBLKSIZE - 1)
00041 #define DBPERVBLK       (VBLKSIZE / DEV_BSIZE)
00042 #define INDIRPERVBLK(fs) (NINDIR(fs) / ((fs)->fs_bsize >> VBLKSHIFT))
00043 #define IPERVBLK(fs)    (INOPB(fs) / ((fs)->fs_bsize >> VBLKSHIFT))
00044 #define       INOPB(fs)       ((fs)->fs_inopb)
00045 #define INO_TO_VBA(fs, ipervblk, x) \
00046     (fsbtodb(fs, cgimin(fs, ino_to_cg(fs, x))) + \
00047     (((x) % (fs)->fs_ipg) / (ipervblk) * DBPERVBLK))
00048 #define INO_TO_VBO(ipervblk, x) ((x) % ipervblk)
00049 
00050 
00051 static int dskread(void *buf, u_int64_t block,size_t count,fileDescriptor *fd) {
00052   fd->mp->device->devInfo->read(fd->mp->device->devInfo->info,buf,block,count);
00053   return(0x0);
00054   }
00055 
00056 //struct dmadat {
00057 //  char blkbuf[VBLKSIZE];  /* filesystem blocks */
00058 //  char indbuf[VBLKSIZE];  /* indir blocks */
00059 //  char sbbuf[SBLOCKSIZE]; /* superblock */
00060 //  char secbuf[DEV_BSIZE]; /* for MBR/disklabel */
00061 //  };
00062 //static struct dmadat *dmadat;
00063 
00064 //static int ls,dsk_meta;
00065 
00066 static int sblock_try[] = SBLOCKSEARCH;
00067 
00068 #if defined(UFS2_ONLY)
00069 #define DIP(field) dp2.field
00070 #elif defined(UFS1_ONLY)
00071 #define DIP(field) dp1.field
00072 #else
00073 #define DIP(field) fs->fs_magic == FS_UFS1_MAGIC ? dp1.field : dp2.field
00074 #endif
00075 
00076 
00077 static ssize_t fsread(ino_t inode, void *buf, size_t nbyte,fileDescriptor *fd) {
00078 #ifndef UFS2_ONLY
00079         static struct ufs1_dinode dp1;
00080 #endif
00081 #ifndef UFS1_ONLY
00082         static struct ufs2_dinode dp2;
00083 #endif
00084         static ino_t inomap;
00085         char *blkbuf;
00086         void *indbuf;
00087         struct fs *fs;
00088         char *s;
00089         size_t n, nb, size, off, vboff;
00090         ufs_lbn_t lbn;
00091         ufs2_daddr_t addr, vbaddr;
00092         static ufs2_daddr_t blkmap, indmap;
00093         u_int u;
00094 
00095 
00096         blkbuf = fd->dmadat->blkbuf;
00097         indbuf = fd->dmadat->indbuf;
00098         fs = (struct fs *)fd->dmadat->sbbuf;
00099 
00100         if (!fd->dsk_meta) {
00101                 inomap = 0;
00102                 for (n = 0; sblock_try[n] != -1; n++) {
00103                         if (dskread(fs, sblock_try[n] / DEV_BSIZE, 16,fd))
00104                                 return -1;
00105                         if ((
00106 #if defined(UFS1_ONLY)
00107                              fs->fs_magic == FS_UFS1_MAGIC
00108 #elif defined(UFS2_ONLY)
00109                             (fs->fs_magic == FS_UFS2_MAGIC &&
00110                             fs->fs_sblockloc == sblock_try[n])
00111 #else
00112                              fs->fs_magic == FS_UFS1_MAGIC ||
00113                             (fs->fs_magic == FS_UFS2_MAGIC &&
00114                             fs->fs_sblockloc == sblock_try[n])
00115 #endif
00116                             ) &&
00117                             fs->fs_bsize <= MAXBSIZE &&
00118                             fs->fs_bsize >= sizeof(struct fs))
00119                                 break;
00120                 }
00121                 if (sblock_try[n] == -1) {
00122                         kprintf("Not ufs\n");
00123                         return -1;
00124                 }
00125                 fd->dsk_meta++;
00126         }
00127 
00128   if (!inode)
00129     return(0x0);
00130 
00131         if (inomap != inode) {
00132                 n = IPERVBLK(fs);
00133                 if (dskread(blkbuf, INO_TO_VBA(fs, n, inode), DBPERVBLK,fd))
00134                         return -1;
00135                 n = INO_TO_VBO(n, inode);
00136 #if defined(UFS1_ONLY)
00137                 dp1 = ((struct ufs1_dinode *)blkbuf)[n];
00138 #elif defined(UFS2_ONLY)
00139                 dp2 = ((struct ufs2_dinode *)blkbuf)[n];
00140 #else
00141                 if (fs->fs_magic == FS_UFS1_MAGIC)
00142                         dp1 = ((struct ufs1_dinode *)blkbuf)[n];
00143                 else
00144                         dp2 = ((struct ufs2_dinode *)blkbuf)[n];
00145 #endif
00146                 inomap = inode;
00147                 fd->offset = 0;
00148                 blkmap = indmap = 0;
00149         }
00150 
00151         s = buf;
00152         size = DIP(di_size);
00153         fd->size = size;
00154         n = size - fd->offset;
00155  //Why?
00156         if (n < 0)
00157           return(0x0);
00158         if (nbyte > n)
00159                 nbyte = n;
00160         nb = nbyte;
00161         while (nb) {
00162                 lbn = lblkno(fs, fd->offset);
00163                 off = blkoff(fs, fd->offset);
00164                 if (lbn < NDADDR) {
00165                         addr = DIP(di_db[lbn]);
00166                 } else if (lbn < NDADDR + NINDIR(fs)) {
00167                         n = INDIRPERVBLK(fs);
00168                         addr = DIP(di_ib[0]);
00169                         u = (u_int)(lbn - NDADDR) / (n * DBPERVBLK);
00170                         vbaddr = fsbtodb(fs, addr) + u;
00171                         if (indmap != vbaddr) {
00172                                 if (dskread(indbuf, vbaddr, DBPERVBLK,fd))
00173                                         return -1;
00174                                 indmap = vbaddr;
00175                         }
00176                         n = (lbn - NDADDR) & (n - 1);
00177 #if defined(UFS1_ONLY)
00178                         addr = ((ufs1_daddr_t *)indbuf)[n];
00179 #elif defined(UFS2_ONLY)
00180                         addr = ((ufs2_daddr_t *)indbuf)[n];
00181 #else
00182                         if (fs->fs_magic == FS_UFS1_MAGIC)
00183                                 addr = ((ufs1_daddr_t *)indbuf)[n];
00184                         else
00185                                 addr = ((ufs2_daddr_t *)indbuf)[n];
00186 #endif
00187                 } else {
00188                         return -1;
00189                 }
00190                 vbaddr = fsbtodb(fs, addr) + (off >> VBLKSHIFT) * DBPERVBLK;
00191                 vboff = off & VBLKMASK;
00192                 n = sblksize(fs, size, lbn) - (off & ~VBLKMASK);
00193                 if (n > VBLKSIZE)
00194                         n = VBLKSIZE;
00195                 if (blkmap != vbaddr) {
00196                         if (dskread(blkbuf, vbaddr, n >> DEV_BSHIFT,fd))
00197                                 return -1;
00198                         blkmap = vbaddr;
00199                 }
00200                 n -= vboff;
00201                 if (n > nb)
00202                         n = nb;
00203                 memcpy(s, blkbuf + vboff, n);
00204                 s += n;
00205                 fd->offset += n;
00206                 nb -= n;
00207         }
00208         return nbyte;
00209 }
00210 
00211 
00212 
00213 
00214 static __inline int fsfind(const char *name, ino_t * ino,fileDescriptor *fd) {
00215   char buf[DEV_BSIZE];
00216   struct dirent *d;
00217   char *s;
00218   ssize_t n;
00219 
00220   fd->offset = 0;
00221   while ((n = fsread(*ino, buf, DEV_BSIZE,fd)) > 0)
00222     for (s = buf; s < buf + DEV_BSIZE;) {
00223       d = (void *)s;
00224       if (!strcmp(name, d->d_name)) {
00225         *ino = d->d_fileno;
00226         return d->d_type;
00227         }
00228       s += d->d_reclen;
00229       }
00230     //if (n != -1 && ls)
00231     //kprintf("\n");
00232     return 0;
00233     }
00234 
00235 
00236 static ino_t lookup(const char *path,fileDescriptor *fd) {
00237   char name[MAXNAMLEN + 1];
00238         const char *s;
00239         ino_t ino;
00240         ssize_t n;
00241         int dt;
00242 
00243         ino = ROOTINO;
00244         dt = DT_DIR;
00245         name[0] = '/';
00246         name[1] = '\0';
00247         for (;;) {
00248                 if (*path == '/')
00249                         path++;
00250                 if (!*path)
00251                         break;
00252                 for (s = path; *s && *s != '/'; s++);
00253                 if ((n = s - path) > MAXNAMLEN)
00254                         return 0;
00255                 //ls = *path == '?' && n == 1 && !*s;
00256                 memcpy(name, path, n);
00257                 name[n] = 0;
00258                 if (dt != DT_DIR) {
00259                         kprintf("%s: not a directory.\n", name);
00260                         return (0);
00261                 }
00262                 if ((dt = fsfind(name, &ino,fd)) <= 0)
00263                         break;
00264                 path = s;
00265         }
00266 
00267 
00268   return dt == DT_REG ? ino : 0;
00269   }
00270 
00271 
00272 static int ufs_openFile(const char *file, fileDescriptor *fd) {
00273   char tmp[2];
00274   int ino = 0;
00275   fd->dmadat = (struct dmadat *)kmalloc(sizeof(struct dmadat));
00276   ino = lookup(file,fd);
00277   fd->offset = 0x0;
00278   fd->ino = ino;
00279   if (ino == 0x0) {
00280     return(-1);
00281     }
00282 
00283   /* Quick Hack for file size */
00284   fsread(fd->ino,&tmp,1,fd);
00285   fd->offset = 0;
00286   /* Return */
00287   fd->perms = 0x1;
00288   return(0x1);
00289   }
00290 
00291 int ufs_readFile(fileDescriptor *fd,char *data,uInt32 offset,long size) {
00292   return(fsread(fd->ino,data,size,fd));
00293   }
00294 
00295 int ufs_writeFile(fileDescriptor *fd, char *data,uInt32 offset,long size) {
00296   kprintf("Writing :)\n");
00297   return(0x0);
00298   }
00299 
00300 /*****************************************************************************************
00301 
00302 Function: int ufs_initialize()
00303 
00304 Description: This will initialize a mount point it loads the BAT and Caches the rootDir
00305 
00306 Notes:
00307 
00308 *****************************************************************************************/
00309 int ufs_initialize(struct vfs_mountPoint *mp) {
00310   /* Return */
00311   return(0x1);
00312   }
00313 
00314 int ufs_init() {
00315   /* Build our ufs struct */
00316   struct fileSystem ufs =
00317    {NULL,                         /* prev        */
00318     NULL,                         /* next        */
00319     (void *)ufs_initialize,       /* vfsInitFS   */
00320     (void *)ufs_readFile,         /* vfsRead     */
00321     (void *)ufs_writeFile,        /* vfsWrite    */
00322     (void *)ufs_openFile,         /* vfsOpenFile */
00323     NULL,                         /* vfsUnlink   */
00324     NULL,                         /* vfsMakeDir  */
00325     NULL,                         /* vfsRemDir   */
00326     NULL,                         /* vfsSync     */
00327     0xAA,                         /* vfsType     */
00328    }; /* UFS */
00329 
00330   if (vfsRegisterFS(ufs) != 0x0) {
00331     kpanic("Unable To Enable UFS");
00332     return(0x1);
00333     }
00334    //dmadat = (struct dmadat *)kmalloc(sizeof(struct dmadat)); 
00335   /* Return */
00336   return(0x0);
00337   }
00338 
00339 /***
00340  END
00341  ***/
00342 

Generated on Fri Dec 15 11:18:55 2006 for UbixOS V2 by  doxygen 1.4.7