OSDN Git Service

Handle I/O errors in exfat_flush_node().
authorresver@gmail.com <resver@gmail.com@60bc1c72-a15a-11de-b98f-4500b42dc123>
Tue, 6 Aug 2013 20:08:06 +0000 (20:08 +0000)
committerresver@gmail.com <resver@gmail.com@60bc1c72-a15a-11de-b98f-4500b42dc123>
Tue, 6 Aug 2013 20:08:06 +0000 (20:08 +0000)
git-svn-id: http://exfat.googlecode.com/svn/trunk@379 60bc1c72-a15a-11de-b98f-4500b42dc123

fuse/main.c
libexfat/exfat.h
libexfat/node.c

index 4bf553e..333c2c4 100644 (file)
@@ -157,8 +157,12 @@ static int fuse_exfat_release(const char* path, struct fuse_file_info* fi)
 static int fuse_exfat_fsync(const char* path, int datasync,
                struct fuse_file_info *fi)
 {
+       int rc;
+
        exfat_debug("[%s] %s", __func__, path);
-       exfat_flush_node(&ef, get_node(fi));
+       rc = exfat_flush_node(&ef, get_node(fi));
+       if (rc != 0)
+               return rc;
        exfat_flush(&ef);
        return exfat_fsync(ef.dev);
 }
index d0dbeae..5a4cff4 100644 (file)
@@ -196,7 +196,7 @@ struct exfat_node* exfat_get_node(struct exfat_node* node);
 void exfat_put_node(struct exfat* ef, struct exfat_node* node);
 int exfat_cache_directory(struct exfat* ef, struct exfat_node* dir);
 void exfat_reset_cache(struct exfat* ef);
-void exfat_flush_node(struct exfat* ef, struct exfat_node* node);
+int exfat_flush_node(struct exfat* ef, struct exfat_node* node);
 int exfat_unlink(struct exfat* ef, struct exfat_node* node);
 int exfat_rmdir(struct exfat* ef, struct exfat_node* node);
 int exfat_mknod(struct exfat* ef, const char* path);
index 48d8272..0e66fc3 100644 (file)
@@ -53,7 +53,9 @@ void exfat_put_node(struct exfat* ef, struct exfat_node* node)
 
        if (node->references == 0)
        {
-               exfat_flush_node(ef, node);
+               /* FIXME handle I/O error */
+               if (exfat_flush_node(ef, node) != 0)
+                       exfat_bug("node flush failed");
                if (node->flags & EXFAT_ATTRIB_UNLINKED)
                {
                        /* free all clusters and node structure itself */
@@ -549,7 +551,7 @@ static void next_entry(struct exfat* ef, const struct exfat_node* parent,
                *cluster = exfat_next_cluster(ef, parent, *cluster);
 }
 
-void exfat_flush_node(struct exfat* ef, struct exfat_node* node)
+int exfat_flush_node(struct exfat* ef, struct exfat_node* node)
 {
        cluster_t cluster;
        off_t offset;
@@ -558,13 +560,13 @@ void exfat_flush_node(struct exfat* ef, struct exfat_node* node)
        struct exfat_entry_meta2 meta2;
 
        if (!(node->flags & EXFAT_ATTRIB_DIRTY))
-               return; /* no need to flush */
+               return 0; /* no need to flush */
 
        if (ef->ro)
                exfat_bug("unable to flush node to read-only FS");
 
        if (node->parent == NULL)
-               return; /* do not flush unlinked node */
+               return 0; /* do not flush unlinked node */
 
        cluster = node->entry_cluster;
        offset = node->entry_offset;
@@ -572,18 +574,22 @@ void exfat_flush_node(struct exfat* ef, struct exfat_node* node)
        next_entry(ef, node->parent, &cluster, &offset);
        meta2_offset = co2o(ef, cluster, offset);
 
-       /* FIXME handle I/O error */
        if (exfat_pread(ef->dev, &meta1, sizeof(meta1), meta1_offset) < 0)
-               exfat_bug("failed to read meta1 entry on flush");
+       {
+               exfat_error("failed to read meta1 entry on flush");
+               return -EIO;
+       }
        if (meta1.type != EXFAT_ENTRY_FILE)
                exfat_bug("invalid type of meta1: 0x%hhx", meta1.type);
        meta1.attrib = cpu_to_le16(node->flags);
        exfat_unix2exfat(node->mtime, &meta1.mdate, &meta1.mtime, &meta1.mtime_cs);
        exfat_unix2exfat(node->atime, &meta1.adate, &meta1.atime, NULL);
 
-       /* FIXME handle I/O error */
        if (exfat_pread(ef->dev, &meta2, sizeof(meta2), meta2_offset) < 0)
-               exfat_bug("failed to read meta2 entry on flush");
+       {
+               exfat_error("failed to read meta2 entry on flush");
+               return -EIO;
+       }
        if (meta2.type != EXFAT_ENTRY_FILE_INFO)
                exfat_bug("invalid type of meta2: 0x%hhx", meta2.type);
        meta2.size = meta2.real_size = cpu_to_le64(node->size);
@@ -596,14 +602,19 @@ void exfat_flush_node(struct exfat* ef, struct exfat_node* node)
 
        meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
 
-       /* FIXME handle I/O error */
        if (exfat_pwrite(ef->dev, &meta1, sizeof(meta1), meta1_offset) < 0)
-               exfat_bug("failed to write meta1 entry on flush");
-       /* FIXME handle I/O error */
+       {
+               exfat_error("failed to write meta1 entry on flush");
+               return -EIO;
+       }
        if (exfat_pwrite(ef->dev, &meta2, sizeof(meta2), meta2_offset) < 0)
-               exfat_bug("failed to write meta2 entry on flush");
+       {
+               exfat_error("failed to write meta2 entry on flush");
+               return -EIO;
+       }
 
        node->flags &= ~EXFAT_ATTRIB_DIRTY;
+       return 0;
 }
 
 static bool erase_entry(struct exfat* ef, struct exfat_node* node)