/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/sysmacros.h>
#ifdef _BOOT
#else
#endif
extern void *bkmem_alloc(size_t);
extern void bkmem_free(void *, size_t);
extern int cf_check_compressed(fileid_t *);
int bootrd_debug;
#ifdef _BOOT
#else
/* PRINTLIKE */
extern void kobj_printf(char *, ...);
#endif
/*
* This fd is used when talking to the device file itself.
*/
/* Only got one of these...ergo, only 1 fs open at once */
/* static */
struct dirinfo {
int loc;
};
static int bufs_close(int);
static void bufs_closeall(int);
static void *get_cache(int);
static void free_cache();
/*
* There is only 1 open (mounted) device at any given time.
* So we can keep a single, global devp file descriptor to
* use to index into the di[] array. This is not true for the
* fi[] array. We can have more than one file open at once,
* so there is no global fd for the fi[].
* The user program must save the fd passed back from open()
* and use it to do subsequent read()'s.
*/
static int
{
return (0);
/* never more than 1 disk block */
return (0);
}
bkmem_alloc(sizeof (struct inode));
return (0);
}
static fileid_t *
{
if (fd >= 0) {
}
return (0);
}
static ino_t
{
char *q;
char c;
int len, r;
printf("null path\n");
return ((ino_t)0);
}
while (*lpathp) {
/* if at the beginning of pathname get root inode */
return ((ino_t)0);
while (*lpathp == '/')
lpathp++; /* skip leading slashes */
q = lpathp;
while (*q != '/' && *q != '\0')
q++; /* find end of component */
c = *q;
*q = '\0'; /* terminate component */
/* Bail out early if opening root */
if (r && (*lpathp == '\0'))
return ((ino_t)UFSROOTINO);
return ((ino_t)0);
filep->fi_blocknum =
return ((ino_t)0);
/* absolute link */
/* copy rest of unprocessed path up */
/* point to unprocessed path */
/* prepend link in before unprocessed path */
continue;
} else
*q = c;
if (c == '\0')
break;
lpathp = q;
continue;
} else {
return ((ino_t)0);
}
}
return (inode);
}
static daddr32_t
{
int i, j, sh;
/*
* blocks 0..NDADDR are direct blocks
*/
return (nb);
}
/*
* addresses NIADDR have single and double indirect blocks.
* the first step is to determine how many levels of indirection.
*/
sh = 1;
for (j = NIADDR; j > 0; j--) {
break;
}
if (j == 0) {
return ((daddr32_t)0);
}
/*
* fetch the first indirect block address from the inode
*/
if (nb == 0) {
return ((daddr32_t)0);
}
/*
* fetch through the indirect blocks
*/
for (; j <= NIADDR; j++) {
return (0);
if (nb == 0) {
return ((daddr32_t)0);
}
}
return (nb);
}
static ino_t
{
int len;
return (0);
return (0);
}
return (0);
}
continue;
}
}
return (0);
}
/*
* get next entry in a directory.
*/
struct direct *
{
int off;
for (;;) {
return (NULL);
}
if (off == 0) {
if (d == 0)
return (NULL);
return (NULL);
}
}
continue;
return (dp);
}
}
/*
* Get the next block of data from the file. If possible, dma right into
* user's buffer
*/
static int
{
caddr_t p;
/* find the amt left to be read in the file */
if (diff <= 0) {
printf("Short read\n");
return (-1);
}
/* which block (or frag) in the file do we read? */
/* which physical block on the device do we read? */
/* either blksize or fragsize */
/*
* optimization if we are reading large blocks of data then
* we can go directly to user's buffer
*/
*rcount = 0;
return (-1);
}
return (0);
return (-1);
}
return (0);
}
/*
* Get the next block of data from the file. Don't attempt to go directly
* to user's buffer.
*/
static int
{
caddr_t p;
dprintf("getblock_noopt: start\n");
/* find the amt left to be read in the file */
if (diff <= 0) {
printf("Short read\n");
return (-1);
}
/* which block (or frag) in the file do we read? */
/* which physical block on the device do we read? */
/* either blksize or fragsize */
/* reading on a ramdisk, just get a pointer to the data */
return (-1);
}
return (0);
}
/*
* This is the high-level read function. It works like this.
* We assume that our IO device buffers up some amount of
* data and that we can get a ptr to it. Thus we need
* and this greatly increases our IO speed. When we already
* have data in the buffer, we just return that data (with bcopy() ).
*/
static ssize_t
{
size_t i, j;
caddr_t n;
int rcount;
return (-1);
}
/* that was easy */
if ((i = count) == 0)
return (0);
n = buf;
while (i > 0) {
return (0); /* encountered an error */
if (j < i)
i = j; /* short read, must have hit EOF */
} else {
/* If we need to reload the buffer, do so */
i -= rcount;
continue;
} else {
/* else just bcopy from our buffer */
j = MIN(i, j);
}
}
buf += j;
i -= j;
}
return (buf - n);
}
/*
* This routine will open a device as it is known by the V2 OBP.
* Interface Defn:
* err = mountroot(string);
* err = 0 on success
* err = -1 on failure
* string: char string describing the properties of the device.
* We must not dork with any fi[]'s here. Save that for later.
*/
static int
{
if (ufs_devp) /* already mounted */
return (0);
ufs_devp->di_dcookie = 0;
head->fi_filedes = 0;
/* Setup read of the superblock */
printf("failed to read superblock\n");
(void) bufs_closeall(1);
return (-1);
}
(void) bufs_closeall(1);
return (-1);
}
dprintf("mountroot succeeded\n");
return (0);
}
/*
* Unmount the currently mounted root fs. In practice, this means
* closing all open files and releasing resources. All of this
* is done by closeall().
*/
static int
bufs_unmountroot(void)
{
return (-1);
(void) bufs_closeall(1);
return (0);
}
/*
* We allocate an fd here for use when talking
* to the file itself.
*/
/*ARGSUSED*/
static int
{
/* build and link a new file descriptor */
return (-1);
}
return (-1);
}
if (cf_check_compressed(filep) != 0)
return (-1);
return (filep->fi_filedes);
}
/*
* We don't do any IO here.
* We just play games with the device pointers.
*/
static off_t
{
/* Make sure user knows what file he is talking to */
return (-1);
} else {
switch (whence) {
case SEEK_CUR:
break;
case SEEK_SET:
break;
default:
case SEEK_END:
break;
}
}
return (0);
}
int
{
return (-1);
return (0);
case IFLNK:
break;
case IFREG:
break;
default:
break;
}
/*
* NOTE: this size will be the compressed size for a compressed file
* This could confuse the caller since we decompress the file behind
* the scenes when the file is read.
*/
return (0);
}
static int
{
/* Make sure user knows what file he is talking to */
return (-1);
/* Clear the ranks */
/* unlink and deallocate node */
return (0);
} else {
/* Big problem */
return (-1);
}
}
/*ARGSUSED*/
static void
{
printf("Filesystem may be inconsistent.\n");
free_cache();
}
static struct cache {
void *data;
int key;
} *icache;
void
{
if (icache) {
} else {
}
}
void *
{
while (entry) {
}
return (NULL);
}
void
{
while (entry) {
}
icache = 0;
}
"boot_ufs",
};