00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
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 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
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  
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     
00231     
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                 
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   
00284   fsread(fd->ino,&tmp,1,fd);
00285   fd->offset = 0;
00286   
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 
00303 
00304 
00305 
00306 
00307 
00308 
00309 int ufs_initialize(struct vfs_mountPoint *mp) {
00310   
00311   return(0x1);
00312   }
00313 
00314 int ufs_init() {
00315   
00316   struct fileSystem ufs =
00317    {NULL,                         
00318     NULL,                         
00319     (void *)ufs_initialize,       
00320     (void *)ufs_readFile,         
00321     (void *)ufs_writeFile,        
00322     (void *)ufs_openFile,         
00323     NULL,                         
00324     NULL,                         
00325     NULL,                         
00326     NULL,                         
00327     0xAA,                         
00328    }; 
00329 
00330   if (vfsRegisterFS(ufs) != 0x0) {
00331     kpanic("Unable To Enable UFS");
00332     return(0x1);
00333     }
00334    
00335   
00336   return(0x0);
00337   }
00338 
00339 
00340 
00341 
00342