/*
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Routines to allocate and deallocate data blocks on the disk
*/
#include <sys/sysmacros.h>
/*
* Convert file logical block (cluster) numbers to disk block numbers.
* Also return number of physically contiguous blocks if asked for.
* Used for reading only. Use pc_balloc for writing.
*/
int
/* may be zero if not wanted */
{
if (lcn < 0)
return (ENOENT);
/*
* FAT12 / FAT16 root directories are a continuous section on disk
* before the actual data clusters. Specialcase this here.
*/
return (ENOENT);
}
if (contigbp) {
}
return (0);
}
return (ENOENT);
}
fsp->pcfs_clsize))) {
return (ENOENT);
}
}
do {
return (ENOENT);
cn >= PCF_LASTCLUSTER &&
return (ENOENT);
} else {
PC_DPRINTF1(1,
"pc_bmap: badfs cn=%d\n", cn);
return (EIO);
}
}
} while (lcn--);
/*
* Cache this cluster, as we'll most likely visit the
* one after this next time. Considerably improves
* performance on sequential reads and writes.
*/
}
}
return (0);
}
/*
* Allocate file logical blocks (clusters).
* Return disk address of last allocated cluster.
*/
int
int zwrite, /* zerofill blocks? */
{
if (lcn < 0) {
return (EFBIG);
}
/*
*/
return (ENOSPC);
return (0);
}
return (ENOSPC);
case PCF_FREECLUSTER:
return (ENOSPC);
case PCF_ERRORCLUSTER:
return (EIO);
}
} else {
return (EIO);
}
}
}
while (lcn-- > 0) {
/*
* Extend file (no holes).
*/
case PCF_FREECLUSTER:
return (ENOSPC);
case PCF_ERRORCLUSTER:
return (EIO);
}
PC_DPRINTF1(1,
"pc_balloc: badfs ncn=%d\n", ncn);
return (EIO);
}
}
/*
* extending the file we're interested in the last
* written cluster and not the last cluster allocated.
*/
return (0);
}
/*
* Free file cluster chain after the first skipcl clusters.
*/
int
{
int n;
panic("pc_bfree");
}
return (0);
}
if (n > fsp->pcfs_ncluster) {
return (EIO);
}
} else {
n = fsp->pcfs_ncluster;
}
if (skipcl == 0) {
else
}
/* Invalidate last used cluster cache */
while (n--) {
return (EIO);
}
if (skipcl == 0) {
} else {
skipcl--;
if (skipcl == 0) {
} else
}
}
break;
break;
}
return (0);
}
/*
* Return the number of free blocks in the filesystem.
*/
int
{
int free = 0;
/*
* make sure the FAT is in core
*/
free++;
}
}
}
return (free);
}
/*
* Cluster manipulation routines.
* FAT must be resident.
*/
/*
* Get the next cluster in the file cluster chain.
* cn = current cluster number in chain
*/
static pc_cluster32_t
{
unsigned char *fp;
panic("pc_getcluster");
switch (fsp->pcfs_fattype) {
case FAT32:
break;
case FAT16:
break;
case FAT12:
if (cn & 01) {
} else {
}
if (cn >= PCF_12BCLUSTER)
cn |= PCF_RESCLUSTER;
break;
default:
}
return (cn);
}
/*
* Set a cluster in the FAT to a value.
* cn = cluster number to be set in FAT
* ncn = new value
*/
void
{
unsigned char *fp;
panic("pc_setcluster");
switch (fsp->pcfs_fattype) {
case FAT32:
break;
case FAT16:
break;
case FAT12:
if (cn & 01) {
fp++;
} else {
}
break;
default:
}
if (ncn == PCF_FREECLUSTER) {
}
}
}
/*
* Allocate a new cluster.
*/
int zwrite) /* boolean for writing zeroes */
{
int error;
panic("pc_addcluster: no FAT");
} else
if (zwrite) {
/*
* zero the new cluster
*/
if (error) {
return (PCF_ERRORCLUSTER);
}
}
return (cn);
}
}
return (PCF_FREECLUSTER);
}
/*
* Get the number of clusters used by a file or subdirectory
*/
int
{
int count = 0;
*ncl = 0;
return (EIO);
}
return (0);
}