# 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