]> git.sven.stormbind.net Git - sven/exfat-utils.git/blobdiff - mkfs/fat.c
New upstream version 1.2.6
[sven/exfat-utils.git] / mkfs / fat.c
index 7baa57393be0f678df52248835398ed0ef10c210..be3a6c3a325ddf63d53f20123c0b611eeac1e36a 100644 (file)
@@ -2,11 +2,12 @@
        fat.c (09.11.10)
        File Allocation Table creation code.
 
        fat.c (09.11.10)
        File Allocation Table creation code.
 
-       Copyright (C) 2009, 2010  Andrew Nayenko
+       Free exFAT implementation.
+       Copyright (C) 2011-2017  Andrew Nayenko
 
 
-       This program is free software: you can redistribute it and/or modify
+       This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        it under the terms of the GNU General Public License as published by
-       the Free Software Foundation, either version 3 of the License, or
+       the Free Software Foundation, either version 2 of the License, or
        (at your option) any later version.
 
        This program is distributed in the hope that it will be useful,
        (at your option) any later version.
 
        This program is distributed in the hope that it will be useful,
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.
 
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.
 
-       You should have received a copy of the GNU General Public License
-       along with this program.  If not, see <http://www.gnu.org/licenses/>.
+       You should have received a copy of the GNU General Public License along
+       with this program; if not, write to the Free Software Foundation, Inc.,
+       51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
 */
 
-#include <unistd.h>
-#include <inttypes.h>
-#include <errno.h>
-#include "mkexfat.h"
+#include "fat.h"
 #include "cbm.h"
 #include "uct.h"
 #include "rootdir.h"
 #include "cbm.h"
 #include "uct.h"
 #include "rootdir.h"
+#include <unistd.h>
 
 
-off_t fat_alignment(void)
+static off_t fat_alignment(void)
 {
 {
-       return (off_t) le32_to_cpu(sb.fat_sector_start) * SECTOR_SIZE(sb);
+       return (off_t) 128 * get_sector_size();
 }
 
 }
 
-off_t fat_size(void)
+static off_t fat_size(void)
 {
 {
-       return (off_t) le32_to_cpu(sb.fat_sector_count) * SECTOR_SIZE(sb);
+       return get_volume_size() / get_cluster_size() * sizeof(cluster_t);
 }
 
 }
 
-static cluster_t fat_write_entry(cluster_t cluster, cluster_t value, int fd)
+static cluster_t fat_write_entry(struct exfat_dev* dev, cluster_t cluster,
+               cluster_t value)
 {
        le32_t fat_entry = cpu_to_le32(value);
 {
        le32_t fat_entry = cpu_to_le32(value);
-       if (write(fd, &fat_entry, sizeof(fat_entry)) == -1)
+       if (exfat_write(dev, &fat_entry, sizeof(fat_entry)) < 0)
+       {
+               exfat_error("failed to write FAT entry 0x%x", value);
                return 0;
                return 0;
+       }
        return cluster + 1;
 }
 
        return cluster + 1;
 }
 
-static cluster_t fat_write_entries(cluster_t cluster, uint64_t length, int fd)
+static cluster_t fat_write_entries(struct exfat_dev* dev, cluster_t cluster,
+               uint64_t length)
 {
 {
-       cluster_t end = cluster + DIV_ROUND_UP(length, CLUSTER_SIZE(sb));
+       cluster_t end = cluster + DIV_ROUND_UP(length, get_cluster_size());
 
        while (cluster < end - 1)
        {
 
        while (cluster < end - 1)
        {
-               cluster = fat_write_entry(cluster, cluster + 1, fd);
+               cluster = fat_write_entry(dev, cluster, cluster + 1);
                if (cluster == 0)
                        return 0;
        }
                if (cluster == 0)
                        return 0;
        }
-       return fat_write_entry(cluster, EXFAT_CLUSTER_END, fd);
+       return fat_write_entry(dev, cluster, EXFAT_CLUSTER_END);
 }
 
 }
 
-int fat_write(off_t base, int fd)
+static int fat_write(struct exfat_dev* dev)
 {
        cluster_t c = 0;
 
 {
        cluster_t c = 0;
 
-       if (base != le32_to_cpu(sb.fat_sector_start) * SECTOR_SIZE(sb))
-               exfat_bug("unexpected FAT location: %"PRIu64" (expected %u)",
-                               base, le32_to_cpu(sb.fat_sector_start) * SECTOR_SIZE(sb));
-
-       if (!(c = fat_write_entry(c, 0xfffffff8, fd))) /* media type */
-               return errno;
-       if (!(c = fat_write_entry(c, 0xffffffff, fd))) /* some weird constant */
-               return errno;
-       if (!(c = fat_write_entries(c, cbm_size(), fd)))
-               return errno;
-       if (!(c = fat_write_entries(c, uct_size(), fd)))
-               return errno;
-       if (!(c = fat_write_entries(c, rootdir_size(), fd)))
-               return errno;
+       if (!(c = fat_write_entry(dev, c, 0xfffffff8))) /* media type */
+               return 1;
+       if (!(c = fat_write_entry(dev, c, 0xffffffff))) /* some weird constant */
+               return 1;
+       if (!(c = fat_write_entries(dev, c, cbm.get_size())))
+               return 1;
+       if (!(c = fat_write_entries(dev, c, uct.get_size())))
+               return 1;
+       if (!(c = fat_write_entries(dev, c, rootdir.get_size())))
+               return 1;
 
        return 0;
 }
 
        return 0;
 }
+
+const struct fs_object fat =
+{
+       .get_alignment = fat_alignment,
+       .get_size = fat_size,
+       .write = fat_write,
+};