[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-kernel
Subject:    Fw: Availability Dates for FENRIS (NetWare) File System for Linux Open Sources
From:       "Jeff Merkey" <jmerkey () timpanogas ! com>
Date:       1999-05-31 22:38:28
[Download RAW message or body]

Linux Community,

We had planned on June 1, 1999 as for release of the tar containing the
source code for FENRIS on our website, however, we had forgotten that Moday
May 31, 1999 is a US holiday (Memorial Day).  As such, FENRIS will be
available the following day in the evening.

We apologize for the inconveniance.  The FENRIS For Linux tar containing the
source code for version 1.4 of NWFS for Linux will be available June 3, 1999
in the morning for download from www.timpanogas.com.  We will make one final
code review pass for bugs and completeness on June 2, 1999, then the code
will be available from our website either the evening of June 2, 1999 or the
following morning (depending on where on planet earth you are when we
publish it to our site).  We also are putting in a fix for Document
Solutions in Alabama that allows Linux to mount NetWare volumes > 560 GB in
size, we are finalizing these changes.

The license statement for this open source is in an attached source file for
everyone's review.  Anyone wanting to make changes or comments to the
license needs to get this info to us NLT June 2, 1999 before we publish the
code.  Also, anyone who feels they contributed that may left out should let
us know so we can get your names into the first release as contributors.

We will also be posting a subsequent release of the Open Source 1.5 in two
weeks, and two weeks thereafter we will post 1.6 (around July 1, 1999).
Releases will then follow as required for bug fixes and enhancements.  It is
anticipated at some point, we will release quarterly to all.  The two
interim releases for June are to integrate bug fixes and to put some final
touches on 4 and 8 way volume mirroring, and write hotfixing.

The nwfs-utils tar containing the open source code utilities to fsck,
create, and maintain NetWare volume and partitions will be available later
in the week, and will also be part of the nwfs quarterly releases.


Very Truly Yours,

Jeff Merkey
CEO, TRG

["nwfile.c" (application/octet-stream)]

/***************************************************************************
*
*   Copyright (c) 1998, 1999 Timpanogas Research Group, Inc.
*   895 West Center Street
*   Orem, Utah  84057
*   jmerkey@timpanogas.com
*
*   This program is free software; you can redistribute it and/or modify it
*   under the terms of the GNU General Public License as published by the
*   Free Software Foundation, version 2, or any later version.
*
*   This program is distributed in the hope that it will be useful, but
*   WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*   General Public License for more details.
*
*   You should have received a copy of the GNU General Public License along
*   with this program; if not, write to the Free Software Foundation, Inc.,
*   675 Mass Ave, Cambridge, MA 02139, USA.
*
*   You are free to modify and re-distribute this program in accordance
*   with the terms specified in the GNU Public License.  The copyright
*   contained in this code is required to be present in any derivative
*   works and you are required to provide the source code for this
*   program as part of any commercial or non-commercial distribution.
*   You are required to respect the rights of the Copyright holders
*   named within this code.
*
*   jmerkey@timpanogas.com and TRG, Inc. are the official maintainers of
*   this code.  You are encouraged to report any bugs, problems, fixes,
*   suggestions, and comments about this software to jmerkey@timpanogas.com
*   or linux-kernel@vger.rutgers.edu.  New releases, patches, bug fixes, and
*   technical documentation can be found at www.timpanogas.com.  TRG will
*   periodically post new releases of this software to www.timpanogas.com
*   that contain bug fixes and enhanced capabilities.
*
*   Original Authorship      :  v1.4
*      source code written by Jeff V. Merkey, TRG, Inc.    11/1/98 to 6/1/99
*
*   Original Contributors    :  v1.4
*      engineer  consulting  Jeff V. Merkey, TRG, Inc.     11/1/98 to 6/1/99
*      technical consulting  Darren Major, TRG, Inc.       11/1/98 to 6/1/99
*      technical consulting  Drew Spencer, Caldera Systems 11/1/98 to 6/1/99
*      technical consulting  Steve Spicer, Document Solutions 4/15/99 6/1/99
*         (testing for very large NetWare volumes > 560 GB)
*
****************************************************************************
*
*
*   AUTHOR   :  Jeff V. Merkey (jmerkey@timpanogas.com)
*   FILE     :  NWFILE.C
*   DESCRIP  :  FENRIS NetWare File Management
*   DATE     :  December 14, 1998
*
*
***************************************************************************/

#include "version.h"
#include "globals.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "nwfs.h"
#include "nwstruct.h"
#include "nwdir.h"
#include "hash.h"
#include "externs.h"


ULONG NWReadFile(VOLUME *volume, DOS *dos, ULONG offset, BYTE *buf, long count)
{
    register long cluster, index;
    register ULONG bytesRead = 0, bytesLeft = 0;
    register ULONG StartIndex, StartOffset;
    register FAT_ENTRY *FAT;
    register ULONG voffset, vsize, vindex, cbytes;

    // adjust size and range check for EOF

    if ((offset + count) > dos->FileSize)
       count = dos->FileSize - offset;

    if (count <= 0)
       return 0;

    // if a subdirectory then return 0
    if (dos->Flags & SUBDIRECTORY_FILE)
       return 0;

    bytesLeft = count;
    StartIndex = offset / volume->ClusterSize;
    StartOffset = offset % volume->ClusterSize;

    // we always start with an index of zero
    index = 0;
    cluster = dos->FirstBlock;
    vindex = StartIndex;

    if ((bytesLeft > 0) && (cluster < 0))
    {
       // check for EOF
       if (cluster == (ULONG) -1)
       {
	  // filesize may exceed allocation, which means the rest of
	  // the file is sparse.  fill zeros into the requested
	  // size.  bytesLeft will have been set by count, which is
	  // range checked to the actual length of the file.

	  if (bytesLeft > 0)
	  {
	     NWFSSetUserSpace(buf, 0, bytesLeft);
	     bytesRead += bytesLeft;
	  }
	  return bytesRead;
       }

       // index should be null here
       if (StartIndex)
       {
	  // filesize may exceed allocation, which means the rest of
	  // the file is sparse.  fill zeros into the requested
	  // size.

	  if (bytesLeft > 0)
	  {
	     NWFSSetUserSpace(buf, 0, bytesLeft);
	     bytesRead += bytesLeft;
	  }
	  return bytesRead;
       }

       // vindex is always equal to StartIndex here
       voffset = StartOffset;

       // if this value exceeds the suballoc record size,
       // ReadSuballoc record will reduce this size to the
       // current record allocation.
       vsize = bytesLeft;

       cbytes = ReadSuballocRecord(volume, voffset, cluster, buf, vsize);
       bytesRead += cbytes;
       bytesLeft -= cbytes;
       buf += cbytes;

       // filesize may exceed allocation, which means the rest of
       // the file is sparse.  fill zeros into the requested
       // size.
       if (bytesLeft > 0)
       {
	  NWFSSetUserSpace(buf, 0, bytesLeft);
	  bytesRead += bytesLeft;
       }
       return bytesRead;
    }

    vindex = StartIndex;
    FAT = GetFatEntry(volume, cluster);
    if (FAT)
       index = FAT->FATIndex;

    while (FAT && FAT->FATCluster && (bytesLeft > 0))
    {
       //  if we found a hole, then return zeros until we
       //  either satisfy the requested read size or
       //  we span to the next valid index entry

       while ((bytesLeft > 0) && (vindex < index))
       {
	  voffset = 0;
	  if (vindex == StartIndex)
	     voffset = StartOffset;

	  vsize = (bytesLeft > (volume->ClusterSize - voffset))
		  ? (volume->ClusterSize - voffset) : bytesLeft;

	  NWFSSetUserSpace(buf, 0, vsize);
	  bytesRead += vsize;
	  bytesLeft -= vsize;
	  buf += vsize;
	  vindex++;
       }

       // found our index block, perform the copy operation

       if ((bytesLeft > 0) && (vindex == index))
       {
	  voffset = 0;
	  if (vindex == StartIndex)
	     voffset = StartOffset;

	  vsize = (bytesLeft > (volume->ClusterSize - voffset))
		  ? (volume->ClusterSize - voffset) : bytesLeft;

	  cbytes = ReadClusterWithOffset(volume, cluster, voffset, buf, vsize,
					 USER_ADDRESS_SPACE);
	  bytesRead += cbytes;
	  bytesLeft -= cbytes;
	  buf += cbytes;
	  vindex++;
       }

       // bump to the next cluster
       cluster = FAT->FATCluster;

       // check if the next cluster is a suballoc element or EOF marker
       if ((bytesLeft > 0) && (cluster < 0))
       {
	  // end of file
	  if (cluster == (ULONG) -1)
	  {
	     // filesize may exceed allocation, which means the rest of
	     // the file is sparse.  fill zeros into the requested
	     // size.
	     if (bytesLeft > 0)
	     {
		NWFSSetUserSpace(buf, 0, bytesLeft);
		bytesRead += bytesLeft;
	     }
	     return bytesRead;
	  }

	  // check for valid index
	  if ((index + 1) == vindex)
	  {
	     voffset = 0;
	     if (vindex == StartIndex)
		voffset = StartOffset;

	     // if this value exceeds the suballoc record size,
	     // ReadSuballoc record will reduce this size to the
	     // current record allocation.
	     vsize = bytesLeft;

	     cbytes = ReadSuballocRecord(volume, voffset, cluster, buf, vsize);
	     bytesRead += cbytes;
	     bytesLeft -= cbytes;
	     buf += cbytes;
	  }

	  // filesize may exceed allocation, which means the rest of
	  // the file is sparse.  fill zeros into the requested
	  // size.
	  if (bytesLeft > 0)
	  {
	     NWFSSetUserSpace(buf, 0, bytesLeft);
	     bytesRead += bytesLeft;
	  }
	  return bytesRead;
       }

       // get next fat table entry and index
       FAT = GetFatEntry(volume, cluster);
       if (FAT)
	  index = FAT->FATIndex;
    }

    // filesize may exceed allocation, which means the rest of
    // the file is sparse.  fill zeros into the requested
    // size.
    if (bytesLeft > 0)
    {
       NWFSSetUserSpace(buf, 0, bytesLeft);
       bytesRead += bytesLeft;
    }
    return bytesRead;

}

ULONG NWWriteFile(VOLUME *volume, DOS *dos, ULONG offset, BYTE *buf, long count)
{
    register long cluster, index;
    register ULONG bytesWritten = 0, bytesLeft = 0, lcount = 0;
    register ULONG StartIndex, StartOffset, SuballocSize;
    register FAT_ENTRY *FAT;
    register ULONG voffset, vsize, vindex, cbytes;
    register long pcluster, ncluster;
    register BYTE *WorkSpace;
    MIRROR_LRU *lru = 0;

    // if a subdirectory then return 0
    if (dos->Flags & SUBDIRECTORY_FILE)
       return 0;

    bytesLeft = count;
    StartIndex = offset / volume->ClusterSize;
    StartOffset = offset % volume->ClusterSize;

    // we always start with an index of zero
    index = 0;
    pcluster = cluster = dos->FirstBlock;
    vindex = StartIndex;

    if ((bytesLeft > 0) && (cluster < 0))
    {
       // check for EOF
       if (cluster == (ULONG) -1)
       {
	  // vindex is always equal to StartIndex here
	  voffset = StartOffset;

	  vsize = (bytesLeft > (volume->ClusterSize - voffset))
		  ? (volume->ClusterSize - voffset) : bytesLeft;

	  // allocate cluster and point forward link to EOF
	  ncluster = AllocateClusterSetIndexSetChain(volume, vindex, (ULONG) -1);
	  if (ncluster == -1)
	  {
	     // if we could not get a free cluster, then return
	     // (out of drive space)
	     return (bytesWritten ? bytesWritten : -1);
	  }

	  // zero fill the new cluster
	  ZeroPhysicalVolumeCluster(volume, ncluster);

	  // this case
	  dos->FirstBlock = ncluster;
	  pcluster = ncluster;

	  cbytes = WriteClusterWithOffset(volume, ncluster, voffset, buf, vsize,
					  USER_ADDRESS_SPACE);
	  bytesWritten += cbytes;
	  bytesLeft -= cbytes;
	  buf += cbytes;
	  vindex++;

	  while (bytesLeft > 0)
	  {
	     voffset = 0;
	     if (vindex == StartIndex)
		voffset = StartOffset;

	     vsize = (bytesLeft > (volume->ClusterSize - voffset))
		     ? (volume->ClusterSize - voffset) : bytesLeft;

	     // allocate cluster and point forward link to EOF
	     ncluster = AllocateClusterSetIndexSetChain(volume, vindex, -1);
	     if (ncluster == -1)
	     {
		// if we could not get a free cluster, then return
		// (out of drive space)
		return (bytesWritten ? bytesWritten : -1);
	     }

	     // zero fill the new cluster
	     ZeroPhysicalVolumeCluster(volume, ncluster);

	     // set previous cluster chain to point to this entry
	     SetClusterValue(volume, pcluster, ncluster);

	     // update previous cluster to new cluster
	     // this will force inserts after the end of this cluster
	     pcluster = ncluster;

	     cbytes = WriteClusterWithOffset(volume, ncluster, voffset, buf, vsize,
					     USER_ADDRESS_SPACE);
	     bytesWritten += cbytes;
	     bytesLeft -= cbytes;
	     buf += cbytes;
	     vindex++;

	  }
	  return (bytesWritten ? bytesWritten : -1);
       }

       // we have detected a suballoc element in the fat chain if we
       // get to this point

       SuballocSize = GetSuballocSize(volume, cluster);

       voffset = 0;
       if (vindex == StartIndex)
	  voffset = StartOffset;

       // this case assumes we will free the current suballoc element

       if ((bytesLeft + voffset) > SuballocSize)
       {
	  WorkSpace = NWFSCacheAlloc(SuballocSize, SA_WORKSPACE_TAG);
	  if (!WorkSpace)
	  {
	     // if we could not get memory to copy the suballoc record,
	     // then return (out of drive space)
	     return (bytesWritten ? bytesWritten : -1);
	  }

	  voffset = 0;
	  if (vindex == StartIndex)
	     voffset = StartOffset;

	  vsize = (bytesLeft > (volume->ClusterSize - voffset))
		  ? (volume->ClusterSize - voffset) : bytesLeft;

	  // allocate cluster and point forward link to EOF
	  ncluster = AllocateClusterSetIndexSetChain(volume, vindex, (ULONG) -1);
	  if (ncluster == -1)
	  {
	     // if we could not get a free cluster, then return
	     // (out of drive space)
	     NWFSFree(WorkSpace);
	     return (bytesWritten ? bytesWritten : -1);
	  }

	  // zero fill the new cluster
	  ZeroPhysicalVolumeCluster(volume, ncluster);

	  // here we read the previous data from the suballoc element
	  cbytes = ReadSuballocData(volume, 0, cluster, WorkSpace, SuballocSize);
	  if (cbytes != SuballocSize)
	  {
	     NWFSFree(WorkSpace);
	     return (bytesWritten ? bytesWritten : -1);
	  }

	  // now write the previous data from the suballoc element
	  // into the newly allocated cluster.
	  cbytes = WriteClusterWithOffset(volume, ncluster, 0, WorkSpace, SuballocSize,
					  KERNEL_ADDRESS_SPACE);
	  if (cbytes != SuballocSize)
	  {
	     NWFSFree(WorkSpace);
	     return (bytesWritten ? bytesWritten : -1);
	  }

	  // free the suballoc element in bit block list
	  FreeSuballocRecord(volume, cluster);

	  // this case
	  dos->FirstBlock = ncluster;
	  pcluster = ncluster;

	  // now write the user data into the suballoc element
	  cbytes = WriteClusterWithOffset(volume, ncluster, voffset, buf, vsize,
					  USER_ADDRESS_SPACE);
	  bytesWritten += cbytes;
	  bytesLeft -= cbytes;
	  buf += cbytes;
	  vindex++;

	  NWFSFree(WorkSpace);

	  while (bytesLeft > 0)
	  {
	     voffset = 0;
	     if (vindex == StartIndex)
		voffset = StartOffset;

	     vsize = (bytesLeft > (volume->ClusterSize - voffset))
		     ? (volume->ClusterSize - voffset) : bytesLeft;

	     // allocate cluster and point forward link to EOF
	     ncluster = AllocateClusterSetIndexSetChain(volume, vindex, -1);
	     if (ncluster == -1)
	     {
		// if we could not get a free cluster, then return
		// (out of drive space)
		return (bytesWritten ? bytesWritten : -1);
	     }

	     // zero fill the new cluster
	     ZeroPhysicalVolumeCluster(volume, ncluster);

	     // set previous cluster chain to point to this entry
	     SetClusterValue(volume, pcluster, ncluster);

	     // update previous cluster to new cluster
	     // this will force inserts after the end of this cluster
	     pcluster = ncluster;

	     cbytes = WriteClusterWithOffset(volume, ncluster, voffset, buf, vsize,
					     USER_ADDRESS_SPACE);
	     bytesWritten += cbytes;
	     bytesLeft -= cbytes;
	     buf += cbytes;
	     vindex++;

	  }
	  return (bytesWritten ? bytesWritten : -1);
       }
       else
       {
	  // for this case, since our target write size fits within
	  // the previously allocated suballoc element, then just
	  // write the data.

	  // vindex will always be equal to StartIndex here
	  voffset = StartOffset;

	  // at this point, bytesLeft is either equal to or
	  // less than the size of the current suballocation
	  // record.

	  vsize = bytesLeft;
	  cbytes = WriteSuballocRecord(volume, voffset, cluster, buf, vsize);

	  bytesWritten += cbytes;
	  bytesLeft -= cbytes;

	  return (bytesWritten ? bytesWritten : -1);
       }
    }

    FAT = GetFatEntryAndLRU(volume, cluster, &lru);
    if (FAT)
       index = FAT->FATIndex;

    while (FAT && FAT->FATCluster && (bytesLeft > 0))
    {
       //  if we found a hole, then allocate and add a new cluster
       //  to the file and continue to add clusters and write until
       //  bytesLeft is < 0 or we find the next valid cluster in the
       //  fat chain

       while ((bytesLeft > 0) && (vindex < index))
       {
	  // we can only get here if we detected the next
	  // fat element is greater than the target index
	  // (the file has holes, and we hit an index
	  // larger than we expected).

	  // we simply extend the file by allocating clusters
	  // until we complete the write or the target index
	  // equals the current cluster.  obvioulsy, we must
	  // insert nodes into the fat chain for each element we
	  // allocate.

	  voffset = 0;
	  if (vindex == StartIndex)
	     voffset = StartOffset;

	  vsize = (bytesLeft > (volume->ClusterSize - voffset))
		  ? (volume->ClusterSize - voffset) : bytesLeft;

	  // allocate cluster and point forward link to next cluster
	  ncluster = AllocateClusterSetIndexSetChain(volume, vindex, cluster);
	  if (ncluster == -1)
	  {
	     // if we could not get a free cluster, then return
	     // (out of drive space)
	     return (bytesWritten ? bytesWritten : -1);
	  }

	  // zero fill the new cluster
	  ZeroPhysicalVolumeCluster(volume, ncluster);

	  // set previous cluster chain to point to this entry
	  // if pcluster and cluster are equal, then we are
	  // inserting at the front of the cluster chain
	  // so adjust the directory block

	  (pcluster != cluster)
	  ? SetClusterValue(volume, pcluster, ncluster)
	  : (dos->FirstBlock = ncluster);

	  // update previous cluster to new cluster
	  pcluster = ncluster;

	  cbytes = WriteClusterWithOffset(volume, ncluster, voffset, buf, vsize,
					  USER_ADDRESS_SPACE);
	  bytesWritten += cbytes;
	  bytesLeft -= cbytes;
	  buf += cbytes;
	  vindex++;

       }

       // found our index block, perform the copy operation

       if ((bytesLeft > 0) && (vindex == index))
       {

	  voffset = 0;
	  if (vindex == StartIndex)
	     voffset = StartOffset;

	  vsize = (bytesLeft > (volume->ClusterSize - voffset))
		  ? (volume->ClusterSize - voffset) : bytesLeft;

	  cbytes = WriteClusterWithOffset(volume, cluster, voffset, buf, vsize,
					  USER_ADDRESS_SPACE);
	  bytesWritten += cbytes;
	  bytesLeft -= cbytes;
	  buf += cbytes;
	  vindex++;

       }

       // save the previous cluster
       pcluster = cluster;

       // bump to the next cluster
       cluster = FAT->FATCluster;

       // check if the next cluster is a suballoc element or EOF
       if ((bytesLeft > 0) && (cluster < 0))
       {
	  // end of file
	  if (cluster == (ULONG) -1)
	  {
	     while (bytesLeft > 0)
	     {
		voffset = 0;
		if (vindex == StartIndex)
		   voffset = StartOffset;

		vsize = (bytesLeft > (volume->ClusterSize - voffset))
			? (volume->ClusterSize - voffset) : bytesLeft;

		// allocate cluster and point forward link to EOF
		ncluster = AllocateClusterSetIndexSetChain(volume, vindex, -1);
		if (ncluster == -1)
		{
		   // if we could not get a free cluster, then return
		   // (out of drive space)
		   return (bytesWritten ? bytesWritten : -1);
		}

		// zero fill the new cluster
		ZeroPhysicalVolumeCluster(volume, ncluster);

		// set previous cluster chain to point to this entry
		SetClusterValue(volume, pcluster, ncluster);

		// update previous cluster to new cluster
		// this will force inserts after the end of this cluster
		pcluster = ncluster;

		cbytes = WriteClusterWithOffset(volume, ncluster, voffset, buf, vsize,
						USER_ADDRESS_SPACE);
		bytesWritten += cbytes;
		bytesLeft -= cbytes;
		buf += cbytes;
		vindex++;

	     }
	     return (bytesWritten ? bytesWritten : -1);
	  }

	  // we have detected a suballoc element in the fat chain if we
	  // get to this point

	  SuballocSize = GetSuballocSize(volume, cluster);

	  voffset = 0;
	  if (vindex == StartIndex)
	     voffset = StartOffset;

	  // this case assumes we will free the current suballoc element
	  // and copy it to a cluster or another suballoc element

	  if ((bytesLeft + voffset) > SuballocSize)
	  {
	     WorkSpace = NWFSCacheAlloc(SuballocSize, SA_WORKSPACE_TAG);
	     if (!WorkSpace)
	     {
		// if we could not get memory to copy the suballoc record,
		// then return (out of drive space)
		return (bytesWritten ? bytesWritten : -1);
	     }

	     voffset = 0;
	     if (vindex == StartIndex)
		voffset = StartOffset;

	     vsize = (bytesLeft > (volume->ClusterSize - voffset))
		     ? (volume->ClusterSize - voffset) : bytesLeft;

	     // allocate cluster and point forward link to EOF
	     ncluster = AllocateClusterSetIndexSetChain(volume, vindex, -1);
	     if (ncluster == -1)
	     {
		// if we could not get a free cluster, then return
		// (out of drive space)
		NWFSFree(WorkSpace);
		return (bytesWritten ? bytesWritten : -1);
	     }

	     // zero fill the new cluster
	     ZeroPhysicalVolumeCluster(volume, ncluster);

	     // here we read the previous data from the suballoc element
	     cbytes = ReadSuballocData(volume, 0, cluster, WorkSpace, SuballocSize);
	     if (cbytes != SuballocSize)
	     {
		NWFSFree(WorkSpace);
		return (bytesWritten ? bytesWritten : -1);
	     }

	     // now write the previous data from the suballoc element
	     // into the newly allocated cluster.
	     cbytes = WriteClusterWithOffset(volume, ncluster, 0, WorkSpace, SuballocSize,
					  KERNEL_ADDRESS_SPACE);
	     if (cbytes != SuballocSize)
	     {
		NWFSFree(WorkSpace);
		return (bytesWritten ? bytesWritten : -1);
	     }

	     // free the suballoc element in bit block list
	     FreeSuballocRecord(volume, cluster);

	     // set previous cluster chain to point to this entry
	     SetClusterValue(volume, pcluster, ncluster);

	     // update previous cluster to new cluster
	     // this will force inserts after the end of this cluster
	     pcluster = ncluster;

	     cbytes = WriteClusterWithOffset(volume, ncluster, voffset, buf, vsize,
					     USER_ADDRESS_SPACE);
	     bytesWritten += cbytes;
	     bytesLeft -= cbytes;
	     buf += cbytes;
	     vindex++;

	     NWFSFree(WorkSpace);

	     while (bytesLeft > 0)
	     {
		voffset = 0;
		if (vindex == StartIndex)
		   voffset = StartOffset;

		vsize = (bytesLeft > (volume->ClusterSize - voffset))
			? (volume->ClusterSize - voffset) : bytesLeft;

		// allocate cluster and point forward link to EOF
		ncluster = AllocateClusterSetIndexSetChain(volume, vindex, -1);
		if (ncluster == -1)
		{
		   // if we could not get a free cluster, then return
		   // (out of drive space)
		   return (bytesWritten ? bytesWritten : -1);
		}

		// zero fill the new cluster
		ZeroPhysicalVolumeCluster(volume, ncluster);

		// set previous cluster chain to point to this entry
		SetClusterValue(volume, pcluster, ncluster);

		// update previous cluster to new cluster
		// this will force inserts after the end of this cluster
		pcluster = ncluster;

		cbytes = WriteClusterWithOffset(volume, ncluster, voffset, buf, vsize,
						USER_ADDRESS_SPACE);
		bytesWritten += cbytes;
		bytesLeft -= cbytes;
		buf += cbytes;
		vindex++;

	     }
	     return (bytesWritten ? bytesWritten : -1);
	  }
	  else
	  {
	     // for this case, since our target write size fits within
	     // the previously allocated suballoc element, then just
	     // write the data.

	     // check for valid index
	     if ((index + 1) == vindex)
	     {
		voffset = 0;
		if (vindex == StartIndex)
		   voffset = StartOffset;

		// at this point, bytesLeft is either equal to or
		// less than the size of the current suballocation
		// record.

		vsize = bytesLeft;
		cbytes = WriteSuballocRecord(volume, voffset, cluster,
					  buf, vsize);
		bytesWritten += cbytes;
		bytesLeft -= cbytes;
	     }
	  }
	  return (bytesWritten ? bytesWritten : -1);
       }

       // get next fat table entry and index
       FAT = GetFatEntryAndLRU(volume, cluster, &lru);

       // if the fat chain terminates, then exit
       if (!FAT)
	  return (bytesWritten ? bytesWritten : -1);

       index = FAT->FATIndex;
       lcount++;
    }
    return (bytesWritten ? bytesWritten : -1);

}



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic