Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0931a41e authored by Alex Deymo's avatar Alex Deymo Committed by android-build-merger
Browse files

fat16copy: Fix allocation logic when extending directories. am: a1c97773

am: a507800e

Change-Id: Ida8f372a1656ff0b4059c8b2d5629ea1b479c9fc
parents 3c6bf619 a507800e
Loading
Loading
Loading
Loading
+40 −75
Original line number Original line Diff line number Diff line
@@ -222,11 +222,8 @@ class fat_dir(object):
      data.seek(0, os.SEEK_END)
      data.seek(0, os.SEEK_END)
      size = data.tell()
      size = data.tell()


    chunk = 0
    # Empty files shouldn't have any clusters assigned.

    chunk = self.backing.fs.allocate(size) if size > 0 else 0
    if size > 0:
      chunk = self.backing.fs.allocate(size)

    (shortname, ext) = self.make_short_name(name)
    (shortname, ext) = self.make_short_name(name)
    self.add_dentry(0, shortname, ext, name, chunk, size)
    self.add_dentry(0, shortname, ext, name, chunk, size)


@@ -393,27 +390,22 @@ class dentry(object):
    record_count = len(longname_record_data) + 1
    record_count = len(longname_record_data) + 1


    found_count = 0
    found_count = 0

    while found_count < record_count:
    while True:
      record = f.read(32)
      record = f.read(32)


      if record is None or len(record) != 32:
      if record is None or len(record) != 32:
        break
        # We reached the EOF, so we need to extend the file with a new cluster.
        f.write("\0" * self.fs.bytes_per_cluster)
        f.seek(-self.fs.bytes_per_cluster, os.SEEK_CUR)
        record = f.read(32)


      marker = struct.unpack("B", record[0])[0]
      marker = struct.unpack("B", record[0])[0]


      if marker == DEL_MARKER or marker == 0:
      if marker == DEL_MARKER or marker == 0:
        found_count += 1
        found_count += 1

        if found_count == record_count:
          break
      else:
      else:
        found_count = 0
        found_count = 0


    if found_count != record_count:
      f.write("\0" * self.fs.bytes_per_cluster)
      f.seek(-self.fs.bytes_per_cluster, os.SEEK_CUR)
    else:
    f.seek(-(record_count * 32), os.SEEK_CUR)
    f.seek(-(record_count * 32), os.SEEK_CUR)
    f.write(entry)
    f.write(entry)


@@ -637,7 +629,6 @@ class fat(object):
    Allocate a new cluster chain big enough to hold at least the given amount
    Allocate a new cluster chain big enough to hold at least the given amount
    of bytes.
    of bytes.
    """
    """

    assert amount > 0, "Must allocate a non-zero amount."
    assert amount > 0, "Must allocate a non-zero amount."


    f = self.f
    f = self.f
@@ -702,40 +693,18 @@ class fat(object):
    Given a cluster which is the *last* cluster in a chain, extend it to hold
    Given a cluster which is the *last* cluster in a chain, extend it to hold
    at least `amount` more bytes.
    at least `amount` more bytes.
    """
    """
    return_cluster = None
    if amount == 0:
      return
    f = self.f
    f = self.f

    entry_offset = FAT_TABLE_START + cluster * 2
    position = FAT_TABLE_START + cluster * 2
    f.seek(entry_offset)
    f.seek(position)

    assert read_le_short(f) == 0xFFFF, "Extending from middle of chain"
    assert read_le_short(f) == 0xFFFF, "Extending from middle of chain"
    rewind_short(f)

    while position + 2 < FAT_TABLE_START + self.fat_size and amount > 0:
      skip_short(f)
      got = read_le_short(f)
      rewind_short(f)
      rewind_short(f)


      if got != 0:
    return_cluster = self.allocate(amount)
        break
    f.seek(entry_offset)

    self.write_cluster_entry(return_cluster)
      cluster += 1
      return_cluster = return_cluster or cluster
      position += 2
      self.write_cluster_entry(cluster)
      amount -= self.bytes_per_cluster

    if amount <= 0:
      self.write_cluster_entry(0xFFFF)
    return return_cluster
    return return_cluster


    new_chunk = self.allocate(amount)
    f.seek(FAT_TABLE_START + cluster * 2)
    self.write_cluster_entry(new_chunk)

    return return_cluster or new_chunk

  def write_file(self, head_cluster, start_byte, data):
  def write_file(self, head_cluster, start_byte, data):
    """
    """
    Write to a given FAT file.
    Write to a given FAT file.
@@ -745,35 +714,31 @@ class fat(object):
    data: The data to write.
    data: The data to write.
    """
    """
    f = self.f
    f = self.f

    last_offset = start_byte + len(data)
    while True:
    current_offset = 0
      if start_byte < self.bytes_per_cluster:
    current_cluster = head_cluster
        to_write = data[:self.bytes_per_cluster - start_byte]

        data = data[self.bytes_per_cluster - start_byte:]
    while current_offset < last_offset:

      # Write everything that falls in the cluster starting at current_offset.
        cluster_bytes_from_root = (head_cluster - 2) * \
      data_begin = max(0, current_offset - start_byte)
            self.bytes_per_cluster
      data_end = min(len(data),
        bytes_from_root = cluster_bytes_from_root + start_byte
                     current_offset + self.bytes_per_cluster - start_byte)
        bytes_from_data_start = bytes_from_root + self.root_entries * 32
      if data_end > data_begin:

        cluster_file_offset = (self.data_start() + self.root_entries * 32 +
        f.seek(self.data_start() + bytes_from_data_start)
                               (current_cluster - 2) * self.bytes_per_cluster)
        f.write(to_write)
        f.seek(cluster_file_offset + max(0, start_byte - current_offset))

        f.write(data[data_begin:data_end])
        if len(data) == 0:

          return
      # Advance to the next cluster in the chain or get a new cluster if needed.

      current_offset += self.bytes_per_cluster
      start_byte -= self.bytes_per_cluster
      if last_offset > current_offset:

        f.seek(FAT_TABLE_START + current_cluster * 2)
      if start_byte < 0:
        start_byte = 0

      f.seek(FAT_TABLE_START + head_cluster * 2)
        next_cluster = read_le_short(f)
        next_cluster = read_le_short(f)
        if next_cluster > MAX_CLUSTER_ID:
        if next_cluster > MAX_CLUSTER_ID:
        head_cluster = self.extend_cluster(head_cluster, len(data))
          next_cluster = self.extend_cluster(current_cluster, len(data))
      else:
        current_cluster = next_cluster
        head_cluster = next_cluster
        assert current_cluster > 0, "Cannot write free cluster"
      assert head_cluster > 0, "Cannot write free cluster"



def add_item(directory, item):
def add_item(directory, item):
  """
  """