/* $NetBSD: ufs.c,v 1.20 1998/03/01 07:15:39 ross Exp $ */
/*-
* Copyright (c) 2002 Networks Associates Technology, Inc.
* All rights reserved.
*
* This software was developed for the FreeBSD Project by Marshall
* Kirk McKusick and Network Associates Laboratories, the Security
* contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
* research program
*
* Copyright (c) 1982, 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* The Mach Operating System project at Carnegie-Mellon University.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
* Copyright (c) 1990, 1991 Carnegie Mellon University
* All Rights Reserved.
*
* Author: David Golub
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
__FBSDID("$FreeBSD$");
/*
* Stand-alone file reading package.
*/
#include <sys/disklabel.h>
#include "stand.h"
#include "string.h"
"ufs",
};
/*
* In-core open file.
*/
struct file {
union dinode {
/* number of blocks mapped by
indirect block at level i */
level i */
/* size of buffer */
};
/*
* Read a new inode into a file structure.
*/
static int
struct open_file *f;
{
char *buf;
int rc;
panic("fs == NULL");
/*
* Read inode and save it.
*/
twiddle(1);
if (rc)
goto out;
goto out;
}
else
/*
* Clear out the old buffers
*/
{
int level;
}
out:
return (rc);
}
/*
* Given an offset in a file, find the disk block number that
* contains that block.
*/
static int
struct open_file *f;
{
int level;
int idx;
int rc;
/*
* Index structure of an inode:
*
* di_db[0..NDADDR-1] hold block numbers for blocks
* 0..NDADDR-1
*
* di_ib[0] index block 0 is the single indirect block
* holds block numbers for blocks
* NDADDR .. NDADDR + NINDIR(fs)-1
*
* di_ib[1] index block 1 is the double indirect block
* holds block numbers for INDEX blocks for blocks
* NDADDR + NINDIR(fs) ..
* NDADDR + NINDIR(fs) + NINDIR(fs)**2 - 1
*
* di_ib[2] index block 2 is the triple indirect block
* holds block numbers for double-indirect
* blocks for blocks
* NDADDR + NINDIR(fs) + NINDIR(fs)**2 ..
* NDADDR + NINDIR(fs) + NINDIR(fs)**2
* + NINDIR(fs)**3 - 1
*/
if (file_block < NDADDR) {
/* Direct block. */
return (0);
}
file_block -= NDADDR;
/*
* nindir[0] = NINDIR
* nindir[1] = NINDIR**2
* nindir[2] = NINDIR**3
* etc
*/
break;
}
/* Block number too high */
return (EFBIG);
}
if (ind_block_num == 0) {
*disk_block_p = 0; /* missing */
return (0);
}
twiddle(1);
if (rc)
return (rc);
return (EIO);
}
if (level > 0) {
} else
idx = file_block;
else
}
return (0);
}
/*
* Write a portion of a file from an internal buffer.
*/
static int
struct open_file *f;
char *buf_p;
{
long off;
int rc;
/*
* Calculate the starting block address and offset.
*/
if (rc)
return (rc);
if (disk_block == 0)
/* Because we can't allocate space on the drive */
return (EFBIG);
/*
* Truncate buffer at end of file, and at the end of
* this block.
*/
/*
* If we don't entirely occlude the block and it's not
* in memory already, read it in first.
*/
twiddle(8);
if (rc)
return (rc);
}
/*
* Copy the user data into the cached block.
*/
/*
* Write the block out to storage.
*/
twiddle(4);
return (rc);
}
/*
* Read a portion of a file into an internal buffer. Return
* the location in the buffer and the amount in the buffer.
*/
static int
struct open_file *f;
char **buf_p; /* out */
{
long off;
int rc;
if (rc)
return (rc);
if (disk_block == 0) {
} else {
twiddle(4);
if (rc)
return (rc);
}
}
/*
* Return address of byte in buffer corresponding to
* offset, and size of remainder of buffer after that
* byte.
*/
/*
* But truncate buffer at end of file.
*/
return (0);
}
/*
* Search a directory for a name and return its
* i_number.
*/
static int
char *name;
struct open_file *f;
{
char *buf;
int rc;
if (rc)
return (rc);
goto next;
/* found entry */
return (0);
}
next:
}
}
return (ENOENT);
}
/*
* Open a file.
*/
static int
const char *upath;
struct open_file *f;
{
int c;
int i, rc;
int nlinks = 0;
/* allocate file system specific data structure */
/* allocate space and read super block */
twiddle(1);
/*
* Try reading the superblock in each of its possible locations.
*/
for (i = 0; sblock_try[i] != -1; i++) {
if (rc)
goto out;
buf_size == SBLOCKSIZE &&
break;
}
if (sblock_try[i] == -1) {
goto out;
}
/*
* Calculate indirect block levels.
*/
{
int level;
mult = 1;
}
}
goto out;
goto out;
}
while (*cp) {
/*
* Remove extra separators
*/
while (*cp == '/')
cp++;
if (*cp == '\0')
break;
/*
* Check that current node is a directory.
*/
goto out;
}
/*
* Get next component of path name.
*/
{
int len = 0;
goto out;
}
cp++;
}
*cp = '\0';
}
/*
* Look up component in current directory.
* Save directory inumber in case we find a
* symbolic link.
*/
*cp = c;
if (rc)
goto out;
/*
* Open next component.
*/
goto out;
/*
* Check for symbolic link.
*/
int len;
++nlinks > MAXSYMLINKS) {
goto out;
}
else
} else {
/*
* Read file for symbolic link
*/
if (!buf)
if (rc)
goto out;
twiddle(1);
if (rc)
goto out;
}
/*
* If relative pathname, restart at parent directory.
* If absolute pathname, restart at root.
*/
if (*cp != '/')
else
goto out;
}
}
/*
* Found terminal component.
*/
rc = 0;
out:
if (buf)
if (path)
if (rc) {
}
return (rc);
}
static int
ufs_close(f)
struct open_file *f;
{
int level;
f->f_fsdata = (void *)0;
return (0);
}
return (0);
}
/*
* Copy a portion of a file into kernel memory.
* Cross block boundaries when necessary.
*/
static int
struct open_file *f;
void *start;
{
char *buf;
int rc = 0;
while (size != 0) {
break;
if (rc)
break;
}
if (resid)
return (rc);
}
/*
* Write to a portion of an already allocated file.
* Cross block boundaries when necessary. Can not
* extend the file.
*/
static int
struct open_file *f;
void *start;
{
int rc = 0;
break;
if (rc)
break;
}
if (resid)
return (rc);
}
static off_t
struct open_file *f;
int where;
{
switch (where) {
case SEEK_SET:
break;
case SEEK_CUR:
break;
case SEEK_END:
break;
default:
return (-1);
}
}
static int
struct open_file *f;
{
/* only important stuff */
return (0);
}
static int
{
char *buf;
int error;
/*
* assume that a directory entry will not be split across blocks
*/
return (ENOENT);
if (error)
return (error);
goto again;
d->d_type = 0; /* illumos ufs does not have type in direct */
return (0);
}