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