]> git.sur5r.net Git - u-boot/blobdiff - fs/fat/fat_write.c
block: pass block dev not num to read/write/erase()
[u-boot] / fs / fat / fat_write.c
index e08cf83b05352ef5dc1cf57033815cdfdbc1c0d1..5ed324ce1a022241a9a43c1a257f7f6ab11279d3 100644 (file)
@@ -41,8 +41,7 @@ static int disk_write(__u32 block, __u32 nr_blocks, void *buf)
                return -1;
        }
 
-       ret = cur_dev->block_write(cur_dev->dev,
-                                  cur_part_info.start + block,
+       ret = cur_dev->block_write(cur_dev, cur_part_info.start + block,
                                   nr_blocks, buf);
        if (nr_blocks && ret == 0)
                return -1;
@@ -710,6 +709,14 @@ set_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,
 
        debug("%llu bytes\n", filesize);
 
+       if (!curclust) {
+               if (filesize) {
+                       debug("error: nonempty clusterless file!\n");
+                       return -1;
+               }
+               return 0;
+       }
+
        actsize = bytesperclust;
        endclust = curclust;
        do {
@@ -721,7 +728,7 @@ set_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,
                                goto getit;
 
                        if (CHECK_CLUST(newclust, mydata->fatsize)) {
-                               debug("curclust: 0x%x\n", newclust);
+                               debug("newclust: 0x%x\n", newclust);
                                debug("Invalid FAT entry\n");
                                return 0;
                        }
@@ -754,8 +761,8 @@ getit:
                filesize -= actsize;
                buffer += actsize;
 
-               if (CHECK_CLUST(curclust, mydata->fatsize)) {
-                       debug("curclust: 0x%x\n", curclust);
+               if (CHECK_CLUST(newclust, mydata->fatsize)) {
+                       debug("newclust: 0x%x\n", newclust);
                        debug("Invalid FAT entry\n");
                        return 0;
                }
@@ -765,15 +772,24 @@ getit:
 }
 
 /*
- * Fill dir_entry
+ * Set start cluster in directory entry
  */
-static void fill_dentry(fsdata *mydata, dir_entry *dentptr,
-       const char *filename, __u32 start_cluster, __u32 size, __u8 attr)
+static void set_start_cluster(const fsdata *mydata, dir_entry *dentptr,
+                               __u32 start_cluster)
 {
        if (mydata->fatsize == 32)
                dentptr->starthi =
                        cpu_to_le16((start_cluster & 0xffff0000) >> 16);
        dentptr->start = cpu_to_le16(start_cluster & 0xffff);
+}
+
+/*
+ * Fill dir_entry
+ */
+static void fill_dentry(fsdata *mydata, dir_entry *dentptr,
+       const char *filename, __u32 start_cluster, __u32 size, __u8 attr)
+{
+       set_start_cluster(mydata, dentptr, start_cluster);
        dentptr->size = cpu_to_le32(size);
 
        dentptr->attr = attr;
@@ -1028,91 +1044,89 @@ static int do_fat_write(const char *filename, void *buffer, loff_t size,
        if (retdent) {
                /* Update file size and start_cluster in a directory entry */
                retdent->size = cpu_to_le32(size);
-               start_cluster = FAT2CPU16(retdent->start);
-               if (mydata->fatsize == 32)
-                       start_cluster |=
-                               (FAT2CPU16(retdent->starthi) << 16);
-
-               ret = check_overflow(mydata, start_cluster, size);
-               if (ret) {
-                       printf("Error: %llu overflow\n", size);
-                       goto exit;
-               }
+               start_cluster = START(retdent);
+
+               if (start_cluster) {
+                       if (size) {
+                               ret = check_overflow(mydata, start_cluster,
+                                                       size);
+                               if (ret) {
+                                       printf("Error: %llu overflow\n", size);
+                                       goto exit;
+                               }
+                       }
 
-               ret = clear_fatent(mydata, start_cluster);
-               if (ret) {
-                       printf("Error: clearing FAT entries\n");
-                       goto exit;
-               }
+                       ret = clear_fatent(mydata, start_cluster);
+                       if (ret) {
+                               printf("Error: clearing FAT entries\n");
+                               goto exit;
+                       }
 
-               ret = set_contents(mydata, retdent, buffer, size, actwrite);
-               if (ret < 0) {
-                       printf("Error: writing contents\n");
-                       goto exit;
-               }
-               debug("attempt to write 0x%llx bytes\n", *actwrite);
+                       if (!size)
+                               set_start_cluster(mydata, retdent, 0);
+               } else if (size) {
+                       ret = start_cluster = find_empty_cluster(mydata);
+                       if (ret < 0) {
+                               printf("Error: finding empty cluster\n");
+                               goto exit;
+                       }
 
-               /* Flush fat buffer */
-               ret = flush_fat_buffer(mydata);
-               if (ret) {
-                       printf("Error: flush fat buffer\n");
-                       goto exit;
-               }
+                       ret = check_overflow(mydata, start_cluster, size);
+                       if (ret) {
+                               printf("Error: %llu overflow\n", size);
+                               goto exit;
+                       }
 
-               /* Write directory table to device */
-               ret = set_cluster(mydata, dir_curclust,
-                           get_dentfromdir_block,
-                           mydata->clust_size * mydata->sect_size);
-               if (ret) {
-                       printf("Error: writing directory entry\n");
-                       goto exit;
+                       set_start_cluster(mydata, retdent, start_cluster);
                }
        } else {
                /* Set short name to set alias checksum field in dir_slot */
                set_name(empty_dentptr, filename);
                fill_dir_slot(mydata, &empty_dentptr, filename);
 
-               ret = start_cluster = find_empty_cluster(mydata);
-               if (ret < 0) {
-                       printf("Error: finding empty cluster\n");
-                       goto exit;
-               }
+               if (size) {
+                       ret = start_cluster = find_empty_cluster(mydata);
+                       if (ret < 0) {
+                               printf("Error: finding empty cluster\n");
+                               goto exit;
+                       }
 
-               ret = check_overflow(mydata, start_cluster, size);
-               if (ret) {
-                       printf("Error: %llu overflow\n", size);
-                       goto exit;
+                       ret = check_overflow(mydata, start_cluster, size);
+                       if (ret) {
+                               printf("Error: %llu overflow\n", size);
+                               goto exit;
+                       }
+               } else {
+                       start_cluster = 0;
                }
 
                /* Set attribute as archieve for regular file */
                fill_dentry(mydata, empty_dentptr, filename,
                        start_cluster, size, 0x20);
 
-               ret = set_contents(mydata, empty_dentptr, buffer, size,
-                                  actwrite);
-               if (ret < 0) {
-                       printf("Error: writing contents\n");
-                       goto exit;
-               }
-               debug("attempt to write 0x%llx bytes\n", *actwrite);
+               retdent = empty_dentptr;
+       }
 
-               /* Flush fat buffer */
-               ret = flush_fat_buffer(mydata);
-               if (ret) {
-                       printf("Error: flush fat buffer\n");
-                       goto exit;
-               }
+       ret = set_contents(mydata, retdent, buffer, size, actwrite);
+       if (ret < 0) {
+               printf("Error: writing contents\n");
+               goto exit;
+       }
+       debug("attempt to write 0x%llx bytes\n", *actwrite);
 
-               /* Write directory table to device */
-               ret = set_cluster(mydata, dir_curclust,
-                           get_dentfromdir_block,
-                           mydata->clust_size * mydata->sect_size);
-               if (ret) {
-                       printf("Error: writing directory entry\n");
-                       goto exit;
-               }
+       /* Flush fat buffer */
+       ret = flush_fat_buffer(mydata);
+       if (ret) {
+               printf("Error: flush fat buffer\n");
+               goto exit;
        }
 
+       /* Write directory table to device */
+       ret = set_cluster(mydata, dir_curclust, get_dentfromdir_block,
+                       mydata->clust_size * mydata->sect_size);
+       if (ret)
+               printf("Error: writing directory entry\n");
+
 exit:
        free(mydata->fatbuf);
        return ret;