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$
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         blkbuf = fd->dmadat->blkbuf;
00096         indbuf = fd->dmadat->indbuf;
00097         fs = (struct fs *)fd->dmadat->sbbuf;
00098         if (!fd->dsk_meta) {
00099                 inomap = 0;
00100                 for (n = 0; sblock_try[n] != -1; n++) {
00101                         if (dskread(fs, sblock_try[n] / DEV_BSIZE, 16,fd))
00102                                 return -1;
00103                         if ((
00104 #if defined(UFS1_ONLY)
00105                              fs->fs_magic == FS_UFS1_MAGIC
00106 #elif defined(UFS2_ONLY)
00107                             (fs->fs_magic == FS_UFS2_MAGIC &&
00108                             fs->fs_sblockloc == sblock_try[n])
00109 #else
00110                              fs->fs_magic == FS_UFS1_MAGIC ||
00111                             (fs->fs_magic == FS_UFS2_MAGIC &&
00112                             fs->fs_sblockloc == sblock_try[n])
00113 #endif
00114                             ) &&
00115                             fs->fs_bsize <= MAXBSIZE &&
00116                             fs->fs_bsize >= sizeof(struct fs))
00117                                 break;
00118                 }
00119                 if (sblock_try[n] == -1) {
00120                         kprintf("Not ufs\n");
00121                         return -1;
00122                 }
00123                 fd->dsk_meta++;
00124         }
00125         if (!inode)
00126                 return 0;
00127         if (inomap != inode) {
00128                 n = IPERVBLK(fs);
00129                 if (dskread(blkbuf, INO_TO_VBA(fs, n, inode), DBPERVBLK,fd))
00130                         return -1;
00131                 n = INO_TO_VBO(n, inode);
00132 #if defined(UFS1_ONLY)
00133                 dp1 = ((struct ufs1_dinode *)blkbuf)[n];
00134 #elif defined(UFS2_ONLY)
00135                 dp2 = ((struct ufs2_dinode *)blkbuf)[n];
00136 #else
00137                 if (fs->fs_magic == FS_UFS1_MAGIC)
00138                         dp1 = ((struct ufs1_dinode *)blkbuf)[n];
00139                 else
00140                         dp2 = ((struct ufs2_dinode *)blkbuf)[n];
00141 #endif
00142                 inomap = inode;
00143                 fd->offset = 0;
00144                 blkmap = indmap = 0;
00145         }
00146         s = buf;
00147         size = DIP(di_size);
00148         fd->size = size;
00149         //kprintf("Size: [%i]\n",size);
00150         n = size - fd->offset;
00151         if (nbyte > n)
00152                 nbyte = n;
00153         nb = nbyte;
00154         while (nb) {
00155                 lbn = lblkno(fs, fd->offset);
00156                 off = blkoff(fs, fd->offset);
00157                 if (lbn < NDADDR) {
00158                         addr = DIP(di_db[lbn]);
00159                 } else if (lbn < NDADDR + NINDIR(fs)) {
00160                         n = INDIRPERVBLK(fs);
00161                         addr = DIP(di_ib[0]);
00162                         u = (u_int)(lbn - NDADDR) / (n * DBPERVBLK);
00163                         vbaddr = fsbtodb(fs, addr) + u;
00164                         if (indmap != vbaddr) {
00165                                 if (dskread(indbuf, vbaddr, DBPERVBLK,fd))
00166                                         return -1;
00167                                 indmap = vbaddr;
00168                         }
00169                         n = (lbn - NDADDR) & (n - 1);
00170 #if defined(UFS1_ONLY)
00171                         addr = ((ufs1_daddr_t *)indbuf)[n];
00172 #elif defined(UFS2_ONLY)
00173                         addr = ((ufs2_daddr_t *)indbuf)[n];
00174 #else
00175                         if (fs->fs_magic == FS_UFS1_MAGIC)
00176                                 addr = ((ufs1_daddr_t *)indbuf)[n];
00177                         else
00178                                 addr = ((ufs2_daddr_t *)indbuf)[n];
00179 #endif
00180                 } else {
00181                         return -1;
00182                 }
00183                 vbaddr = fsbtodb(fs, addr) + (off >> VBLKSHIFT) * DBPERVBLK;
00184                 vboff = off & VBLKMASK;
00185                 n = sblksize(fs, size, lbn) - (off & ~VBLKMASK);
00186                 if (n > VBLKSIZE)
00187                         n = VBLKSIZE;
00188                 if (blkmap != vbaddr) {
00189                         if (dskread(blkbuf, vbaddr, n >> DEV_BSHIFT,fd))
00190                                 return -1;
00191                         blkmap = vbaddr;
00192                 }
00193                 n -= vboff;
00194                 if (n > nb)
00195                         n = nb;
00196                 memcpy(s, blkbuf + vboff, n);
00197                 s += n;
00198                 fd->offset += n;
00199                 nb -= n;
00200         }
00201         return nbyte;
00202 }
00203 
00204 
00205 
00206 
00207 static __inline int fsfind(const char *name, ino_t * ino,fileDescriptor *fd) {
00208   char buf[DEV_BSIZE];
00209   struct dirent *d;
00210   char *s;
00211   ssize_t n;
00212 
00213   fd->offset = 0;
00214   while ((n = fsread(*ino, buf, DEV_BSIZE,fd)) > 0)
00215     for (s = buf; s < buf + DEV_BSIZE;) {
00216       d = (void *)s;
00217       if (!strcmp(name, d->d_name)) {
00218         *ino = d->d_fileno;
00219         return d->d_type;
00220         }
00221       s += d->d_reclen;
00222       }
00223     //if (n != -1 && ls)
00224     //kprintf("\n");
00225     return 0;
00226     }
00227 
00228 
00229 static ino_t lookup(const char *path,fileDescriptor *fd) {
00230   char name[MAXNAMLEN + 1];
00231         const char *s;
00232         ino_t ino;
00233         ssize_t n;
00234         int dt;
00235 
00236         ino = ROOTINO;
00237         dt = DT_DIR;
00238         name[0] = '/';
00239         name[1] = '\0';
00240         for (;;) {
00241                 if (*path == '/')
00242                         path++;
00243                 if (!*path)
00244                         break;
00245                 for (s = path; *s && *s != '/'; s++);
00246                 if ((n = s - path) > MAXNAMLEN)
00247                         return 0;
00248                 //ls = *path == '?' && n == 1 && !*s;
00249                 memcpy(name, path, n);
00250                 name[n] = 0;
00251                 if (dt != DT_DIR) {
00252                         kprintf("%s: not a directory.\n", name);
00253                         return (0);
00254                 }
00255                 if ((dt = fsfind(name, &ino,fd)) <= 0)
00256                         break;
00257                 path = s;
00258         }
00259 
00260 
00261   return dt == DT_REG ? ino : 0;
00262   }
00263 
00264 
00265 static int ufs_openFile(const char *file, fileDescriptor *fd) {
00266   char tmp[2];
00267   int ino = 0;
00268   fd->dmadat = (struct dmadat *)kmalloc(sizeof(struct dmadat));
00269   ino = lookup(file,fd);
00270   fd->offset = 0x0;
00271   fd->ino = ino;
00272   if (ino == 0x0) {
00273     return(-1);
00274     }
00275 
00276   /* Quick Hack for file size */
00277   fsread(fd->ino,&tmp,1,fd);
00278   fd->offset = 0;
00279   /* Return */
00280   fd->perms = 0x1;
00281   return(0x1);
00282   }
00283 
00284 int ufs_readFile(fileDescriptor *fd,char *data,uInt32 offset,long size) {
00285   fsread(fd->ino,data,size,fd);
00286   return(0x0);
00287   }
00288 
00289 int ufs_writeFile(fileDescriptor *fd, char *data,uInt32 offset,long size) {
00290   kprintf("Writing :)\n");
00291   return(0x0);
00292   }
00293 
00294 /*****************************************************************************************
00295 
00296 Function: int ufs_initialize()
00297 
00298 Description: This will initialize a mount point it loads the BAT and Caches the rootDir
00299 
00300 Notes:
00301 
00302 *****************************************************************************************/
00303 int ufs_initialize(vfs_mountPoint_t *mp) {
00304   /* Return */
00305   return(0x1);
00306   }
00307 
00308 int ufs_init() {
00309   /* Build our ufs struct */
00310   struct fileSystem ufs =
00311    {NULL,                         /* prev        */
00312     NULL,                         /* next        */
00313     (void *)ufs_initialize,       /* vfsInitFS   */
00314     (void *)ufs_readFile,         /* vfsRead     */
00315     (void *)ufs_writeFile,        /* vfsWrite    */
00316     (void *)ufs_openFile,         /* vfsOpenFile */
00317     NULL,                         /* vfsUnlink   */
00318     NULL,                         /* vfsMakeDir  */
00319     NULL,                         /* vfsRemDir   */
00320     NULL,                         /* vfsSync     */
00321     0xAA,                         /* vfsType     */
00322    }; /* UFS */
00323 
00324   if (vfsRegisterFS(ufs) != 0x0) {
00325     kpanic("Unable To Enable UFS");
00326     return(0x1);
00327     }
00328    //dmadat = (struct dmadat *)kmalloc(sizeof(struct dmadat)); 
00329   /* Return */
00330   return(0x0);
00331   }
00332 
00333 /***
00334  END
00335  ***/
00336 

Generated on Sun Dec 3 02:38:05 2006 for UbixOS V2 by  doxygen 1.4.7