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 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
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
00224
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
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
00277 fsread(fd->ino,&tmp,1,fd);
00278 fd->offset = 0;
00279
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
00297
00298
00299
00300
00301
00302
00303 int ufs_initialize(vfs_mountPoint_t *mp) {
00304
00305 return(0x1);
00306 }
00307
00308 int ufs_init() {
00309
00310 struct fileSystem ufs =
00311 {NULL,
00312 NULL,
00313 (void *)ufs_initialize,
00314 (void *)ufs_readFile,
00315 (void *)ufs_writeFile,
00316 (void *)ufs_openFile,
00317 NULL,
00318 NULL,
00319 NULL,
00320 NULL,
00321 0xAA,
00322 };
00323
00324 if (vfsRegisterFS(ufs) != 0x0) {
00325 kpanic("Unable To Enable UFS");
00326 return(0x1);
00327 }
00328
00329
00330 return(0x0);
00331 }
00332
00333
00334
00335
00336