OSDN Git Service

Handle I/O error in exfat_next_cluster().
[android-x86/external-exfat.git] / libexfat / node.c
index fea371b..3d27ad5 100644 (file)
@@ -544,13 +544,21 @@ void exfat_reset_cache(struct exfat* ef)
        reset_cache(ef, ef->root);
 }
 
-static void next_entry(struct exfat* ef, const struct exfat_node* parent,
+static bool next_entry(struct exfat* ef, const struct exfat_node* parent,
                cluster_t* cluster, off_t* offset)
 {
        *offset += sizeof(struct exfat_entry);
        if (*offset % CLUSTER_SIZE(*ef->sb) == 0)
-               /* next cluster cannot be invalid */
+       {
                *cluster = exfat_next_cluster(ef, parent, *cluster);
+               if (CLUSTER_INVALID(*cluster))
+               {
+                       exfat_error("invalid cluster %#x while getting next entry",
+                                       *cluster);
+                       return false;
+               }
+       }
+       return true;
 }
 
 int exfat_flush_node(struct exfat* ef, struct exfat_node* node)
@@ -573,7 +581,8 @@ int exfat_flush_node(struct exfat* ef, struct exfat_node* node)
        cluster = node->entry_cluster;
        offset = node->entry_offset;
        meta1_offset = co2o(ef, cluster, offset);
-       next_entry(ef, node->parent, &cluster, &offset);
+       if (!next_entry(ef, node->parent, &cluster, &offset))
+               return -EIO;
        meta2_offset = co2o(ef, cluster, offset);
 
        if (exfat_pread(ef->dev, &meta1, sizeof(meta1), meta1_offset) < 0)
@@ -633,7 +642,8 @@ static bool erase_entry(struct exfat* ef, struct exfat_node* node)
                return false;
        }
 
-       next_entry(ef, node->parent, &cluster, &offset);
+       if (!next_entry(ef, node->parent, &cluster, &offset))
+               return false;
        entry_type = EXFAT_ENTRY_FILE_INFO & ~EXFAT_ENTRY_VALID;
        if (exfat_pwrite(ef->dev, &entry_type, 1, co2o(ef, cluster, offset)) < 0)
        {
@@ -643,7 +653,8 @@ static bool erase_entry(struct exfat* ef, struct exfat_node* node)
 
        while (name_entries--)
        {
-               next_entry(ef, node->parent, &cluster, &offset);
+               if (!next_entry(ef, node->parent, &cluster, &offset))
+                       return false;
                entry_type = EXFAT_ENTRY_FILE_NAME & ~EXFAT_ENTRY_VALID;
                if (exfat_pwrite(ef->dev, &entry_type, 1,
                                co2o(ef, cluster, offset)) < 0)
@@ -838,7 +849,8 @@ static int write_entry(struct exfat* ef, struct exfat_node* dir,
                exfat_error("failed to write meta1 entry");
                return -EIO;
        }
-       next_entry(ef, dir, &cluster, &offset);
+       if (!next_entry(ef, dir, &cluster, &offset))
+               return -EIO;
        if (exfat_pwrite(ef->dev, &meta2, sizeof(meta2),
                        co2o(ef, cluster, offset)) < 0)
        {
@@ -851,7 +863,8 @@ static int write_entry(struct exfat* ef, struct exfat_node* dir,
                memcpy(name_entry.name, node->name + i * EXFAT_ENAME_MAX,
                                MIN(EXFAT_ENAME_MAX, EXFAT_NAME_MAX - i * EXFAT_ENAME_MAX) *
                                sizeof(le16_t));
-               next_entry(ef, dir, &cluster, &offset);
+               if (!next_entry(ef, dir, &cluster, &offset))
+                       return -EIO;
                if (exfat_pwrite(ef->dev, &name_entry, sizeof(name_entry),
                                co2o(ef, cluster, offset)) < 0)
                {
@@ -945,7 +958,8 @@ static int rename_entry(struct exfat* ef, struct exfat_node* dir,
                exfat_error("failed to read meta1 entry on rename");
                return -EIO;
        }
-       next_entry(ef, node->parent, &old_cluster, &old_offset);
+       if (!next_entry(ef, node->parent, &old_cluster, &old_offset))
+               return -EIO;
        if (exfat_pread(ef->dev, &meta2, sizeof(meta2),
                        co2o(ef, old_cluster, old_offset)) < 0)
        {
@@ -969,7 +983,8 @@ static int rename_entry(struct exfat* ef, struct exfat_node* dir,
                exfat_error("failed to write meta1 entry on rename");
                return -EIO;
        }
-       next_entry(ef, dir, &new_cluster, &new_offset);
+       if (!next_entry(ef, dir, &new_cluster, &new_offset))
+               return -EIO;
        if (exfat_pwrite(ef->dev, &meta2, sizeof(meta2),
                        co2o(ef, new_cluster, new_offset)) < 0)
        {
@@ -982,7 +997,8 @@ static int rename_entry(struct exfat* ef, struct exfat_node* dir,
                struct exfat_entry_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
                memcpy(name_entry.name, name + i * EXFAT_ENAME_MAX,
                                EXFAT_ENAME_MAX * sizeof(le16_t));
-               next_entry(ef, dir, &new_cluster, &new_offset);
+               if (!next_entry(ef, dir, &new_cluster, &new_offset))
+                       return -EIO;
                if (exfat_pwrite(ef->dev, &name_entry, sizeof(name_entry),
                                co2o(ef, new_cluster, new_offset)) < 0)
                {