Exemplo n.º 1
0
/*
 * NAME:	file->alloc()
 * DESCRIPTION:	reserve allocation blocks for a file
 */
long f_alloc(hfsfile *file)
{
  hfsvol *vol = file->vol;
  unsigned long clumpsz;
  ExtDescriptor blocks;

  clumpsz = file->cat.u.fil.filClpSize;
  if (clumpsz == 0)
    {
      if (file == &vol->ext.f)
	clumpsz = vol->mdb.drXTClpSiz;
      else if (file == &vol->cat.f)
	clumpsz = vol->mdb.drCTClpSiz;
      else
	clumpsz = vol->mdb.drClpSiz;
    }

  blocks.xdrNumABlks = clumpsz / vol->mdb.drAlBlkSiz;

  if (v_allocblocks(vol, &blocks) == -1)
    goto fail;

  if (f_addextent(file, &blocks) == -1)
    {
      v_freeblocks(vol, &blocks);
      goto fail;
    }

  return blocks.xdrNumABlks;

fail:
  return -1;
}
Exemplo n.º 2
0
/*
 * NAME:	file->alloc()
 * DESCRIPTION:	reserve disk blocks for a file
 */
int f_alloc(hfsfile *file)
{
  hfsvol *vol = file->vol;
  ExtDescriptor blocks;
  ExtDataRec *extrec;
  unsigned long *pylen, clumpsz;
  unsigned int start, end;
  node n;
  int i;

  clumpsz = file->clump;
  if (clumpsz == 0)
    clumpsz = vol->mdb.drClpSiz;

  blocks.xdrNumABlks = clumpsz / vol->mdb.drAlBlkSiz;

  if (v_allocblocks(vol, &blocks) < 0)
    return -1;

  /* update the file's extents */

  f_getptrs(file, 0, &pylen, &extrec);

  start  = file->fabn;
  end    = *pylen / vol->mdb.drAlBlkSiz;

  n.nnum = 0;
  i      = -1;

  while (start < end)
    {
      for (i = 0; i < 3; ++i)
	{
	  unsigned int num;

	  num    = file->ext[i].xdrNumABlks;
	  start += num;

	  if (start == end)
	    break;
	  else if (start > end)
	    {
	      v_freeblocks(vol, &blocks);
	      ERROR(EIO, "file extents exceed file physical length");
	      return -1;
	    }
	  else if (num == 0)
	    {
	      v_freeblocks(vol, &blocks);
	      ERROR(EIO, "empty file extent");
	      return -1;
	    }
	}

      if (start == end)
	break;

      if (v_extsearch(file, start, &file->ext, &n) <= 0)
	{
	  v_freeblocks(vol, &blocks);
	  return -1;
	}

      file->fabn = start;
    }

  if (i >= 0 &&
      file->ext[i].xdrStABN + file->ext[i].xdrNumABlks == blocks.xdrStABN)
    file->ext[i].xdrNumABlks += blocks.xdrNumABlks;
  else
    {
      /* create a new extent descriptor */

      if (++i < 3)
	file->ext[i] = blocks;
      else
	{
	  ExtKeyRec key;
	  unsigned char record[HFS_EXTRECMAXLEN];
	  int reclen;

	  /* record is full; create a new one */

	  file->ext[0] = blocks;

	  for (i = 1; i < 3; ++i)
	    {
	      file->ext[i].xdrStABN    = 0;
	      file->ext[i].xdrNumABlks = 0;
	    }

	  file->fabn = start;

	  r_makeextkey(&key, file->fork, file->cat.u.fil.filFlNum, end);
	  r_packextkey(&key, record, &reclen);
	  r_packextdata(&file->ext, HFS_RECDATA(record), &reclen);

	  if (bt_insert(&vol->ext, record, reclen) < 0)
	    {
	      v_freeblocks(vol, &blocks);
	      return -1;
	    }

	  i = -1;
	}
    }

  if (i >= 0)
    {
      /* store the modified extent record */

      if (file->fabn)
	{
	  if ((n.nnum == 0 &&
	       v_extsearch(file, file->fabn, 0, &n) <= 0) ||
	      v_putextrec(&file->ext, &n) < 0)
	    {
	      v_freeblocks(vol, &blocks);
	      return -1;
	    }
	}
      else
	memcpy(extrec, file->ext, sizeof(ExtDataRec));
    }

  *pylen += blocks.xdrNumABlks * vol->mdb.drAlBlkSiz;

  file->flags |= HFS_UPDATE_CATREC;

  return blocks.xdrNumABlks;
}