UbixOS  2.0
ufs.c
Go to the documentation of this file.
1 /*****************************************************************************************
2  Copyright (c) 2002-2004 The UbixOS Project
3  All rights reserved.
4 
5  Redistribution and use in source and binary forms, with or without modification, are
6  permitted provided that the following conditions are met:
7 
8  Redistributions of source code must retain the above copyright notice, this list of
9  conditions, the following disclaimer and the list of authors. Redistributions in binary
10  form must reproduce the above copyright notice, this list of conditions, the following
11  disclaimer and the list of authors in the documentation and/or other materials provided
12  with the distribution. Neither the name of the UbixOS Project nor the names of its
13  contributors may be used to endorse or promote products derived from this software
14  without specific prior written permission.
15 
16  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
17  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
19  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
23  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26  $Id: ufs.c 102 2016-01-12 03:59:34Z reddawg $
27 
28  *****************************************************************************************/
29 
30 #include <sys/types.h>
31 #include <vfs/vfs.h>
32 #include <vfs/file.h>
33 #include <ufs/ufs.h>
34 #include <ufs/ffs.h>
35 #include <lib/kprintf.h>
36 #include <lib/kmalloc.h>
37 #include <ubixos/kpanic.h>
38 #include <string.h>
39 
40 #define VBLKSHIFT 12
41 #define VBLKSIZE (1 << VBLKSHIFT)
42 #define VBLKMASK (VBLKSIZE - 1)
43 #define DBPERVBLK (VBLKSIZE / DEV_BSIZE)
44 #define INDIRPERVBLK(fs) (NINDIR(fs) / ((fs)->fs_bsize >> VBLKSHIFT))
45 #define IPERVBLK(fs) (INOPB(fs) / ((fs)->fs_bsize >> VBLKSHIFT))
46 #define INOPB(fs) ((fs)->fs_inopb)
47 #define INO_TO_VBA(fs, ipervblk, x) \
48  (fsbtodb(fs, cgimin(fs, ino_to_cg(fs, x))) + \
49  (((x) % (fs)->fs_ipg) / (ipervblk) * DBPERVBLK))
50 #define INO_TO_VBO(ipervblk, x) ((x) % ipervblk)
51 
52 static int dskread(void *buf, uint64_t block, size_t count, fileDescriptor_t *fd) {
53  fd->mp->device->devInfo->read(fd->mp->device->devInfo->info, buf, block, count);
54  return (0x0);
55 }
56 
57 //struct dmadat {
58 // char blkbuf[VBLKSIZE]; /* filesystem blocks */
59 // char indbuf[VBLKSIZE]; /* indir blocks */
60 // char sbbuf[SBLOCKSIZE]; /* superblock */
61 // char secbuf[DEV_BSIZE]; /* for MBR/disklabel */
62 // };
63 //static struct dmadat *dmadat;
64 
65 //static int ls,dsk_meta;
66 
67 static int sblock_try[] = SBLOCKSEARCH;
68 
69 #if defined(UFS2_ONLY)
70 #define DIP(field) dp2.field
71 #elif defined(UFS1_ONLY)
72 #define DIP(field) dp1.field
73 #else
74 #define DIP(field) fs->fs_magic == FS_UFS1_MAGIC ? dp1.field : dp2.field
75 #endif
76 
77 static ssize_t fsread(ino_t inode, void *buf, size_t nbyte, fileDescriptor_t *fd) {
78 #ifndef UFS2_ONLY
79  static struct ufs1_dinode dp1;
80 #endif
81 #ifndef UFS1_ONLY
82  static struct ufs2_dinode dp2;
83 #endif
84  static ino_t inomap;
85  char *blkbuf;
86  void *indbuf;
87  struct fs *fs;
88  char *s;
89  size_t n, nb, size, off, vboff;
90  ufs_lbn_t lbn;
91  ufs2_daddr_t addr, vbaddr;
92  static ufs2_daddr_t blkmap, indmap;
93  u_int u;
94 
95  blkbuf = fd->dmadat->blkbuf;
96  indbuf = fd->dmadat->indbuf;
97  fs = (struct fs *) fd->dmadat->sbbuf;
98 
99  if (!fd->dsk_meta) {
100  inomap = 0;
101  for (n = 0; sblock_try[n] != -1; n++) {
102  if (dskread(fs, sblock_try[n] / DEV_BSIZE, 16, fd))
103  return -1;
104  if ((
105 #if defined(UFS1_ONLY)
107 #elif defined(UFS2_ONLY)
108  (fs->fs_magic == FS_UFS2_MAGIC && fs->fs_sblockloc == sblock_try[n])
109 #else
110  fs->fs_magic == FS_UFS1_MAGIC || (fs->fs_magic == FS_UFS2_MAGIC && fs->fs_sblockloc == sblock_try[n])
111 #endif
112  ) && fs->fs_bsize <= MAXBSIZE && fs->fs_bsize >= sizeof(struct fs))
113  break;
114  //MrOlsen 2017-12-14 this was for debugging kprintf("Finding SBlock: [%s][0x%X][%i - %i]\n", fs->fs_fsmnt, fs->fs_magic, sblock_try[n], sblock_try[n] / DEV_BSIZE);
115  }
116  if (sblock_try[n] == -1) {
117  kprintf("Not ufs\n");
118  return -1;
119  }
120  fd->dsk_meta++;
121  }
122 
123  if (!inode)
124  return (0x0);
125 
126  if (inomap != inode) {
127  n = IPERVBLK(fs);
128  if (dskread(blkbuf, INO_TO_VBA(fs, n, inode), DBPERVBLK, fd))
129  return -1;
130  n = INO_TO_VBO(n, inode);
131 #if defined(UFS1_ONLY)
132  dp1 = ((struct ufs1_dinode *)blkbuf)[n];
133  memcpy(fd->inode.ufs1, dp1, sizeof(struct ufs1_dinode));
134 #elif defined(UFS2_ONLY)
135  dp2 = ((struct ufs2_dinode *)blkbuf)[n];
136  memcpy(fd->inode.ufs2, dp2, sizeof(struct ufs2_dinode));
137 #else
138  if (fs->fs_magic == FS_UFS1_MAGIC) {
139  dp1 = ((struct ufs1_dinode *) blkbuf)[n];
140  memcpy(&fd->inode.u.ufs1_i, &dp1, sizeof(struct ufs1_dinode));
141  }
142  else{
143  dp2 = ((struct ufs2_dinode *) blkbuf)[n];
144  memcpy(&fd->inode.u.ufs2_i, &dp2, sizeof(struct ufs2_dinode));
145  }
146 #endif
147  inomap = inode;
148  fd->offset = 0;
149  blkmap = indmap = 0;
150  }
151 
152  s = buf;
153  size = DIP(di_size);
154  fd->size = size;
155  n = size - fd->offset;
156  //Why?
157  if (n < 0)
158  return (0x0);
159  if (nbyte > n)
160  nbyte = n;
161  nb = nbyte;
162  while (nb) {
163  lbn = lblkno(fs, fd->offset);
164  off = blkoff(fs, fd->offset);
165  if (lbn < NDADDR) {
166  addr = DIP(di_db[lbn]);
167  } else if (lbn < NDADDR + NINDIR(fs)) {
168  n = INDIRPERVBLK(fs);
169  addr = DIP(di_ib[0]);
170  u = (u_int) (lbn - NDADDR) / (n * DBPERVBLK);
171  vbaddr = fsbtodb(fs, addr) + u;
172  if (indmap != vbaddr) {
173  if (dskread(indbuf, vbaddr, DBPERVBLK, fd))
174  return -1;
175  indmap = vbaddr;
176  }
177  n = (lbn - NDADDR) & (n - 1);
178 #if defined(UFS1_ONLY)
179  addr = ((ufs1_daddr_t *)indbuf)[n];
180 #elif defined(UFS2_ONLY)
181  addr = ((ufs2_daddr_t *)indbuf)[n];
182 #else
183  if (fs->fs_magic == FS_UFS1_MAGIC)
184  addr = ((ufs1_daddr_t *) indbuf)[n];
185  else
186  addr = ((ufs2_daddr_t *) indbuf)[n];
187 #endif
188  } else {
189  return -1;
190  }
191  vbaddr = fsbtodb(fs, addr) + (off >> VBLKSHIFT) * DBPERVBLK;
192  vboff = off & VBLKMASK;
193  n = sblksize(fs, size, lbn) - (off & ~VBLKMASK);
194  if (n > VBLKSIZE)
195  n = VBLKSIZE;
196  if (blkmap != vbaddr) {
197  if (dskread(blkbuf, vbaddr, n >> DEV_BSHIFT, fd))
198  return -1;
199  blkmap = vbaddr;
200  }
201  n -= vboff;
202  if (n > nb)
203  n = nb;
204  memcpy(s, blkbuf + vboff, n);
205  s += n;
206  fd->offset += n;
207  nb -= n;
208  }
209  return nbyte;
210 }
211 
212 static __inline int fsfind(const char *name, ino_t * ino, fileDescriptor_t *fd) {
213  char buf[DEV_BSIZE];
214  struct dirent *d;
215  char *s;
216  ssize_t n;
217 
218  fd->offset = 0;
219  while ((n = fsread(*ino, buf, DEV_BSIZE, fd)) > 0)
220  for (s = buf; s < buf + DEV_BSIZE;) {
221  d = (void *) s;
222  if (!strcmp(name, d->d_name)) {
223  *ino = d->d_fileno;
224  return d->d_type;
225  }
226  s += d->d_reclen;
227  }
228  *ino = 0x0;
229  return 0;
230 }
231 
232 static ino_t lookup(const char *path, fileDescriptor_t *fd) {
233  char name[MAXNAMLEN + 1];
234  const char *s;
235  ino_t ino;
236  ssize_t n;
237  int dt;
238 
239  ino = ROOTINO;
240  dt = DT_DIR;
241  name[0] = '/';
242  name[1] = '\0';
243  for (;;) {
244  if (*path == '/')
245  path++;
246  if (!*path)
247  break;
248  for (s = path; *s && *s != '/'; s++)
249  ;
250  if ((n = s - path) > MAXNAMLEN)
251  return 0;
252  //ls = *path == '?' && n == 1 && !*s;
253  memcpy(name, path, n);
254  name[n] = 0;
255  if (dt != DT_DIR) {
256  kprintf("%s: not a directory.\n", name);
257  return (0);
258  }
259  if ((dt = fsfind(name, &ino, fd)) <= 0)
260  break;
261  path = s;
262  }
263  return ino;
264  return dt == DT_REG ? ino : 0;
265 }
266 
267 static int ufs_openFile(const char *file, fileDescriptor_t *fd) {
268  char tmp[2];
269  int ino = 0;
270 
271  fd->dmadat = (struct dmadat *) kmalloc(sizeof(struct dmadat));
272 
273  ino = lookup(file, fd);
274 
275  fd->offset = 0x0;
276  fd->ino = ino;
277 
278  if (ino == 0x0) {
279  kfree(fd->dmadat);
280  return (-1);
281  }
282 
283  /* Quick Hack for file size */
284  fsread(fd->ino, &tmp, 1, fd);
285  fd->offset = 0;
286 
287  /* Return */
288  fd->perms = 0x1;
289  return (0x1);
290 }
291 
292 int ufs_readFile(fileDescriptor_t *fd, char *data, uInt32 offset, long size) {
293  return (fsread(fd->ino, data, size, fd));
294 }
295 
296 int ufs_writeFile(fileDescriptor_t *fd, char *data, uInt32 offset, long size) {
297  kprintf("Writing :)\n");
298  return (0x0);
299 }
300 
301 /*****************************************************************************************
302 
303  Function: int ufs_initialize()
304 
305  Description: This will initialize a mount point it loads the BAT and Caches the rootDir
306 
307  Notes:
308 
309  *****************************************************************************************/
310 int ufs_initialize(struct vfs_mountPoint *mp) {
311  /* Return */
312  return (0x1);
313 }
314 
315 int ufs_init() {
316  /* Build our ufs struct */
317  struct fileSystem ufs = { NULL, /* prev */
318  NULL, /* next */
319  (void *) ufs_initialize, /* vfsInitFS */
320  (void *) ufs_readFile, /* vfsRead */
321  (void *) ufs_writeFile, /* vfsWrite */
322  (void *) ufs_openFile, /* vfsOpenFile */
323  NULL, /* vfsUnlink */
324  NULL, /* vfsMakeDir */
325  NULL, /* vfsRemDir */
326  NULL, /* vfsSync */
327  0xAA, /* vfsType */
328  }; /* UFS */
329 
330  if (vfsRegisterFS(ufs) != 0x0) {
331  kpanic("Unable To Enable UFS");
332  return (0x1);
333  }
334  //dmadat = (struct dmadat *)kmalloc(sizeof(struct dmadat));
335  /* Return */
336  return (0x0);
337 }
338 
339 /***
340  END
341  ***/
fs::fs_magic
int32_t fs_magic
Definition: fs.h:365
inode::ufs1_i
struct ufs1_dinode ufs1_i
Definition: inode.h:74
ufs2_dinode::di_size
u_int64_t di_size
Definition: ufs.h:110
MAXBSIZE
#define MAXBSIZE
Definition: ufs.h:53
IPERVBLK
#define IPERVBLK(fs)
Definition: ufs.c:44
uInt32
unsigned long int uInt32
Definition: objgfx30.h:49
VBLKSIZE
#define VBLKSIZE
Definition: ufs.c:40
__inline
#define __inline
Definition: cdefs.h:179
ufs_initialize
int ufs_initialize(struct vfs_mountPoint *mp)
Definition: ufs.c:308
file.h
vfs.h
fileDescriptor::dmadat
struct dmadat * dmadat
Definition: file.h:77
ufs1_daddr_t
int32_t ufs1_daddr_t
Definition: ufs.h:86
MAXNAMLEN
#define MAXNAMLEN
Definition: ufs.h:36
string.h
dmadat::sbbuf
char sbbuf[8192]
Definition: file.h:58
fileDescriptor::offset
off_t offset
Definition: file.h:69
fileDescriptor
Definition: file.h:62
DT_DIR
#define DT_DIR
Definition: ufs.h:38
file
Definition: descrip.h:67
kfree
void kfree(void *baseAddr)
Definition: kmalloc.c:342
uint64_t
__uint64_t uint64_t
Definition: types.h:47
lookup
int lookup(struct inode *dir, const char *name, int len, struct inode **result)
Definition: namei.c:68
SBLOCKSEARCH
#define SBLOCKSEARCH
Definition: fs.h:76
strcmp
int strcmp(const char *str1, const char *str2)
NDADDR
#define NDADDR
Definition: ufs.h:101
ino_t
__ino_t ino_t
Definition: types.h:93
fileDescriptor::dsk_meta
int dsk_meta
Definition: file.h:78
fileSystem
filesSystem Structure
Definition: vfs.h:59
kpanic
void kpanic(const char *fmt,...)
print panic message and halt system
Definition: kpanic.c:41
types.h
ROOTINO
#define ROOTINO
Definition: ufs.h:37
INDIRPERVBLK
#define INDIRPERVBLK(fs)
Definition: ufs.c:43
dmadat::blkbuf
char blkbuf[(1<< 12)]
Definition: file.h:56
blkoff
#define blkoff(fs, loc)
Definition: fs.h:570
memcpy
void * memcpy(const void *dst, const void *src, size_t length)
fs
Definition: fs.h:260
fileDescriptor::mp
struct vfs_mountPoint * mp
Definition: file.h:65
vfsRegisterFS
int vfsRegisterFS(struct fileSystem newFS)
register a file system
Definition: vfs.c:79
vfs_mountPoint
Definition: mount.h:66
kpanic.h
ufs_writeFile
int ufs_writeFile(fileDescriptor_t *fd, char *data, uInt32 offset, long size)
Definition: ufs.c:295
inode
Definition: inode.h:39
kprintf.h
FS_UFS2_MAGIC
#define FS_UFS2_MAGIC
Definition: fs.h:377
dirent::d_reclen
__uint16_t d_reclen
Definition: ufs.h:94
dirent
Definition: ufs.h:92
VBLKMASK
#define VBLKMASK
Definition: ufs.c:41
NINDIR
#define NINDIR(fs)
Definition: fs.h:622
dirent::d_name
char d_name[255+1]
Definition: ufs.h:97
buf
Definition: buf.h:35
ufs_readFile
int ufs_readFile(fileDescriptor_t *fd, char *data, uInt32 offset, long size)
Definition: ufs.c:291
inode::u
union inode::@22 u
FS_UFS1_MAGIC
#define FS_UFS1_MAGIC
Definition: fs.h:376
inode::ufs2_i
struct ufs2_dinode ufs2_i
Definition: inode.h:75
ufs2_dinode::di_db
ufs2_daddr_t di_db[12]
Definition: ufs.h:125
ufs_lbn_t
int64_t ufs_lbn_t
Definition: ufs.h:88
sblksize
#define sblksize(fs, size, lbn)
Definition: fs.h:614
fileDescriptor::ino
uint32_t ino
Definition: file.h:66
fs::fs_bsize
int32_t fs_bsize
Definition: fs.h:273
DIP
#define DIP(field)
Definition: ufs.c:73
fileDescriptor::inode
struct inode inode
Definition: file.h:80
device_interface::read
int(* read)(void *, void *, uInt32, uInt32)
Definition: device.h:52
lblkno
#define lblkno(fs, loc)
Definition: fs.h:581
ufs_init
int ufs_init()
Definition: ufs.c:313
fileDescriptor::perms
uint32_t perms
Definition: file.h:76
name
const char * name
Definition: pci.c:37
ufs.h
INO_TO_VBA
#define INO_TO_VBA(fs, ipervblk, x)
Definition: ufs.c:46
DT_REG
#define DT_REG
Definition: ufs.h:35
fs::fs_sblockloc
int64_t fs_sblockloc
Definition: fs.h:338
dirent::d_fileno
__uint32_t d_fileno
Definition: ufs.h:93
device_interface::info
void * info
Definition: device.h:51
DBPERVBLK
#define DBPERVBLK
Definition: ufs.c:42
vfs_mountPoint::device
struct device_node * device
Definition: mount.h:70
ufs1_dinode
Definition: ufs.h:130
kmalloc
void * kmalloc(uInt32 len)
Definition: kmalloc.c:241
ufs2_dinode
Definition: ufs.h:104
dmadat::indbuf
char indbuf[(1<< 12)]
Definition: file.h:57
DEV_BSHIFT
#define DEV_BSHIFT
Definition: gpt.h:41
dmadat
Definition: file.h:55
INO_TO_VBO
#define INO_TO_VBO(ipervblk, x)
Definition: ufs.c:49
device_node::devInfo
struct device_interface * devInfo
Definition: device.h:37
ssize_t
__ssize_t ssize_t
Definition: types.h:117
ffs.h
kprintf
int kprintf(const char *,...)
Definition: kprintf.c:259
u_int
unsigned int u_int
Definition: types.h:72
fileDescriptor::size
uint32_t size
Definition: file.h:70
VBLKSHIFT
#define VBLKSHIFT
Definition: ufs.c:39
dirent::d_type
__uint8_t d_type
Definition: ufs.h:95
fsbtodb
#define fsbtodb(fs, b)
Definition: fs.h:521
DEV_BSIZE
#define DEV_BSIZE
Definition: gpt.h:42
kmalloc.h
ufs2_dinode::di_ib
ufs2_daddr_t di_ib[3]
Definition: ufs.h:126
blkmap
#define blkmap(fs, map, loc)
Definition: fs.h:562
NULL
#define NULL
Definition: fat_string.h:17
ufs2_daddr_t
int64_t ufs2_daddr_t
Definition: ufs.h:87