/*-
* Copyright (c) 1999,2000 Jonathan Lemon <jlemon@freebsd.org>
* All rights reserved.
*
* 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
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*/
__FBSDID("$FreeBSD$");
/*-
* Copyright (c) 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. 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.
*/
#include "stand.h"
#include "string.h"
static int ext2fs_close(struct open_file *f);
DT_UNKNOWN : dtmap[x]
"ext2fs",
};
/*
* file system block to disk address
*/
/*
* inode to block group offset
* inode to block group
* inode to disk address
* inode to block offset
*/
/*
* superblock describing ext2fs
*/
struct ext2fs_disk {
};
struct ext2fs_core {
};
struct ext2fs {
};
struct ext2blkgrp {
};
struct ext2dinode {
};
struct ext2dirent {
};
struct file {
indirect block at level i */
at level i */
buffer */
};
/* forward decls */
/*
* Open a file.
*/
static int
{
int nlinks = 0;
int error = 0;
char c;
/* allocate file system specific data structure */
return (ENOMEM);
/* allocate space and read super block */
twiddle(1);
if (error)
goto out;
goto out;
}
/*
* compute in-core values for the superblock
*/
} else {
}
/*
* we have to load in the "group descriptors" here
*/
twiddle(1);
if (error)
goto out;
/*
* XXX
* validation of values? (blocksize, descriptors, etc?)
*/
/*
* Calculate indirect block levels.
*/
mult = 1;
for (i = 0; i < NIADDR; i++) {
}
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.
*/
len = 0;
if (++len > EXT2_MAXNAMLEN) {
goto out;
}
cp++;
}
*cp = '\0';
/*
* Look up component in current directory.
* Save directory inumber in case we find a
* symbolic link.
*/
*cp = c;
if (error)
goto out;
/*
* Open next component.
*/
goto out;
/*
* Check for symbolic link.
*/
int len;
++nlinks > MAXSYMLINKS) {
goto out;
}
} else {
/*
* Read file for symbolic link
*/
if (! buf)
if (error)
goto out;
twiddle(1);
if (error)
goto out;
}
/*
* If relative pathname, restart at parent directory.
* If absolute pathname, restart at root.
*/
if (*cp != '/')
else
goto out;
}
}
/*
* Found terminal component.
*/
error = 0;
out:
if (buf)
if (path)
if (error) {
}
return (error);
}
/*
* Read a new inode into a file structure.
*/
static int
{
char *buf;
/*
* Read inode and save it.
*/
twiddle(1);
if (error)
goto out;
goto out;
}
/* clear out old buffers */
out:
return (error);
}
/*
* Given an offset in a file, find the disk block number that
* contains that block.
*/
static int
{
int error;
/*
* 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 (error)
return (error);
return (EIO);
}
if (level > 0) {
} else {
idx = file_block;
}
}
return (0);
}
/*
* Read a portion of a file into an internal buffer. Return
* the location in the buffer and the amount in the buffer.
*/
static int
{
long off;
int error = 0;
if (error)
goto done;
if (disk_block == 0) {
} else {
twiddle(4);
if (error)
goto done;
}
}
/*
* 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.
*/
done:
return (error);
}
/*
* Search a directory for a name and return its
* i_number.
*/
static int
{
char *buf;
int error;
if (error)
return (error);
goto next;
/* found entry */
return (0);
}
next:
}
}
return (ENOENT);
}
static int
{
int level;
f->f_fsdata = (void *)0;
return (0);
}
return (0);
}
static int
{
char *buf;
int error = 0;
while (size != 0) {
break;
if (error)
break;
}
if (resid)
return (error);
}
static off_t
{
switch (where) {
case SEEK_SET:
break;
case SEEK_CUR:
break;
case SEEK_END:
break;
default:
return (-1);
}
}
static int
{
/* 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;
return (0);
}